@@ -211,20 +211,29 @@ namespace {
211
211
212
212
struct NominalTypeDescriptorCacheEntry {
213
213
private:
214
- std::string Name;
214
+ const char *Name;
215
+ size_t NameLength;
215
216
const ContextDescriptor *Description;
216
217
217
218
public:
218
219
NominalTypeDescriptorCacheEntry (const llvm::StringRef name,
219
220
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; }
221
229
222
- const ContextDescriptor * getDescription ( ) {
223
- return Description ;
230
+ bool matchesKey (llvm::StringRef aName ) {
231
+ return aName == llvm::StringRef{Name, NameLength} ;
224
232
}
225
233
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 });
228
237
}
229
238
230
239
template <class ... T>
@@ -235,7 +244,7 @@ namespace {
235
244
} // end anonymous namespace
236
245
237
246
struct TypeMetadataPrivateState {
238
- ConcurrentMap <NominalTypeDescriptorCacheEntry> NominalCache;
247
+ ConcurrentReadableHashMap <NominalTypeDescriptorCacheEntry> NominalCache;
239
248
ConcurrentReadableArray<TypeMetadataSection> SectionsToScan;
240
249
241
250
TypeMetadataPrivateState () {
@@ -713,8 +722,11 @@ _findContextDescriptor(Demangle::NodePointer node,
713
722
714
723
// Look for an existing entry.
715
724
// 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
+ }
718
730
719
731
// Check type metadata records
720
732
// Scan any newly loaded images for context descriptors, then try the context
@@ -726,7 +738,13 @@ _findContextDescriptor(Demangle::NodePointer node,
726
738
foundContext = _searchConformancesByMangledTypeName (node);
727
739
728
740
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
+ });
730
748
731
749
return foundContext;
732
750
}
@@ -746,18 +764,29 @@ namespace {
746
764
747
765
struct ProtocolDescriptorCacheEntry {
748
766
private:
749
- std::string Name;
767
+ const char *Name;
768
+ size_t NameLength;
750
769
const ProtocolDescriptor *Description;
751
770
752
771
public:
753
772
ProtocolDescriptorCacheEntry (const llvm::StringRef name,
754
773
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
+ }
756
780
757
- const ProtocolDescriptor *getDescription () { return Description; }
781
+ const ProtocolDescriptor *getDescription () const { return Description; }
758
782
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 });
761
790
}
762
791
763
792
template <class ... T>
@@ -767,7 +796,7 @@ namespace {
767
796
};
768
797
769
798
struct ProtocolMetadataPrivateState {
770
- ConcurrentMap <ProtocolDescriptorCacheEntry> ProtocolCache;
799
+ ConcurrentReadableHashMap <ProtocolDescriptorCacheEntry> ProtocolCache;
771
800
ConcurrentReadableArray<ProtocolSection> SectionsToScan;
772
801
773
802
ProtocolMetadataPrivateState () {
@@ -849,14 +878,23 @@ _findProtocolDescriptor(NodePointer node,
849
878
850
879
// Look for an existing entry.
851
880
// 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
+ }
854
886
855
887
// Check type metadata records
856
888
foundProtocol = _searchProtocolRecords (T, node);
857
889
858
890
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
+ });
860
898
}
861
899
862
900
return foundProtocol;
0 commit comments