Browse Source

Merge pull request #2143 from chfast/evmjit_fixes

EVM JIT fixes
cl-refactor
Gav Wood 10 years ago
parent
commit
f7e04de551
  1. 43
      evmjit/libevmjit/Array.cpp
  2. 27
      evmjit/libevmjit/Cache.cpp

43
evmjit/libevmjit/Array.cpp

@ -9,8 +9,6 @@
#include "Runtime.h" #include "Runtime.h"
#include "Utils.h" #include "Utils.h"
#include <set> // DEBUG only
namespace dev namespace dev
{ {
namespace eth namespace eth
@ -269,52 +267,15 @@ void Array::extend(llvm::Value* _arrayPtr, llvm::Value* _size)
} }
} }
namespace
{
struct AllocatedMemoryWatchdog
{
std::set<void*> allocatedMemory;
~AllocatedMemoryWatchdog()
{
if (!allocatedMemory.empty())
{
DLOG(mem) << allocatedMemory.size() << " MEM LEAKS!\n";
for (auto&& leak : allocatedMemory)
DLOG(mem) << "\t" << leak << "\n";
}
}
};
AllocatedMemoryWatchdog watchdog;
}
extern "C" extern "C"
{ {
using namespace dev::eth::jit;
EXPORT void* ext_realloc(void* _data, size_t _size) noexcept EXPORT void* ext_realloc(void* _data, size_t _size) noexcept
{ {
//std::cerr << "REALLOC: " << _data << " [" << _size << "]" << std::endl; return std::realloc(_data, _size);
auto newData = std::realloc(_data, _size);
if (_data != newData)
{
DLOG(mem) << "REALLOC: " << newData << " <- " << _data << " [" << _size << "]\n";
watchdog.allocatedMemory.erase(_data);
watchdog.allocatedMemory.insert(newData);
}
return newData;
} }
EXPORT void ext_free(void* _data) noexcept EXPORT void ext_free(void* _data) noexcept
{ {
std::free(_data); std::free(_data);
if (_data)
{
DLOG(mem) << "FREE : " << _data << "\n";
watchdog.allocatedMemory.erase(_data);
} }
} }
} // extern "C"

27
evmjit/libevmjit/Cache.cpp

@ -1,5 +1,7 @@
#include "Cache.h" #include "Cache.h"
#include <mutex>
#include "preprocessor/llvm_includes_start.h" #include "preprocessor/llvm_includes_start.h"
#include <llvm/IR/Module.h> #include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h> #include <llvm/IR/LLVMContext.h>
@ -23,6 +25,8 @@ namespace jit
namespace namespace
{ {
using Guard = std::lock_guard<std::mutex>;
std::mutex x_cacheMutex;
CacheMode g_mode; CacheMode g_mode;
llvm::MemoryBuffer* g_lastObject; llvm::MemoryBuffer* g_lastObject;
ExecutionEngineListener* g_listener; ExecutionEngineListener* g_listener;
@ -43,6 +47,9 @@ namespace
ObjectCache* Cache::getObjectCache(CacheMode _mode, ExecutionEngineListener* _listener) ObjectCache* Cache::getObjectCache(CacheMode _mode, ExecutionEngineListener* _listener)
{ {
static ObjectCache objectCache; static ObjectCache objectCache;
Guard g{x_cacheMutex};
g_mode = _mode; g_mode = _mode;
g_listener = _listener; g_listener = _listener;
return &objectCache; return &objectCache;
@ -50,6 +57,8 @@ ObjectCache* Cache::getObjectCache(CacheMode _mode, ExecutionEngineListener* _li
void Cache::clear() void Cache::clear()
{ {
Guard g{x_cacheMutex};
using namespace llvm::sys; using namespace llvm::sys;
llvm::SmallString<256> cachePath; llvm::SmallString<256> cachePath;
path::system_temp_directory(false, cachePath); path::system_temp_directory(false, cachePath);
@ -62,6 +71,8 @@ void Cache::clear()
void Cache::preload(llvm::ExecutionEngine& _ee, std::unordered_map<std::string, uint64_t>& _funcCache) void Cache::preload(llvm::ExecutionEngine& _ee, std::unordered_map<std::string, uint64_t>& _funcCache)
{ {
Guard g{x_cacheMutex};
// TODO: Cache dir should be in one place // TODO: Cache dir should be in one place
using namespace llvm::sys; using namespace llvm::sys;
llvm::SmallString<256> cachePath; llvm::SmallString<256> cachePath;
@ -92,11 +103,14 @@ void Cache::preload(llvm::ExecutionEngine& _ee, std::unordered_map<std::string,
std::unique_ptr<llvm::Module> Cache::getObject(std::string const& id) std::unique_ptr<llvm::Module> Cache::getObject(std::string const& id)
{ {
Guard g{x_cacheMutex};
if (g_mode != CacheMode::on && g_mode != CacheMode::read) if (g_mode != CacheMode::on && g_mode != CacheMode::read)
return nullptr; return nullptr;
if (g_listener) // TODO: Disabled because is not thread-safe.
g_listener->stateChanged(ExecState::CacheLoad); //if (g_listener)
// g_listener->stateChanged(ExecState::CacheLoad);
DLOG(cache) << id << ": search\n"; DLOG(cache) << id << ": search\n";
if (!CHECK(!g_lastObject)) if (!CHECK(!g_lastObject))
@ -136,12 +150,15 @@ std::unique_ptr<llvm::Module> Cache::getObject(std::string const& id)
void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBuffer const* _object) void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBuffer const* _object)
{ {
Guard g{x_cacheMutex};
// Only in "on" and "write" mode // Only in "on" and "write" mode
if (g_mode != CacheMode::on && g_mode != CacheMode::write) if (g_mode != CacheMode::on && g_mode != CacheMode::write)
return; return;
if (g_listener) // TODO: Disabled because is not thread-safe.
g_listener->stateChanged(ExecState::CacheWrite); // if (g_listener)
// g_listener->stateChanged(ExecState::CacheWrite);
auto&& id = _module->getModuleIdentifier(); auto&& id = _module->getModuleIdentifier();
llvm::SmallString<256> cachePath; llvm::SmallString<256> cachePath;
@ -161,6 +178,8 @@ void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::Memory
llvm::MemoryBuffer* ObjectCache::getObject(llvm::Module const* _module) llvm::MemoryBuffer* ObjectCache::getObject(llvm::Module const* _module)
{ {
Guard g{x_cacheMutex};
DLOG(cache) << _module->getModuleIdentifier() << ": use\n"; DLOG(cache) << _module->getModuleIdentifier() << ": use\n";
auto o = g_lastObject; auto o = g_lastObject;
g_lastObject = nullptr; g_lastObject = nullptr;

Loading…
Cancel
Save