josephwen Adds caching for MC JIT.
New MCCacheReader in addition to the classic JIT's CacheReader.[cpp|h].
New MCCacheWriter in addition to the classic JIT's CacheReader.[cpp|h].
Change-Id: Iffd490caf25136d52cefc1c6bc2a78fa991236cd
diff --git a/lib/ExecutionEngine/Script.cpp b/lib/ExecutionEngine/Script.cpp
index 0dbb8b6..4e81864 100644
--- a/lib/ExecutionEngine/Script.cpp
+++ b/lib/ExecutionEngine/Script.cpp
@@ -20,6 +20,8 @@
#include "CacheReader.h"
#include "CacheWriter.h"
+#include "MCCacheReader.h"
+#include "MCCacheWriter.h"
#include "ContextManager.h"
#include "DebugHelper.h"
#include "FileHandle.h"
@@ -194,6 +196,34 @@
#if USE_CACHE
+bool getObjPath(std::string &objPath) {
+ size_t found0 = objPath.find("@");
+ size_t found1 = objPath.rfind("@");
+
+ if (found0 == found1 ||
+ found0 == std::string::npos ||
+ found1 == std::string::npos) {
+ LOGE("Ill formatted resource name '%s'. The name should contain 2 @s",
+ objPath.c_str());
+ return false;
+ }
+
+ objPath.replace(found0, found1 - found0 + 1, "", 0);
+ objPath.resize(objPath.length() - 3);
+
+ LOGV("objPath = %s", objPath.c_str());
+ return true;
+}
+
+bool getInfoPath(std::string &infoPath) {
+ getObjPath(infoPath);
+ infoPath.erase(infoPath.size() - 1, 1);
+ infoPath.append("info");
+
+ LOGV("infoPath = %s", infoPath.c_str());
+ return true;
+}
+
int Script::internalLoadCache() {
if (getBooleanProp("debug.bcc.nocache")) {
// Android system environment property disable the cache mechanism by
@@ -207,15 +237,38 @@
// we don't know where to open the cache file.
return 1;
}
+ FileHandle objFile, infoFile;
- FileHandle file;
+ std::string objPath(mCachePath);
+ std::string infoPath(mCachePath);
- if (file.open(mCachePath, OpenMode::Read) < 0) {
+#if USE_MCJIT
+ getObjPath(objPath);
+ getInfoPath(infoPath);
+ #endif
+
+ if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
// Unable to open the cache file in read mode.
return 1;
}
+ #if USE_OLD_JIT
CacheReader reader;
+ #endif
+#if USE_MCJIT
+ if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
+ // Unable to open the cache file in read mode.
+ return 1;
+ }
+
+ MCCacheReader reader;
+
+ // Register symbol lookup function
+ if (mpExtSymbolLookupFn) {
+ reader.registerSymbolCallback(mpExtSymbolLookupFn,
+ mpExtSymbolLookupFnContext);
+ }
+ #endif
// Dependencies
#if USE_LIBBCC_SHA1SUM
@@ -231,7 +284,12 @@
}
// Read cache file
- ScriptCached *cached = reader.readCacheFile(&file, this);
+#if USE_MCJIT
+ ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
+#endif
+#if USE_OLD_JIT
+ ScriptCached *cached = reader.readCacheFile(&objFile, this);
+#endif
if (!cached) {
mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
return 1;
@@ -250,7 +308,6 @@
}
#endif
-
int Script::internalCompile() {
// Create the ScriptCompiled object
mCompiled = new (std::nothrow) ScriptCompiled(this);
@@ -312,20 +369,42 @@
// we don't have to cache it.
if (mCachePath &&
+#if USE_OLD_JIT
!mIsContextSlotNotAvail &&
ContextManager::get().isManagingContext(getContext()) &&
+#endif
!getBooleanProp("debug.bcc.nocache")) {
- FileHandle file;
+ FileHandle infoFile, objFile;
+
+ std::string objPath(mCachePath);
+ std::string infoPath(mCachePath);
+
+#if USE_MCJIT
+ getObjPath(objPath);
+ getInfoPath(infoPath);
+#endif
// Remove the file if it already exists before writing the new file.
// The old file may still be mapped elsewhere in memory and we do not want
// to modify its contents. (The same script may be running concurrently in
// the same process or a different process!)
- ::unlink(mCachePath);
+ ::unlink(objPath.c_str());
+#if USE_MCJIT
+ ::unlink(infoPath.c_str());
+#endif
- if (file.open(mCachePath, OpenMode::Write) >= 0) {
+ if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0
+#if USE_MCJIT
+ && infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0
+#endif
+ ) {
+#if USE_MCJIT
+ MCCacheWriter writer;
+#endif
+#if USE_OLD_JIT
CacheWriter writer;
+#endif
// Dependencies
#if USE_LIBBCC_SHA1SUM
@@ -347,15 +426,29 @@
(uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
"__isThreadable");
}
+#if USE_OLD_JIT
+ if (!writer.writeCacheFile(&objFile, this, libRS_threadable)) {
+#endif
+#if USE_MCJIT
+ if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
+#endif
+ objFile.truncate();
+ objFile.close();
- if (!writer.writeCacheFile(&file, this, libRS_threadable)) {
- file.truncate();
- file.close();
-
- if (unlink(mCachePath) != 0) {
+ if (unlink(objPath.c_str()) != 0) {
LOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
- mCachePath, strerror(errno));
+ objPath.c_str(), strerror(errno));
}
+
+#if USE_MCJIT
+ infoFile.truncate();
+ infoFile.close();
+
+ if (unlink(infoPath.c_str()) != 0) {
+ LOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
+ infoPath.c_str(), strerror(errno));
+ }
+#endif
}
}
}
@@ -573,5 +666,25 @@
}
return 0;
}
+#if USE_MCJIT
+size_t Script::getELFSize() const {
+ switch (mStatus) {
+ case ScriptStatus::Compiled: return mCompiled->getELFSize();
+
+ default:
+ return NULL;
+ }
+ return 0;
+}
+
+const char *Script::getELF() const {
+ switch (mStatus) {
+ case ScriptStatus::Compiled: return mCompiled->getELF();
+
+ default:
+ return NULL;
+ }
+}
+#endif
} // namespace bcc