3939#include < vector>
4040#include < list>
4141#include < new>
42+ #include < cstring>
4243
4344using namespace swift ;
4445using 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+
475486bool
476487swift::_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