Skip to content

Commit fe6e280

Browse files
committed
Add a Utility to Read Extended Existential Type Shapes
1 parent f76f1a7 commit fe6e280

File tree

1 file changed

+65
-1
lines changed

1 file changed

+65
-1
lines changed

include/swift/Remote/MetadataReader.h

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)