1717#ifndef SWIFT_REMOTE_METADATAREADER_H
1818#define SWIFT_REMOTE_METADATAREADER_H
1919
20+ #include " llvm/ADT/Hashing.h"
21+
2022#include " swift/Runtime/Metadata.h"
2123#include " swift/Remote/MemoryReader.h"
2224#include " swift/Demangling/Demangler.h"
@@ -193,8 +195,18 @@ class MetadataReader {
193195 // / amounts of data when we encounter corrupt values for sizes/counts.
194196 static const uint64_t MaxMetadataSize = 1048576 ; // 1MB
195197
196- // / A cache of built types, keyed by the address of the type.
197- std::unordered_map<StoredPointer, BuiltType> TypeCache;
198+ // / Define a has function for a std::pair<StoredPointer, bool>
199+ struct TypeCacheKeyHash {
200+ std::size_t operator ()(const std::pair<StoredPointer, bool > &x) const {
201+ return llvm::hash_combine (x.first , x.second );
202+ }
203+ };
204+
205+ // / A cache of built types, keyed by the address of the type and whether the
206+ // / request ignored articial superclasses or not.
207+ std::unordered_map<std::pair<StoredPointer, bool >, BuiltType,
208+ TypeCacheKeyHash>
209+ TypeCache;
198210
199211 using MetadataRef = RemoteRef<const TargetMetadata<Runtime>>;
200212 using OwnedMetadataRef = MemoryReader::ReadBytesResult;
@@ -821,7 +833,9 @@ class MetadataReader {
821833 readTypeFromMetadata (StoredPointer MetadataAddress,
822834 bool skipArtificialSubclasses = false ,
823835 int recursion_limit = defaultTypeRecursionLimit) {
824- auto Cached = TypeCache.find (MetadataAddress);
836+ std::pair<StoredPointer, bool > TypeCacheKey (MetadataAddress,
837+ skipArtificialSubclasses);
838+ auto Cached = TypeCache.find (TypeCacheKey);
825839 if (Cached != TypeCache.end ())
826840 return Cached->second ;
827841
@@ -841,7 +855,7 @@ class MetadataReader {
841855 // Insert a negative result into the cache now so that, if we recur with
842856 // the same address, we will return the negative result with the check
843857 // just above.
844- TypeCache.insert ({MetadataAddress , BuiltType ()});
858+ TypeCache.insert ({TypeCacheKey , BuiltType ()});
845859
846860 auto Meta = readMetadata (MetadataAddress);
847861 if (!Meta) return BuiltType ();
@@ -890,7 +904,7 @@ class MetadataReader {
890904
891905 auto BuiltTuple =
892906 Builder.createTupleType (elementTypes, labels);
893- TypeCache[MetadataAddress ] = BuiltTuple;
907+ TypeCache[TypeCacheKey ] = BuiltTuple;
894908 return BuiltTuple;
895909 }
896910 case MetadataKind::Function: {
@@ -947,7 +961,7 @@ class MetadataReader {
947961
948962 auto BuiltFunction = Builder.createFunctionType (
949963 Parameters, Result, flags, diffKind, globalActor);
950- TypeCache[MetadataAddress ] = BuiltFunction;
964+ TypeCache[TypeCacheKey ] = BuiltFunction;
951965 return BuiltFunction;
952966 }
953967 case MetadataKind::Existential: {
@@ -998,7 +1012,7 @@ class MetadataReader {
9981012 }
9991013 auto BuiltExist = Builder.createProtocolCompositionType (
10001014 Protocols, SuperclassType, HasExplicitAnyObject);
1001- TypeCache[MetadataAddress ] = BuiltExist;
1015+ TypeCache[TypeCacheKey ] = BuiltExist;
10021016 return BuiltExist;
10031017 }
10041018 case MetadataKind::ExtendedExistential: {
@@ -1076,7 +1090,7 @@ class MetadataReader {
10761090 }
10771091 }
10781092
1079- TypeCache[MetadataAddress ] = builtProto;
1093+ TypeCache[TypeCacheKey ] = builtProto;
10801094 return builtProto;
10811095 }
10821096
@@ -1086,7 +1100,7 @@ class MetadataReader {
10861100 readTypeFromMetadata (Metatype->InstanceType , false , recursion_limit);
10871101 if (!Instance) return BuiltType ();
10881102 auto BuiltMetatype = Builder.createMetatypeType (Instance);
1089- TypeCache[MetadataAddress ] = BuiltMetatype;
1103+ TypeCache[TypeCacheKey ] = BuiltMetatype;
10901104 return BuiltMetatype;
10911105 }
10921106 case MetadataKind::ObjCClassWrapper: {
@@ -1098,7 +1112,7 @@ class MetadataReader {
10981112 return BuiltType ();
10991113
11001114 auto BuiltObjCClass = Builder.createObjCClassType (std::move (className));
1101- TypeCache[MetadataAddress ] = BuiltObjCClass;
1115+ TypeCache[TypeCacheKey ] = BuiltObjCClass;
11021116 return BuiltObjCClass;
11031117 }
11041118 case MetadataKind::ExistentialMetatype: {
@@ -1107,7 +1121,7 @@ class MetadataReader {
11071121 readTypeFromMetadata (Exist->InstanceType , false , recursion_limit);
11081122 if (!Instance) return BuiltType ();
11091123 auto BuiltExist = Builder.createExistentialMetatypeType (Instance);
1110- TypeCache[MetadataAddress ] = BuiltExist;
1124+ TypeCache[TypeCacheKey ] = BuiltExist;
11111125 return BuiltExist;
11121126 }
11131127 case MetadataKind::ForeignReferenceType:
@@ -1131,7 +1145,7 @@ class MetadataReader {
11311145 auto name = mangling.result ();
11321146
11331147 auto BuiltForeign = Builder.createForeignClassType (std::move (name));
1134- TypeCache[MetadataAddress ] = BuiltForeign;
1148+ TypeCache[TypeCacheKey ] = BuiltForeign;
11351149 return BuiltForeign;
11361150 }
11371151 case MetadataKind::HeapLocalVariable:
@@ -1142,7 +1156,7 @@ class MetadataReader {
11421156 case MetadataKind::Opaque:
11431157 default : {
11441158 auto BuiltOpaque = Builder.getOpaqueType ();
1145- TypeCache[MetadataAddress ] = BuiltOpaque;
1159+ TypeCache[TypeCacheKey ] = BuiltOpaque;
11461160 return BuiltOpaque;
11471161 }
11481162 }
@@ -3084,9 +3098,12 @@ class MetadataReader {
30843098 // If we've skipped an artificial subclasses, check the cache at
30853099 // the superclass. (This also protects against recursion.)
30863100 if (skipArtificialSubclasses && metadata != origMetadata) {
3087- auto it = TypeCache.find (getAddress (metadata));
3088- if (it != TypeCache.end ())
3101+ auto it =
3102+ TypeCache.find ({getAddress (metadata), skipArtificialSubclasses});
3103+ if (it != TypeCache.end ()) {
3104+ TypeCache.erase ({getAddress (origMetadata), skipArtificialSubclasses});
30893105 return it->second ;
3106+ }
30903107 }
30913108
30923109 // Read the nominal type descriptor.
@@ -3115,12 +3132,12 @@ class MetadataReader {
31153132 if (!nominal)
31163133 return BuiltType ();
31173134
3118- TypeCache[getAddress (metadata)] = nominal;
3135+ TypeCache[{ getAddress (metadata), skipArtificialSubclasses} ] = nominal;
31193136
31203137 // If we've skipped an artificial subclass, remove the
31213138 // recursion-protection entry we made for it.
31223139 if (skipArtificialSubclasses && metadata != origMetadata) {
3123- TypeCache.erase (getAddress (origMetadata));
3140+ TypeCache.erase ({ getAddress (origMetadata), skipArtificialSubclasses} );
31243141 }
31253142
31263143 return nominal;
@@ -3151,7 +3168,7 @@ class MetadataReader {
31513168 skipArtificialSubclasses, recursion_limit);
31523169 }
31533170
3154- TypeCache[origMetadataPtr] = BuiltObjCClass;
3171+ TypeCache[{ origMetadataPtr, skipArtificialSubclasses} ] = BuiltObjCClass;
31553172 return BuiltObjCClass;
31563173 }
31573174
0 commit comments