@@ -194,6 +194,10 @@ class MetadataReader {
194194 RemoteRef<const TargetContextDescriptor<Runtime>>;
195195 using OwnedContextDescriptorRef = MemoryReader::ReadBytesResult;
196196
197+ using ShapeRef =
198+ RemoteRef<const TargetExtendedExistentialTypeShape<Runtime>>;
199+ using OwnedShapeRef = MemoryReader::ReadBytesResult;
200+
197201 // / A reference to a context descriptor that may be in an unloaded image.
198202 class ParentContextDescriptorRef {
199203 bool IsResolved;
@@ -263,13 +267,18 @@ class MetadataReader {
263267 return !isResolved () || getResolved ();
264268 }
265269 };
270+
266271 // / A cache of read nominal type descriptors, keyed by the address of the
267272 // / nominal type descriptor.
268273 std::unordered_map<StoredPointer, OwnedContextDescriptorRef>
269274 ContextDescriptorCache;
270275
271276 using OwnedProtocolDescriptorRef =
272277 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;
273282
274283 enum class IsaEncodingKind {
275284 // / We haven't checked yet.
@@ -1011,7 +1020,62 @@ class MetadataReader {
10111020 return ParentContextDescriptorRef (
10121021 readContextDescriptor (address.getResolvedAddress ().getAddressData ()));
10131022 }
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+
10151079 // / Given the address of a context descriptor, attempt to read it.
10161080 ContextDescriptorRef
10171081 readContextDescriptor (StoredPointer address) {
0 commit comments