@@ -69,31 +69,81 @@ class NodeFactory {
6969 }
7070
7171 static void freeSlabs (Slab *slab);
72-
72+
73+ // / If not null, the NodeFactory from which this factory borrowed free memory.
74+ NodeFactory *BorrowedFrom = nullptr ;
75+
76+ // / True if some other NodeFactory borrowed free memory from this factory.
77+ bool isBorrowed = false ;
78+
79+ #ifdef NODE_FACTORY_DEBUGGING
80+ size_t allocatedMemory = 0 ;
81+ static int nestingLevel;
82+ std::string indent () { return std::string (nestingLevel * 2 , ' ' ); }
83+ #endif
84+
7385public:
7486
7587 NodeFactory () {
7688#ifdef NODE_FACTORY_DEBUGGING
77- std::cerr << " ## New NodeFactory " << this << " \n " ;
89+ std::cerr << indent () << " ## New NodeFactory\n " ;
90+ nestingLevel++;
7891#endif
7992 }
80-
93+
94+ // / Provide pre-allocated memory, e.g. memory on the stack.
95+ // /
96+ // / Only if this memory overflows, the factory begins to malloc.
97+ void providePreallocatedMemory (char *Memory, size_t Size) {
98+ #ifdef NODE_FACTORY_DEBUGGING
99+ std::cerr << indent () << " ++ provide preallocated memory, size = "
100+ << Size << ' \n ' ;
101+ #endif
102+ assert (!CurPtr && !End && !CurrentSlab);
103+ CurPtr = Memory;
104+ End = CurPtr + Size;
105+ }
106+
107+ // / Borrow free memory from another factory \p BorrowFrom.
108+ // /
109+ // / While this factory is alive, no allocations can be done in the
110+ // / \p BorrowFrom factory.
111+ void providePreallocatedMemory (NodeFactory &BorrowFrom) {
112+ assert (!CurPtr && !End && !CurrentSlab);
113+ assert (!BorrowFrom.isBorrowed && !BorrowedFrom);
114+ BorrowFrom.isBorrowed = true ;
115+ BorrowedFrom = &BorrowFrom;
116+ CurPtr = BorrowFrom.CurPtr ;
117+ End = BorrowFrom.End ;
118+ #ifdef NODE_FACTORY_DEBUGGING
119+ std::cerr << indent () << " ++ borrow memory, size = "
120+ << (End - CurPtr) << ' \n ' ;
121+ #endif
122+ }
123+
81124 virtual ~NodeFactory () {
82125 freeSlabs (CurrentSlab);
83126#ifdef NODE_FACTORY_DEBUGGING
84- std::cerr << " Delete NodeFactory " << this << " \n " ;
127+ nestingLevel--;
128+ std::cerr << indent () << " ## Delete NodeFactory: allocated memory = "
129+ << allocatedMemory << ' \n ' ;
85130#endif
131+ if (BorrowedFrom) {
132+ BorrowedFrom->isBorrowed = false ;
133+ }
86134 }
87135
88136 virtual void clear ();
89137
90138 // / Allocates an object of type T or an array of objects of type T.
91139 template <typename T> T *Allocate (size_t NumObjects = 1 ) {
140+ assert (!isBorrowed);
92141 size_t ObjectSize = NumObjects * sizeof (T);
93142 CurPtr = align (CurPtr, alignof (T));
94143#ifdef NODE_FACTORY_DEBUGGING
95- std::cerr << " alloc " << ObjectSize << " , CurPtr = "
144+ std::cerr << indent () << " alloc " << ObjectSize << " , CurPtr = "
96145 << (void *)CurPtr << " \n " ;
146+ allocatedMemory += ObjectSize;
97147#endif
98148
99149 // Do we have enough space in the current slab?
@@ -113,7 +163,7 @@ class NodeFactory {
113163 End = (char *)newSlab + AllocSize;
114164 assert (CurPtr + ObjectSize <= End);
115165#ifdef NODE_FACTORY_DEBUGGING
116- std::cerr << " ** new slab " << newSlab << " , allocsize = "
166+ std::cerr << indent () << " ** new slab " << newSlab << " , allocsize = "
117167 << AllocSize << " , CurPtr = " << (void *)CurPtr
118168 << " , End = " << (void *)End << " \n " ;
119169#endif
@@ -132,14 +182,15 @@ class NodeFactory {
132182 // / new memory address.
133183 // / The \p Capacity is enlarged at least by \p MinGrowth, but can also be
134184 // / enlarged by a bigger value.
135- template <typename T> void Reallocate (T *&Objects, size_t &Capacity,
185+ template <typename T> void Reallocate (T *&Objects, uint32_t &Capacity,
136186 size_t MinGrowth) {
187+ assert (!isBorrowed);
137188 size_t OldAllocSize = Capacity * sizeof (T);
138189 size_t AdditionalAlloc = MinGrowth * sizeof (T);
139190
140191#ifdef NODE_FACTORY_DEBUGGING
141- std::cerr << " realloc " << Objects << " , num = " << NumObjects
142- << " (size = " << OldAllocSize << " ), Growth = " << Growth
192+ std::cerr << indent () << " realloc: capacity = " << Capacity
193+ << " (size = " << OldAllocSize << " ), growth = " << MinGrowth
143194 << " (size = " << AdditionalAlloc << " )\n " ;
144195#endif
145196 if ((char *)Objects + OldAllocSize == CurPtr
@@ -149,7 +200,8 @@ class NodeFactory {
149200 CurPtr += AdditionalAlloc;
150201 Capacity += MinGrowth;
151202#ifdef NODE_FACTORY_DEBUGGING
152- std::cerr << " ** can grow: CurPtr = " << (void *)CurPtr << " \n " ;
203+ std::cerr << indent () << " ** can grow: " << (void *)CurPtr << ' \n ' ;
204+ allocatedMemory += AdditionalAlloc;
153205#endif
154206 return ;
155207 }
@@ -203,8 +255,8 @@ template<typename T> class Vector {
203255
204256protected:
205257 T *Elems = nullptr ;
206- size_t NumElems = 0 ;
207- size_t Capacity = 0 ;
258+ uint32_t NumElems = 0 ;
259+ uint32_t Capacity = 0 ;
208260
209261public:
210262 using iterator = T *;
@@ -469,7 +521,7 @@ class Demangler : public NodeFactory {
469521 NodePointer demangleThunkOrSpecialization ();
470522 NodePointer demangleGenericSpecialization (Node::Kind SpecKind);
471523 NodePointer demangleFunctionSpecialization ();
472- NodePointer demangleFuncSpecParam (Node::IndexType ParamIdx );
524+ NodePointer demangleFuncSpecParam (Node::Kind Kind );
473525 NodePointer addFuncSpecParamNumber (NodePointer Param,
474526 FunctionSigSpecializationParamKind Kind);
475527
@@ -536,7 +588,19 @@ class Demangler : public NodeFactory {
536588 // / Demangler or with a call of clear().
537589 NodePointer demangleType (StringRef MangledName);
538590};
539-
591+
592+ // / A demangler which uses stack space for its initial memory.
593+ // /
594+ // / The \p Size paramter specifies the size of the stack space.
595+ template <size_t Size> class StackAllocatedDemangler : public Demangler {
596+ char StackSpace[Size];
597+
598+ public:
599+ StackAllocatedDemangler () {
600+ providePreallocatedMemory (StackSpace, Size);
601+ }
602+ };
603+
540604NodePointer demangleOldSymbolAsNode (StringRef MangledName,
541605 NodeFactory &Factory);
542606} // end namespace Demangle
0 commit comments