diff --git a/libevmjit/Cache.cpp b/libevmjit/Cache.cpp index 115322fef..f9ca47398 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 42e56f544..6d1585329 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 66d840fd5..162851ae8 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();