mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 04:36:42 +00:00
Object cache
This commit is contained in:
parent
5be8c59ff1
commit
ec30ce47af
2 changed files with 44 additions and 14 deletions
|
|
@ -3,6 +3,9 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <llvm/IR/Module.h>
|
#include <llvm/IR/Module.h>
|
||||||
|
#include <llvm/Support/Path.h>
|
||||||
|
#include <llvm/Support/FileSystem.h>
|
||||||
|
#include <llvm/Support/raw_os_ostream.h>
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
|
|
@ -23,16 +26,32 @@ ObjectCache* Cache::getObjectCache()
|
||||||
|
|
||||||
void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBuffer const* _object)
|
void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBuffer const* _object)
|
||||||
{
|
{
|
||||||
auto&& key = _module->getModuleIdentifier();
|
auto&& id = _module->getModuleIdentifier();
|
||||||
std::unique_ptr<llvm::MemoryBuffer> obj(llvm::MemoryBuffer::getMemBufferCopy(_object->getBuffer()));
|
llvm::SmallString<256> cachePath;
|
||||||
m_map.insert(std::make_pair(key, std::move(obj)));
|
llvm::sys::path::system_temp_directory(false, cachePath);
|
||||||
|
llvm::sys::path::append(cachePath, "evm_objs");
|
||||||
|
|
||||||
|
if (llvm::sys::fs::create_directory(cachePath.str()))
|
||||||
|
return; // TODO: Add log
|
||||||
|
|
||||||
|
llvm::sys::path::append(cachePath, id);
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
llvm::raw_fd_ostream cacheFile(cachePath.c_str(), error, llvm::sys::fs::F_None);
|
||||||
|
cacheFile << _object->getBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::MemoryBuffer* ObjectCache::getObject(llvm::Module const* _module)
|
llvm::MemoryBuffer* ObjectCache::getObject(llvm::Module const* _module)
|
||||||
{
|
{
|
||||||
auto it = m_map.find(_module->getModuleIdentifier());
|
auto&& id = _module->getModuleIdentifier();
|
||||||
if (it != m_map.end())
|
llvm::SmallString<256> cachePath;
|
||||||
return llvm::MemoryBuffer::getMemBufferCopy(it->second->getBuffer());
|
llvm::sys::path::system_temp_directory(false, cachePath);
|
||||||
|
llvm::sys::path::append(cachePath, "evm_objs", id);
|
||||||
|
|
||||||
|
if (auto r = llvm::MemoryBuffer::getFile(cachePath.str(), -1, false))
|
||||||
|
return llvm::MemoryBuffer::getMemBufferCopy(r.get()->getBuffer());
|
||||||
|
else if (r.getError() != std::make_error_code(std::errc::no_such_file_or_directory))
|
||||||
|
std::cerr << r.getError().message(); // TODO: Add log
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
#include "Cache.h"
|
#include "Cache.h"
|
||||||
|
|
||||||
|
extern "C" void env_sha3(dev::eth::jit::byte const* _begin, uint64_t _size, std::array<dev::eth::jit::byte, 32>* o_hash);
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
namespace eth
|
namespace eth
|
||||||
|
|
@ -39,18 +41,26 @@ ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime)
|
||||||
|
|
||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string codeHash(bytes const& _code)
|
||||||
|
{
|
||||||
|
std::array<dev::eth::jit::byte, 32> binHash;
|
||||||
|
env_sha3(_code.data(), _code.size(), &binHash);
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
for (auto i: binHash)
|
||||||
|
os << std::hex << std::setfill('0') << std::setw(2) << (int)(std::make_unsigned<decltype(i)>::type)i;
|
||||||
|
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
|
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?
|
||||||
|
|
||||||
|
auto mainFuncName = codeHash(_code);
|
||||||
// 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{};
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -60,6 +70,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto module = Compiler({}).compile(_code, mainFuncName);
|
auto module = Compiler({}).compile(_code, mainFuncName);
|
||||||
|
//module->dump();
|
||||||
if (!ee)
|
if (!ee)
|
||||||
{
|
{
|
||||||
llvm::InitializeNativeTarget();
|
llvm::InitializeNativeTarget();
|
||||||
|
|
@ -70,7 +81,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en
|
||||||
builder.setUseMCJIT(true);
|
builder.setUseMCJIT(true);
|
||||||
std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
|
std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
|
||||||
builder.setMCJITMemoryManager(memoryManager.get());
|
builder.setMCJITMemoryManager(memoryManager.get());
|
||||||
builder.setOptLevel(llvm::CodeGenOpt::None);
|
builder.setOptLevel(llvm::CodeGenOpt::Default);
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -84,7 +95,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en
|
||||||
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());
|
||||||
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
|
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue