Skip to content

Commit 4af53c5

Browse files
committed
Runtime: The class metadata relocation function can be null
IRGen always just emits a simple implementation that immediately calls swift_relocateClassMetadata(); so allow the function to be null in this case to save on code size.
1 parent d5bd4a0 commit 4af53c5

File tree

4 files changed

+32
-61
lines changed

4 files changed

+32
-61
lines changed

include/swift/ABI/Metadata.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3349,7 +3349,11 @@ using MetadataRelocator =
33493349
template <typename Runtime>
33503350
struct TargetResilientClassMetadataPattern {
33513351
/// A function that allocates metadata with the correct size at runtime.
3352-
TargetRelativeDirectPointer<Runtime, MetadataRelocator> RelocationFunction;
3352+
///
3353+
/// If this is null, the runtime instead calls swift_relocateClassMetadata(),
3354+
/// passing in the class descriptor and this pattern.
3355+
TargetRelativeDirectPointer<Runtime, MetadataRelocator, /*nullable*/ true>
3356+
RelocationFunction;
33533357

33543358
/// The heap-destructor function.
33553359
TargetRelativeDirectPointer<Runtime, HeapObjectDestroyer> Destroy;
@@ -3410,14 +3414,10 @@ struct TargetSingletonMetadataInitialization {
34103414
classDescription->hasResilientSuperclass());
34113415
}
34123416

3417+
/// This method can only be called from the runtime itself. It is defined
3418+
/// in MetadataCache.h.
34133419
TargetMetadata<Runtime> *allocate(
3414-
const TargetTypeContextDescriptor<Runtime> *description) const {
3415-
if (hasResilientClassPattern(description)) {
3416-
return ResilientPattern->RelocationFunction(description,
3417-
ResilientPattern.get());
3418-
}
3419-
return IncompleteMetadata.get();
3420-
}
3420+
const TargetTypeContextDescriptor<Runtime> *description) const;
34213421
};
34223422

34233423
template <typename Runtime>

lib/IRGen/GenMeta.cpp

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2742,9 +2742,9 @@ namespace {
27422742
}
27432743

27442744
void addRelocationFunction() {
2745-
auto function = IGM.getAddrOfTypeMetadataInstantiationFunction(
2746-
Target, NotForDefinition);
2747-
B.addRelativeAddress(function);
2745+
// We don't use this yet, but it's available as a future customization
2746+
// point.
2747+
B.addRelativeAddressOrNull(nullptr);
27482748
}
27492749

27502750
void addDestructorFunction() {
@@ -2792,39 +2792,6 @@ namespace {
27922792
emitInitializeClassMetadata(IGF, Target, FieldLayout, metadata,
27932793
collector);
27942794
});
2795-
2796-
emitRelocationFunction();
2797-
}
2798-
2799-
private:
2800-
/// Emit the create function for a class with resilient ancestry.
2801-
void emitRelocationFunction() {
2802-
// using MetadataRelocator =
2803-
// Metadata *(TypeContextDescriptor *type, void *pattern);
2804-
llvm::Function *f =
2805-
IGM.getAddrOfTypeMetadataInstantiationFunction(Target, ForDefinition);
2806-
f->setAttributes(IGM.constructInitialAttributes());
2807-
2808-
IRGenFunction IGF(IGM, f);
2809-
2810-
// Skip instrumentation when building for TSan to avoid false positives.
2811-
// The synchronization for this happens in the Runtime and we do not see it.
2812-
if (IGM.IRGen.Opts.Sanitizers & SanitizerKind::Thread)
2813-
f->removeFnAttr(llvm::Attribute::SanitizeThread);
2814-
2815-
if (IGM.DebugInfo)
2816-
IGM.DebugInfo->emitArtificialFunction(IGF, f);
2817-
2818-
Explosion params = IGF.collectParameters();
2819-
llvm::Value *descriptor = params.claimNext();
2820-
llvm::Value *pattern = params.claimNext();
2821-
2822-
// Allocate class metadata using the pattern we emitted.
2823-
llvm::Value *metadata =
2824-
IGF.Builder.CreateCall(IGF.IGM.getRelocateClassMetadataFn(),
2825-
{descriptor, pattern});
2826-
2827-
IGF.Builder.CreateRet(metadata);
28282795
}
28292796
};
28302797

stdlib/public/runtime/Metadata.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@
7272
using namespace swift;
7373
using namespace metadataimpl;
7474

75+
template<>
76+
Metadata *TargetSingletonMetadataInitialization<InProcess>::allocate(
77+
const TypeContextDescriptor *description) const {
78+
// If this class has resilient ancestry, the size of the metadata is not known
79+
// at compile time, so we allocate it dynamically, filling it in from a
80+
// pattern.
81+
if (hasResilientClassPattern(description)) {
82+
auto *pattern = ResilientPattern.get();
83+
84+
// If there is a relocation function, call it.
85+
if (auto *fn = ResilientPattern->RelocationFunction.get())
86+
return fn(description, pattern);
87+
88+
// Otherwise, use the default behavior.
89+
auto *classDescription = cast<ClassDescriptor>(description);
90+
return swift_relocateClassMetadata(classDescription, pattern);
91+
}
92+
return IncompleteMetadata.get();
93+
}
94+
7595
/// Copy the generic arguments into place in a newly-allocated metadata.
7696
static void installGenericArguments(Metadata *metadata,
7797
const TypeContextDescriptor *description,

test/IRGen/class_resilience.swift

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383

8484
// CHECK: @"$s16class_resilience14ResilientChildCMP" = internal constant <{{.*}}> <{
8585
// -- instantiation function:
86-
// CHECK-SAME: @"$s16class_resilience14ResilientChildCMi"
86+
// CHECK-SAME: i32 0,
8787
// -- destructor:
8888
// CHECK-SAME: @"$s16class_resilience14ResilientChildCfD"
8989
// -- ivar destroyer:
@@ -525,14 +525,6 @@ extension ResilientGenericOutsideParent {
525525
// CHECK-NEXT: ret void
526526

527527

528-
// ResilientChild metadata relocation function
529-
530-
// CHECK-LABEL: define internal %swift.type* @"$s16class_resilience14ResilientChildCMi"(%swift.type_descriptor*, i8*)
531-
// CHECK-NEXT: entry:
532-
// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, i8* %1)
533-
// CHECK-NEXT: ret %swift.type* [[METADATA]]
534-
535-
536528
// FixedLayoutChild metadata initialization function
537529

538530
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s16class_resilience16FixedLayoutChildCMr"(%swift.type*, i8*, i8**)
@@ -541,14 +533,6 @@ extension ResilientGenericOutsideParent {
541533
// CHECK: call void @swift_initClassMetadata(%swift.type* %0, [[INT]] 0, [[INT]] 1, i8*** {{%.*}}, [[INT]]* {{%.*}})
542534

543535

544-
// FixedLayoutChild metadata relocation function
545-
546-
// CHECK-LABEL: define internal %swift.type* @"$s16class_resilience16FixedLayoutChildCMi"(%swift.type_descriptor*, i8*)
547-
// CHECK-NEXT: entry:
548-
// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type_descriptor* %0, i8* %1)
549-
// CHECK-NEXT: ret %swift.type* [[METADATA]]
550-
551-
552536
// ResilientGenericChild metadata initialization function
553537

554538
// CHECK-LABEL: define internal %swift.type* @"$s16class_resilience21ResilientGenericChildCMi"(%swift.type_descriptor*, i8**, i8*)

0 commit comments

Comments
 (0)