@@ -194,6 +194,10 @@ class MetadataReader {
194
194
RemoteRef<const TargetContextDescriptor<Runtime>>;
195
195
using OwnedContextDescriptorRef = MemoryReader::ReadBytesResult;
196
196
197
+ using ShapeRef =
198
+ RemoteRef<const TargetExtendedExistentialTypeShape<Runtime>>;
199
+ using OwnedShapeRef = MemoryReader::ReadBytesResult;
200
+
197
201
// / A reference to a context descriptor that may be in an unloaded image.
198
202
class ParentContextDescriptorRef {
199
203
bool IsResolved;
@@ -263,13 +267,18 @@ class MetadataReader {
263
267
return !isResolved () || getResolved ();
264
268
}
265
269
};
270
+
266
271
// / A cache of read nominal type descriptors, keyed by the address of the
267
272
// / nominal type descriptor.
268
273
std::unordered_map<StoredPointer, OwnedContextDescriptorRef>
269
274
ContextDescriptorCache;
270
275
271
276
using OwnedProtocolDescriptorRef =
272
277
std::unique_ptr<const TargetProtocolDescriptor<Runtime>, delete_with_free>;
278
+ // / A cache of read extended existential shape metadata, keyed by the
279
+ // / address of the shape metadata.
280
+ std::unordered_map<StoredPointer, OwnedShapeRef>
281
+ ShapeCache;
273
282
274
283
enum class IsaEncodingKind {
275
284
// / We haven't checked yet.
@@ -1011,7 +1020,62 @@ class MetadataReader {
1011
1020
return ParentContextDescriptorRef (
1012
1021
readContextDescriptor (address.getResolvedAddress ().getAddressData ()));
1013
1022
}
1014
-
1023
+
1024
+ ShapeRef
1025
+ readShape (StoredPointer address) {
1026
+ if (address == 0 )
1027
+ return nullptr ;
1028
+
1029
+ auto cached = ShapeCache.find (address);
1030
+ if (cached != ShapeCache.end ())
1031
+ return ShapeRef (address,
1032
+ reinterpret_cast <const TargetExtendedExistentialTypeShape<Runtime> *>(
1033
+ cached->second .get ()));
1034
+
1035
+ ExtendedExistentialTypeShapeFlags flags;
1036
+ if (!Reader->readBytes (RemoteAddress (address), (uint8_t *)&flags,
1037
+ sizeof (flags)))
1038
+ return nullptr ;
1039
+
1040
+ // Read the size of the requirement signature.
1041
+ uint64_t reqSigGenericSize = 0 ;
1042
+ uint64_t genericHeaderSize = sizeof (GenericContextDescriptorHeader);
1043
+ {
1044
+ GenericContextDescriptorHeader header;
1045
+ auto headerAddr = address + sizeof (flags);
1046
+
1047
+ if (!Reader->readBytes (RemoteAddress (headerAddr),
1048
+ (uint8_t *)&header, sizeof (header)))
1049
+ return nullptr ;
1050
+
1051
+ reqSigGenericSize = reqSigGenericSize
1052
+ + (header.NumParams + 3u & ~3u )
1053
+ + header.NumRequirements
1054
+ * sizeof (TargetGenericRequirementDescriptor<Runtime>);
1055
+ }
1056
+ uint64_t typeExprSize = flags.hasTypeExpression () ? sizeof (StoredPointer) : 0 ;
1057
+ uint64_t suggestedVWSize = flags.hasSuggestedValueWitnesses () ? sizeof (StoredPointer) : 0 ;
1058
+
1059
+ uint64_t size = sizeof (ExtendedExistentialTypeShapeFlags) +
1060
+ sizeof (TargetRelativeDirectPointer<Runtime, const char ,
1061
+ /* nullable*/ false >) +
1062
+ genericHeaderSize + typeExprSize + suggestedVWSize +
1063
+ reqSigGenericSize;
1064
+ if (size > MaxMetadataSize)
1065
+ return nullptr ;
1066
+ auto readResult = Reader->readBytes (RemoteAddress (address), size);
1067
+ if (!readResult)
1068
+ return nullptr ;
1069
+
1070
+ auto descriptor =
1071
+ reinterpret_cast <const TargetExtendedExistentialTypeShape<Runtime> *>(
1072
+ readResult.get ());
1073
+
1074
+ ShapeCache.insert (
1075
+ std::make_pair (address, std::move (readResult)));
1076
+ return ShapeRef (address, descriptor);
1077
+ }
1078
+
1015
1079
// / Given the address of a context descriptor, attempt to read it.
1016
1080
ContextDescriptorRef
1017
1081
readContextDescriptor (StoredPointer address) {
0 commit comments