From ec30ce47af9bd3be28ec304681c8bb2174c9a154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 2 Jan 2015 12:24:38 +0100 Subject: [PATCH] Object cache --- libevmjit/Cache.cpp | 31 +++++++++++++++++++++++++------ libevmjit/ExecutionEngine.cpp | 27 +++++++++++++++++++-------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/libevmjit/Cache.cpp b/libevmjit/Cache.cpp index bbd2c95b8..a887d91e9 100644 --- a/libevmjit/Cache.cpp +++ b/libevmjit/Cache.cpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include 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 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; } diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 23a64da65..862586575 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -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* 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 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::type)i; + + return os.str(); +} + } ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env) { static std::unique_ptr ee; // TODO: Use Managed Objects from LLVM? - - // TODO: Better hash of code needed, probably SHA3 - std::string code{reinterpret_cast(_code.data()), _code.size()}; - auto hash = std::hash{}(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 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