Add new libbcc API bccPrepareExecutableEx
We are undergoing a migration to new bccPrepareExecutable,
which splits cachePath argument into cacheDir and cacheName
(no file extension).
Change-Id: I48ecb9bc6c038650bf766318ff96b78723d0f4bc
diff --git a/lib/ExecutionEngine/Script.cpp b/lib/ExecutionEngine/Script.cpp
index 1fcde93..ec52b60 100644
--- a/lib/ExecutionEngine/Script.cpp
+++ b/lib/ExecutionEngine/Script.cpp
@@ -172,7 +172,9 @@
}
-int Script::prepareExecutable(char const *cachePath, unsigned long flags) {
+int Script::prepareExecutable(char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags) {
if (mStatus != ScriptStatus::Unknown) {
mErrorCode = BCC_INVALID_OPERATION;
LOGE("Invalid operation: %s\n", __func__);
@@ -180,10 +182,19 @@
}
#if USE_CACHE
- // Load Cache File
- mCachePath = cachePath;
- if (cachePath && internalLoadCache() == 0) {
- return 0;
+ if (cacheDir && cacheName) {
+ // Set Cache Directory and File Name
+ mCacheDir = cacheDir;
+ mCacheName = cacheName;
+
+ if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
+ mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
+ }
+
+ // Load Cache File
+ if (internalLoadCache() == 0) {
+ return 0;
+ }
}
#endif
@@ -196,34 +207,6 @@
#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
@@ -232,36 +215,36 @@
return 1;
}
- if (!mCachePath) {
+ if (mCacheDir.empty() || mCacheName.empty()) {
// The application developer has not specify the cachePath, so
// we don't know where to open the cache file.
return 1;
}
- FileHandle objFile, infoFile;
- std::string objPath(mCachePath);
- std::string infoPath(mCachePath);
-
-#if USE_MCJIT
- getObjPath(objPath);
- getInfoPath(infoPath);
+#if USE_OLD_JIT
+ std::string objPath(mCacheDir + mCacheName + ".oBCC");
+#elif USE_MCJIT
+ std::string objPath(mCacheDir + mCacheName + ".o");
+ std::string infoPath(mCacheDir + mCacheName + ".info");
#endif
+ FileHandle objFile;
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 !USE_OLD_JIT && USE_MCJIT
+ FileHandle infoFile;
if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
// Unable to open the cache file in read mode.
return 1;
}
+#endif
+#if USE_OLD_JIT
+ CacheReader reader;
+#elif USE_MCJIT
MCCacheReader reader;
// Register symbol lookup function
@@ -282,13 +265,12 @@
}
// Read cache file
-#if USE_MCJIT
+#if USE_OLD_JIT
+ ScriptCached *cached = reader.readCacheFile(&objFile, this);
+#elif 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();
@@ -366,43 +348,44 @@
// Note: If the address of the context is not in the context slot, then
// we don't have to cache it.
- if (mCachePath &&
+ if (!mCacheDir.empty() &&
+ !mCacheName.empty() &&
#if USE_OLD_JIT
!mIsContextSlotNotAvail &&
ContextManager::get().isManagingContext(getContext()) &&
#endif
!getBooleanProp("debug.bcc.nocache")) {
- FileHandle infoFile, objFile;
+ FileHandle objFile;
- std::string objPath(mCachePath);
- std::string infoPath(mCachePath);
-
-#if USE_MCJIT
- getObjPath(objPath);
- getInfoPath(infoPath);
+#if USE_OLD_JIT
+ std::string objPath(mCacheDir + mCacheName + ".oBCC");
+#elif USE_MCJIT
+ FileHandle infoFile;
+ std::string objPath(mCacheDir + mCacheName + ".o");
+ std::string infoPath(mCacheDir + mCacheName + ".info");
#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(objPath.c_str());
-#if USE_MCJIT
+#if !USE_OLD_JIT && USE_MCJIT
::unlink(infoPath.c_str());
#endif
if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0
-#if USE_MCJIT
+#if !USE_OLD_JIT && USE_MCJIT
&& infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0
#endif
- ) {
+ ) {
-#if USE_MCJIT
- MCCacheWriter writer;
-#endif
#if USE_OLD_JIT
CacheWriter writer;
+#elif USE_MCJIT
+ MCCacheWriter writer;
#endif
#ifdef TARGET_BUILD
@@ -428,8 +411,7 @@
#if USE_OLD_JIT
if (!writer.writeCacheFile(&objFile, this, libRS_threadable)) {
-#endif
-#if USE_MCJIT
+#elif USE_MCJIT
if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
#endif
objFile.truncate();
@@ -440,7 +422,7 @@
objPath.c_str(), strerror(errno));
}
-#if USE_MCJIT
+#if !USE_OLD_JIT && USE_MCJIT
infoFile.truncate();
infoFile.close();
diff --git a/lib/ExecutionEngine/Script.h b/lib/ExecutionEngine/Script.h
index 12cfd85..4f99581 100644
--- a/lib/ExecutionEngine/Script.h
+++ b/lib/ExecutionEngine/Script.h
@@ -56,7 +56,10 @@
#endif
};
- char const *mCachePath;
+#if USE_CACHE
+ std::string mCacheDir;
+ std::string mCacheName;
+#endif
bool mIsContextSlotNotAvail;
@@ -72,7 +75,7 @@
public:
Script() : mErrorCode(BCC_NO_ERROR), mStatus(ScriptStatus::Unknown),
- mCachePath(NULL), mIsContextSlotNotAvail(false),
+ mIsContextSlotNotAvail(false),
mpExtSymbolLookupFn(NULL), mpExtSymbolLookupFnContext(NULL) {
Compiler::GlobalInitialization();
@@ -96,7 +99,9 @@
char const *path,
unsigned long flags);
- int prepareExecutable(char const *cachePath, unsigned long flags);
+ int prepareExecutable(char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags);
char const *getCompilerErrorMessage();
diff --git a/lib/ExecutionEngine/bcc.cpp b/lib/ExecutionEngine/bcc.cpp
index fd79e94..e02ddc5 100644
--- a/lib/ExecutionEngine/bcc.cpp
+++ b/lib/ExecutionEngine/bcc.cpp
@@ -26,6 +26,8 @@
#include "DebugHelper.h"
#include "Script.h"
+#include <string>
+
#include <utils/StopWatch.h>
using namespace bcc;
@@ -104,16 +106,65 @@
}
+inline static bool parseOldStyleCachePath(std::string &cacheDir,
+ std::string &cacheName,
+ std::string const &path) {
+ size_t found0 = path.find("@");
+ size_t found1 = path.rfind("@");
+ size_t found2 = std::string::npos;
+
+ if (found0 == found1 ||
+ found0 == std::string::npos ||
+ found1 == std::string::npos) {
+ LOGE("Ill formatted resource name '%s'. The name should contain 2 @s",
+ path.c_str());
+ return false;
+ }
+
+ std::string ext(".oBCC");
+
+ if (path.size() > ext.size() &&
+ path.compare(path.size() - ext.size(), ext.size(), ext) == 0) {
+ found2 = path.size() - ext.size();
+ }
+
+ cacheDir = path.substr(0, found0);
+ cacheName = path.substr(found1 + 1, found2 - found1 - 1);
+
+ LOGD("cacheDir = %s\n", cacheDir.c_str());
+ LOGD("cacheName = %s\n", cacheName.c_str());
+ return true;
+}
+
+
extern "C" int bccPrepareExecutable(BCCScriptRef script,
char const *cachePath,
unsigned long flags) {
BCC_FUNC_LOGGER();
+ std::string cacheDir, cacheName;
+ if (!parseOldStyleCachePath(cacheDir, cacheName, cachePath)) {
+ return 1;
+ }
+
+ return bccPrepareExecutableEx(script,
+ cacheDir.c_str(),
+ cacheName.c_str(),
+ flags);
+}
+
+
+extern "C" int bccPrepareExecutableEx(BCCScriptRef script,
+ char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags) {
+ BCC_FUNC_LOGGER();
+
#if defined(__arm__)
android::StopWatch compileTimer("bcc: PrepareExecutable time");
#endif
- return unwrap(script)->prepareExecutable(cachePath, flags);
+ return unwrap(script)->prepareExecutable(cacheDir, cacheName, flags);
}