@@ -211,20 +211,29 @@ namespace {
211211
212212 struct NominalTypeDescriptorCacheEntry {
213213 private:
214- std::string Name;
214+ const char *Name;
215+ size_t NameLength;
215216 const ContextDescriptor *Description;
216217
217218 public:
218219 NominalTypeDescriptorCacheEntry (const llvm::StringRef name,
219220 const ContextDescriptor *description)
220- : Name(name.str()), Description(description) {}
221+ : Description(description) {
222+ char *nameCopy = reinterpret_cast <char *>(malloc (name.size ()));
223+ memcpy (nameCopy, name.data (), name.size ());
224+ Name = nameCopy;
225+ NameLength = name.size ();
226+ }
227+
228+ const ContextDescriptor *getDescription () const { return Description; }
221229
222- const ContextDescriptor * getDescription ( ) {
223- return Description ;
230+ bool matchesKey (llvm::StringRef aName ) {
231+ return aName == llvm::StringRef{Name, NameLength} ;
224232 }
225233
226- int compareWithKey (llvm::StringRef aName) const {
227- return aName.compare (Name);
234+ friend llvm::hash_code
235+ hash_value (const NominalTypeDescriptorCacheEntry &value) {
236+ return hash_value (llvm::StringRef{value.Name , value.NameLength });
228237 }
229238
230239 template <class ... T>
@@ -235,7 +244,7 @@ namespace {
235244} // end anonymous namespace
236245
237246struct TypeMetadataPrivateState {
238- ConcurrentMap <NominalTypeDescriptorCacheEntry> NominalCache;
247+ ConcurrentReadableHashMap <NominalTypeDescriptorCacheEntry> NominalCache;
239248 ConcurrentReadableArray<TypeMetadataSection> SectionsToScan;
240249
241250 TypeMetadataPrivateState () {
@@ -713,8 +722,11 @@ _findContextDescriptor(Demangle::NodePointer node,
713722
714723 // Look for an existing entry.
715724 // Find the bucket for the metadata entry.
716- if (auto Value = T.NominalCache .find (mangledName))
717- return Value->getDescription ();
725+ {
726+ auto snapshot = T.NominalCache .snapshot ();
727+ if (auto Value = snapshot.find (mangledName))
728+ return Value->getDescription ();
729+ }
718730
719731 // Check type metadata records
720732 // Scan any newly loaded images for context descriptors, then try the context
@@ -726,7 +738,13 @@ _findContextDescriptor(Demangle::NodePointer node,
726738 foundContext = _searchConformancesByMangledTypeName (node);
727739
728740 if (foundContext)
729- T.NominalCache .getOrInsert (mangledName, foundContext);
741+ T.NominalCache .getOrInsert (mangledName, [&](NominalTypeDescriptorCacheEntry
742+ *entry,
743+ bool created) {
744+ if (created)
745+ new (entry) NominalTypeDescriptorCacheEntry{mangledName, foundContext};
746+ return true ;
747+ });
730748
731749 return foundContext;
732750}
@@ -746,18 +764,29 @@ namespace {
746764
747765 struct ProtocolDescriptorCacheEntry {
748766 private:
749- std::string Name;
767+ const char *Name;
768+ size_t NameLength;
750769 const ProtocolDescriptor *Description;
751770
752771 public:
753772 ProtocolDescriptorCacheEntry (const llvm::StringRef name,
754773 const ProtocolDescriptor *description)
755- : Name(name.str()), Description(description) {}
774+ : Description(description) {
775+ char *nameCopy = reinterpret_cast <char *>(malloc (name.size ()));
776+ memcpy (nameCopy, name.data (), name.size ());
777+ Name = nameCopy;
778+ NameLength = name.size ();
779+ }
756780
757- const ProtocolDescriptor *getDescription () { return Description; }
781+ const ProtocolDescriptor *getDescription () const { return Description; }
758782
759- int compareWithKey (llvm::StringRef aName) const {
760- return aName.compare (Name);
783+ bool matchesKey (llvm::StringRef aName) {
784+ return aName == llvm::StringRef{Name, NameLength};
785+ }
786+
787+ friend llvm::hash_code
788+ hash_value (const ProtocolDescriptorCacheEntry &value) {
789+ return hash_value (llvm::StringRef{value.Name , value.NameLength });
761790 }
762791
763792 template <class ... T>
@@ -767,7 +796,7 @@ namespace {
767796 };
768797
769798 struct ProtocolMetadataPrivateState {
770- ConcurrentMap <ProtocolDescriptorCacheEntry> ProtocolCache;
799+ ConcurrentReadableHashMap <ProtocolDescriptorCacheEntry> ProtocolCache;
771800 ConcurrentReadableArray<ProtocolSection> SectionsToScan;
772801
773802 ProtocolMetadataPrivateState () {
@@ -849,14 +878,23 @@ _findProtocolDescriptor(NodePointer node,
849878
850879 // Look for an existing entry.
851880 // Find the bucket for the metadata entry.
852- if (auto Value = T.ProtocolCache .find (mangledName))
853- return Value->getDescription ();
881+ {
882+ auto snapshot = T.ProtocolCache .snapshot ();
883+ if (auto Value = snapshot.find (mangledName))
884+ return Value->getDescription ();
885+ }
854886
855887 // Check type metadata records
856888 foundProtocol = _searchProtocolRecords (T, node);
857889
858890 if (foundProtocol) {
859- T.ProtocolCache .getOrInsert (mangledName, foundProtocol);
891+ T.ProtocolCache .getOrInsert (mangledName, [&](ProtocolDescriptorCacheEntry
892+ *entry,
893+ bool created) {
894+ if (created)
895+ new (entry) ProtocolDescriptorCacheEntry{mangledName, foundProtocol};
896+ return true ;
897+ });
860898 }
861899
862900 return foundProtocol;
0 commit comments