Skip to content

Commit ea0f2c4

Browse files
committed
Implement readSizeOfFieldsNotBelongingToInstanceFromTypeRef
Implement readSizeOfFieldsNotBelongingToInstanceFromTypeRef as an alternative way to finding out the end of the fields that belong to the instance when reading the field's start from binary is not possible (for example, embedded Swift doesn't emit any reflection metadata on the binary).
1 parent 7b6f45c commit ea0f2c4

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

include/swift/Remote/MetadataReader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ class MetadataReader {
617617

618618
/// Given a remote pointer to class metadata, attempt to discover its class
619619
/// instance size and whether fields should use the resilient layout strategy.
620-
llvm::Optional<unsigned> readInstanceStartAndAlignmentFromClassMetadata(
620+
llvm::Optional<unsigned> readInstanceStartFromClassMetadata(
621621
StoredPointer MetadataAddress) {
622622
auto meta = readMetadata(MetadataAddress);
623623
if (!meta || meta->getKind() != MetadataKind::Class)

include/swift/RemoteInspection/ReflectionContext.h

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,7 @@ class ReflectionContext
908908
// Figure out where the stored properties of this class begin
909909
// by looking at the size of the superclass
910910
auto start =
911-
this->readInstanceStartAndAlignmentFromClassMetadata(MetadataAddress);
911+
this->readInstanceStartFromClassMetadata(MetadataAddress);
912912

913913
// Perform layout
914914
if (start)
@@ -1202,8 +1202,42 @@ class ReflectionContext
12021202
}
12031203
}
12041204

1205-
const RecordTypeInfo *getRecordTypeInfo(const TypeRef *TR,
1206-
remote::TypeInfoProvider *ExternalTypeInfo) {
1205+
/// Given a typeref, attempt to calculate where the fields that don't belong
1206+
/// to this instance ends. For example, for a superclass, the size of it's non
1207+
/// instance fields would be one word for the isa pointer plus one word for
1208+
/// the refcount field. For a subclass the size would be the superclass's size
1209+
/// (including fields). Note that this is not the same as the start of the
1210+
/// subclass's fields, as this value does not account for padding. Check
1211+
/// MetadataReader::readInstanceStartFromClassMetadata for similar
1212+
/// functionality.
1213+
llvm::Optional<unsigned>
1214+
readSizeOfFieldsNotBelongingToInstanceFromTypeRef(const TypeRef *TR) {
1215+
size_t isaAndRetainCountSize = sizeof(StoredSize) + sizeof(long long);
1216+
1217+
const TypeRef *superclass = getBuilder().lookupSuperclass(TR);
1218+
if (!superclass)
1219+
// If there is no superclass the stat of the instance's field is right
1220+
// after the isa and retain fields.
1221+
return isaAndRetainCountSize;
1222+
1223+
auto superclassStart =
1224+
readSizeOfFieldsNotBelongingToInstanceFromTypeRef(superclass);
1225+
if (!superclassStart)
1226+
return llvm::None;
1227+
1228+
auto *superTI = getBuilder().getTypeConverter().getClassInstanceTypeInfo(
1229+
superclass, *superclassStart, nullptr);
1230+
if (!superTI)
1231+
return llvm::None;
1232+
1233+
// The start of the subclass's fields is right after the super class's ones.
1234+
size_t start = superTI->getSize();
1235+
return start;
1236+
}
1237+
1238+
const RecordTypeInfo *
1239+
getRecordTypeInfo(const TypeRef *TR,
1240+
remote::TypeInfoProvider *ExternalTypeInfo) {
12071241
auto *TypeInfo = getTypeInfo(TR, ExternalTypeInfo);
12081242
return dyn_cast_or_null<const RecordTypeInfo>(TypeInfo);
12091243
}

0 commit comments

Comments
 (0)