Skip to content

Commit c6abbfa

Browse files
committed
Remangler: don't construct a std::string for hashing and comparing identifiers
This avoids memory allocations.
1 parent 3c73685 commit c6abbfa

File tree

2 files changed

+46
-28
lines changed

2 files changed

+46
-28
lines changed

lib/Demangling/Remangler.cpp

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,62 @@ static void unreachable(const char *Message) {
3838
std::abort();
3939
}
4040

41+
static char getCharOfNodeText(Node *node, unsigned idx) {
42+
switch (node->getKind()) {
43+
case Node::Kind::InfixOperator:
44+
case Node::Kind::PrefixOperator:
45+
case Node::Kind::PostfixOperator:
46+
return Mangle::translateOperatorChar(node->getText()[idx]);
47+
default:
48+
return node->getText()[idx];
49+
}
50+
}
51+
52+
bool SubstitutionEntry::identifierEquals(Node *lhs, Node *rhs) {
53+
unsigned length = lhs->getText().size();
54+
if (rhs->getText().size() != length)
55+
return false;
56+
// The fast path.
57+
if (lhs->getKind() == rhs->getKind())
58+
return lhs->getText() == rhs->getText();
59+
// The slow path.
60+
for (unsigned i = 0; i < length; ++i) {
61+
if (getCharOfNodeText(lhs, i) != getCharOfNodeText(rhs, i))
62+
return false;
63+
}
64+
return true;
65+
}
66+
4167
void SubstitutionEntry::deepHash(Node *node) {
4268
if (treatAsIdentifier) {
4369
combineHash((size_t) Node::Kind::Identifier);
44-
std::string tmp;
45-
combineHash(getTextForSubstitution(node, tmp));
46-
return;
70+
assert(node->hasText());
71+
switch (node->getKind()) {
72+
case Node::Kind::InfixOperator:
73+
case Node::Kind::PrefixOperator:
74+
case Node::Kind::PostfixOperator:
75+
for (char c : node->getText()) {
76+
combineHash((unsigned char)translateOperatorChar(c));
77+
}
78+
return;
79+
default:
80+
break;
81+
}
82+
} else {
83+
combineHash((size_t) node->getKind());
4784
}
48-
combineHash((size_t) node->getKind());
4985
if (node->hasIndex()) {
5086
combineHash(node->getIndex());
5187
} else if (node->hasText()) {
52-
combineHash(node->getText());
88+
for (char c : node->getText()) {
89+
combineHash((unsigned char) c);
90+
}
5391
}
5492
for (Node *child : *node) {
5593
deepHash(child);
5694
}
5795
}
5896

59-
StringRef SubstitutionEntry::getTextForSubstitution(Node *node, std::string &tmp) {
60-
switch (node->getKind()) {
61-
case Node::Kind::InfixOperator:
62-
case Node::Kind::PrefixOperator:
63-
case Node::Kind::PostfixOperator:
64-
tmp = Mangle::translateOperator(node->getText());
65-
return tmp;
66-
default:
67-
return node->getText();
68-
}
69-
}
70-
7197
bool SubstitutionEntry::deepEquals(Node *lhs, Node *rhs) const {
7298
if (lhs->getKind() != rhs->getKind())
7399
return false;

lib/Demangling/RemanglerBase.h

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,19 @@ class SubstitutionEntry {
5353
if (lhs.treatAsIdentifier != rhs.treatAsIdentifier)
5454
return false;
5555
if (lhs.treatAsIdentifier) {
56-
std::string tmp1, tmp2;
57-
return (getTextForSubstitution(lhs.TheNode, tmp1) ==
58-
getTextForSubstitution(rhs.TheNode, tmp2));
56+
return identifierEquals(lhs.TheNode, rhs.TheNode);
5957
}
6058
return lhs.deepEquals(lhs.TheNode, rhs.TheNode);
6159
}
6260

61+
static bool identifierEquals(Node *lhs, Node *rhs);
62+
6363
void combineHash(size_t newValue) {
6464
StoredHash = 33 * StoredHash + newValue;
6565
}
6666

67-
void combineHash(StringRef Text) {
68-
for (char c : Text) {
69-
combineHash((unsigned char) c);
70-
}
71-
}
72-
7367
void deepHash(Node *node);
7468

75-
static StringRef getTextForSubstitution(Node *node, std::string &tmp);
76-
7769
bool deepEquals(Node *lhs, Node *rhs) const;
7870
};
7971

0 commit comments

Comments
 (0)