mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 04:36:42 +00:00
ExecBundle - all information needed to execute a JIT-compiled contracts
This commit is contained in:
parent
b3a17341e4
commit
2a7111ce41
4 changed files with 64 additions and 15 deletions
12
libevmjit/Cache.cpp
Normal file
12
libevmjit/Cache.cpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include "Cache.h"
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace eth
|
||||
{
|
||||
namespace jit
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
25
libevmjit/Cache.h
Normal file
25
libevmjit/Cache.h
Normal file
|
|
@ -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:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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…
Reference in a new issue