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 "Stack.h"
|
||||||
#include "Type.h"
|
#include "Type.h"
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
#include "Cache.h"
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
|
|
@ -34,8 +35,7 @@ namespace jit
|
||||||
|
|
||||||
ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
|
ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
|
||||||
{
|
{
|
||||||
Compiler::Options defaultOptions;
|
auto module = Compiler({}).compile(_code);
|
||||||
auto module = Compiler(defaultOptions).compile(_code);
|
|
||||||
return run(std::move(module), _data, _env);
|
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
|
triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format
|
||||||
module->setTargetTriple(triple.str());
|
module->setTargetTriple(triple.str());
|
||||||
|
|
||||||
auto exec = std::unique_ptr<llvm::ExecutionEngine>(builder.create());
|
ExecBundle exec;
|
||||||
if (!exec)
|
exec.engine.reset(builder.create());
|
||||||
|
if (!exec.engine)
|
||||||
return ReturnCode::LLVMConfigError;
|
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
|
||||||
|
|
||||||
auto finalizationStartTime = std::chrono::high_resolution_clock::now();
|
auto finalizationStartTime = std::chrono::high_resolution_clock::now();
|
||||||
exec->finalizeObject();
|
exec.engine->finalizeObject();
|
||||||
auto finalizationEndTime = std::chrono::high_resolution_clock::now();
|
auto finalizationEndTime = std::chrono::high_resolution_clock::now();
|
||||||
clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(finalizationEndTime - finalizationStartTime).count();
|
clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(finalizationEndTime - finalizationStartTime).count();
|
||||||
|
|
||||||
auto executionStartTime = std::chrono::high_resolution_clock::now();
|
auto executionStartTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
auto entryFunc = module->getFunction("main");
|
exec.entryFunc = module->getFunction("main");
|
||||||
if (!entryFunc)
|
if (!exec.entryFunc)
|
||||||
return ReturnCode::LLVMLinkError;
|
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;
|
ReturnCode returnCode;
|
||||||
std::jmp_buf buf;
|
std::jmp_buf buf;
|
||||||
Runtime runtime(_data, _env, buf);
|
Runtime runtime(_data, _env, buf);
|
||||||
auto r = setjmp(buf);
|
auto r = setjmp(buf);
|
||||||
if (r == 0)
|
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());
|
returnCode = static_cast<ReturnCode>(result.IntVal.getZExtValue());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
returnCode = static_cast<ReturnCode>(r);
|
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)
|
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);
|
auto&& log = clog(JIT);
|
||||||
log << "RETURN [ ";
|
log << "RETURN [ ";
|
||||||
|
|
@ -116,8 +126,6 @@ ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeDa
|
||||||
else
|
else
|
||||||
clog(JIT) << "RETURN " << (int)returnCode;
|
clog(JIT) << "RETURN " << (int)returnCode;
|
||||||
|
|
||||||
clog(JIT) << "\n";
|
|
||||||
|
|
||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ namespace eth
|
||||||
{
|
{
|
||||||
namespace jit
|
namespace jit
|
||||||
{
|
{
|
||||||
|
class ExecBundle;
|
||||||
|
|
||||||
class ExecutionEngine
|
class ExecutionEngine
|
||||||
{
|
{
|
||||||
|
|
@ -25,6 +26,9 @@ public:
|
||||||
ReturnCode run(std::unique_ptr<llvm::Module> module, RuntimeData* _data, Env* _env);
|
ReturnCode run(std::unique_ptr<llvm::Module> module, RuntimeData* _data, Env* _env);
|
||||||
|
|
||||||
bytes returnData;
|
bytes returnData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ReturnCode run(ExecBundle const& _exec, RuntimeData* _data, Env* _env);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue