diff --git a/libevmjit/Cache.cpp b/libevmjit/Cache.cpp new file mode 100644 index 000000000..acc560309 --- /dev/null +++ b/libevmjit/Cache.cpp @@ -0,0 +1,12 @@ +#include "Cache.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +} +} +} diff --git a/libevmjit/Cache.h b/libevmjit/Cache.h new file mode 100644 index 000000000..e75bce27f --- /dev/null +++ b/libevmjit/Cache.h @@ -0,0 +1,25 @@ +#pragma once + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +/// A bundle of objects and information needed for a contract execution +struct ExecBundle +{ + std::unique_ptr engine; + llvm::Function* entryFunc = nullptr; +}; + +class Cache +{ +public: + +}; + +} +} +} diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 0960f872b..9648bb5cb 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -24,6 +24,7 @@ #include "Stack.h" #include "Type.h" #include "Compiler.h" +#include "Cache.h" namespace dev { @@ -34,8 +35,7 @@ namespace jit ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env) { - Compiler::Options defaultOptions; - auto module = Compiler(defaultOptions).compile(_code); + auto module = Compiler({}).compile(_code); return run(std::move(module), _data, _env); } @@ -71,41 +71,51 @@ ReturnCode ExecutionEngine::run(std::unique_ptr _module, RuntimeDa triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format module->setTargetTriple(triple.str()); - auto exec = std::unique_ptr(builder.create()); - if (!exec) + ExecBundle exec; + exec.engine.reset(builder.create()); + if (!exec.engine) return ReturnCode::LLVMConfigError; _module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module auto finalizationStartTime = std::chrono::high_resolution_clock::now(); - exec->finalizeObject(); + 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(); - auto entryFunc = module->getFunction("main"); - if (!entryFunc) + exec.entryFunc = module->getFunction("main"); + if (!exec.entryFunc) return ReturnCode::LLVMLinkError; + auto returnCode = run(exec, _data, _env); + + auto executionEndTime = std::chrono::high_resolution_clock::now(); + clog(JIT) << " + " << std::chrono::duration_cast(executionEndTime - executionStartTime).count() << " ms "; + //clog(JIT) << "Max stack size: " << Stack::maxStackSize; + + clog(JIT) << "\n"; + + return returnCode; +} + +ReturnCode ExecutionEngine::run(ExecBundle const& _exec, RuntimeData* _data, Env* _env) +{ ReturnCode returnCode; std::jmp_buf buf; Runtime runtime(_data, _env, buf); auto r = setjmp(buf); if (r == 0) { - auto result = exec->runFunction(entryFunc, {{}, llvm::GenericValue(&runtime)}); + auto result = _exec.engine->runFunction(_exec.entryFunc, {{}, llvm::GenericValue(&runtime)}); returnCode = static_cast(result.IntVal.getZExtValue()); } else returnCode = static_cast(r); - - auto executionEndTime = std::chrono::high_resolution_clock::now(); - clog(JIT) << " + " << std::chrono::duration_cast(executionEndTime - executionStartTime).count() << " ms "; - //clog(JIT) << "Max stack size: " << Stack::maxStackSize; if (returnCode == ReturnCode::Return) { - returnData = runtime.getReturnData(); // TODO: It might be better to place is in Runtime interface + returnData = runtime.getReturnData(); auto&& log = clog(JIT); log << "RETURN [ "; @@ -116,8 +126,6 @@ ReturnCode ExecutionEngine::run(std::unique_ptr _module, RuntimeDa else clog(JIT) << "RETURN " << (int)returnCode; - clog(JIT) << "\n"; - return returnCode; } diff --git a/libevmjit/ExecutionEngine.h b/libevmjit/ExecutionEngine.h index 3adceb404..8eb4ff347 100644 --- a/libevmjit/ExecutionEngine.h +++ b/libevmjit/ExecutionEngine.h @@ -13,6 +13,7 @@ namespace eth { namespace jit { +class ExecBundle; class ExecutionEngine { @@ -25,6 +26,9 @@ public: ReturnCode run(std::unique_ptr module, RuntimeData* _data, Env* _env); bytes returnData; + +private: + ReturnCode run(ExecBundle const& _exec, RuntimeData* _data, Env* _env); }; }