Skip to content

Commit 2afb9b7

Browse files
authored
Merge pull request #42390 from ladd/stringRefEqualsCString
Dynamic type lookup string compare optimization
2 parents 3306c63 + f4d0c3c commit 2afb9b7

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <vector>
4040
#include <list>
4141
#include <new>
42+
#include <cstring>
4243

4344
using namespace swift;
4445
using namespace Demangle;
@@ -472,6 +473,16 @@ static bool sameObjCTypeManglings(Demangle::NodePointer node1,
472473
}
473474
#endif
474475

476+
/// Optimization for the case where we need to compare a StringRef and a null terminated C string
477+
/// Not converting s2 to a StringRef avoids the need to call both strlen and memcmp when non-matching
478+
/// but equal length
479+
static bool stringRefEqualsCString(StringRef s1, const char *s2) {
480+
size_t length = s1.size();
481+
// It may be possible for s1 to contain embedded NULL characters
482+
// so additionally validate that the lengths match
483+
return strncmp(s1.data(), s2, length) == 0 && strlen(s2) == length;
484+
}
485+
475486
bool
476487
swift::_contextDescriptorMatchesMangling(const ContextDescriptor *context,
477488
Demangle::NodePointer node) {
@@ -496,7 +507,7 @@ swift::_contextDescriptorMatchesMangling(const ContextDescriptor *context,
496507
// Match to a mangled module name.
497508
if (node->getKind() != Demangle::Node::Kind::Module)
498509
return false;
499-
if (!node->getText().equals(module->Name.get()))
510+
if (!stringRefEqualsCString(node->getText(), module->Name.get()))
500511
return false;
501512

502513
node = nullptr;
@@ -568,7 +579,7 @@ swift::_contextDescriptorMatchesMangling(const ContextDescriptor *context,
568579
auto nameNode = node->getChild(1);
569580
if (nameNode->getKind() != Demangle::Node::Kind::Identifier)
570581
return false;
571-
if (nameNode->getText() == proto->Name.get()) {
582+
if (stringRefEqualsCString(nameNode->getText(), proto->Name.get())) {
572583
node = node->getChild(0);
573584
break;
574585
}

0 commit comments

Comments
 (0)