diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 47e751b754df8..c7602e535a52d 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -407,11 +407,6 @@ class FunctionMover : public ValueMaterializer // Check whether we already emitted it once if (emitted_function_symtab.find(shadow) != emitted_function_symtab.end()) return InjectFunctionProto(F); - uint64_t addr = jl_mcjmm->getSymbolAddress(F->getName()); - if (addr) { - emitted_function_symtab[shadow] = addr; - return InjectFunctionProto(F); - } Function *oldF = destModule->getFunction(F->getName()); if (oldF) diff --git a/src/codegen.cpp b/src/codegen.cpp index ac1e9ce456d07..6107f1add7397 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -203,7 +203,6 @@ ExecutionEngine *jl_ExecutionEngine; static Module *shadow_module; static Module *builtins_module; static Module *active_module; -static RTDyldMemoryManager *jl_mcjmm; #define jl_Module (builder.GetInsertBlock()->getParent()->getParent()) #else static Module *jl_Module; @@ -1002,9 +1001,6 @@ static uint64_t getAddressForOrCompileFunction(llvm::Function *llvmf) #ifdef JL_DEBUG_BUILD llvm::raw_fd_ostream out(1,false); #endif - uint64_t addr = jl_mcjmm->getSymbolAddress(llvmf->getName()); - if (addr) - return addr; Function *ActiveF = active_module->getFunction(llvmf->getName()); // Must have been in a prior module. Safe to ask the execution engine // to emit it. @@ -1043,7 +1039,7 @@ static uint64_t getAddressForOrCompileFunction(llvm::Function *llvmf) #endif jl_finalize_module(active_module); } - addr = jl_ExecutionEngine->getFunctionAddress(llvmf->getName()); + uint64_t addr = jl_ExecutionEngine->getFunctionAddress(llvmf->getName()); assert(addr != 0); if (!imaging_mode) { active_module = new Module("julia", jl_LLVMContext); @@ -1298,6 +1294,8 @@ extern int jl_get_llvmf_info(uint64_t fptr, uint64_t *symsize, uint64_t *slide, #endif ); +extern "C" +uint64_t jl_getUnwindInfo(uint64_t dwAddr); // Get pointer to llvm::Function instance, compiling if necessary extern "C" JL_DLLEXPORT @@ -1324,88 +1322,78 @@ void *jl_get_llvmf(jl_function_t *f, jl_tupletype_t *tt, bool getwrapper, bool g linfo = jl_get_unspecialized(linfo); } -#if defined(USE_ORCJIT) || defined(USE_MCJIT) - if (linfo->functionObjects.functionObject == NULL && linfo->functionObjects.specFunctionObject == NULL) { - jl_compile_linfo(linfo, NULL); - } - if (getdeclarations) { - JL_GC_POP(); - if (getwrapper || linfo->functionObjects.specFunctionObject == NULL) - return linfo->functionObjects.functionObject; + if (!getdeclarations) { + Function *llvmDecl = nullptr; + if (!getwrapper && linfo->functionObjects.specFunctionObject != NULL) + llvmDecl = (Function*)linfo->functionObjects.specFunctionObject; else - return linfo->functionObjects.specFunctionObject; - } - - Function *llvmDecl = nullptr; - if (!getwrapper && linfo->functionObjects.specFunctionObject != NULL) - llvmDecl = (Function*)linfo->functionObjects.specFunctionObject; - else - llvmDecl = (Function*)linfo->functionObjects.functionObject; - - Function *llvmf = active_module->getFunction(llvmDecl->getName()); - // Not in active module anymore, recompile - // Now that in either case, we need to run the FPM manually, - // since this is now usually done as part of object emission - if (!llvmf) { - Function *other; - jl_llvm_functions_t declarations; - emit_function(linfo, nullptr, &declarations, nullptr); - if (getwrapper || !declarations.specFunctionObject) { - llvmf = (llvm::Function*)declarations.functionObject; - other = (llvm::Function*)declarations.specFunctionObject; + llvmDecl = (Function*)linfo->functionObjects.functionObject; +#if defined(USE_ORCJIT) || defined(USE_MCJIT) + Function *llvmf = llvmDecl ? active_module->getFunction(llvmDecl->getName()) : NULL; + // Note that in either case, we need to run the FPM manually, + // since this is now usually done as part of object emission +#else + Function *llvmf = llvmDecl && !llvmDecl->isDeclaration() ? llvmDecl : NULL; +#endif + if (!llvmf) { + Function *other; + jl_llvm_functions_t declarations; + emit_function(linfo, nullptr, &declarations, nullptr); + if (getwrapper || !declarations.specFunctionObject) { + llvmf = (llvm::Function*)declarations.functionObject; + other = (llvm::Function*)declarations.specFunctionObject; + } + else { + llvmf = (llvm::Function*)declarations.specFunctionObject; + other = (llvm::Function*)declarations.functionObject; + } + if (other) + other->eraseFromParent(); +#if defined(USE_ORCJIT) || defined(USE_MCJIT) + FPM->run(*llvmf); +#endif + llvmf->removeFromParent(); + if (llvmDecl) + llvmf->setName(llvmDecl->getName()); } else { - llvmf = (llvm::Function*)declarations.specFunctionObject; - other = (llvm::Function*)declarations.functionObject; - } - if (other) - other->eraseFromParent(); - FPM->run(*llvmf); - llvmf->removeFromParent(); - } - else { - ValueToValueMapTy VMap; - llvmf = CloneFunction(llvmf,VMap,false); - active_module->getFunctionList().push_back(llvmf); - FPM->run(*llvmf); - llvmf->removeFromParent(); - } - JL_GC_POP(); - return llvmf; -#else - if (linfo->functionObjects.specFunctionObject != NULL) { - // found in the system image: force a recompile - Function *llvmf = (Function*)linfo->functionObjects.specFunctionObject; - if (llvmf->isDeclaration()) { - linfo->functionObjects.specFunctionObject = NULL; - linfo->functionObjects.functionObject = NULL; + ValueToValueMapTy VMap; + llvmf = CloneFunction(llvmf, VMap, false); +#if defined(USE_ORCJIT) || defined(USE_MCJIT) + active_module->getFunctionList().push_back(llvmf); + FPM->run(*llvmf); + llvmf->removeFromParent(); +#endif } + JL_GC_POP(); + return llvmf; } - if (linfo->functionObjects.functionObject != NULL) { + + if (linfo->fptr && !jl_getUnwindInfo((uintptr_t)linfo->fptr)) { + // Not in in the current ExecutionEngine // found in the system image: force a recompile - Function *llvmf = (Function*)linfo->functionObjects.functionObject; - if (llvmf->isDeclaration()) { - linfo->functionObjects.specFunctionObject = NULL; - linfo->functionObjects.functionObject = NULL; - } + linfo->functionObjects.specFunctionObject = NULL; + linfo->functionObjects.functionObject = NULL; + linfo->fptr = NULL; } - if (linfo->functionObjects.functionObject == NULL && - linfo->functionObjects.specFunctionObject == NULL) { + if (linfo->functionObjects.functionObject == NULL) { jl_compile_linfo(linfo, NULL); } - JL_GC_POP(); Function *llvmf; - if (!getwrapper && linfo->functionObjects.specFunctionObject != NULL) + if (!getwrapper && linfo->functionObjects.specFunctionObject != NULL) { llvmf = (Function*)linfo->functionObjects.specFunctionObject; - else - llvmf = (Function*)linfo->functionObjects.functionObject; - if (getdeclarations) - return llvmf; + } else { - ValueToValueMapTy VMap; - return CloneFunction(llvmf,VMap,false); + llvmf = (Function*)linfo->functionObjects.functionObject; + } +#if !defined(USE_ORCJIT) && !defined(USE_MCJIT) + if (!getdeclarations) { + ValueToValueMapTy VMap; + llvmf = CloneFunction(llvmf, VMap, false); } #endif + JL_GC_POP(); + return llvmf; } extern "C" JL_DLLEXPORT @@ -5990,9 +5978,6 @@ extern "C" void jl_init_codegen(void) // turn on JIT support for libunwind to walk the stack options.JITExceptionHandling = 1; #endif -#ifdef USE_MCJIT - jl_mcjmm = new SectionMemoryManager(); -#endif #ifdef LLVM36 EngineBuilder eb((std::unique_ptr(engine_module))); diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 44eaa2edd3a02..7ef9c270102b8 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -1154,23 +1154,36 @@ RTDyldMemoryManager *createRTDyldMemoryManagerOSX() #endif -#if defined(_OS_WINDOWS_) #ifdef USE_MCJIT extern "C" -DWORD64 jl_getUnwindInfo(ULONG64 dwAddr) +uint64_t jl_getUnwindInfo(uint64_t dwAddr) { std::map &objmap = jl_jit_events->getObjectMap(); std::map::iterator it = objmap.lower_bound(dwAddr); - DWORD64 ipstart = 0; // ip of the first instruction in the function (if found) + uint64_t ipstart = 0; // ip of the first instruction in the function (if found) if (it != objmap.end() && (intptr_t)(*it).first + (*it).second.size > dwAddr) { - ipstart = (DWORD64)(intptr_t)(*it).first; + ipstart = (uint64_t)(intptr_t)(*it).first; } uv_rwlock_rdunlock(&threadsafe); return ipstart; } +#else +extern "C" +uint64_t jl_getUnwindInfo(uint64_t dwAddr) +{ + std::map &info = jl_jit_events->getMap(); + std::map::iterator it = info.lower_bound(dwAddr); + uint64_t ipstart = 0; // ip of the first instruction in the function (if found) + if (it != info.end() && (intptr_t)(*it).first + (*it).second.lengthAdr > dwAddr) { + ipstart = (uint64_t)(intptr_t)(*it).first; + } + uv_rwlock_rdunlock(&threadsafe); + return ipstart; +} +#endif -#else //ifdef USE_MCJIT -#if defined(_CPU_X86_64_) + +#if defined(_OS_WINDOWS_) && !defined(USE_MCJIT) && defined(_CPU_X86_64_) // Custom memory manager for exception handling on Windows // we overallocate 48 bytes at the end of each function // for unwind information (see NotifyFunctionEmitted) @@ -1258,19 +1271,4 @@ JITMemoryManager *createJITMemoryManagerWin() { return new JITMemoryManagerWin(); } -#else -extern "C" -DWORD64 jl_getUnwindInfo(ULONG64 dwAddr) -{ - std::map &info = jl_jit_events->getMap(); - std::map::iterator it = info.lower_bound(dwAddr); - DWORD64 ipstart = 0; // ip of the first instruction in the function (if found) - if (it != info.end() && (intptr_t)(*it).first + (*it).second.lengthAdr > dwAddr) { - ipstart = (DWORD64)(intptr_t)(*it).first; - } - uv_rwlock_rdunlock(&threadsafe); - return ipstart; -} -#endif -#endif #endif diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 349f7ec12c830..2bf87c3e7b219 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -330,12 +330,8 @@ class JuliaOJIT { [&](const std::string &Name) { // TODO: consider moving the FunctionMover resolver here // Step 0: ObjectLinkingLayer has checked whether it is in the current module - // Step 1: Check against list of known external globals - GlobalSymbolTableT::const_iterator pos = GlobalSymbolTable.find(Name); - if (pos != GlobalSymbolTable.end()) - return RuntimeDyld::SymbolInfo((intptr_t)pos->second, JITSymbolFlags::Exported); - // Step 2: Search all previously emitted symbols - if (auto Sym = findSymbol(Name)) + // Step 1: See if it's something known to the ExecutionEngine + if (auto Sym = findSymbol(Name, true)) return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags()); // Step 2: Search the program symbols @@ -355,27 +351,34 @@ class JuliaOJIT { void removeModule(ModuleHandleT H) { CompileLayer->removeModuleSet(H); } - orc::JITSymbol findSymbol(const std::string &Name) + orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { - return CompileLayer->findSymbol(Name, true); + if (ExportedSymbolsOnly) { + // Step 1: Check against list of known external globals + GlobalSymbolTableT::const_iterator pos = GlobalSymbolTable.find(Name); + if (pos != GlobalSymbolTable.end()) + return orc::JITSymbol((uintptr_t)pos->second, JITSymbolFlags::Exported); + } + // Step 2: Search all previously emitted symbols + return CompileLayer->findSymbol(Name, ExportedSymbolsOnly); } orc::JITSymbol findUnmangledSymbol(const std::string Name) { - return findSymbol(mangle(Name)); + return findSymbol(mangle(Name), true); } uint64_t getGlobalValueAddress(const std::string &Name) { - return CompileLayer->findSymbol(mangle(Name), false).getAddress(); + return findSymbol(mangle(Name), false).getAddress(); } uint64_t getFunctionAddress(const std::string &Name) { - return CompileLayer->findSymbol(mangle(Name), false).getAddress(); + return findSymbol(mangle(Name), false).getAddress(); } - uint64_t FindFunctionNamed(const std::string &Name) + Function *FindFunctionNamed(const std::string &Name) { return 0; // Functions are not kept around } diff --git a/src/julia_internal.h b/src/julia_internal.h index efc6f40893181..b8ba32de3450f 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -268,10 +268,10 @@ jl_value_t *skip_meta(jl_array_t *body); int has_meta(jl_array_t *body, jl_sym_t *sym); // backtraces +uint64_t jl_getUnwindInfo(uint64_t dwBase); #ifdef _OS_WINDOWS_ extern HANDLE hMainThread; typedef CONTEXT *bt_context_t; -DWORD64 jl_getUnwindInfo(ULONG64 dwBase); extern volatile int jl_in_stackwalk; #else #define UNW_LOCAL_ONLY