mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Use the Objective-C runtime to unique selectors in JIT'd code.
When generating IR for the JIT, use sel_registerName() to unique the selector references we generate. Static code doesn't need this pessimization. Fixes <rdar://problem/12764732>. Swift SVN r3403
This commit is contained in:
@@ -56,7 +56,11 @@ public:
|
||||
/// The optimization level, as in -O2.
|
||||
unsigned OptLevel : 2;
|
||||
|
||||
Options() : OutputKind(OutputKind::LLVMAssembly), Verify(true), OptLevel(0) {}
|
||||
/// \brief Whether we're generating IR for the JIT.
|
||||
unsigned UseJIT : 1;
|
||||
|
||||
Options() : OutputKind(OutputKind::LLVMAssembly), Verify(true), OptLevel(0),
|
||||
UseJIT(false) {}
|
||||
};
|
||||
|
||||
} // end namespace irgen
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Module.h"
|
||||
|
||||
#include "swift/IRGen/Options.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/Types.h"
|
||||
|
||||
@@ -68,6 +69,17 @@ llvm::Constant *IRGenModule::getObjCMsgSendStretFn() {
|
||||
return ObjCMsgSendStretFn;
|
||||
}
|
||||
|
||||
llvm::Constant *IRGenModule::getObjCSelRegisterNameFn() {
|
||||
if (ObjCSelRegisterNameFn) return ObjCSelRegisterNameFn;
|
||||
|
||||
// SEL sel_registerName(const char *str);
|
||||
llvm::Type *argTypes[1] = { Int8PtrTy };
|
||||
auto fnType = llvm::FunctionType::get(Int8PtrTy, argTypes, false);
|
||||
ObjCSelRegisterNameFn = createObjCRuntimeFunction(*this, "sel_registerName",
|
||||
fnType);
|
||||
return ObjCSelRegisterNameFn;
|
||||
}
|
||||
|
||||
#define DEFINE_OBJC_RUNTIME_FUNCTION(LABEL, NAME, RETTY) \
|
||||
llvm::Constant *IRGenModule::getObjC##LABEL##Fn() { \
|
||||
if (ObjC##LABEL##Fn) return ObjC##LABEL##Fn; \
|
||||
@@ -418,10 +430,24 @@ CallEmission irgen::prepareObjCMethodCall(IRGenFunction &IGF, FuncDecl *method,
|
||||
selfValues.addUnmanaged(value.getValue());
|
||||
|
||||
// Add the selector value.
|
||||
llvm::Value *selectorV;
|
||||
Selector selector(method);
|
||||
if (IGF.IGM.Opts.UseJIT) {
|
||||
// When generating JIT'd code, we need to call sel_registerName() to force
|
||||
// the runtime to unique the selector.
|
||||
auto selectorRef = IGF.IGM.getAddrOfObjCSelectorRef(selector.str());
|
||||
auto selectorV =
|
||||
IGF.Builder.CreateLoad(Address(selectorRef, IGF.IGM.getPointerAlignment()));
|
||||
selectorV = IGF.Builder.CreateLoad(Address(selectorRef,
|
||||
IGF.IGM.getPointerAlignment()));
|
||||
selectorV = IGF.Builder.CreateCall(IGF.IGM.getObjCSelRegisterNameFn(),
|
||||
selectorV);
|
||||
} else {
|
||||
// When generating statically-compiled code, just build a reference to
|
||||
// the selector.
|
||||
auto selectorRef = IGF.IGM.getAddrOfObjCSelectorRef(selector.str());
|
||||
selectorV = IGF.Builder.CreateLoad(Address(selectorRef,
|
||||
IGF.IGM.getPointerAlignment()));
|
||||
}
|
||||
|
||||
selfValues.addUnmanaged(selectorV);
|
||||
|
||||
// Add that to the emission.
|
||||
|
||||
@@ -208,6 +208,8 @@ public:
|
||||
llvm::Constant *getObjCMsgSendFn();
|
||||
llvm::Constant *getObjCMsgSendStretFn();
|
||||
|
||||
llvm::Constant *getObjCSelRegisterNameFn();
|
||||
|
||||
llvm::Constant *getGetFunctionMetadataFn();
|
||||
llvm::Constant *getGetGenericMetadataFn();
|
||||
llvm::Constant *getGetMetatypeMetadataFn();
|
||||
@@ -232,6 +234,7 @@ private:
|
||||
llvm::Constant *ObjCReleaseFn = nullptr;
|
||||
llvm::Constant *ObjCMsgSendFn = nullptr;
|
||||
llvm::Constant *ObjCMsgSendStretFn = nullptr;
|
||||
llvm::Constant *ObjCSelRegisterNameFn = nullptr;
|
||||
|
||||
//--- Generic ---------------------------------------------------------------
|
||||
public:
|
||||
|
||||
@@ -143,6 +143,7 @@ void swift::RunImmediately(TranslationUnit *TU) {
|
||||
Options.Triple = llvm::sys::getDefaultTargetTriple();
|
||||
Options.OptLevel = 2;
|
||||
Options.OutputKind = irgen::OutputKind::Module;
|
||||
Options.UseJIT = true;
|
||||
|
||||
// IRGen the main module.
|
||||
llvm::LLVMContext LLVMContext;
|
||||
@@ -299,6 +300,7 @@ void swift::REPL(ASTContext &Context) {
|
||||
Options.Triple = llvm::sys::getDefaultTargetTriple();
|
||||
Options.OptLevel = 0;
|
||||
Options.OutputKind = irgen::OutputKind::Module;
|
||||
Options.UseJIT = true;
|
||||
|
||||
EditLineWrapper e;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user