diff options
-rw-r--r-- | lib/ExecutionEngine/JIT/JITEmitter.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index cb12642367..8b5071b31d 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -138,6 +138,9 @@ namespace { // to. std::map<void*, Function*> StubToFunctionMap; + /// ExternalFnToStubMap - This is the equivalent of FunctionToStubMap for + /// external functions. + std::map<void*, void*> ExternalFnToStubMap; public: JITResolver(MachineCodeEmitter &mce) : MCE(mce) { LazyResolverFn = @@ -148,6 +151,10 @@ namespace { /// one on demand as needed. void *getFunctionStub(Function *F); + /// getExternalFunctionStub - Return a stub for the function at the + /// specified address, created lazily on demand. + void *getExternalFunctionStub(void *FnAddr); + /// AddCallbackAtLocation - If the target is capable of rewriting an /// instruction without the use of a stub, record the location of the use so /// we know which function is being used at the location. @@ -204,6 +211,20 @@ void *JITResolver::getFunctionStub(Function *F) { return Stub; } +/// getExternalFunctionStub - Return a stub for the function at the +/// specified address, created lazily on demand. +void *JITResolver::getExternalFunctionStub(void *FnAddr) { + // If we already have a stub for this function, recycle it. + void *&Stub = ExternalFnToStubMap[FnAddr]; + if (Stub) return Stub; + + Stub = TheJIT->getJITInfo().emitFunctionStub(FnAddr, MCE); + DEBUG(std::cerr << "JIT: Stub emitted at [" << Stub + << "] for external function at '" << FnAddr << "'\n"); + return Stub; +} + + /// JITCompilerFn - This function is called when a lazy compilation stub has /// been entered. It looks up which function this stub corresponds to, compiles /// it if necessary, then returns the resultant function pointer. @@ -350,9 +371,13 @@ void JITEmitter::finishFunction(MachineFunction &F) { for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { MachineRelocation &MR = Relocations[i]; void *ResultPtr; - if (MR.isString()) + if (MR.isString()) { ResultPtr = TheJIT->getPointerToNamedFunction(MR.getString()); - else + + // If the target REALLY wants a stub for this function, emit it now. + if (!MR.doesntNeedFunctionStub()) + ResultPtr = getJITResolver(this).getExternalFunctionStub(ResultPtr); + } else ResultPtr = getPointerToGlobal(MR.getGlobalValue(), CurBlock+MR.getMachineCodeOffset(), MR.doesntNeedFunctionStub()); |