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.
|
/// The optimization level, as in -O2.
|
||||||
unsigned OptLevel : 2;
|
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
|
} // end namespace irgen
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
|
|
||||||
|
#include "swift/IRGen/Options.h"
|
||||||
#include "swift/AST/Decl.h"
|
#include "swift/AST/Decl.h"
|
||||||
#include "swift/AST/Types.h"
|
#include "swift/AST/Types.h"
|
||||||
|
|
||||||
@@ -68,6 +69,17 @@ llvm::Constant *IRGenModule::getObjCMsgSendStretFn() {
|
|||||||
return ObjCMsgSendStretFn;
|
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) \
|
#define DEFINE_OBJC_RUNTIME_FUNCTION(LABEL, NAME, RETTY) \
|
||||||
llvm::Constant *IRGenModule::getObjC##LABEL##Fn() { \
|
llvm::Constant *IRGenModule::getObjC##LABEL##Fn() { \
|
||||||
if (ObjC##LABEL##Fn) return ObjC##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());
|
selfValues.addUnmanaged(value.getValue());
|
||||||
|
|
||||||
// Add the selector value.
|
// Add the selector value.
|
||||||
|
llvm::Value *selectorV;
|
||||||
Selector selector(method);
|
Selector selector(method);
|
||||||
auto selectorRef = IGF.IGM.getAddrOfObjCSelectorRef(selector.str());
|
if (IGF.IGM.Opts.UseJIT) {
|
||||||
auto selectorV =
|
// When generating JIT'd code, we need to call sel_registerName() to force
|
||||||
IGF.Builder.CreateLoad(Address(selectorRef, IGF.IGM.getPointerAlignment()));
|
// the runtime to unique the selector.
|
||||||
|
auto selectorRef = IGF.IGM.getAddrOfObjCSelectorRef(selector.str());
|
||||||
|
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);
|
selfValues.addUnmanaged(selectorV);
|
||||||
|
|
||||||
// Add that to the emission.
|
// Add that to the emission.
|
||||||
|
|||||||
@@ -208,6 +208,8 @@ public:
|
|||||||
llvm::Constant *getObjCMsgSendFn();
|
llvm::Constant *getObjCMsgSendFn();
|
||||||
llvm::Constant *getObjCMsgSendStretFn();
|
llvm::Constant *getObjCMsgSendStretFn();
|
||||||
|
|
||||||
|
llvm::Constant *getObjCSelRegisterNameFn();
|
||||||
|
|
||||||
llvm::Constant *getGetFunctionMetadataFn();
|
llvm::Constant *getGetFunctionMetadataFn();
|
||||||
llvm::Constant *getGetGenericMetadataFn();
|
llvm::Constant *getGetGenericMetadataFn();
|
||||||
llvm::Constant *getGetMetatypeMetadataFn();
|
llvm::Constant *getGetMetatypeMetadataFn();
|
||||||
@@ -232,6 +234,7 @@ private:
|
|||||||
llvm::Constant *ObjCReleaseFn = nullptr;
|
llvm::Constant *ObjCReleaseFn = nullptr;
|
||||||
llvm::Constant *ObjCMsgSendFn = nullptr;
|
llvm::Constant *ObjCMsgSendFn = nullptr;
|
||||||
llvm::Constant *ObjCMsgSendStretFn = nullptr;
|
llvm::Constant *ObjCMsgSendStretFn = nullptr;
|
||||||
|
llvm::Constant *ObjCSelRegisterNameFn = nullptr;
|
||||||
|
|
||||||
//--- Generic ---------------------------------------------------------------
|
//--- Generic ---------------------------------------------------------------
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ void swift::RunImmediately(TranslationUnit *TU) {
|
|||||||
Options.Triple = llvm::sys::getDefaultTargetTriple();
|
Options.Triple = llvm::sys::getDefaultTargetTriple();
|
||||||
Options.OptLevel = 2;
|
Options.OptLevel = 2;
|
||||||
Options.OutputKind = irgen::OutputKind::Module;
|
Options.OutputKind = irgen::OutputKind::Module;
|
||||||
|
Options.UseJIT = true;
|
||||||
|
|
||||||
// IRGen the main module.
|
// IRGen the main module.
|
||||||
llvm::LLVMContext LLVMContext;
|
llvm::LLVMContext LLVMContext;
|
||||||
llvm::Module Module(TU->Name.str(), LLVMContext);
|
llvm::Module Module(TU->Name.str(), LLVMContext);
|
||||||
@@ -299,7 +300,8 @@ void swift::REPL(ASTContext &Context) {
|
|||||||
Options.Triple = llvm::sys::getDefaultTargetTriple();
|
Options.Triple = llvm::sys::getDefaultTargetTriple();
|
||||||
Options.OptLevel = 0;
|
Options.OptLevel = 0;
|
||||||
Options.OutputKind = irgen::OutputKind::Module;
|
Options.OutputKind = irgen::OutputKind::Module;
|
||||||
|
Options.UseJIT = true;
|
||||||
|
|
||||||
EditLineWrapper e;
|
EditLineWrapper e;
|
||||||
|
|
||||||
char* CurBuffer = const_cast<char*>(Buffer->getBufferStart());
|
char* CurBuffer = const_cast<char*>(Buffer->getBufferStart());
|
||||||
|
|||||||
Reference in New Issue
Block a user