Skip to content

Commit e2d516f

Browse files
authored
Merge pull request #71328 from augusto2112/instance-start-typeref
Implement ReflectionContext::readInstanceStartFromTypeRef
2 parents 558c91b + 18a80f8 commit e2d516f

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+
computeUnalignedFieldStartOffset(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+
computeUnalignedFieldStartOffset(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)