Browse Source

ExecBundle - all information needed to execute a JIT-compiled contracts

cl-refactor
Paweł Bylica 10 years ago
parent
commit
2a7111ce41
  1. 12
      libevmjit/Cache.cpp
  2. 25
      libevmjit/Cache.h
  3. 38
      libevmjit/ExecutionEngine.cpp
  4. 4
      libevmjit/ExecutionEngine.h

12
libevmjit/Cache.cpp

@ -0,0 +1,12 @@
#include "Cache.h"
namespace dev
{
namespace eth
{
namespace jit
{
}
}
}

25
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<llvm::ExecutionEngine> engine;
llvm::Function* entryFunc = nullptr;
};
class Cache
{
public:
};
}
}
}

38
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<llvm::Module> _module, RuntimeDa
triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format
module->setTargetTriple(triple.str());
auto exec = std::unique_ptr<llvm::ExecutionEngine>(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<std::chrono::milliseconds>(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<std::chrono::milliseconds>(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<ReturnCode>(result.IntVal.getZExtValue());
}
else
returnCode = static_cast<ReturnCode>(r);
auto executionEndTime = std::chrono::high_resolution_clock::now();
clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(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<llvm::Module> _module, RuntimeDa
else
clog(JIT) << "RETURN " << (int)returnCode;
clog(JIT) << "\n";
return returnCode;
}

4
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<llvm::Module> module, RuntimeData* _data, Env* _env);
bytes returnData;
private:
ReturnCode run(ExecBundle const& _exec, RuntimeData* _data, Env* _env);
};
}

Loading…
Cancel
Save