From 2b83b75c4b1885193bb05dcb4ecafe995c69ca35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 18 Dec 2014 14:27:59 +0100 Subject: [PATCH] Object cache wit memory leaks --- libevmjit/Cache.cpp | 23 +++++++++++++++++++++++ libevmjit/Cache.h | 22 ++++++++++++++++++++++ libevmjit/ExecutionEngine.cpp | 3 +++ 3 files changed, 48 insertions(+) diff --git a/libevmjit/Cache.cpp b/libevmjit/Cache.cpp index 115322fef3..f9ca473988 100644 --- a/libevmjit/Cache.cpp +++ b/libevmjit/Cache.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace dev { @@ -45,6 +46,28 @@ ExecBundle* Cache::findExec(Cache::Key _key) return nullptr; } +ObjectCache* Cache::getObjectCache() +{ + static ObjectCache objectCache; + return &objectCache; +} + + +void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBuffer const* _object) +{ + auto&& key = _module->getModuleIdentifier(); + auto obj = llvm::MemoryBuffer::getMemBufferCopy(_object->getBuffer()); + m_map.insert(std::make_pair(key, obj)); +} + +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()); + return nullptr; +} + } } } diff --git a/libevmjit/Cache.h b/libevmjit/Cache.h index 42e56f5442..6d15853295 100644 --- a/libevmjit/Cache.h +++ b/libevmjit/Cache.h @@ -1,7 +1,9 @@ #pragma once #include +#include #include +#include namespace dev @@ -26,6 +28,24 @@ public: void operator=(ExecBundle) = delete; }; + +class ObjectCache : public llvm::ObjectCache +{ +public: + /// notifyObjectCompiled - Provides a pointer to compiled code for Module M. + virtual void notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBuffer const* _object) final override; + + /// getObjectCopy - Returns a pointer to a newly allocated MemoryBuffer that + /// contains the object which corresponds with Module M, or 0 if an object is + /// not available. The caller owns both the MemoryBuffer returned by this + /// and the memory it references. + virtual llvm::MemoryBuffer* getObject(llvm::Module const* _module) final override; + +private: + std::unordered_map m_map; +}; + + class Cache { public: @@ -33,6 +53,8 @@ public: static ExecBundle& registerExec(Key _key, ExecBundle&& _exec); static ExecBundle* findExec(Key _key); + + static ObjectCache* getObjectCache(); }; } diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 66d840fd5b..162851ae8f 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -42,6 +42,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en }*/ auto module = Compiler({}).compile(_code); + //module->dump(); return run(std::move(module), _data, _env, _code); } @@ -73,6 +74,8 @@ ReturnCode ExecutionEngine::run(std::unique_ptr _module, RuntimeDa _module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module memoryManager.release(); // and memory manager + exec.engine->setObjectCache(Cache::getObjectCache()); + // TODO: Finalization not needed when llvm::ExecutionEngine::getFunctionAddress used //auto finalizationStartTime = std::chrono::high_resolution_clock::now(); //exec.engine->finalizeObject();