Skip to content

Commit ab68f0d

Browse files
authored
Merge pull request #18893 from slavapestov/resilient-class-pattern
Use a true-const pattern to initialize non-generic resilient class metadata
2 parents 04790f1 + 03cb6d1 commit ab68f0d

18 files changed

+371
-218
lines changed

Diff for: include/swift/ABI/Metadata.h

+42-7
Original file line numberDiff line numberDiff line change
@@ -3085,7 +3085,7 @@ class TargetGenericMetadataPatternTrailingObjects :
30853085
}
30863086
};
30873087

3088-
/// An instantiation pattern for class metadata.
3088+
/// An instantiation pattern for generic class metadata.
30893089
template <typename Runtime>
30903090
struct TargetGenericClassMetadataPattern final :
30913091
TargetGenericMetadataPattern<Runtime>,
@@ -3138,7 +3138,7 @@ struct TargetGenericClassMetadataPattern final :
31383138
using GenericClassMetadataPattern =
31393139
TargetGenericClassMetadataPattern<InProcess>;
31403140

3141-
/// An instantiation pattern for value metadata.
3141+
/// An instantiation pattern for generic value metadata.
31423142
template <typename Runtime>
31433143
struct TargetGenericValueMetadataPattern final :
31443144
TargetGenericMetadataPattern<Runtime>,
@@ -3316,10 +3316,43 @@ struct TargetInPlaceValueMetadataCache {
33163316
using InPlaceValueMetadataCache =
33173317
TargetInPlaceValueMetadataCache<InProcess>;
33183318

3319+
template <typename Runtime>
3320+
struct TargetResilientClassMetadataPattern;
3321+
33193322
/// An instantiation pattern for non-generic resilient class metadata.
33203323
/// Used in conjunction with InPlaceValueMetadataInitialization.
33213324
using MetadataRelocator =
3322-
Metadata *(const TargetTypeContextDescriptor<InProcess> *description);
3325+
Metadata *(const TargetTypeContextDescriptor<InProcess> *type,
3326+
const TargetResilientClassMetadataPattern<InProcess> *pattern);
3327+
3328+
/// An instantiation pattern for non-generic resilient class metadata.
3329+
template <typename Runtime>
3330+
struct TargetResilientClassMetadataPattern {
3331+
/// If the class descriptor's hasResilientSuperclass() flag is set,
3332+
/// this field instead points at a function that allocates metadata
3333+
/// with the correct size at runtime.
3334+
TargetRelativeDirectPointer<Runtime, MetadataRelocator> RelocationFunction;
3335+
3336+
/// The heap-destructor function.
3337+
TargetRelativeDirectPointer<Runtime, HeapObjectDestroyer> Destroy;
3338+
3339+
/// The ivar-destructor function.
3340+
TargetRelativeDirectPointer<Runtime, ClassIVarDestroyer> IVarDestroyer;
3341+
3342+
/// The class flags.
3343+
ClassFlags Flags;
3344+
3345+
// The following fields are only present in ObjC interop.
3346+
3347+
/// Our ClassROData.
3348+
TargetRelativeDirectPointer<Runtime, void> Data;
3349+
3350+
/// Our metaclass.
3351+
TargetRelativeDirectPointer<Runtime, TargetAnyClassMetadata<Runtime>> Metaclass;
3352+
};
3353+
3354+
using ResilientClassMetadataPattern =
3355+
TargetResilientClassMetadataPattern<InProcess>;
33233356

33243357
/// The control structure for performing non-trivial initialization of
33253358
/// singleton value metadata, which is required when e.g. a non-generic
@@ -3340,8 +3373,8 @@ struct TargetInPlaceValueMetadataInitialization {
33403373
/// If the class descriptor's hasResilientSuperclass() flag is set,
33413374
/// this field instead points at a function that allocates metadata
33423375
/// with the correct size at runtime.
3343-
TargetRelativeDirectPointer<Runtime, MetadataRelocator>
3344-
RelocationFunction;
3376+
TargetRelativeDirectPointer<Runtime, TargetResilientClassMetadataPattern<Runtime>>
3377+
ResilientPattern;
33453378
};
33463379

33473380
/// The completion function. The pattern will always be null.
@@ -3358,8 +3391,10 @@ struct TargetInPlaceValueMetadataInitialization {
33583391

33593392
TargetMetadata<Runtime> *allocate(
33603393
const TargetTypeContextDescriptor<Runtime> *description) const {
3361-
if (hasRelocationFunction(description))
3362-
return RelocationFunction(description);
3394+
if (hasRelocationFunction(description)) {
3395+
return ResilientPattern->RelocationFunction(description,
3396+
ResilientPattern.get());
3397+
}
33633398
return IncompleteMetadata.get();
33643399
}
33653400
};

Diff for: include/swift/Runtime/Metadata.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -574,15 +574,13 @@ void swift_initStructMetadata(StructMetadata *self,
574574
const TypeLayout * const *fieldTypes,
575575
uint32_t *fieldOffsets);
576576

577-
/// Relocate the metadata for a class and copy fields from the given template.
578-
/// The final size of the metadata is calculated at runtime from the size of
579-
/// the superclass metadata together with the given number of immediate
580-
/// members.
577+
/// Allocate the metadata for a class and copy fields from the given pattern.
578+
/// The final size of the metadata is calculated at runtime from the metadata
579+
/// bounds in the class descriptor.
581580
SWIFT_RUNTIME_EXPORT
582581
ClassMetadata *
583582
swift_relocateClassMetadata(ClassDescriptor *descriptor,
584-
ClassMetadata *pattern,
585-
size_t patternSize);
583+
ResilientClassMetadataPattern *pattern);
586584

587585
/// Initialize the field offset vector for a dependent-layout class, using the
588586
/// "Universal" layout strategy.

Diff for: include/swift/Runtime/RuntimeFunctions.def

+6-7
Original file line numberDiff line numberDiff line change
@@ -670,19 +670,19 @@ FUNCTION(GetGenericMetadata, swift_getGenericMetadata, SwiftCC,
670670

671671
// Metadata *swift_allocateGenericClassMetadata(ClassDescriptor *type,
672672
// const void * const *arguments,
673-
// const void * const *template);
673+
// const void *template);
674674
FUNCTION(AllocateGenericClassMetadata, swift_allocateGenericClassMetadata,
675675
C_CC, RETURNS(TypeMetadataPtrTy),
676-
ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrPtrTy),
676+
ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrTy),
677677
ATTRS(NoUnwind))
678678

679679
// Metadata *swift_allocateGenericValueMetadata(ValueTypeDescriptor *type,
680680
// const void * const *arguments,
681-
// const void * const *template,
681+
// const void *template,
682682
// size_t extraSize);
683683
FUNCTION(AllocateGenericValueMetadata, swift_allocateGenericValueMetadata,
684684
C_CC, RETURNS(TypeMetadataPtrTy),
685-
ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrPtrTy, SizeTy),
685+
ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrTy, SizeTy),
686686
ATTRS(NoUnwind))
687687

688688
// MetadataResponse swift_checkMetadataState(MetadataRequest request,
@@ -809,12 +809,11 @@ FUNCTION(GetExistentialMetadata,
809809
ATTRS(NoUnwind, ReadOnly))
810810

811811
// Metadata *swift_relocateClassMetadata(TypeContextDescriptor *descriptor,
812-
// Metadata *pattern,
813-
// size_t patternSize);
812+
// const void *pattern);
814813
FUNCTION(RelocateClassMetadata,
815814
swift_relocateClassMetadata, C_CC,
816815
RETURNS(TypeMetadataPtrTy),
817-
ARGS(TypeContextDescriptorPtrTy, TypeMetadataPtrTy, SizeTy),
816+
ARGS(TypeContextDescriptorPtrTy, Int8PtrTy),
818817
ATTRS(NoUnwind))
819818

820819
// struct FieldInfo { size_t Size; size_t AlignMask; };

Diff for: lib/IRGen/GenDecl.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -3282,8 +3282,9 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
32823282
assert(init);
32833283

32843284
if (isPattern) {
3285+
assert(isConstant && "Type metadata patterns must be constant");
32853286
auto addr = getAddrOfTypeMetadataPattern(concreteType->getAnyNominal(),
3286-
isConstant, init, section);
3287+
init, section);
32873288

32883289
return cast<llvm::GlobalValue>(addr);
32893290
}
@@ -3488,12 +3489,11 @@ ConstantReference IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
34883489

34893490
llvm::Constant *
34903491
IRGenModule::getAddrOfTypeMetadataPattern(NominalTypeDecl *D) {
3491-
return getAddrOfTypeMetadataPattern(D, false, ConstantInit(), "");
3492+
return getAddrOfTypeMetadataPattern(D, ConstantInit(), "");
34923493
}
34933494

34943495
llvm::Constant *
34953496
IRGenModule::getAddrOfTypeMetadataPattern(NominalTypeDecl *D,
3496-
bool isConstant,
34973497
ConstantInit init,
34983498
StringRef section) {
34993499
if (!init)
@@ -3502,7 +3502,7 @@ IRGenModule::getAddrOfTypeMetadataPattern(NominalTypeDecl *D,
35023502
auto alignment = getPointerAlignment();
35033503
LinkEntity entity = LinkEntity::forTypeMetadataPattern(D);
35043504
auto addr = getAddrOfLLVMVariable(entity, alignment, init,
3505-
Int8PtrTy, DebugTypeInfo());
3505+
Int8Ty, DebugTypeInfo());
35063506

35073507
if (init) {
35083508
auto var = cast<llvm::GlobalVariable>(addr);
@@ -3565,7 +3565,7 @@ IRGenModule::getAddrOfTypeMetadataInstantiationFunction(NominalTypeDecl *D,
35653565
/// Generic arguments.
35663566
Int8PtrPtrTy,
35673567
/// Generic metadata pattern.
3568-
Int8PtrPtrTy
3568+
Int8PtrTy
35693569
};
35703570

35713571
fnType = llvm::FunctionType::get(TypeMetadataPtrTy, argTys,
@@ -3577,6 +3577,8 @@ IRGenModule::getAddrOfTypeMetadataInstantiationFunction(NominalTypeDecl *D,
35773577
llvm::Type *argTys[] = {
35783578
/// Type descriptor.
35793579
TypeContextDescriptorPtrTy,
3580+
/// Resilient metadata pattern.
3581+
Int8PtrTy
35803582
};
35813583

35823584
fnType = llvm::FunctionType::get(TypeMetadataPtrTy, argTys,

0 commit comments

Comments
 (0)