Skip to content

Commit d6868ac

Browse files
committed
IRGen: Categories on class stubs should go in a separate list and section
1 parent 2846fa6 commit d6868ac

File tree

8 files changed

+53
-42
lines changed

8 files changed

+53
-42
lines changed

lib/IRGen/GenCast.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ FailableCastResult irgen::emitClassIdenticalCast(IRGenFunction &IGF,
107107
llvm::Value *targetMetadata;
108108
if ((targetMetadata =
109109
tryEmitConstantHeapMetadataRef(IGF.IGM, toType.getASTType(),
110-
/*allowUninitialized*/ false,
111-
/*allowStub*/ false))) {
110+
/*allowUninitialized*/ false))) {
112111
// ok
113112
} else {
114113
targetMetadata

lib/IRGen/GenClass.cpp

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,32 @@ namespace {
11941194
if (categoryCount > 0)
11951195
os << categoryCount;
11961196
}
1197-
1197+
1198+
llvm::Constant *getClassMetadataRef() {
1199+
auto *theClass = getClass();
1200+
1201+
if (theClass->hasClangNode())
1202+
return IGM.getAddrOfObjCClass(theClass, NotForDefinition);
1203+
1204+
// Note that getClassMetadataStrategy() will return
1205+
// ClassMetadataStrategy::Resilient if the class is
1206+
// from another resilience domain, even if inside that
1207+
// resilience domain the class has fixed metadata
1208+
// layout.
1209+
//
1210+
// Since a class only has a class stub if its class
1211+
// hierarchy crosses resilience domains, we use a
1212+
// slightly different query here.
1213+
if (theClass->checkAncestry(AncestryFlags::ResilientOther)) {
1214+
assert(IGM.Context.LangOpts.EnableObjCResilientClassStubs);
1215+
return IGM.getAddrOfObjCResilientClassStub(theClass, NotForDefinition,
1216+
TypeMetadataAddress::AddressPoint);
1217+
}
1218+
1219+
auto type = getSelfType(theClass).getASTType();
1220+
return tryEmitConstantHeapMetadataRef(IGM, type, /*allowUninit*/ true);
1221+
}
1222+
11981223
public:
11991224
llvm::Constant *emitCategory() {
12001225
assert(TheExtension && "can't emit category data for a class");
@@ -1205,18 +1230,7 @@ namespace {
12051230
// char const *name;
12061231
fields.add(IGM.getAddrOfGlobalString(CategoryName));
12071232
// const class_t *theClass;
1208-
if (getClass()->hasClangNode())
1209-
fields.add(IGM.getAddrOfObjCClass(getClass(), NotForDefinition));
1210-
else {
1211-
auto type = getSelfType(getClass()).getASTType();
1212-
llvm::Constant *metadata =
1213-
tryEmitConstantHeapMetadataRef(IGM, type,
1214-
/*allowUninit*/ true,
1215-
/*allowStub*/ true);
1216-
assert(metadata &&
1217-
"extended objc class doesn't have constant metadata?");
1218-
fields.add(metadata);
1219-
}
1233+
fields.add(getClassMetadataRef());
12201234
// const method_list_t *instanceMethods;
12211235
fields.add(buildInstanceMethodList());
12221236
// const method_list_t *classMethods;

lib/IRGen/GenDecl.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,12 @@ void IRGenModule::emitGlobalLists() {
928928
"regular,no_dead_strip"),
929929
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
930930

931+
// And categories on class stubs.
932+
emitGlobalList(*this, ObjCCategoriesOnStubs, "objc_categories_stubs",
933+
GetObjCSectionName("__objc_catlist2",
934+
"regular,no_dead_strip"),
935+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
936+
931937
// Emit nonlazily realized class references in a second magic section to make
932938
// sure they are realized by the Objective-C runtime before any instances
933939
// are allocated.
@@ -3802,7 +3808,15 @@ void IRGenModule::emitExtension(ExtensionDecl *ext) {
38023808
"foreign types cannot have categories emitted");
38033809
llvm::Constant *category = emitCategoryData(*this, ext);
38043810
category = llvm::ConstantExpr::getBitCast(category, Int8PtrTy);
3805-
ObjCCategories.push_back(category);
3811+
3812+
auto *theClass = ext->getSelfClassDecl();
3813+
3814+
// Categories on class stubs are added to a separate list.
3815+
if (theClass->checkAncestry(AncestryFlags::ResilientOther))
3816+
ObjCCategoriesOnStubs.push_back(category);
3817+
else
3818+
ObjCCategories.push_back(category);
3819+
38063820
ObjCCategoryDecls.push_back(ext);
38073821
}
38083822
}

lib/IRGen/GenMeta.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2649,8 +2649,7 @@ namespace {
26492649
Type type = Target->mapTypeIntoContext(Target->getSuperclass());
26502650
auto *metadata = tryEmitConstantHeapMetadataRef(
26512651
IGM, type->getCanonicalType(),
2652-
/*allowUninit*/ false,
2653-
/*allowStub*/ false);
2652+
/*allowUninit*/ false);
26542653
assert(metadata != nullptr);
26552654
B.add(metadata);
26562655
}

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,8 @@ class IRGenModule {
987987
SmallVector<llvm::WeakTrackingVH, 4> ObjCNonLazyClasses;
988988
/// List of Objective-C categories, bitcast to i8*.
989989
SmallVector<llvm::WeakTrackingVH, 4> ObjCCategories;
990+
/// List of Objective-C categories on class stubs, bitcast to i8*.
991+
SmallVector<llvm::WeakTrackingVH, 4> ObjCCategoriesOnStubs;
990992
/// List of non-ObjC protocols described by this module.
991993
SmallVector<ProtocolDecl *, 4> SwiftProtocols;
992994
/// List of protocol conformances to generate descriptors for.

lib/IRGen/MetadataRequest.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -517,29 +517,10 @@ irgen::getRuntimeReifiedType(IRGenModule &IGM, CanType type) {
517517
llvm::Constant *
518518
irgen::tryEmitConstantHeapMetadataRef(IRGenModule &IGM,
519519
CanType type,
520-
bool allowDynamicUninitialized,
521-
bool allowStub) {
520+
bool allowDynamicUninitialized) {
522521
auto theDecl = type->getClassOrBoundGenericClass();
523522
assert(theDecl && "emitting constant heap metadata ref for non-class type?");
524523

525-
// Note that getClassMetadataStrategy() will return
526-
// ClassMetadataStrategy::Resilient if the class is
527-
// from another resilience domain, even if inside that
528-
// resilience domain the class has fixed metadata
529-
// layout.
530-
//
531-
// Since a class only has a class stub if its class
532-
// hierarchy crosses resilience domains, we use a
533-
// slightly different query here.
534-
if (theDecl->checkAncestry(AncestryFlags::ResilientOther)) {
535-
if (allowStub && IGM.Context.LangOpts.EnableObjCResilientClassStubs) {
536-
return IGM.getAddrOfObjCResilientClassStub(theDecl, NotForDefinition,
537-
TypeMetadataAddress::AddressPoint);
538-
}
539-
540-
return nullptr;
541-
}
542-
543524
switch (IGM.getClassMetadataStrategy(theDecl)) {
544525
case ClassMetadataStrategy::Resilient:
545526
case ClassMetadataStrategy::Singleton:

lib/IRGen/MetadataRequest.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,7 @@ CanType getRuntimeReifiedType(IRGenModule &IGM, CanType type);
592592
/// by a constant.
593593
llvm::Constant *tryEmitConstantHeapMetadataRef(IRGenModule &IGM,
594594
CanType type,
595-
bool allowUninitialized,
596-
bool allowStub);
595+
bool allowUninitialized);
597596

598597
enum class MetadataValueType { ObjCClass, TypeMetadata };
599598

test/IRGen/class_update_callback_with_stub.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,14 @@ import resilient_objc_class
104104
// -- The category list
105105

106106
// CHECK-LABEL: @objc_categories = internal global
107+
// CHECK-SAME: @"_CATEGORY__TtC15resilient_class22ResilientOutsideParent_$_class_update_callback_with_stub"
108+
// CHECK-SAME: , section "__DATA,__objc_catlist,regular,no_dead_strip"
109+
110+
// CHECK-LABEL: @objc_categories_stubs = internal global
107111
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub17ResilientSubclass_$_class_update_callback_with_stub"
108112
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub25ResilientNSObjectSubclass_$_class_update_callback_with_stub"
109113
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub27FixedLayoutNSObjectSubclass_$_class_update_callback_with_stub"
110-
// CHECK-SAME: @"_CATEGORY__TtC15resilient_class22ResilientOutsideParent_$_class_update_callback_with_stub"
111-
// CHECK-SAME: , section "__DATA,__objc_catlist,regular,no_dead_strip"
114+
// CHECK-SAME: , section "__DATA,__objc_catlist2,regular,no_dead_strip"
112115

113116

114117
// -- Address point for class stubs

0 commit comments

Comments
 (0)