@@ -193,8 +193,18 @@ class MetadataReader {
193
193
// / amounts of data when we encounter corrupt values for sizes/counts.
194
194
static const uint64_t MaxMetadataSize = 1048576 ; // 1MB
195
195
196
- // / A cache of built types, keyed by the address of the type.
197
- std::unordered_map<StoredPointer, BuiltType> TypeCache;
196
+ // / Define a has function for a std::pair<StoredPointer, bool>
197
+ struct TypeCacheKeyHash {
198
+ std::size_t operator ()(const std::pair<StoredPointer, bool > &x) const {
199
+ return std::hash<StoredPointer>()(x.first ) ^ std::hash<bool >()(x.second );
200
+ }
201
+ };
202
+
203
+ // / A cache of built types, keyed by the address of the type and whether the
204
+ // / request ignored articial superclasses or not.
205
+ std::unordered_map<std::pair<StoredPointer, bool >, BuiltType,
206
+ TypeCacheKeyHash>
207
+ TypeCache;
198
208
199
209
using MetadataRef = RemoteRef<const TargetMetadata<Runtime>>;
200
210
using OwnedMetadataRef = MemoryReader::ReadBytesResult;
@@ -821,7 +831,9 @@ class MetadataReader {
821
831
readTypeFromMetadata (StoredPointer MetadataAddress,
822
832
bool skipArtificialSubclasses = false ,
823
833
int recursion_limit = defaultTypeRecursionLimit) {
824
- auto Cached = TypeCache.find (MetadataAddress);
834
+ std::pair<StoredPointer, bool > TypeCacheKey (MetadataAddress,
835
+ skipArtificialSubclasses);
836
+ auto Cached = TypeCache.find (TypeCacheKey);
825
837
if (Cached != TypeCache.end ())
826
838
return Cached->second ;
827
839
@@ -841,7 +853,7 @@ class MetadataReader {
841
853
// Insert a negative result into the cache now so that, if we recur with
842
854
// the same address, we will return the negative result with the check
843
855
// just above.
844
- TypeCache.insert ({MetadataAddress , BuiltType ()});
856
+ TypeCache.insert ({TypeCacheKey , BuiltType ()});
845
857
846
858
auto Meta = readMetadata (MetadataAddress);
847
859
if (!Meta) return BuiltType ();
@@ -890,7 +902,7 @@ class MetadataReader {
890
902
891
903
auto BuiltTuple =
892
904
Builder.createTupleType (elementTypes, labels);
893
- TypeCache[MetadataAddress ] = BuiltTuple;
905
+ TypeCache[TypeCacheKey ] = BuiltTuple;
894
906
return BuiltTuple;
895
907
}
896
908
case MetadataKind::Function: {
@@ -947,7 +959,7 @@ class MetadataReader {
947
959
948
960
auto BuiltFunction = Builder.createFunctionType (
949
961
Parameters, Result, flags, diffKind, globalActor);
950
- TypeCache[MetadataAddress ] = BuiltFunction;
962
+ TypeCache[TypeCacheKey ] = BuiltFunction;
951
963
return BuiltFunction;
952
964
}
953
965
case MetadataKind::Existential: {
@@ -998,7 +1010,7 @@ class MetadataReader {
998
1010
}
999
1011
auto BuiltExist = Builder.createProtocolCompositionType (
1000
1012
Protocols, SuperclassType, HasExplicitAnyObject);
1001
- TypeCache[MetadataAddress ] = BuiltExist;
1013
+ TypeCache[TypeCacheKey ] = BuiltExist;
1002
1014
return BuiltExist;
1003
1015
}
1004
1016
case MetadataKind::ExtendedExistential: {
@@ -1076,7 +1088,7 @@ class MetadataReader {
1076
1088
}
1077
1089
}
1078
1090
1079
- TypeCache[MetadataAddress ] = builtProto;
1091
+ TypeCache[TypeCacheKey ] = builtProto;
1080
1092
return builtProto;
1081
1093
}
1082
1094
@@ -1086,7 +1098,7 @@ class MetadataReader {
1086
1098
readTypeFromMetadata (Metatype->InstanceType , false , recursion_limit);
1087
1099
if (!Instance) return BuiltType ();
1088
1100
auto BuiltMetatype = Builder.createMetatypeType (Instance);
1089
- TypeCache[MetadataAddress ] = BuiltMetatype;
1101
+ TypeCache[TypeCacheKey ] = BuiltMetatype;
1090
1102
return BuiltMetatype;
1091
1103
}
1092
1104
case MetadataKind::ObjCClassWrapper: {
@@ -1098,7 +1110,7 @@ class MetadataReader {
1098
1110
return BuiltType ();
1099
1111
1100
1112
auto BuiltObjCClass = Builder.createObjCClassType (std::move (className));
1101
- TypeCache[MetadataAddress ] = BuiltObjCClass;
1113
+ TypeCache[TypeCacheKey ] = BuiltObjCClass;
1102
1114
return BuiltObjCClass;
1103
1115
}
1104
1116
case MetadataKind::ExistentialMetatype: {
@@ -1107,7 +1119,7 @@ class MetadataReader {
1107
1119
readTypeFromMetadata (Exist->InstanceType , false , recursion_limit);
1108
1120
if (!Instance) return BuiltType ();
1109
1121
auto BuiltExist = Builder.createExistentialMetatypeType (Instance);
1110
- TypeCache[MetadataAddress ] = BuiltExist;
1122
+ TypeCache[TypeCacheKey ] = BuiltExist;
1111
1123
return BuiltExist;
1112
1124
}
1113
1125
case MetadataKind::ForeignReferenceType:
@@ -1131,7 +1143,7 @@ class MetadataReader {
1131
1143
auto name = mangling.result ();
1132
1144
1133
1145
auto BuiltForeign = Builder.createForeignClassType (std::move (name));
1134
- TypeCache[MetadataAddress ] = BuiltForeign;
1146
+ TypeCache[TypeCacheKey ] = BuiltForeign;
1135
1147
return BuiltForeign;
1136
1148
}
1137
1149
case MetadataKind::HeapLocalVariable:
@@ -1142,7 +1154,7 @@ class MetadataReader {
1142
1154
case MetadataKind::Opaque:
1143
1155
default : {
1144
1156
auto BuiltOpaque = Builder.getOpaqueType ();
1145
- TypeCache[MetadataAddress ] = BuiltOpaque;
1157
+ TypeCache[TypeCacheKey ] = BuiltOpaque;
1146
1158
return BuiltOpaque;
1147
1159
}
1148
1160
}
@@ -3084,9 +3096,12 @@ class MetadataReader {
3084
3096
// If we've skipped an artificial subclasses, check the cache at
3085
3097
// the superclass. (This also protects against recursion.)
3086
3098
if (skipArtificialSubclasses && metadata != origMetadata) {
3087
- auto it = TypeCache.find (getAddress (metadata));
3088
- if (it != TypeCache.end ())
3099
+ auto it =
3100
+ TypeCache.find ({getAddress (metadata), skipArtificialSubclasses});
3101
+ if (it != TypeCache.end ()) {
3102
+ TypeCache.erase ({getAddress (origMetadata), skipArtificialSubclasses});
3089
3103
return it->second ;
3104
+ }
3090
3105
}
3091
3106
3092
3107
// Read the nominal type descriptor.
@@ -3115,12 +3130,12 @@ class MetadataReader {
3115
3130
if (!nominal)
3116
3131
return BuiltType ();
3117
3132
3118
- TypeCache[getAddress (metadata)] = nominal;
3133
+ TypeCache[{ getAddress (metadata), skipArtificialSubclasses} ] = nominal;
3119
3134
3120
3135
// If we've skipped an artificial subclass, remove the
3121
3136
// recursion-protection entry we made for it.
3122
3137
if (skipArtificialSubclasses && metadata != origMetadata) {
3123
- TypeCache.erase (getAddress (origMetadata));
3138
+ TypeCache.erase ({ getAddress (origMetadata), skipArtificialSubclasses} );
3124
3139
}
3125
3140
3126
3141
return nominal;
@@ -3151,7 +3166,7 @@ class MetadataReader {
3151
3166
skipArtificialSubclasses, recursion_limit);
3152
3167
}
3153
3168
3154
- TypeCache[origMetadataPtr] = BuiltObjCClass;
3169
+ TypeCache[{ origMetadataPtr, skipArtificialSubclasses} ] = BuiltObjCClass;
3155
3170
return BuiltObjCClass;
3156
3171
}
3157
3172
0 commit comments