mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 12:46:44 +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 <iostream>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/Support/Path.h>
|
||||
#include <llvm/Support/FileSystem.h>
|
||||
#include <llvm/Support/raw_os_ostream.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
|
|
@ -23,16 +26,32 @@ ObjectCache* Cache::getObjectCache()
|
|||
|
||||
void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBuffer const* _object)
|
||||
{
|
||||
auto&& key = _module->getModuleIdentifier();
|
||||
std::unique_ptr<llvm::MemoryBuffer> obj(llvm::MemoryBuffer::getMemBufferCopy(_object->getBuffer()));
|
||||
m_map.insert(std::make_pair(key, std::move(obj)));
|
||||
auto&& id = _module->getModuleIdentifier();
|
||||
llvm::SmallString<256> cachePath;
|
||||
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)
|
||||
{
|
||||
auto it = m_map.find(_module->getModuleIdentifier());
|
||||
if (it != m_map.end())
|
||||
return llvm::MemoryBuffer::getMemBufferCopy(it->second->getBuffer());
|
||||
auto&& id = _module->getModuleIdentifier();
|
||||
llvm::SmallString<256> cachePath;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#include "Compiler.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 eth
|
||||
|
|
@ -39,18 +41,26 @@ ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime)
|
|||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
auto mainFuncName = codeHash(_code);
|
||||
EntryFuncPtr entryFuncPtr{};
|
||||
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
|
||||
{
|
||||
auto module = Compiler({}).compile(_code, mainFuncName);
|
||||
//module->dump();
|
||||
if (!ee)
|
||||
{
|
||||
llvm::InitializeNativeTarget();
|
||||
|
|
@ -70,7 +81,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en
|
|||
builder.setUseMCJIT(true);
|
||||
std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
|
||||
builder.setMCJITMemoryManager(memoryManager.get());
|
||||
builder.setOptLevel(llvm::CodeGenOpt::None);
|
||||
builder.setOptLevel(llvm::CodeGenOpt::Default);
|
||||
|
||||
auto triple = llvm::Triple(llvm::sys::getProcessTriple());
|
||||
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
|
||||
memoryManager.release(); // and memory manager
|
||||
|
||||
//ee->setObjectCache(Cache::getObjectCache());
|
||||
ee->setObjectCache(Cache::getObjectCache());
|
||||
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in a new issue