Skip to content

Commit 6e0d1d3

Browse files
authored
Merge pull request #19719 from DougGregor/superclass-mangled-name
[ABI] Use mangled superclass names from class context descriptors.
2 parents 4ba96f2 + 4c21623 commit 6e0d1d3

15 files changed

+173
-193
lines changed

include/swift/ABI/Metadata.h

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3617,12 +3617,24 @@ struct TargetStoredClassMetadataBounds {
36173617
using StoredClassMetadataBounds =
36183618
TargetStoredClassMetadataBounds<InProcess>;
36193619

3620+
template <typename Runtime>
3621+
struct TargetResilientSuperclass {
3622+
/// The superclass of this class. This pointer can be interpreted
3623+
/// using the superclass reference kind stored in the type context
3624+
/// descriptor flags. It is null if the class has no formal superclass.
3625+
///
3626+
/// Note that SwiftObject, the implicit superclass of all Swift root
3627+
/// classes when building with ObjC compatibility, does not appear here.
3628+
TargetRelativeDirectPointer<Runtime, const void, /*nullable*/true> Superclass;
3629+
};
3630+
36203631
template <typename Runtime>
36213632
class TargetClassDescriptor final
36223633
: public TargetTypeContextDescriptor<Runtime>,
36233634
public TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
36243635
TargetTypeGenericContextDescriptorHeader,
36253636
/*additional trailing objects:*/
3637+
TargetResilientSuperclass<Runtime>,
36263638
TargetForeignMetadataInitialization<Runtime>,
36273639
TargetSingletonMetadataInitialization<Runtime>,
36283640
TargetVTableDescriptorHeader<Runtime>,
@@ -3633,6 +3645,7 @@ class TargetClassDescriptor final
36333645
using TrailingGenericContextObjects =
36343646
TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
36353647
TargetTypeGenericContextDescriptorHeader,
3648+
TargetResilientSuperclass<Runtime>,
36363649
TargetForeignMetadataInitialization<Runtime>,
36373650
TargetSingletonMetadataInitialization<Runtime>,
36383651
TargetVTableDescriptorHeader<Runtime>,
@@ -3649,6 +3662,7 @@ class TargetClassDescriptor final
36493662
using VTableDescriptorHeader = TargetVTableDescriptorHeader<Runtime>;
36503663
using OverrideTableHeader = TargetOverrideTableHeader<Runtime>;
36513664
using MethodOverrideDescriptor = TargetMethodOverrideDescriptor<Runtime>;
3665+
using ResilientSuperclass = TargetResilientSuperclass<Runtime>;
36523666
using ForeignMetadataInitialization =
36533667
TargetForeignMetadataInitialization<Runtime>;
36543668
using SingletonMetadataInitialization =
@@ -3664,22 +3678,14 @@ class TargetClassDescriptor final
36643678
using TrailingGenericContextObjects::getGenericParams;
36653679
using TargetTypeContextDescriptor<Runtime>::getTypeContextDescriptorFlags;
36663680

3667-
/// The superclass of this class. This pointer can be interpreted
3668-
/// using the superclass reference kind stored in the type context
3669-
/// descriptor flags. It is null if the class has no formal superclass.
3670-
///
3671-
/// Note that SwiftObject, the implicit superclass of all Swift root
3672-
/// classes when building with ObjC compatibility, does not appear here.
3673-
TargetRelativeDirectPointer<Runtime, const void, /*nullable*/true> Superclass;
3674-
3675-
/// Does this class have a formal superclass?
3676-
bool hasSuperclass() const {
3677-
return !Superclass.isNull();
3681+
TypeReferenceKind getResilientSuperclassReferenceKind() const {
3682+
return getTypeContextDescriptorFlags()
3683+
.class_getResilientSuperclassReferenceKind();
36783684
}
36793685

3680-
TypeReferenceKind getSuperclassReferenceKind() const {
3681-
return getTypeContextDescriptorFlags().class_getSuperclassReferenceKind();
3682-
}
3686+
/// The type of the superclass, expressed as a mangled type name that can
3687+
/// refer to the generic arguments of the subclass type.
3688+
TargetRelativeDirectPointer<Runtime, const char> SuperclassType;
36833689

36843690
union {
36853691
/// If this descriptor does not have a resilient superclass, this is the
@@ -3740,6 +3746,10 @@ class TargetClassDescriptor final
37403746

37413747
using TrailingGenericContextObjects::numTrailingObjects;
37423748

3749+
size_t numTrailingObjects(OverloadToken<ResilientSuperclass>) const {
3750+
return this->hasResilientSuperclass() ? 1 : 0;
3751+
}
3752+
37433753
size_t numTrailingObjects(OverloadToken<ForeignMetadataInitialization>) const{
37443754
return this->hasForeignMetadataInitialization() ? 1 : 0;
37453755
}
@@ -3771,6 +3781,12 @@ class TargetClassDescriptor final
37713781
}
37723782

37733783
public:
3784+
const TargetRelativeDirectPointer<Runtime, const void, /*nullable*/true> &
3785+
getResilientSuperclass() const {
3786+
assert(this->hasResilientSuperclass());
3787+
return this->template getTrailingObjects<ResilientSuperclass>()->Superclass;
3788+
}
3789+
37743790
const ForeignMetadataInitialization &getForeignMetadataInitialization() const{
37753791
assert(this->hasForeignMetadataInitialization());
37763792
return *this->template getTrailingObjects<ForeignMetadataInitialization>();

include/swift/ABI/MetadataValues.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,12 +1253,12 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
12531253

12541254
// Type-specific flags:
12551255

1256-
/// The kind of reference that this class makes to its superclass
1256+
/// The kind of reference that this class makes to its resilient superclass
12571257
/// descriptor. A TypeReferenceKind.
12581258
///
12591259
/// Only meaningful for class descriptors.
1260-
Class_SuperclassReferenceKind = 9,
1261-
Class_SuperclassReferenceKind_width = 3,
1260+
Class_ResilientSuperclassReferenceKind = 9,
1261+
Class_ResilientSuperclassReferenceKind_width = 3,
12621262

12631263
/// Whether the immediate class members in this metadata are allocated
12641264
/// at negative offsets. For now, we don't use this.
@@ -1331,11 +1331,11 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
13311331
class_areImmediateMembersNegative,
13321332
class_setAreImmediateMembersNegative)
13331333

1334-
FLAGSET_DEFINE_FIELD_ACCESSORS(Class_SuperclassReferenceKind,
1335-
Class_SuperclassReferenceKind_width,
1334+
FLAGSET_DEFINE_FIELD_ACCESSORS(Class_ResilientSuperclassReferenceKind,
1335+
Class_ResilientSuperclassReferenceKind_width,
13361336
TypeReferenceKind,
1337-
class_getSuperclassReferenceKind,
1338-
class_setSuperclassReferenceKind)
1337+
class_getResilientSuperclassReferenceKind,
1338+
class_setResilientSuperclassReferenceKind)
13391339
};
13401340

13411341
/// Flags for protocol context descriptors. These values are used as the

include/swift/Remote/MetadataReader.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,15 +728,18 @@ class MetadataReader {
728728
Optional<ClassMetadataBounds>
729729
readMetadataBoundsOfSuperclass(ContextDescriptorRef subclassRef) {
730730
auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
731+
if (!subclass->hasResilientSuperclass())
732+
return ClassMetadataBounds::forSwiftRootClass();
731733

732734
auto rawSuperclass =
733-
resolveNullableRelativeField(subclassRef, subclass->Superclass);
735+
resolveNullableRelativeField(subclassRef,
736+
subclass->getResilientSuperclass());
734737
if (!rawSuperclass) {
735738
return ClassMetadataBounds::forSwiftRootClass();
736739
}
737740

738741
return forTypeReference<ClassMetadataBounds>(
739-
subclass->getSuperclassReferenceKind(), *rawSuperclass,
742+
subclass->getResilientSuperclassReferenceKind(), *rawSuperclass,
740743
[&](ContextDescriptorRef superclass)
741744
-> Optional<ClassMetadataBounds> {
742745
if (!isa<TargetClassDescriptor<Runtime>>(superclass))

include/swift/Runtime/Metadata.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,6 @@ swift_relocateClassMetadata(ClassDescriptor *descriptor,
629629
/// class metadata pattern by swift_allocateGenericClassMetadata().
630630
SWIFT_RUNTIME_EXPORT
631631
void swift_initClassMetadata(ClassMetadata *self,
632-
ClassMetadata *super,
633632
ClassLayoutFlags flags,
634633
size_t numFields,
635634
const TypeLayout * const *fieldTypes,
@@ -646,7 +645,6 @@ void swift_initClassMetadata(ClassMetadata *self,
646645
/// size is not known at compile time.
647646
SWIFT_RUNTIME_EXPORT
648647
void swift_updateClassMetadata(ClassMetadata *self,
649-
ClassMetadata *super,
650648
ClassLayoutFlags flags,
651649
size_t numFields,
652650
const TypeLayout * const *fieldTypes,

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -773,30 +773,28 @@ FUNCTION(RelocateClassMetadata,
773773

774774
// struct FieldInfo { size_t Size; size_t AlignMask; };
775775
// void swift_initClassMetadata(Metadata *self,
776-
// Metadata *super,
777776
// ClassLayoutFlags flags,
778777
// size_t numFields,
779778
// TypeLayout * const *fieldTypes,
780779
// size_t *fieldOffsets);
781780
FUNCTION(InitClassMetadata,
782781
swift_initClassMetadata, C_CC,
783782
RETURNS(VoidTy),
784-
ARGS(TypeMetadataPtrTy, TypeMetadataPtrTy, SizeTy, SizeTy,
783+
ARGS(TypeMetadataPtrTy, SizeTy, SizeTy,
785784
Int8PtrPtrTy->getPointerTo(),
786785
SizeTy->getPointerTo()),
787786
ATTRS(NoUnwind))
788787

789788
// struct FieldInfo { size_t Size; size_t AlignMask; };
790789
// void swift_updateClassMetadata(Metadata *self,
791-
// Metadata *super,
792790
// ClassLayoutFlags flags,
793791
// size_t numFields,
794792
// TypeLayout * const *fieldTypes,
795793
// size_t *fieldOffsets);
796794
FUNCTION(UpdateClassMetadata,
797795
swift_updateClassMetadata, C_CC,
798796
RETURNS(VoidTy),
799-
ARGS(TypeMetadataPtrTy, TypeMetadataPtrTy, SizeTy, SizeTy,
797+
ARGS(TypeMetadataPtrTy, SizeTy, SizeTy,
800798
Int8PtrPtrTy->getPointerTo(),
801799
SizeTy->getPointerTo()),
802800
ATTRS(NoUnwind))

lib/IRGen/GenMeta.cpp

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,7 @@ namespace {
918918
asImpl().addReflectionFieldDescriptor();
919919
asImpl().addLayoutInfo();
920920
asImpl().addGenericSignature();
921+
asImpl().maybeAddResilientSuperclass();
921922
asImpl().maybeAddMetadataInitialization();
922923
}
923924

@@ -1263,7 +1264,9 @@ namespace {
12631264
setCommonFlags(flags);
12641265
return flags.getOpaqueValue();
12651266
}
1266-
1267+
1268+
void maybeAddResilientSuperclass() { }
1269+
12671270
void addReflectionFieldDescriptor() {
12681271
// Structs are reflectable unless we emit them with opaque reflection
12691272
// metadata.
@@ -1334,6 +1337,8 @@ namespace {
13341337
return flags.getOpaqueValue();
13351338
}
13361339

1340+
void maybeAddResilientSuperclass() { }
1341+
13371342
void addReflectionFieldDescriptor() {
13381343
// Some enum layout strategies (viz. C compatible layout) aren't
13391344
// supported by reflection.
@@ -1363,7 +1368,7 @@ namespace {
13631368
// Non-null unless the type is foreign.
13641369
ClassMetadataLayout *MetadataLayout = nullptr;
13651370

1366-
Optional<TypeEntityReference> SuperClassRef;
1371+
Optional<TypeEntityReference> ResilientSuperClassRef;
13671372

13681373
SILVTable *VTable;
13691374
bool Resilient;
@@ -1382,8 +1387,10 @@ namespace {
13821387

13831388
MetadataLayout = &IGM.getClassMetadataLayout(Type);
13841389

1385-
if (auto superclassDecl = getType()->getSuperclassDecl())
1386-
SuperClassRef = IGM.getTypeEntityReference(superclassDecl);
1390+
if (auto superclassDecl = getType()->getSuperclassDecl()) {
1391+
if (MetadataLayout && MetadataLayout->hasResilientSuperclass())
1392+
ResilientSuperClassRef = IGM.getTypeEntityReference(superclassDecl);
1393+
}
13871394

13881395
addVTableEntries(getType());
13891396
}
@@ -1436,13 +1443,21 @@ namespace {
14361443
flags.class_setHasResilientSuperclass(true);
14371444
}
14381445

1439-
if (SuperClassRef) {
1440-
flags.class_setSuperclassReferenceKind(SuperClassRef->getKind());
1446+
if (ResilientSuperClassRef) {
1447+
flags.class_setResilientSuperclassReferenceKind(
1448+
ResilientSuperClassRef->getKind());
14411449
}
14421450

14431451
return flags.getOpaqueValue();
14441452
}
14451453

1454+
void maybeAddResilientSuperclass() {
1455+
// RelativeDirectPointer<const void, /*nullable*/ true> SuperClass;
1456+
if (ResilientSuperClassRef) {
1457+
B.addRelativeAddress(ResilientSuperClassRef->getValue());
1458+
}
1459+
}
1460+
14461461
void addReflectionFieldDescriptor() {
14471462
// Classes are always reflectable, unless reflection is disabled or this
14481463
// is a foreign class.
@@ -1574,15 +1589,17 @@ namespace {
15741589
}
15751590

15761591
void addLayoutInfo() {
1577-
auto properties = getType()->getStoredProperties();
15781592

1579-
// RelativeDirectPointer<const void, /*nullable*/ true> SuperClass;
1580-
if (SuperClassRef) {
1581-
B.addRelativeAddress(SuperClassRef->getValue());
1593+
// TargetRelativeDirectPointer<Runtime, const char> SuperclassType;
1594+
if (auto superclassType = getType()->getSuperclass()) {
1595+
B.addRelativeAddress(IGM.getTypeRef(superclassType->getCanonicalType(),
1596+
MangledTypeRefRole::Metadata));
15821597
} else {
15831598
B.addInt32(0);
15841599
}
15851600

1601+
auto properties = getType()->getStoredProperties();
1602+
15861603
// union {
15871604
// uint32_t MetadataNegativeSizeInWords;
15881605
// RelativeDirectPointer<StoredClassMetadataBounds>
@@ -1797,28 +1814,10 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
17971814
if (!doesClassMetadataRequireRelocation(IGM, classDecl))
17981815
flags |= ClassLayoutFlags::HasStaticVTable;
17991816

1800-
// Get the superclass metadata, if the class has one.
1801-
llvm::Value *superclassMetadata;
1802-
if (auto superclassType = classDecl->getSuperclass()) {
1803-
superclassType = classDecl->mapTypeIntoContext(superclassType);
1804-
1805-
auto request = DynamicMetadataRequest::getNonBlocking(
1806-
MetadataState::NonTransitiveComplete, collector);
1807-
1808-
superclassMetadata =
1809-
emitClassHeapMetadataRef(IGF, superclassType->getCanonicalType(),
1810-
MetadataValueType::TypeMetadata,
1811-
request,
1812-
/*allowUninit*/ false);
1813-
} else {
1814-
superclassMetadata =
1815-
llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy);
1816-
}
1817-
18181817
if (doesClassMetadataRequireInitialization(IGM, classDecl)) {
18191818
// Call swift_initClassMetadata().
18201819
IGF.Builder.CreateCall(IGM.getInitClassMetadataFn(),
1821-
{metadata, superclassMetadata,
1820+
{metadata,
18221821
IGM.getSize(Size(uintptr_t(flags))),
18231822
numFields, fields.getAddress(), fieldVector});
18241823
} else {
@@ -1829,7 +1828,7 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
18291828
// already references the superclass in this case, but we still want
18301829
// to ensure the superclass metadata is initialized first.
18311830
IGF.Builder.CreateCall(IGM.getUpdateClassMetadataFn(),
1832-
{metadata, superclassMetadata,
1831+
{metadata,
18331832
IGM.getSize(Size(uintptr_t(flags))),
18341833
numFields, fields.getAddress(), fieldVector});
18351834
}

lib/IRGen/GenReflection.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,21 @@ class PrintMetadataSource
165165
};
166166

167167
llvm::Constant *IRGenModule::getTypeRef(CanType type, MangledTypeRefRole role) {
168+
switch (role) {
169+
case MangledTypeRefRole::DefaultAssociatedTypeWitness:
170+
case MangledTypeRefRole::Metadata:
171+
// Note that we're using all of the nominal types referenced by this type.
172+
type.findIf([&](CanType type) -> bool {
173+
if (auto nominal = type.getAnyNominal())
174+
this->IRGen.noteUseOfTypeMetadata(nominal);
175+
return false;
176+
});
177+
break;
178+
179+
case MangledTypeRefRole::Reflection:
180+
break;
181+
}
182+
168183
IRGenMangler Mangler;
169184
auto SymbolicName = Mangler.mangleTypeForReflection(*this, type);
170185
return getAddrOfStringForTypeRef(SymbolicName, role);

0 commit comments

Comments
 (0)