-}
-
-JITResolver *JITResolver::TheJITResolver = 0;
-
-/// getFunctionStubIfAvailable - This returns a pointer to a function stub
-/// if it has already been created.
-void *JITResolver::getFunctionStubIfAvailable(Function *F) {
- MutexGuard locked(TheJIT->lock);
-
- // If we already have a stub for this function, recycle it.
- void *&Stub = state.getFunctionToStubMap(locked)[F];
- return Stub;
-}
-
-/// getFunctionStub - This returns a pointer to a function stub, creating
-/// one on demand as needed.
-void *JITResolver::getFunctionStub(Function *F) {
- MutexGuard locked(TheJIT->lock);
-
- // If we already have a stub for this function, recycle it.
- void *&Stub = state.getFunctionToStubMap(locked)[F];
- if (Stub) return Stub;
-
- // Call the lazy resolver function unless we are JIT'ing non-lazily, in which
- // case we must resolve the symbol now.
- void *Actual = TheJIT->isLazyCompilationDisabled()
- ? (void *)0 : (void *)(intptr_t)LazyResolverFn;
-
- // If this is an external declaration, attempt to resolve the address now
- // to place in the stub.
- if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) {
- Actual = TheJIT->getPointerToFunction(F);
-
- // If we resolved the symbol to a null address (eg. a weak external)
- // don't emit a stub. Return a null pointer to the application. If dlsym
- // stubs are enabled, not being able to resolve the address is not
- // meaningful.
- if (!Actual && !TheJIT->areDlsymStubsEnabled()) return 0;
- }
-
- // Codegen a new stub, calling the lazy resolver or the actual address of the
- // external function, if it was resolved.
- Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual,
- *TheJIT->getCodeEmitter());
-
- if (Actual != (void*)(intptr_t)LazyResolverFn) {
- // If we are getting the stub for an external function, we really want the
- // address of the stub in the GlobalAddressMap for the JIT, not the address
- // of the external function.
- TheJIT->updateGlobalMapping(F, Stub);
- }
-
- DEBUG(errs() << "JIT: Stub emitted at [" << Stub << "] for function '"
- << F->getName() << "'\n");
-
- // Finally, keep track of the stub-to-Function mapping so that the
- // JITCompilerFn knows which function to compile!
- state.getStubToFunctionMap(locked)[Stub] = F;
-
- // If we are JIT'ing non-lazily but need to call a function that does not
- // exist yet, add it to the JIT's work list so that we can fill in the stub
- // address later.
- if (!Actual && TheJIT->isLazyCompilationDisabled())
- if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode())
- TheJIT->addPendingFunction(F);
-
- return Stub;
-}
-
-/// getGlobalValueIndirectSym - Return a lazy pointer containing the specified
-/// GV address.
-void *JITResolver::getGlobalValueIndirectSym(GlobalValue *GV, void *GVAddress) {
- MutexGuard locked(TheJIT->lock);
-
- // If we already have a stub for this global variable, recycle it.
- void *&IndirectSym = state.getGlobalToIndirectSymMap(locked)[GV];
- if (IndirectSym) return IndirectSym;
-
- // Otherwise, codegen a new indirect symbol.
- IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV, GVAddress,
- *TheJIT->getCodeEmitter());
-
- DEBUG(errs() << "JIT: Indirect symbol emitted at [" << IndirectSym
- << "] for GV '" << GV->getName() << "'\n");
-
- return IndirectSym;
-}
-
-/// 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(0, FnAddr,
- *TheJIT->getCodeEmitter());