mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #60231 from aschwaighofer/generic_objc_method_list_section
IRGen: Add a list of class_ro_t referenced from generic class metadata patterns to a section __swift_rodatas
This commit is contained in:
@@ -401,6 +401,9 @@ public:
|
||||
/// Internalize symbols (static library) - do not export any public symbols.
|
||||
unsigned InternalizeSymbols : 1;
|
||||
|
||||
/// Emit a section with references to class_ro_t* in generic class patterns.
|
||||
unsigned EmitGenericRODatas : 1;
|
||||
|
||||
/// Whether to avoid emitting zerofill globals as preallocated type metadata
|
||||
/// and protocol conformance caches.
|
||||
unsigned NoPreallocatedInstantiationCaches : 1;
|
||||
@@ -475,7 +478,7 @@ public:
|
||||
EnableGlobalISel(false), VirtualFunctionElimination(false),
|
||||
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
|
||||
InternalizeAtLink(false), InternalizeSymbols(false),
|
||||
NoPreallocatedInstantiationCaches(false),
|
||||
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
|
||||
DisableReadonlyStaticObjects(false), CmdArgs(),
|
||||
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
||||
TypeInfoFilter(TypeInfoDumpFilter::All) {
|
||||
|
||||
@@ -1085,4 +1085,13 @@ def enable_new_llvm_pass_manager :
|
||||
def disable_new_llvm_pass_manager :
|
||||
Flag<["-"], "disable-new-llvm-pass-manager">,
|
||||
HelpText<"Disable the new llvm pass manager">;
|
||||
|
||||
def disable_emit_generic_class_ro_t_list :
|
||||
Flag<["-"], "disable-emit-generic-class-ro_t-list">,
|
||||
HelpText<"Disable emission of a section with references to class_ro_t of "
|
||||
"generic class patterns">;
|
||||
def enable_emit_generic_class_ro_t_list :
|
||||
Flag<["-"], "enable-emit-generic-class-ro_t-list">,
|
||||
HelpText<"Enable emission of a section with references to class_ro_t of "
|
||||
"generic class patterns">;
|
||||
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]
|
||||
|
||||
@@ -2397,6 +2397,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
||||
Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Never;
|
||||
}
|
||||
|
||||
Opts.EmitGenericRODatas =
|
||||
Args.hasFlag(OPT_enable_emit_generic_class_ro_t_list,
|
||||
OPT_disable_emit_generic_class_ro_t_list,
|
||||
Opts.EmitGenericRODatas);
|
||||
|
||||
Opts.LegacyPassManager =
|
||||
Args.hasFlag(OPT_disable_new_llvm_pass_manager,
|
||||
OPT_enable_new_llvm_pass_manager,
|
||||
|
||||
@@ -556,7 +556,7 @@ static llvm::GlobalVariable *
|
||||
emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
|
||||
StringRef name, StringRef section,
|
||||
llvm::GlobalValue::LinkageTypes linkage, llvm::Type *eltTy,
|
||||
bool isConstant, bool asContiguousArray) {
|
||||
bool isConstant, bool asContiguousArray, bool canBeStrippedByLinker = false) {
|
||||
// Do nothing if the list is empty.
|
||||
if (handles.empty()) return nullptr;
|
||||
|
||||
@@ -578,8 +578,12 @@ emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
|
||||
var->setSection(section);
|
||||
var->setAlignment(llvm::MaybeAlign(alignment.getValue()));
|
||||
disableAddressSanitizer(IGM, var);
|
||||
if (llvm::GlobalValue::isLocalLinkage(linkage))
|
||||
IGM.addUsedGlobal(var);
|
||||
if (llvm::GlobalValue::isLocalLinkage(linkage)) {
|
||||
if (canBeStrippedByLinker)
|
||||
IGM.addCompilerUsedGlobal(var);
|
||||
else
|
||||
IGM.addUsedGlobal(var);
|
||||
}
|
||||
|
||||
if (IGM.IRGen.Opts.ConditionalRuntimeRecords) {
|
||||
// Allow dead-stripping `var` (the runtime record from the global list)
|
||||
@@ -616,8 +620,12 @@ emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
|
||||
|
||||
// Mark the variable as used if doesn't have external linkage.
|
||||
// (Note that we'd specifically like to not put @llvm.used in itself.)
|
||||
if (llvm::GlobalValue::isLocalLinkage(linkage))
|
||||
IGM.addUsedGlobal(var);
|
||||
if (llvm::GlobalValue::isLocalLinkage(linkage)) {
|
||||
if (canBeStrippedByLinker)
|
||||
IGM.addCompilerUsedGlobal(var);
|
||||
else
|
||||
IGM.addUsedGlobal(var);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
@@ -962,6 +970,10 @@ void IRGenModule::addCompilerUsedGlobal(llvm::GlobalValue *global) {
|
||||
LLVMCompilerUsed.push_back(global);
|
||||
}
|
||||
|
||||
void IRGenModule::addGenericROData(llvm::Constant *RODataAddr) {
|
||||
GenericRODatas.push_back(RODataAddr);
|
||||
}
|
||||
|
||||
/// Add the given global value to the Objective-C class list.
|
||||
void IRGenModule::addObjCClass(llvm::Constant *classPtr, bool nonlazy) {
|
||||
ObjCClasses.push_back(classPtr);
|
||||
@@ -1067,6 +1079,14 @@ void IRGenModule::SetCStringLiteralSection(llvm::GlobalVariable *GV,
|
||||
|
||||
void IRGenModule::emitGlobalLists() {
|
||||
if (ObjCInterop) {
|
||||
if (IRGen.Opts.EmitGenericRODatas) {
|
||||
emitGlobalList(
|
||||
*this, GenericRODatas, "generic_ro_datas",
|
||||
GetObjCSectionName("__swift_rodatas", "regular"),
|
||||
llvm::GlobalValue::InternalLinkage, Int8PtrTy, /*isConstant*/ false,
|
||||
/*asContiguousArray*/ true, /*canBeStrippedByLinker*/ true);
|
||||
}
|
||||
|
||||
// Objective-C class references go in a variable with a meaningless
|
||||
// name but a magic section.
|
||||
emitGlobalList(
|
||||
|
||||
@@ -4043,6 +4043,8 @@ namespace {
|
||||
// Any bytes before this will be zeroed. Currently we don't take
|
||||
// advantage of this.
|
||||
Size patternOffset = Size(0);
|
||||
Size classROData = Size(0);
|
||||
Size metaclassROData = Size(0);
|
||||
|
||||
if (IGM.ObjCInterop) {
|
||||
// Add the metaclass object.
|
||||
@@ -4057,13 +4059,27 @@ namespace {
|
||||
IGM.getOffsetInWords(patternOffset + roDataPoints.first));
|
||||
B.fillPlaceholderWithInt(*MetaclassRODataOffset, IGM.Int16Ty,
|
||||
IGM.getOffsetInWords(patternOffset + roDataPoints.second));
|
||||
classROData = patternOffset + roDataPoints.first;
|
||||
metaclassROData = patternOffset + roDataPoints.second;
|
||||
}
|
||||
|
||||
auto patternSize = subB.getNextOffsetFromGlobal();
|
||||
|
||||
auto global = subB.finishAndCreateGlobal("", IGM.getPointerAlignment(),
|
||||
/*constant*/ true);
|
||||
if (IGM.ObjCInterop) {
|
||||
auto getRODataAtOffset = [&] (Size offset) -> llvm::Constant * {
|
||||
auto t0 = llvm::ConstantExpr::getBitCast(global, IGM.Int8PtrTy);
|
||||
llvm::Constant *indices[] = {llvm::ConstantInt::get(IGM.Int32Ty, offset.getValue())};
|
||||
return llvm::ConstantExpr::getBitCast(
|
||||
llvm::ConstantExpr::getInBoundsGetElementPtr(IGM.Int8Ty,
|
||||
t0, indices),
|
||||
IGM.Int8PtrTy);
|
||||
|
||||
};
|
||||
IGM.addGenericROData(getRODataAtOffset(classROData));
|
||||
IGM.addGenericROData(getRODataAtOffset(metaclassROData));
|
||||
}
|
||||
return { global, patternOffset, patternSize };
|
||||
}
|
||||
|
||||
|
||||
@@ -1080,6 +1080,7 @@ public:
|
||||
|
||||
void addUsedGlobal(llvm::GlobalValue *global);
|
||||
void addCompilerUsedGlobal(llvm::GlobalValue *global);
|
||||
void addGenericROData(llvm::Constant *addr);
|
||||
void addObjCClass(llvm::Constant *addr, bool nonlazy);
|
||||
void addObjCClassStub(llvm::Constant *addr);
|
||||
void addProtocolConformance(ConformanceDescription &&conformance);
|
||||
@@ -1198,6 +1199,8 @@ private:
|
||||
/// Metadata nodes for autolinking info.
|
||||
SmallVector<LinkLibrary, 32> AutolinkEntries;
|
||||
|
||||
// List of ro_data_t referenced from generic class patterns.
|
||||
SmallVector<llvm::WeakTrackingVH, 4> GenericRODatas;
|
||||
/// List of Objective-C classes, bitcast to i8*.
|
||||
SmallVector<llvm::WeakTrackingVH, 4> ObjCClasses;
|
||||
/// List of Objective-C classes that require nonlazy realization, bitcast to
|
||||
|
||||
46
test/IRGen/generic_class_rodata_list.swift
Normal file
46
test/IRGen/generic_class_rodata_list.swift
Normal file
@@ -0,0 +1,46 @@
|
||||
// RUN: %target-swift-frontend -enable-emit-generic-class-ro_t-list -S %s -o - | %FileCheck %s
|
||||
// REQUIRES: objc_interop
|
||||
// REQUIRES: CPU=x86_64 || CPU=arm64
|
||||
// REQUIRES: OS=macosx
|
||||
|
||||
// CHECK: ___unnamed_1:
|
||||
// CHECK: .quad _OBJC_METACLASS_$__TtCs12_SwiftObject
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad __objc_empty_cache
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad 0
|
||||
// Start of rodata_t
|
||||
// CHECK: .long 128
|
||||
// CHECK: .long 16
|
||||
// CHECK: .long 16
|
||||
// CHECK: .long 0
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad __INSTANCE_METHODS__TtC25generic_class_rodata_list9Something
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad 0
|
||||
// Start of rodata_t
|
||||
// CHECK: .long 129
|
||||
// CHECK: .long 40
|
||||
// CHECK: .long 40
|
||||
// CHECK: .long 0
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad 0
|
||||
// CHECK: .quad __CLASS_METHODS__TtC25generic_class_rodata_list9Somethin
|
||||
|
||||
// CHECK: .section __DATA,__swift_rodatas
|
||||
// CHECK: .p2align 3
|
||||
// CHECK:_generic_ro_datas:
|
||||
// CHECK: .quad ___unnamed_1+40
|
||||
// CHECK: .quad ___unnamed_1+112
|
||||
|
||||
import Foundation
|
||||
|
||||
public class Something<T> {
|
||||
@objc
|
||||
public func myMethod() { print("hello") }
|
||||
@objc
|
||||
public static func myStaticMethod() { print("static") }
|
||||
}
|
||||
Reference in New Issue
Block a user