Skip to content

Commit edddf31

Browse files
committed
IRGen: Add method lists of generic class patterns to their own section
Put the method lists in generic class patterns in a section __objc_methodlist such that they are discoverable by the linker. The linker can then make them relative like it can for regular objective c class metadata. rdar://66634459
1 parent 83d9781 commit edddf31

File tree

2 files changed

+39
-24
lines changed

2 files changed

+39
-24
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,9 +1436,10 @@ namespace {
14361436
weakLinkage);
14371437
}
14381438

1439-
void emitRODataFields(ConstantStructBuilder &b,
1440-
ForMetaClass_t forMeta,
1441-
HasUpdateCallback_t hasUpdater) {
1439+
void emitRODataFields(
1440+
ConstantStructBuilder &b, ForMetaClass_t forMeta,
1441+
HasUpdateCallback_t hasUpdater,
1442+
ForGenericPattern_t isForGeneric = IsNotForGenericPattern) {
14421443
assert(FieldLayout && "can't emit rodata for a category");
14431444

14441445
// struct _class_ro_t {
@@ -1497,7 +1498,7 @@ namespace {
14971498
emitAndAddMethodList(b,
14981499
forMeta ? MethodListKind::ClassMethods
14991500
: MethodListKind::InstanceMethods,
1500-
llvm::GlobalVariable::InternalLinkage);
1501+
llvm::GlobalVariable::InternalLinkage, isForGeneric);
15011502

15021503
// const protocol_list_t *baseProtocols;
15031504
// Apparently, this list is the same in the class and the metaclass.
@@ -1530,7 +1531,7 @@ namespace {
15301531

15311532
// };
15321533
}
1533-
1534+
15341535
llvm::Constant *emitROData(ForMetaClass_t forMeta,
15351536
HasUpdateCallback_t hasUpdater) {
15361537
ConstantInitBuilder builder(IGM);
@@ -1763,9 +1764,10 @@ namespace {
17631764
};
17641765

17651766
/// Emit the method list and add the pointer to the `builder`.
1766-
void emitAndAddMethodList(ConstantInitBuilder::StructBuilder &builder,
1767-
MethodListKind kind,
1768-
llvm::GlobalValue::LinkageTypes linkage) {
1767+
void emitAndAddMethodList(
1768+
ConstantInitBuilder::StructBuilder &builder, MethodListKind kind,
1769+
llvm::GlobalValue::LinkageTypes linkage,
1770+
ForGenericPattern_t isForGeneric = IsNotForGenericPattern) {
17691771
ArrayRef<MethodDescriptor> methods;
17701772
StringRef namePrefix;
17711773
switch (kind) {
@@ -1791,7 +1793,7 @@ namespace {
17911793
break;
17921794
}
17931795
llvm::Constant *methodListPtr =
1794-
buildMethodList(methods, namePrefix, linkage);
1796+
buildMethodList(methods, namePrefix, linkage, isForGeneric);
17951797
builder.add(methodListPtr);
17961798
}
17971799

@@ -1837,7 +1839,8 @@ namespace {
18371839
/// This method does not return a value of a predictable type.
18381840
llvm::Constant *buildMethodList(ArrayRef<MethodDescriptor> methods,
18391841
StringRef name,
1840-
llvm::GlobalValue::LinkageTypes linkage) {
1842+
llvm::GlobalValue::LinkageTypes linkage,
1843+
ForGenericPattern_t isForGeneric) {
18411844
return buildOptionalList(
18421845
methods, 3 * IGM.getPointerSize(), name,
18431846
/*isConst*/ false, linkage,
@@ -2146,10 +2149,11 @@ namespace {
21462149
/// \param optionalEltSize - if non-zero, a size which needs
21472150
/// to be placed in the list header
21482151
template <class C, class Fn>
2149-
llvm::Constant *buildOptionalList(const C &objects, Size optionalEltSize,
2150-
StringRef nameBase, bool isConst,
2151-
llvm::GlobalValue::LinkageTypes linkage,
2152-
Fn &&buildElement) {
2152+
llvm::Constant *buildOptionalList(
2153+
const C &objects, Size optionalEltSize, StringRef nameBase,
2154+
bool isConst, llvm::GlobalValue::LinkageTypes linkage,
2155+
Fn &&buildElement,
2156+
ForGenericPattern_t isForGeneric = IsNotForGenericPattern) {
21532157
if (objects.empty())
21542158
return null();
21552159

@@ -2187,7 +2191,8 @@ namespace {
21872191

21882192
fields.fillPlaceholderWithInt(countPosition, countType, count);
21892193

2190-
return buildGlobalVariable(fields, nameBase, isConst, linkage);
2194+
return buildGlobalVariable(fields, nameBase, isConst, linkage,
2195+
isForGeneric);
21912196
}
21922197

21932198
/// Get the name of the class or protocol to mangle into the ObjC symbol
@@ -2216,9 +2221,10 @@ namespace {
22162221
/// Build a private global variable as a structure containing the
22172222
/// given fields.
22182223
template <class B>
2219-
llvm::Constant *
2220-
buildGlobalVariable(B &fields, StringRef nameBase, bool isConst,
2221-
llvm::GlobalValue::LinkageTypes linkage) {
2224+
llvm::Constant *buildGlobalVariable(
2225+
B &fields, StringRef nameBase, bool isConst,
2226+
llvm::GlobalValue::LinkageTypes linkage,
2227+
ForGenericPattern_t isForGeneric = IsNotForGenericPattern) {
22222228
llvm::SmallString<64> nameBuffer;
22232229
auto var =
22242230
fields.finishAndCreateGlobal(Twine(nameBase)
@@ -2235,8 +2241,12 @@ namespace {
22352241

22362242
switch (IGM.TargetInfo.OutputObjectFormat) {
22372243
case llvm::Triple::MachO:
2238-
var->setSection(isConst ? "__DATA, __objc_const"
2239-
: "__DATA, __objc_data");
2244+
if (isForGeneric) {
2245+
var->setSection("__DATA, __objc_methlist,regular");
2246+
} else {
2247+
var->setSection(isConst ? "__DATA, __objc_const"
2248+
: "__DATA, __objc_data");
2249+
}
22402250
break;
22412251
case llvm::Triple::XCOFF:
22422252
case llvm::Triple::COFF:
@@ -2447,17 +2457,17 @@ irgen::emitClassPrivateDataFields(IRGenModule &IGM,
24472457

24482458
// Note: an update callback is only ever used with the in-place
24492459
// initialization pattern, which precludes generic classes.
2450-
builder.emitRODataFields(classRO,
2451-
ForClass,
2452-
DoesNotHaveUpdateCallback);
2460+
builder.emitRODataFields(classRO, ForClass, DoesNotHaveUpdateCallback,
2461+
IsForGenericPattern);
24532462
classRO.finishAndAddTo(init);
24542463
}
24552464

24562465
Size startOfMetaclassRO = init.getNextOffsetFromGlobal();
24572466
assert(startOfMetaclassRO.isMultipleOf(IGM.getPointerSize()));
24582467
{
24592468
auto classRO = init.beginStruct();
2460-
builder.emitRODataFields(classRO, ForMetaClass, DoesNotHaveUpdateCallback);
2469+
builder.emitRODataFields(classRO, ForMetaClass, DoesNotHaveUpdateCallback,
2470+
IsForGenericPattern);
24612471
classRO.finishAndAddTo(init);
24622472
}
24632473

lib/IRGen/GenClass.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ namespace irgen {
7878
HasUpdateCallback = true
7979
};
8080

81+
enum ForGenericPattern_t : bool {
82+
IsNotForGenericPattern = false,
83+
IsForGenericPattern = true
84+
};
85+
8186
/// Creates a layout for the class \p classType with allocated tail elements
8287
/// \p tailTypes.
8388
///

0 commit comments

Comments
 (0)