mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Do not compile LLVM module if machine code available in memory
This commit is contained in:
parent
2b31cba5d2
commit
3df5a125fa
5 changed files with 49 additions and 56 deletions
|
|
@ -132,7 +132,7 @@ int main(int argc, char** argv)
|
|||
compilerOptions.rewriteSwitchToBranches = optimize || options.count("rewrite-switch") > 0;
|
||||
|
||||
auto compiler = eth::jit::Compiler(compilerOptions);
|
||||
auto module = compiler.compile(bytecode);
|
||||
auto module = compiler.compile(bytecode, "main");
|
||||
|
||||
auto compilationEndTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
|
@ -201,7 +201,8 @@ int main(int argc, char** argv)
|
|||
data.code = bytecode.data();
|
||||
|
||||
// BROKEN: env_* functions must be implemented & RuntimeData struct created
|
||||
auto result = engine.run(std::move(module), &data, nullptr, bytecode);
|
||||
// TODO: Do not compile module again
|
||||
auto result = engine.run(bytecode, &data, nullptr);
|
||||
return static_cast<int>(result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,19 +152,14 @@ void Compiler::createBasicBlocks(bytes const& _bytecode)
|
|||
m_indirectJumpTargets.push_back(&basicBlocks.find(*it)->second);
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode)
|
||||
std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::string const& _id)
|
||||
{
|
||||
// TODO: Better hash of code needed, probably SHA3
|
||||
std::string code{reinterpret_cast<char const*>(_bytecode.data()), _bytecode.size()};
|
||||
auto hash = std::hash<std::string>{}(code);
|
||||
auto strHash = std::to_string(hash);
|
||||
|
||||
auto compilationStartTime = std::chrono::high_resolution_clock::now();
|
||||
auto module = std::unique_ptr<llvm::Module>(new llvm::Module(strHash, m_builder.getContext()));
|
||||
auto module = std::unique_ptr<llvm::Module>(new llvm::Module(_id, m_builder.getContext()));
|
||||
|
||||
// Create main function
|
||||
auto mainFuncType = llvm::FunctionType::get(Type::MainReturn, Type::RuntimePtr, false);
|
||||
m_mainFunc = llvm::Function::Create(mainFuncType, llvm::Function::ExternalLinkage, strHash, module.get());
|
||||
m_mainFunc = llvm::Function::Create(mainFuncType, llvm::Function::ExternalLinkage, _id, module.get());
|
||||
m_mainFunc->getArgumentList().front().setName("rt");
|
||||
|
||||
// Create the basic blocks.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
Compiler(Options const& _options);
|
||||
|
||||
std::unique_ptr<llvm::Module> compile(bytes const& _bytecode);
|
||||
std::unique_ptr<llvm::Module> compile(bytes const& _bytecode, std::string const& _id);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -21,13 +21,6 @@ namespace eth
|
|||
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
|
||||
{
|
||||
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?
|
||||
|
||||
|
||||
// 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{};
|
||||
auto&& mainFuncName = _module->getModuleIdentifier();
|
||||
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)
|
||||
{
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
|
||||
llvm::EngineBuilder builder(_module.get());
|
||||
llvm::EngineBuilder builder(module.get());
|
||||
builder.setEngineKind(llvm::EngineKind::JIT);
|
||||
builder.setUseMCJIT(true);
|
||||
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());
|
||||
if (triple.getOS() == llvm::Triple::OSType::Win32)
|
||||
triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format
|
||||
_module->setTargetTriple(triple.str());
|
||||
module->setTargetTriple(triple.str());
|
||||
|
||||
ee.reset(builder.create());
|
||||
if (!ee)
|
||||
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
|
||||
|
||||
//ee->setObjectCache(Cache::getObjectCache());
|
||||
|
|
@ -85,14 +89,14 @@ ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeDa
|
|||
}
|
||||
else
|
||||
{
|
||||
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
|
||||
if (!entryFuncPtr)
|
||||
{
|
||||
ee->addModule(_module.get());
|
||||
_module.release();
|
||||
ee->addModule(module.get());
|
||||
module.release();
|
||||
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(entryFuncPtr);
|
||||
|
||||
auto executionStartTime = std::chrono::high_resolution_clock::now();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
class Module;
|
||||
}
|
||||
|
||||
#include "RuntimeData.h"
|
||||
|
||||
namespace dev
|
||||
|
|
@ -13,7 +8,6 @@ namespace eth
|
|||
{
|
||||
namespace jit
|
||||
{
|
||||
class ExecBundle;
|
||||
|
||||
class ExecutionEngine
|
||||
{
|
||||
|
|
@ -23,7 +17,6 @@ public:
|
|||
void operator=(ExecutionEngine) = delete;
|
||||
|
||||
ReturnCode run(bytes const& _code, RuntimeData* _data, Env* _env);
|
||||
ReturnCode run(std::unique_ptr<llvm::Module> module, RuntimeData* _data, Env* _env, bytes const& _code);
|
||||
|
||||
bytes returnData;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue