Skip to content

Commit 03cb6d1

Browse files
committed
IRGen/Runtime: Use a true-const pattern to initialize non-generic resilient class metadata
Previously we would emit class metadata for classes with resilient ancestry, and relocate it at runtime once the correct size was known. However most of the fields were blank, so it makes more sense to construct the metadata from scratch, and store the few bits that we do need in a true-const pattern where we can use relative pointers.
1 parent 120be25 commit 03cb6d1

File tree

7 files changed

+308
-139
lines changed

7 files changed

+308
-139
lines changed

include/swift/ABI/Metadata.h

Lines changed: 42 additions & 7 deletions
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
};

include/swift/Runtime/Metadata.h

Lines changed: 4 additions & 6 deletions
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.

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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; };

lib/IRGen/GenDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)