Skip to content

Commit a074bc2

Browse files
committed
Add new APIs for init/updateClassMetadata that can report dependencies.
1 parent d07efd3 commit a074bc2

File tree

3 files changed

+138
-42
lines changed

3 files changed

+138
-42
lines changed

include/swift/Runtime/Metadata.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,14 @@ void swift_initClassMetadata(ClassMetadata *self,
597597
const TypeLayout * const *fieldTypes,
598598
size_t *fieldOffsets);
599599

600+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
601+
MetadataDependency
602+
swift_initClassMetadata2(ClassMetadata *self,
603+
ClassLayoutFlags flags,
604+
size_t numFields,
605+
const TypeLayout * const *fieldTypes,
606+
size_t *fieldOffsets);
607+
600608
#if SWIFT_OBJC_INTEROP
601609
/// Initialize various fields of the class metadata.
602610
///
@@ -612,6 +620,14 @@ void swift_updateClassMetadata(ClassMetadata *self,
612620
size_t numFields,
613621
const TypeLayout * const *fieldTypes,
614622
size_t *fieldOffsets);
623+
624+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
625+
MetadataDependency
626+
swift_updateClassMetadata2(ClassMetadata *self,
627+
ClassLayoutFlags flags,
628+
size_t numFields,
629+
const TypeLayout * const *fieldTypes,
630+
size_t *fieldOffsets);
615631
#endif
616632

617633
/// Given class metadata, a class descriptor and a method descriptor, look up

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,34 @@ FUNCTION(UpdateClassMetadata,
808808
SizeTy->getPointerTo()),
809809
ATTRS(NoUnwind))
810810

811+
// struct FieldInfo { size_t Size; size_t AlignMask; };
812+
// MetadataDependency swift_initClassMetadata2(Metadata *self,
813+
// ClassLayoutFlags flags,
814+
// size_t numFields,
815+
// TypeLayout * const *fieldTypes,
816+
// size_t *fieldOffsets);
817+
FUNCTION(InitClassMetadata2,
818+
swift_initClassMetadata2, SwiftCC,
819+
RETURNS(TypeMetadataDependencyTy),
820+
ARGS(TypeMetadataPtrTy, SizeTy, SizeTy,
821+
Int8PtrPtrTy->getPointerTo(),
822+
SizeTy->getPointerTo()),
823+
ATTRS(NoUnwind))
824+
825+
// struct FieldInfo { size_t Size; size_t AlignMask; };
826+
// MetadataDependency swift_updateClassMetadata2(Metadata *self,
827+
// ClassLayoutFlags flags,
828+
// size_t numFields,
829+
// TypeLayout * const *fieldTypes,
830+
// size_t *fieldOffsets);
831+
FUNCTION(UpdateClassMetadata2,
832+
swift_updateClassMetadata2, SwiftCC,
833+
RETURNS(TypeMetadataDependencyTy),
834+
ARGS(TypeMetadataPtrTy, SizeTy, SizeTy,
835+
Int8PtrPtrTy->getPointerTo(),
836+
SizeTy->getPointerTo()),
837+
ATTRS(NoUnwind))
838+
811839
// void *swift_lookUpClassMethod(Metadata *metadata,
812840
// ClassDescriptor *description,
813841
// MethodDescriptor *method);

stdlib/public/runtime/Metadata.cpp

Lines changed: 94 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,10 +2474,10 @@ static void initObjCClass(ClassMetadata *self,
24742474
/// corresponding entry in \p fieldOffsets, before asking the Objective-C
24752475
/// runtime to realize the class. The Objective-C runtime will then slide the
24762476
/// offsets in \p fieldOffsets.
2477-
static void initGenericObjCClass(ClassMetadata *self,
2478-
size_t numFields,
2479-
const TypeLayout * const *fieldTypes,
2480-
size_t *fieldOffsets) {
2477+
static MetadataDependency
2478+
initGenericObjCClass(ClassMetadata *self, size_t numFields,
2479+
const TypeLayout * const *fieldTypes,
2480+
size_t *fieldOffsets) {
24812481
// If the class is generic, we need to give it a name for Objective-C.
24822482
initGenericClassObjCName(self);
24832483

@@ -2580,24 +2580,25 @@ static void initGenericObjCClass(ClassMetadata *self,
25802580
delete [] _globalIvarOffsets;
25812581
}
25822582
}
2583+
2584+
return MetadataDependency();
25832585
}
25842586
#endif
25852587

2586-
void
2587-
swift::swift_initClassMetadata(ClassMetadata *self,
2588-
ClassLayoutFlags layoutFlags,
2589-
size_t numFields,
2590-
const TypeLayout * const *fieldTypes,
2591-
size_t *fieldOffsets) {
2588+
SWIFT_CC(swift)
2589+
static std::pair<MetadataDependency, const ClassMetadata *>
2590+
getSuperclassMetadata(ClassMetadata *self, bool allowDependency) {
25922591
// If there is a mangled superclass name, demangle it to the superclass
25932592
// type.
25942593
const ClassMetadata *super = nullptr;
25952594
if (auto superclassNameBase = self->getDescription()->SuperclassType.get()) {
25962595
StringRef superclassName =
25972596
Demangle::makeSymbolicMangledNameStringRef(superclassNameBase);
25982597
SubstGenericParametersFromMetadata substitutions(self);
2599-
MetadataRequest request(/*FIXME*/MetadataState::Abstract,
2600-
/*non-blocking*/ false);
2598+
MetadataRequest request(allowDependency
2599+
? MetadataState::NonTransitiveComplete
2600+
: /*FIXME*/ MetadataState::Abstract,
2601+
/*non-blocking*/ allowDependency);
26012602
MetadataResponse response =
26022603
swift_getTypeByMangledName(request, superclassName,
26032604
substitutions, substitutions).getResponse();
@@ -2609,6 +2610,13 @@ swift::swift_initClassMetadata(ClassMetadata *self,
26092610
superclassName.str().c_str());
26102611
}
26112612

2613+
// If the request isn't satisfied, we have a new dependency.
2614+
if (!request.isSatisfiedBy(response.State)) {
2615+
assert(allowDependency);
2616+
return {MetadataDependency(superclass, request.getState()),
2617+
cast<ClassMetadata>(superclass)};
2618+
}
2619+
26122620
#if SWIFT_OBJC_INTEROP
26132621
if (auto objcWrapper = dyn_cast<ObjCClassWrapperMetadata>(superclass))
26142622
superclass = objcWrapper->Class;
@@ -2617,6 +2625,22 @@ swift::swift_initClassMetadata(ClassMetadata *self,
26172625
super = cast<ClassMetadata>(superclass);
26182626
}
26192627

2628+
return {MetadataDependency(), super};
2629+
}
2630+
2631+
static SWIFT_CC(swift) MetadataDependency
2632+
_swift_initClassMetadataImpl(ClassMetadata *self,
2633+
ClassLayoutFlags layoutFlags,
2634+
size_t numFields,
2635+
const TypeLayout * const *fieldTypes,
2636+
size_t *fieldOffsets,
2637+
bool allowDependency) {
2638+
// Try to install the superclass.
2639+
auto superDependencyAndSuper = getSuperclassMetadata(self, allowDependency);
2640+
if (superDependencyAndSuper.first)
2641+
return superDependencyAndSuper.first;
2642+
auto super = superDependencyAndSuper.second;
2643+
26202644
self->Superclass = super;
26212645

26222646
#if SWIFT_OBJC_INTEROP
@@ -2657,6 +2681,29 @@ swift::swift_initClassMetadata(ClassMetadata *self,
26572681
swift_instantiateObjCClass(self);
26582682
}
26592683
#endif
2684+
2685+
return MetadataDependency();
2686+
}
2687+
2688+
void swift::swift_initClassMetadata(ClassMetadata *self,
2689+
ClassLayoutFlags layoutFlags,
2690+
size_t numFields,
2691+
const TypeLayout * const *fieldTypes,
2692+
size_t *fieldOffsets) {
2693+
(void) _swift_initClassMetadataImpl(self, layoutFlags, numFields,
2694+
fieldTypes, fieldOffsets,
2695+
/*allowDependency*/ false);
2696+
}
2697+
2698+
MetadataDependency
2699+
swift::swift_initClassMetadata2(ClassMetadata *self,
2700+
ClassLayoutFlags layoutFlags,
2701+
size_t numFields,
2702+
const TypeLayout * const *fieldTypes,
2703+
size_t *fieldOffsets) {
2704+
return _swift_initClassMetadataImpl(self, layoutFlags, numFields,
2705+
fieldTypes, fieldOffsets,
2706+
/*allowDependency*/ true);
26602707
}
26612708

26622709
#if SWIFT_OBJC_INTEROP
@@ -2666,12 +2713,14 @@ swift::swift_initClassMetadata(ClassMetadata *self,
26662713
#pragma clang diagnostic push
26672714
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
26682715

2669-
void
2670-
swift::swift_updateClassMetadata(ClassMetadata *self,
2671-
ClassLayoutFlags layoutFlags,
2672-
size_t numFields,
2673-
const TypeLayout * const *fieldTypes,
2674-
size_t *fieldOffsets) {
2716+
2717+
static SWIFT_CC(swift) MetadataDependency
2718+
_swift_updateClassMetadataImpl(ClassMetadata *self,
2719+
ClassLayoutFlags layoutFlags,
2720+
size_t numFields,
2721+
const TypeLayout * const *fieldTypes,
2722+
size_t *fieldOffsets,
2723+
bool allowDependency) {
26752724
#ifndef OBJC_REALIZECLASSFROMSWIFT_DEFINED
26762725
// Temporary workaround until _objc_realizeClassFromSwift is in the SDK.
26772726
static auto _objc_realizeClassFromSwift =
@@ -2684,30 +2733,10 @@ swift::swift_updateClassMetadata(ClassMetadata *self,
26842733
// If we're on a newer runtime, we're going to be initializing the
26852734
// field offset vector. Realize the superclass metadata first, even
26862735
// though our superclass field references it statically.
2687-
const ClassMetadata *super = nullptr;
2688-
2689-
if (auto superclassNameBase = self->getDescription()->SuperclassType.get()) {
2690-
StringRef superclassName =
2691-
Demangle::makeSymbolicMangledNameStringRef(superclassNameBase);
2692-
SubstGenericParametersFromMetadata substitutions(self);
2693-
MetadataRequest request(/*FIXME*/MetadataState::Abstract,
2694-
/*non-blocking*/ false);
2695-
MetadataResponse response =
2696-
swift_getTypeByMangledName(request, superclassName,
2697-
substitutions, substitutions).getResponse();
2698-
const Metadata *superclass = response.Value;
2699-
if (!superclass) {
2700-
fatalError(0,
2701-
"failed to demangle superclass of %s from mangled name '%s'\n",
2702-
self->getDescription()->Name.get(),
2703-
superclassName.str().c_str());
2704-
}
2705-
2706-
if (auto objcWrapper = dyn_cast<ObjCClassWrapperMetadata>(superclass))
2707-
superclass = objcWrapper->Class;
2708-
2709-
super = cast<ClassMetadata>(superclass);
2710-
}
2736+
auto superDependencyAndSuper = getSuperclassMetadata(self, allowDependency);
2737+
if (superDependencyAndSuper.first)
2738+
return superDependencyAndSuper.first;
2739+
const ClassMetadata *super = superDependencyAndSuper.second;
27112740

27122741
// Check that it matches what's already in there.
27132742
if (!super)
@@ -2741,6 +2770,29 @@ swift::swift_updateClassMetadata(ClassMetadata *self,
27412770
// See remark above about how this slides field offset globals.
27422771
_objc_realizeClassFromSwift((Class)self, (Class)self);
27432772
}
2773+
2774+
return MetadataDependency();
2775+
}
2776+
2777+
void swift::swift_updateClassMetadata(ClassMetadata *self,
2778+
ClassLayoutFlags layoutFlags,
2779+
size_t numFields,
2780+
const TypeLayout * const *fieldTypes,
2781+
size_t *fieldOffsets) {
2782+
(void) _swift_updateClassMetadataImpl(self, layoutFlags, numFields,
2783+
fieldTypes, fieldOffsets,
2784+
/*allowDependency*/ false);
2785+
}
2786+
2787+
MetadataDependency
2788+
swift::swift_updateClassMetadata2(ClassMetadata *self,
2789+
ClassLayoutFlags layoutFlags,
2790+
size_t numFields,
2791+
const TypeLayout * const *fieldTypes,
2792+
size_t *fieldOffsets) {
2793+
return _swift_updateClassMetadataImpl(self, layoutFlags, numFields,
2794+
fieldTypes, fieldOffsets,
2795+
/*allowDependency*/ true);
27442796
}
27452797

27462798
#pragma clang diagnostic pop

0 commit comments

Comments
 (0)