Use build fingerprint and compile command for caching.
If either of those have changed, we need to invalidate the
compiled bit code.
Change-Id: Ic0c392ea5bfff5bf6dc8511740306895b1b12c82
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index 81e70f0..8350d00 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -216,29 +216,53 @@
const static char *BCC_EXE_PATH = "/system/bin/bcc";
-static bool compileBitcode(const char *cacheDir,
- const char *resName,
+static void setCompileArguments(std::vector<const char*>* args, const android::String8& bcFileName,
+ const char* cacheDir, const char* resName, const char* core_lib,
+ bool useRSDebugContext, const char* bccPluginName) {
+ rsAssert(cacheDir && resName && core_lib);
+ args->push_back(BCC_EXE_PATH);
+ args->push_back("-o");
+ args->push_back(resName);
+ args->push_back("-output_path");
+ args->push_back(cacheDir);
+ args->push_back("-bclib");
+ args->push_back(core_lib);
+ args->push_back("-mtriple");
+ args->push_back(DEFAULT_TARGET_TRIPLE_STRING);
+
+ // Execute the bcc compiler.
+ if (useRSDebugContext) {
+ args->push_back("-rs-debug-ctx");
+ } else {
+ // Only load additional libraries for compiles that don't use
+ // the debug context.
+ if (bccPluginName && strlen(bccPluginName) > 0) {
+ args->push_back("-load");
+ args->push_back(bccPluginName);
+ }
+ }
+
+ args->push_back(bcFileName.string());
+ args->push_back(NULL);
+}
+
+static bool compileBitcode(const android::String8& bcFileName,
const char *bitcode,
size_t bitcodeSize,
- const char *core_lib,
- bool useRSDebugContext,
- const char *bccPluginName) {
- rsAssert(cacheDir && resName && bitcode && bitcodeSize && core_lib);
+ const char** compileArguments,
+ const std::string& compileCommandLine) {
+ rsAssert(bitcode && bitcodeSize);
- android::String8 bcFilename(cacheDir);
- bcFilename.append("/");
- bcFilename.append(resName);
- bcFilename.append(".bc");
- FILE *bcfile = fopen(bcFilename.string(), "w");
+ FILE *bcfile = fopen(bcFileName.string(), "w");
if (!bcfile) {
- ALOGE("Could not write to %s", bcFilename.string());
+ ALOGE("Could not write to %s", bcFileName.string());
return false;
}
size_t nwritten = fwrite(bitcode, 1, bitcodeSize, bcfile);
fclose(bcfile);
if (nwritten != bitcodeSize) {
ALOGE("Could not write %zu bytes to %s", bitcodeSize,
- bcFilename.string());
+ bcFileName.string());
return false;
}
@@ -250,40 +274,9 @@
return false;
}
case 0: { // Child process
- std::vector<std::string> args;
- args.push_back(BCC_EXE_PATH);
- args.push_back("-o");
- args.push_back(resName);
- args.push_back("-output_path");
- args.push_back(cacheDir);
- args.push_back("-bclib");
- args.push_back(core_lib);
- args.push_back("-mtriple");
- args.push_back(DEFAULT_TARGET_TRIPLE_STRING);
+ ALOGV("Invoking BCC with: %s", compileCommandLine.c_str());
+ execv(BCC_EXE_PATH, (char* const*)compileArguments);
- // Execute the bcc compiler.
- if (useRSDebugContext) {
- args.push_back("-rs-debug-ctx");
- } else {
- // Only load additional libraries for compiles that don't use
- // the debug context.
- if (bccPluginName && strlen(bccPluginName) > 0) {
- args.push_back("-load");
- args.push_back(bccPluginName);
- }
- }
-
- args.push_back(bcFilename.string());
-
- const char **cargs = new const char *[args.size() + 1];
- for (uint32_t i = 0; i < args.size(); i++) {
- cargs[i] = args[i].c_str();
- }
- cargs[args.size()] = NULL;
-
- execv(BCC_EXE_PATH, (char *const *)cargs);
-
- delete [] cargs;
ALOGE("execv() failed: %s", strerror(errno));
abort();
return false;
@@ -318,13 +311,9 @@
#define MAKE_STR_HELPER(S) #S
#define MAKE_STR(S) MAKE_STR_HELPER(S)
#define EXPORT_VAR_STR "exportVarCount: "
-#define EXPORT_VAR_STR_LEN strlen(EXPORT_VAR_STR)
#define EXPORT_FUNC_STR "exportFuncCount: "
-#define EXPORT_FUNC_STR_LEN strlen(EXPORT_FUNC_STR)
#define EXPORT_FOREACH_STR "exportForEachCount: "
-#define EXPORT_FOREACH_STR_LEN strlen(EXPORT_FOREACH_STR)
#define OBJECT_SLOT_STR "objectSlotCount: "
-#define OBJECT_SLOT_STR_LEN strlen(OBJECT_SLOT_STR)
// Copy up to a newline or size chars from str -> s, updating str
// Returns s when successful and NULL when '\0' is finally reached.
@@ -390,7 +379,6 @@
mCtx->lockMutex();
#ifndef RS_COMPATIBILITY_LIB
- bcc::RSExecutable *exec = NULL;
bool useRSDebugContext = false;
mCompilerContext = NULL;
@@ -424,63 +412,79 @@
setupCompilerCallback(mCompilerDriver);
}
- bcinfo::MetadataExtractor ME((const char *) bitcode, bitcodeSize);
- if (!ME.extract()) {
+ bcinfo::MetadataExtractor bitcodeMetadata((const char *) bitcode, bitcodeSize);
+ if (!bitcodeMetadata.extract()) {
ALOGE("Could not extract metadata from bitcode");
return false;
}
- const char* core_lib = findCoreLib(ME, (const char*)bitcode, bitcodeSize);
+ const char* core_lib = findCoreLib(bitcodeMetadata, (const char*)bitcode, bitcodeSize);
if (mCtx->getContext()->getContextType() == RS_CONTEXT_TYPE_DEBUG) {
mCompilerDriver->setDebugContext(true);
useRSDebugContext = true;
- // Skip the cache lookup
- } else if (!is_force_recompile()) {
- // New cache infrastructure goes here
-
}
- if (exec == NULL) {
- bool built = compileBitcode(cacheDir, resName, (const char *)bitcode,
- bitcodeSize, core_lib, useRSDebugContext,
- bccPluginName);
- if (built) {
- exec = bcc::RSCompilerDriver::loadScript(cacheDir, resName,
- (const char *)bitcode, bitcodeSize, mResolver);
+ android::String8 bcFileName(cacheDir);
+ bcFileName.append("/");
+ bcFileName.append(resName);
+ bcFileName.append(".bc");
+
+ std::vector<const char*> compileArguments;
+ setCompileArguments(&compileArguments, bcFileName, cacheDir, resName, core_lib,
+ useRSDebugContext, bccPluginName);
+ // The last argument of compileArguments ia a NULL, so remove 1 from the size.
+ std::string compileCommandLine =
+ bcc::getCommandLine(compileArguments.size() - 1, compileArguments.data());
+
+ if (!is_force_recompile()) {
+ // Load the compiled script that's in the cache, if any.
+ mExecutable = bcc::RSCompilerDriver::loadScript(cacheDir, resName, (const char*)bitcode,
+ bitcodeSize, compileCommandLine.c_str(),
+ mResolver);
+ }
+
+ // If we can't, it's either not there or out of date. We compile the bit code and try loading
+ // again.
+ if (mExecutable == NULL) {
+ if (!compileBitcode(bcFileName, (const char*)bitcode, bitcodeSize, compileArguments.data(),
+ compileCommandLine)) {
+ ALOGE("bcc: FAILS to compile '%s'", resName);
+ mCtx->unlockMutex();
+ return false;
+ }
+ mExecutable = bcc::RSCompilerDriver::loadScript(cacheDir, resName, (const char*)bitcode,
+ bitcodeSize, compileCommandLine.c_str(),
+ mResolver);
+ if (mExecutable == NULL) {
+ ALOGE("bcc: FAILS to load freshly compiled executable for '%s'", resName);
+ mCtx->unlockMutex();
+ return false;
}
}
- if (exec == NULL) {
- ALOGE("bcc: FAILS to prepare executable for '%s'", resName);
- mCtx->unlockMutex();
- return false;
- }
-
- mExecutable = exec;
-
- exec->setThreadable(mIsThreadable);
- if (!exec->syncInfo()) {
+ mExecutable->setThreadable(mIsThreadable);
+ if (!mExecutable->syncInfo()) {
ALOGW("bcc: FAILS to synchronize the RS info file to the disk");
}
- mRoot = reinterpret_cast<int (*)()>(exec->getSymbolAddress("root"));
+ mRoot = reinterpret_cast<int (*)()>(mExecutable->getSymbolAddress("root"));
mRootExpand =
- reinterpret_cast<int (*)()>(exec->getSymbolAddress("root.expand"));
- mInit = reinterpret_cast<void (*)()>(exec->getSymbolAddress("init"));
+ reinterpret_cast<int (*)()>(mExecutable->getSymbolAddress("root.expand"));
+ mInit = reinterpret_cast<void (*)()>(mExecutable->getSymbolAddress("init"));
mFreeChildren =
- reinterpret_cast<void (*)()>(exec->getSymbolAddress(".rs.dtor"));
+ reinterpret_cast<void (*)()>(mExecutable->getSymbolAddress(".rs.dtor"));
- if (ME.getExportVarCount()) {
- mBoundAllocs = new Allocation *[ME.getExportVarCount()];
- memset(mBoundAllocs, 0, sizeof(void *) * ME.getExportVarCount());
+ if (bitcodeMetadata.getExportVarCount()) {
+ mBoundAllocs = new Allocation *[bitcodeMetadata.getExportVarCount()];
+ memset(mBoundAllocs, 0, sizeof(void *) * bitcodeMetadata.getExportVarCount());
}
- for (size_t i = 0; i < ME.getExportForEachSignatureCount(); i++) {
- char* name = new char[strlen(ME.getExportForEachNameList()[i]) + 1];
- mExportedForEachFuncList.push_back(std::make_pair(name,
- ME.getExportForEachSignatureList()[i]));
+ for (size_t i = 0; i < bitcodeMetadata.getExportForEachSignatureCount(); i++) {
+ char* name = new char[strlen(bitcodeMetadata.getExportForEachNameList()[i]) + 1];
+ mExportedForEachFuncList.push_back(
+ std::make_pair(name, bitcodeMetadata.getExportForEachSignatureList()[i]));
}
#else // RS_COMPATIBILITY_LIB is defined
diff --git a/cpu_ref/rsCpuScript.h b/cpu_ref/rsCpuScript.h
index 7531a86..666379d 100644
--- a/cpu_ref/rsCpuScript.h
+++ b/cpu_ref/rsCpuScript.h
@@ -112,7 +112,8 @@
const Script *mScript;
#ifndef RS_COMPATIBILITY_LIB
- const char* findCoreLib(const bcinfo::MetadataExtractor& ME, const char* bitcode,
+ // Returns the path to the core library we'll use.
+ const char* findCoreLib(const bcinfo::MetadataExtractor& bitCodeMetaData, const char* bitcode,
size_t bitcodeSize);
int (*mRoot)();
int (*mRootExpand)();
@@ -150,10 +151,8 @@
Allocation **mBoundAllocs;
void * mIntrinsicData;
bool mIsThreadable;
-
};
-
Allocation * rsdScriptGetAllocationForPointer(
const Context *dc,
const Script *script,