Skip to content

Commit 7d7dc5a

Browse files
committed
Demangler: Use a bump-pointer allocator for node allocation.
This makes the demangler about 10 times faster. It also changes the lifetimes of nodes. Previously nodes were reference-counted. Now the returned demangle node-tree is owned by the Demangler class and it’s lifetime ends with the lifetime of the Demangler. Therefore the old (and already deprecated) global functions demangleSymbolAsNode and demangleTypeAsNode are no longer available. Another change is that the demangling for reflection now only supports the new mangling (which should be no problem because we are generating only new mangled names for reflection).
1 parent d64f763 commit 7d7dc5a

File tree

24 files changed

+1178
-972
lines changed

24 files changed

+1178
-972
lines changed

include/swift/Basic/Demangle.h

Lines changed: 33 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct DemangleOptions {
7575
};
7676

7777
class Node;
78-
typedef std::shared_ptr<Node> NodePointer;
78+
typedef Node *NodePointer;
7979

8080
enum class FunctionSigSpecializationParamKind : unsigned {
8181
// Option Flags use bits 0-5. This give us 6 bits implying 64 entries to
@@ -123,11 +123,10 @@ enum class Directness {
123123
Direct, Indirect
124124
};
125125

126-
struct NodeFactory;
126+
class NodeFactory;
127127
class Context;
128128

129-
130-
class Node : public std::enable_shared_from_this<Node> {
129+
class Node {
131130
public:
132131
enum class Kind : uint16_t {
133132
#define NODE(ID) ID,
@@ -136,6 +135,8 @@ class Node : public std::enable_shared_from_this<Node> {
136135

137136
typedef uint64_t IndexType;
138137

138+
friend class NodeFactory;
139+
139140
private:
140141
Kind NodeKind;
141142

@@ -145,20 +146,20 @@ class Node : public std::enable_shared_from_this<Node> {
145146
PayloadKind NodePayloadKind;
146147

147148
union {
148-
std::string TextPayload;
149+
llvm::StringRef TextPayload;
149150
IndexType IndexPayload;
150151
};
151152

152-
// FIXME: use allocator.
153-
typedef std::vector<NodePointer> NodeVector;
154-
NodeVector Children;
153+
NodePointer *Children = nullptr;
154+
size_t NumChildren = 0;
155+
size_t ReservedChildren = 0;
155156

156157
Node(Kind k)
157158
: NodeKind(k), NodePayloadKind(PayloadKind::None) {
158159
}
159-
Node(Kind k, std::string &&t)
160+
Node(Kind k, llvm::StringRef t)
160161
: NodeKind(k), NodePayloadKind(PayloadKind::Text) {
161-
new (&TextPayload) std::string(std::move(t));
162+
TextPayload = t;
162163
}
163164
Node(Kind k, IndexType index)
164165
: NodeKind(k), NodePayloadKind(PayloadKind::Index) {
@@ -167,15 +168,11 @@ class Node : public std::enable_shared_from_this<Node> {
167168
Node(const Node &) = delete;
168169
Node &operator=(const Node &) = delete;
169170

170-
friend struct NodeFactory;
171-
172171
public:
173-
~Node();
174-
175172
Kind getKind() const { return NodeKind; }
176173

177174
bool hasText() const { return NodePayloadKind == PayloadKind::Text; }
178-
const std::string &getText() const {
175+
llvm::StringRef getText() const {
179176
assert(hasText());
180177
return TextPayload;
181178
}
@@ -186,37 +183,29 @@ class Node : public std::enable_shared_from_this<Node> {
186183
return IndexPayload;
187184
}
188185

189-
typedef NodeVector::iterator iterator;
190-
typedef NodeVector::const_iterator const_iterator;
191-
typedef NodeVector::size_type size_type;
192-
193-
bool hasChildren() const { return !Children.empty(); }
194-
size_t getNumChildren() const { return Children.size(); }
195-
iterator begin() { return Children.begin(); }
196-
iterator end() { return Children.end(); }
197-
const_iterator begin() const { return Children.begin(); }
198-
const_iterator end() const { return Children.end(); }
199-
200-
NodePointer getFirstChild() const { return Children.front(); }
201-
NodePointer getChild(size_t index) const { return Children[index]; }
202-
203-
/// Deprecated - use addChild(NodePointer Child, Context &Ctx) instead.
204-
NodePointer addChild(NodePointer child) {
205-
assert(child && "adding null child!");
206-
Children.push_back(child);
207-
return child;
186+
typedef NodePointer *iterator;
187+
typedef const NodePointer *const_iterator;
188+
typedef size_t size_type;
189+
190+
bool hasChildren() const { return NumChildren != 0; }
191+
size_t getNumChildren() const { return NumChildren; }
192+
iterator begin() { return Children; }
193+
iterator end() { return Children + NumChildren; }
194+
const_iterator begin() const { return Children; }
195+
const_iterator end() const { return Children + NumChildren; }
196+
197+
NodePointer getFirstChild() const {
198+
assert(NumChildren >= 1);
199+
return Children[0];
208200
}
209-
210-
/// Deprecated - use addChild(NodePointer Child, Context &Ctx) instead.
211-
void addChildren(NodePointer child1, NodePointer child2) {
212-
addChild(std::move(child1));
213-
addChild(std::move(child2));
201+
NodePointer getChild(size_t index) const {
202+
assert(NumChildren > index);
203+
return Children[index];
214204
}
215205

216-
/// Add a new node as a child of this one.
217206
void addChild(NodePointer Child, Context &Ctx);
218207

219-
/// Add a new node as a child of this one.
208+
// Only to be used by the demangler parsers.
220209
void addChild(NodePointer Child, NodeFactory &Factory);
221210
};
222211

@@ -245,6 +234,8 @@ class Demangler;
245234
/// allocations.
246235
///
247236
class Context {
237+
Demangler *D;
238+
248239
friend class Node;
249240

250241
public:
@@ -360,33 +351,6 @@ demangleSymbolAsString(llvm::StringRef MangledName,
360351
MangledName.size(), Options);
361352
}
362353

363-
/// Deprecated - use Context::demangleTypeAsNode instead.
364-
NodePointer
365-
demangleTypeAsNode(const char *mangledName, size_t mangledNameLength,
366-
const DemangleOptions &options = DemangleOptions());
367-
368-
/// Deprecated - use Context::demangleTypeAsNode instead.
369-
inline NodePointer
370-
demangleTypeAsNode(const std::string &mangledName,
371-
const DemangleOptions &options = DemangleOptions()) {
372-
return demangleTypeAsNode(mangledName.data(), mangledName.size(), options);
373-
}
374-
375-
/// Deprecated - use Context::isThunkSymbol instead.
376-
bool isThunkSymbol(const char *mangledName, size_t mangledNameLength);
377-
378-
/// Deprecated - use Context::demangleSymbolAsNode instead.
379-
NodePointer
380-
demangleSymbolAsNode(const char *mangledName, size_t mangledNameLength,
381-
const DemangleOptions &options = DemangleOptions());
382-
383-
/// Deprecated - use Context::demangleSymbolAsNode instead.
384-
inline NodePointer
385-
demangleSymbolAsNode(const std::string &mangledName,
386-
const DemangleOptions &options = DemangleOptions()) {
387-
return demangleSymbolAsNode(mangledName.data(), mangledName.size(), options);
388-
}
389-
390354
/// Standalong utility function to demangle the given type as string.
391355
///
392356
/// If performance is an issue when demangling multiple symbols,
@@ -465,26 +429,6 @@ inline std::string mangleNode(const NodePointer &root, bool NewMangling) {
465429
std::string nodeToString(NodePointer Root,
466430
const DemangleOptions &Options = DemangleOptions());
467431

468-
/// Deprecated - use Context::createNode instead.
469-
struct NodeFactory {
470-
static NodePointer create(Node::Kind K) {
471-
return NodePointer(new Node(K));
472-
}
473-
static NodePointer create(Node::Kind K, Node::IndexType Index) {
474-
return NodePointer(new Node(K, Index));
475-
}
476-
static NodePointer create(Node::Kind K, llvm::StringRef Text) {
477-
return NodePointer(new Node(K, Text));
478-
}
479-
static NodePointer create(Node::Kind K, std::string &&Text) {
480-
return NodePointer(new Node(K, std::move(Text)));
481-
}
482-
template <size_t N>
483-
static NodePointer create(Node::Kind K, const char (&Text)[N]) {
484-
return NodePointer(new Node(K, llvm::StringRef(Text)));
485-
}
486-
};
487-
488432
/// A class for printing to a std::string.
489433
class DemanglerPrinter {
490434
public:
@@ -532,7 +476,7 @@ class DemanglerPrinter {
532476

533477
bool mangleStandardSubstitution(Node *node, DemanglerPrinter &Out);
534478
bool isSpecialized(Node *node);
535-
NodePointer getUnspecialized(Node *node);
479+
NodePointer getUnspecialized(Node *node, NodeFactory &Factory);
536480

537481
/// Is a character considered a digit by the demangling grammar?
538482
///

include/swift/Basic/DemangleWrappers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class NodeDumper {
3434
NodePointer Root;
3535

3636
public:
37-
NodeDumper(NodePointer Root): Root(std::move(Root)) {}
37+
NodeDumper(NodePointer Root): Root(Root) {}
3838
void dump() const;
3939
void print(llvm::raw_ostream &Out) const;
4040
};

0 commit comments

Comments
 (0)