|
@ -21,13 +21,6 @@ namespace eth |
|
|
namespace jit |
|
|
namespace jit |
|
|
{ |
|
|
{ |
|
|
|
|
|
|
|
|
ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env) |
|
|
|
|
|
{ |
|
|
|
|
|
auto module = Compiler({}).compile(_code); |
|
|
|
|
|
//module->dump();
|
|
|
|
|
|
return run(std::move(module), _data, _env, _code); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
namespace |
|
|
namespace |
|
|
{ |
|
|
{ |
|
|
typedef ReturnCode(*EntryFuncPtr)(Runtime*); |
|
|
typedef ReturnCode(*EntryFuncPtr)(Runtime*); |
|
@ -48,20 +41,31 @@ ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeData* _data, Env* _env, bytes const& _code) |
|
|
ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env) |
|
|
{ |
|
|
{ |
|
|
static std::unique_ptr<llvm::ExecutionEngine> ee; // TODO: Use Managed Objects from LLVM?
|
|
|
static std::unique_ptr<llvm::ExecutionEngine> ee; // TODO: Use Managed Objects from LLVM?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Better hash of code needed, probably SHA3
|
|
|
|
|
|
std::string code{reinterpret_cast<char const*>(_code.data()), _code.size()}; |
|
|
|
|
|
auto hash = std::hash<std::string>{}(code); |
|
|
|
|
|
auto mainFuncName = std::to_string(hash); |
|
|
|
|
|
|
|
|
EntryFuncPtr entryFuncPtr{}; |
|
|
EntryFuncPtr entryFuncPtr{}; |
|
|
auto&& mainFuncName = _module->getModuleIdentifier(); |
|
|
|
|
|
Runtime runtime(_data, _env); // TODO: I don't know why but it must be created before getFunctionAddress() calls
|
|
|
Runtime runtime(_data, _env); // TODO: I don't know why but it must be created before getFunctionAddress() calls
|
|
|
|
|
|
|
|
|
|
|
|
if (ee && (entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName))) |
|
|
|
|
|
{ |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
auto module = Compiler({}).compile(_code, mainFuncName); |
|
|
if (!ee) |
|
|
if (!ee) |
|
|
{ |
|
|
{ |
|
|
llvm::InitializeNativeTarget(); |
|
|
llvm::InitializeNativeTarget(); |
|
|
llvm::InitializeNativeTargetAsmPrinter(); |
|
|
llvm::InitializeNativeTargetAsmPrinter(); |
|
|
|
|
|
|
|
|
llvm::EngineBuilder builder(_module.get()); |
|
|
llvm::EngineBuilder builder(module.get()); |
|
|
builder.setEngineKind(llvm::EngineKind::JIT); |
|
|
builder.setEngineKind(llvm::EngineKind::JIT); |
|
|
builder.setUseMCJIT(true); |
|
|
builder.setUseMCJIT(true); |
|
|
std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager); |
|
|
std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager); |
|
@ -71,13 +75,13 @@ ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeDa |
|
|
auto triple = llvm::Triple(llvm::sys::getProcessTriple()); |
|
|
auto triple = llvm::Triple(llvm::sys::getProcessTriple()); |
|
|
if (triple.getOS() == llvm::Triple::OSType::Win32) |
|
|
if (triple.getOS() == llvm::Triple::OSType::Win32) |
|
|
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()); |
|
|
|
|
|
|
|
|
ee.reset(builder.create()); |
|
|
ee.reset(builder.create()); |
|
|
if (!ee) |
|
|
if (!ee) |
|
|
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
|
|
|
memoryManager.release(); // and memory manager
|
|
|
memoryManager.release(); // and memory manager
|
|
|
|
|
|
|
|
|
//ee->setObjectCache(Cache::getObjectCache());
|
|
|
//ee->setObjectCache(Cache::getObjectCache());
|
|
@ -85,14 +89,14 @@ ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeDa |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName); |
|
|
|
|
|
if (!entryFuncPtr) |
|
|
if (!entryFuncPtr) |
|
|
{ |
|
|
{ |
|
|
ee->addModule(_module.get()); |
|
|
ee->addModule(module.get()); |
|
|
_module.release(); |
|
|
module.release(); |
|
|
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName); |
|
|
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
assert(entryFuncPtr); |
|
|
assert(entryFuncPtr); |
|
|
|
|
|
|
|
|
auto executionStartTime = std::chrono::high_resolution_clock::now(); |
|
|
auto executionStartTime = std::chrono::high_resolution_clock::now(); |
|
|