Skip to content

Commit 98849e9

Browse files
committed
Implement readUnalignedFieldStartOffsetFromTypeRef
Implement readUnalignedFieldStartOffsetFromTypeRef as an alternative way to finding out the start 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 98849e9

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-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: 36 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,41 @@ class ReflectionContext
12021202
}
12031203
}
12041204

1205-
const RecordTypeInfo *getRecordTypeInfo(const TypeRef *TR,
1206-
remote::TypeInfoProvider *ExternalTypeInfo) {
1205+
/// Given a typeref, attempt to calculate the unaligned start of this
1206+
/// instance's fields. For example, for a type without a superclass, the start
1207+
/// of the instance fields would after the word for the isa pointer and the
1208+
/// word for the refcount field. For a subclass the start would be the after
1209+
/// the superclass's fields. For a version of this function that performs the
1210+
/// same job but starting out with an instance pointer check
1211+
/// MetadataReader::readInstanceStartFromClassMetadata.
1212+
llvm::Optional<unsigned>
1213+
readUnalignedFieldStartOffsetFromTypeRef(const TypeRef *TR) {
1214+
size_t isaAndRetainCountSize = sizeof(StoredSize) + sizeof(long long);
1215+
1216+
const TypeRef *superclass = getBuilder().lookupSuperclass(TR);
1217+
if (!superclass)
1218+
// If there is no superclass the stat of the instance's field is right
1219+
// after the isa and retain fields.
1220+
return isaAndRetainCountSize;
1221+
1222+
auto superclassStart =
1223+
readUnalignedFieldStartOffsetFromTypeRef(superclass);
1224+
if (!superclassStart)
1225+
return llvm::None;
1226+
1227+
auto *superTI = getBuilder().getTypeConverter().getClassInstanceTypeInfo(
1228+
superclass, *superclassStart, nullptr);
1229+
if (!superTI)
1230+
return llvm::None;
1231+
1232+
// The start of the subclass's fields is right after the super class's ones.
1233+
size_t start = superTI->getSize();
1234+
return start;
1235+
}
1236+
1237+
const RecordTypeInfo *
1238+
getRecordTypeInfo(const TypeRef *TR,
1239+
remote::TypeInfoProvider *ExternalTypeInfo) {
12071240
auto *TypeInfo = getTypeInfo(TR, ExternalTypeInfo);
12081241
return dyn_cast_or_null<const RecordTypeInfo>(TypeInfo);
12091242
}

0 commit comments

Comments
 (0)