From 16c26613f19ee00d88ddd6ab93f44f7ac09267e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 18 Mar 2015 12:20:04 +0100 Subject: [PATCH] Additional cache options: readonly, writeonly and clear. --- libevmjit/Cache.cpp | 23 ++++++++++++++++++++++- libevmjit/Cache.h | 14 +++++++++++++- libevmjit/ExecutionEngine.cpp | 14 ++++++++++++-- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/libevmjit/Cache.cpp b/libevmjit/Cache.cpp index 6b140dd84..d3cda1098 100644 --- a/libevmjit/Cache.cpp +++ b/libevmjit/Cache.cpp @@ -22,6 +22,7 @@ namespace jit namespace { + CacheMode g_mode; llvm::MemoryBuffer* g_lastObject; ExecutionEngineListener* g_listener; static const size_t c_versionStampLength = 32; @@ -38,15 +39,31 @@ namespace } } -ObjectCache* Cache::getObjectCache(ExecutionEngineListener* _listener) +ObjectCache* Cache::getObjectCache(CacheMode _mode, ExecutionEngineListener* _listener) { static ObjectCache objectCache; + g_mode = _mode; g_listener = _listener; return &objectCache; } +void Cache::clear() +{ + using namespace llvm::sys; + llvm::SmallString<256> cachePath; + path::system_temp_directory(false, cachePath); + path::append(cachePath, "evm_objs"); + + std::error_code err; + for (auto it = fs::directory_iterator{cachePath.str(), err}; it != fs::directory_iterator{}; it.increment(err)) + fs::remove(it->path()); +} + std::unique_ptr Cache::getObject(std::string const& id) { + if (g_mode != CacheMode::on && g_mode != CacheMode::read) + return nullptr; + if (g_listener) g_listener->stateChanged(ExecState::CacheLoad); @@ -88,6 +105,10 @@ std::unique_ptr Cache::getObject(std::string const& id) void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::MemoryBuffer const* _object) { + // Only in "on" and "write" mode + if (g_mode != CacheMode::on && g_mode != CacheMode::write) + return; + if (g_listener) g_listener->stateChanged(ExecState::CacheWrite); diff --git a/libevmjit/Cache.h b/libevmjit/Cache.h index e8f01d38d..b0d26d080 100644 --- a/libevmjit/Cache.h +++ b/libevmjit/Cache.h @@ -12,6 +12,15 @@ namespace jit { class ExecutionEngineListener; +enum class CacheMode +{ + on, + off, + read, + write, + clear +}; + class ObjectCache : public llvm::ObjectCache { public: @@ -29,8 +38,11 @@ public: class Cache { public: - static ObjectCache* getObjectCache(ExecutionEngineListener* _listener); + static ObjectCache* getObjectCache(CacheMode _mode, ExecutionEngineListener* _listener); static std::unique_ptr getObject(std::string const& id); + + /// Clears cache storage + static void clear(); }; } diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index e1c0780d9..f9588fbea 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -67,7 +67,14 @@ void printVersion() namespace cl = llvm::cl; cl::opt g_optimize{"O", cl::desc{"Optimize"}}; -cl::opt g_cache{"cache", cl::desc{"Cache compiled EVM code on disk"}, cl::init(true)}; +cl::opt g_cache{"cache", cl::desc{"Cache compiled EVM code on disk"}, + cl::values( + clEnumValN(CacheMode::on, "1", "Enabled"), + clEnumValN(CacheMode::off, "0", "Disabled"), + clEnumValN(CacheMode::read, "r", "Read only. No new objects are added to cache."), + clEnumValN(CacheMode::write, "w", "Write only. No objects are loaded from cache."), + clEnumValN(CacheMode::clear, "c", "Clear the cache storage. Cache is disabled."), + clEnumValEnd)}; cl::opt g_stats{"st", cl::desc{"Statistics"}}; cl::opt g_dump{"dump", cl::desc{"Dump LLVM IR module"}}; @@ -89,11 +96,14 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env) std::unique_ptr listener{new ExecStats}; listener->stateChanged(ExecState::Started); - auto objectCache = g_cache ? Cache::getObjectCache(listener.get()) : nullptr; + auto objectCache = (g_cache != CacheMode::off && g_cache != CacheMode::clear) ? Cache::getObjectCache(g_cache, listener.get()) : nullptr; static std::unique_ptr ee; if (!ee) { + if (g_cache == CacheMode::clear) + Cache::clear(); + llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter();