Browse Source

Using one ExecutionEngine to cache compiled contracts

cl-refactor
Paweł Bylica 10 years ago
parent
commit
9d9e73ac91
  1. 2
      libevmjit/Cache.h
  2. 53
      libevmjit/ExecutionEngine.cpp

2
libevmjit/Cache.h

@ -17,7 +17,7 @@ namespace jit
class ExecBundle
{
public:
std::unique_ptr<llvm::ExecutionEngine> engine;
llvm::ExecutionEngine* engine = nullptr;
std::string mainFuncName;
ExecBundle() = default;

53
libevmjit/ExecutionEngine.cpp

@ -48,10 +48,22 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en
ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeData* _data, Env* _env, bytes const& _code)
{
llvm::sys::PrintStackTraceOnErrorSignal();
static const auto program = "EVM JIT";
llvm::PrettyStackTraceProgram X(1, &program);
// TODO: Use it in evmcc
//llvm::sys::PrintStackTraceOnErrorSignal();
//static const auto program = "EVM JIT";
//llvm::PrettyStackTraceProgram X(1, &program);
static std::unique_ptr<llvm::ExecutionEngine> ee; // TODO: Use Managed Objects from LLVM?
typedef ReturnCode(*EntryFuncPtr)(Runtime*);
EntryFuncPtr entryFuncPtr{};
ExecBundle exec;
exec.mainFuncName = _module->getModuleIdentifier();
if (!ee)
{
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
@ -67,15 +79,37 @@ ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeDa
triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format
_module->setTargetTriple(triple.str());
ExecBundle exec;
exec.mainFuncName = _module->getModuleIdentifier();
exec.engine.reset(builder.create());
if (!exec.engine)
ee.reset(builder.create());
if (!ee)
return ReturnCode::LLVMConfigError;
_module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
memoryManager.release(); // and memory manager
exec.engine->setObjectCache(Cache::getObjectCache());
//ee->setObjectCache(Cache::getObjectCache());
}
else
{
if (entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(_module->getModuleIdentifier()))
{
entryFuncPtr = nullptr;
}
else
{
ee->addModule(_module.get());
//std::cerr << _module->getModuleIdentifier() << "\n";
_module.release();
}
}
assert(ee);
//ExecBundle exec;
//exec.engine.reset(builder.create());
//if (!exec.engine)
// return ReturnCode::LLVMConfigError;
exec.engine = ee.get();
// TODO: Finalization not needed when llvm::ExecutionEngine::getFunctionAddress used
//auto finalizationStartTime = std::chrono::high_resolution_clock::now();
@ -113,13 +147,16 @@ ReturnCode runEntryFunc(ExecBundle const& _exec, Runtime* _runtime)
typedef ReturnCode(*EntryFuncPtr)(Runtime*);
auto entryFuncPtr = (EntryFuncPtr)_exec.engine->getFunctionAddress(_exec.mainFuncName);
//std::cerr << _exec.mainFuncName << " F: " << entryFuncPtr << "\n";
ReturnCode returnCode{};
//std::cerr << _exec.mainFuncName << " +S: " << &returnCode << "\n";
auto sj = setjmp(_runtime->getJmpBuf());
if (sj == 0)
returnCode = entryFuncPtr(_runtime);
else
returnCode = static_cast<ReturnCode>(sj);
//std::cerr << _exec.mainFuncName << " -S: " << &returnCode << "\n";
return returnCode;
}
}

Loading…
Cancel
Save