Browse Source

Object cache

cl-refactor
Paweł Bylica 10 years ago
parent
commit
ec30ce47af
  1. 31
      libevmjit/Cache.cpp
  2. 27
      libevmjit/ExecutionEngine.cpp

31
libevmjit/Cache.cpp

@ -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;
} }

27
libevmjit/ExecutionEngine.cpp

@ -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…
Cancel
Save