diff --git a/libevmjit/Cache.h b/libevmjit/Cache.h index 9fd695bfe..42e56f544 100644 --- a/libevmjit/Cache.h +++ b/libevmjit/Cache.h @@ -16,12 +16,11 @@ class ExecBundle { public: std::unique_ptr engine; - llvm::Function* entryFunc = nullptr; ExecBundle() = default; ExecBundle(ExecBundle&& _other): - engine(std::move(_other.engine)), - entryFunc(_other.entryFunc) {} + engine(std::move(_other.engine)) + {} ExecBundle(ExecBundle const&) = delete; void operator=(ExecBundle) = delete; diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 27ff5dca4..fd217e4ee 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -53,47 +53,37 @@ ReturnCode ExecutionEngine::run(std::unique_ptr _module, RuntimeDa static const auto program = "EVM JIT"; llvm::PrettyStackTraceProgram X(1, &program); - auto&& context = llvm::getGlobalContext(); - llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); llvm::InitializeNativeTargetAsmParser(); - std::string errorMsg; llvm::EngineBuilder builder(module); - //builder.setMArch(MArch); - //builder.setMCPU(MCPU); - //builder.setMAttrs(MAttrs); - //builder.setRelocationModel(RelocModel); - //builder.setCodeModel(CMModel); - builder.setErrorStr(&errorMsg); builder.setEngineKind(llvm::EngineKind::JIT); builder.setUseMCJIT(true); - builder.setMCJITMemoryManager(new llvm::SectionMemoryManager()); + std::unique_ptr memoryManager(new llvm::SectionMemoryManager); + builder.setMCJITMemoryManager(memoryManager.get()); builder.setOptLevel(llvm::CodeGenOpt::None); auto triple = llvm::Triple(llvm::sys::getProcessTriple()); if (triple.getOS() == llvm::Triple::OSType::Win32) - triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format + triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format module->setTargetTriple(triple.str()); ExecBundle exec; exec.engine.reset(builder.create()); if (!exec.engine) return ReturnCode::LLVMConfigError; - _module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module + _module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module + memoryManager.release(); // and memory manager - auto finalizationStartTime = std::chrono::high_resolution_clock::now(); - exec.engine->finalizeObject(); - auto finalizationEndTime = std::chrono::high_resolution_clock::now(); - clog(JIT) << " + " << std::chrono::duration_cast(finalizationEndTime - finalizationStartTime).count(); + // TODO: Finalization not needed when llvm::ExecutionEngine::getFunctionAddress used + //auto finalizationStartTime = std::chrono::high_resolution_clock::now(); + //exec.engine->finalizeObject(); + //auto finalizationEndTime = std::chrono::high_resolution_clock::now(); + //clog(JIT) << " + " << std::chrono::duration_cast(finalizationEndTime - finalizationStartTime).count(); auto executionStartTime = std::chrono::high_resolution_clock::now(); - exec.entryFunc = module->getFunction("main"); - if (!exec.entryFunc) - return ReturnCode::LLVMLinkError; - std::string key{reinterpret_cast(_code.data()), _code.size()}; //auto& cachedExec = Cache::registerExec(key, std::move(exec)); auto returnCode = run(exec, _data, _env); @@ -120,8 +110,7 @@ ReturnCode runEntryFunc(ExecBundle const& _exec, Runtime* _runtime) // to allow function to be executed. // That might be related to memory manager. Can we share one? typedef ReturnCode(*EntryFuncPtr)(Runtime*); - auto entryFuncVoidPtr = _exec.engine->getPointerToFunction(_exec.entryFunc); - auto entryFuncPtr = static_cast(entryFuncVoidPtr); + auto entryFuncPtr = (EntryFuncPtr)_exec.engine->getFunctionAddress("main"); ReturnCode returnCode{}; auto sj = setjmp(_runtime->getJmpBuf());