diff --git a/libevmjit/Cache.cpp b/libevmjit/Cache.cpp index 4dbcd281d..8d66a7922 100644 --- a/libevmjit/Cache.cpp +++ b/libevmjit/Cache.cpp @@ -11,6 +11,7 @@ #include "ExecutionEngine.h" #include "Utils.h" +#include "BuildInfo.gen.h" namespace dev { @@ -23,6 +24,18 @@ namespace { llvm::MemoryBuffer* g_lastObject; ExecutionEngineListener* g_listener; + static const size_t c_versionStampLength = 32; + + llvm::StringRef getLibVersionStamp() + { + static auto version = llvm::SmallString{}; + if (version.empty()) + { + version = EVMJIT_VERSION_FULL; + version.resize(c_versionStampLength); + } + return version; + } } ObjectCache* Cache::getObjectCache(ExecutionEngineListener* _listener) @@ -45,24 +58,19 @@ std::unique_ptr Cache::getObject(std::string const& id) llvm::sys::path::system_temp_directory(false, cachePath); llvm::sys::path::append(cachePath, "evm_objs", id); -#if defined(__GNUC__) && !defined(NDEBUG) - llvm::sys::fs::file_status st; - auto err = llvm::sys::fs::status(cachePath.str(), st); - if (err) - return nullptr; - auto mtime = st.getLastModificationTime().toEpochTime(); - - std::tm tm; - strptime(__DATE__ __TIME__, " %b %d %Y %H:%M:%S", &tm); - auto btime = (uint64_t)std::mktime(&tm); - if (btime > mtime) - return nullptr; -#endif - if (auto r = llvm::MemoryBuffer::getFile(cachePath.str(), -1, false)) - g_lastObject = llvm::MemoryBuffer::getMemBufferCopy(r.get()->getBuffer()); + { + auto& buf = r.get(); + auto objVersionStamp = buf->getBufferSize() >= c_versionStampLength ? llvm::StringRef{buf->getBufferEnd() - c_versionStampLength, c_versionStampLength} : llvm::StringRef{}; + if (objVersionStamp == getLibVersionStamp()) + g_lastObject = llvm::MemoryBuffer::getMemBufferCopy(r.get()->getBuffer()); + else + DLOG(cache) << "Unmatched version: " << objVersionStamp.str() << ", expected " << getLibVersionStamp().str() << "\n"; + } else if (r.getError() != std::make_error_code(std::errc::no_such_file_or_directory)) - std::cerr << r.getError().message(); // TODO: Add log + { + DLOG(cache) << r.getError().message(); // TODO: Add warning log + } if (g_lastObject) // if object found create fake module { @@ -91,14 +99,14 @@ void ObjectCache::notifyObjectCompiled(llvm::Module const* _module, llvm::Memory llvm::sys::path::append(cachePath, "evm_objs"); if (llvm::sys::fs::create_directory(cachePath.str())) - return; // TODO: Add log + DLOG(cache) << "Cannot create cache dir " << cachePath.str().str() << "\n"; llvm::sys::path::append(cachePath, id); DLOG(cache) << id << ": write\n"; std::string error; llvm::raw_fd_ostream cacheFile(cachePath.c_str(), error, llvm::sys::fs::F_None); - cacheFile << _object->getBuffer(); + cacheFile << _object->getBuffer() << getLibVersionStamp(); } llvm::MemoryBuffer* ObjectCache::getObject(llvm::Module const* _module)