Add bccPrepareSharedObject
Unlike bccPrepareExecuteable, bccPrepareSharedObject does not
resolve external symbols; therefore it only generate cache file
not execuable.
Change-Id: I3ef093015a4f54011fbf298123cac2464230b408
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index c1c9267..09c0890 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -308,7 +308,7 @@
}
-int Compiler::compile() {
+int Compiler::compile(bool compileOnly) {
llvm::Target const *Target = NULL;
llvm::TargetData *TD = NULL;
llvm::TargetMachine *TM = NULL;
@@ -370,11 +370,77 @@
#endif
#if USE_MCJIT
- if (runMCCodeGen(new llvm::TargetData(*TD), TM,
- ExportVarMetadata, ExportFuncMetadata) != 0) {
+ if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
goto on_bcc_compile_error;
}
+ if (compileOnly)
+ return 0;
+
+ // Load the ELF Object
+ mRSExecutable =
+ rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
+ mEmittedELFExecutable.size(),
+ &resolveSymbolAdapter, this);
+
+ if (!mRSExecutable) {
+ setError("Fail to load emitted ELF relocatable file");
+ goto on_bcc_compile_error;
+ }
+
+ if (ExportVarMetadata) {
+ ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
+ std::vector<std::string> &varNameList = mpResult->mExportVarsName;
+
+ for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
+ llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
+ if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
+ llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
+ if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
+ llvm::StringRef ExportVarName =
+ static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
+
+ varList.push_back(
+ rsloaderGetSymbolAddress(mRSExecutable,
+ ExportVarName.str().c_str()));
+ varNameList.push_back(ExportVarName.str());
+#if DEBUG_MCJIT_REFLECT
+ LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
+ varList.back());
+#endif
+ continue;
+ }
+ }
+
+ varList.push_back(NULL);
+ }
+ }
+
+ if (ExportFuncMetadata) {
+ ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
+ std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
+
+ for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
+ llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
+ if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
+ llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
+ if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
+ llvm::StringRef ExportFuncName =
+ static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
+
+ funcList.push_back(
+ rsloaderGetSymbolAddress(mRSExecutable,
+ ExportFuncName.str().c_str()));
+ funcNameList.push_back(ExportFuncName.str());
+#if DEBUG_MCJIT_RELECT
+ LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
+ funcList.back());
+#endif
+ }
+ }
+ }
+ }
+
#if DEBUG_MCJIT_DISASSEMBLER
{
// Get MC codegen emitted function name list
@@ -599,9 +665,7 @@
#if USE_MCJIT
-int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
- llvm::NamedMDNode const *ExportVarMetadata,
- llvm::NamedMDNode const *ExportFuncMetadata) {
+int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
// Decorate mEmittedELFExecutable with formatted ostream
llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
@@ -624,75 +688,6 @@
MCCodeGenPasses.run(*mModule);
OutSVOS.flush();
-
- // Load the ELF Object
- mRSExecutable =
- rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
- mEmittedELFExecutable.size(),
- &resolveSymbolAdapter, this);
-
- if (!mRSExecutable) {
- setError("Fail to load emitted ELF relocatable file");
- return 1;
- }
-
-#if !USE_OLD_JIT
- // Note: If old JIT is compiled then we prefer the old version instead of the
- // new version.
-
- if (ExportVarMetadata) {
- ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
- std::vector<std::string> &varNameList = mpResult->mExportVarsName;
-
- for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
- if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
- llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
- if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportVarName =
- static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
-
- varList.push_back(
- rsloaderGetSymbolAddress(mRSExecutable,
- ExportVarName.str().c_str()));
- varNameList.push_back(ExportVarName.str());
-#if DEBUG_MCJIT_REFLECT
- LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
- varList.back());
-#endif
- continue;
- }
- }
-
- varList.push_back(NULL);
- }
- }
-
- if (ExportFuncMetadata) {
- ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
- std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
-
- for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
- if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
- llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
- if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportFuncName =
- static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
-
- funcList.push_back(
- rsloaderGetSymbolAddress(mRSExecutable,
- ExportFuncName.str().c_str()));
- funcNameList.push_back(ExportFuncName.str());
-#if DEBUG_MCJIT_RELECT
- LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
- funcList.back());
-#endif
- }
- }
- }
- }
-#endif // !USE_OLD_JIT
return 0;
}
#endif // USE_MCJIT
diff --git a/lib/ExecutionEngine/Compiler.h b/lib/ExecutionEngine/Compiler.h
index 82e0be2..c6938a6 100644
--- a/lib/ExecutionEngine/Compiler.h
+++ b/lib/ExecutionEngine/Compiler.h
@@ -153,7 +153,7 @@
int linkModule(llvm::Module *module);
- int compile();
+ int compile(bool compileOnly);
char const *getErrorMessage() {
return mError.c_str();
@@ -171,9 +171,7 @@
llvm::NamedMDNode const *ExportVarMetadata,
llvm::NamedMDNode const *ExportFuncMetadata);
- int runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
- llvm::NamedMDNode const *ExportVarMetadata,
- llvm::NamedMDNode const *ExportFuncMetadata);
+ int runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM);
#if USE_MCJIT
static void *resolveSymbolAdapter(void *context, char const *name);
diff --git a/lib/ExecutionEngine/MCCacheReader.cpp b/lib/ExecutionEngine/MCCacheReader.cpp
index 82b7cdc..39e567f 100644
--- a/lib/ExecutionEngine/MCCacheReader.cpp
+++ b/lib/ExecutionEngine/MCCacheReader.cpp
@@ -54,9 +54,24 @@
ScriptCached *MCCacheReader::readCacheFile(FileHandle *objFile,
FileHandle *infoFile,
Script *S) {
+ bool result = checkCacheFile(objFile, infoFile, S)
+ && readPragmaList()
+ && readObjectSlotList()
+ && readObjFile()
+ && readVarNameList()
+ && readFuncNameList()
+ //&& relocate()
+ ;
+
+ return result ? mpResult.take() : NULL;
+}
+
+bool MCCacheReader::checkCacheFile(FileHandle *objFile,
+ FileHandle *infoFile,
+ Script *S) {
// Check file handle
if (!objFile || objFile->getFD() < 0 || !infoFile || infoFile->getFD() < 0) {
- return NULL;
+ return false;
}
mObjFile = objFile;
@@ -67,7 +82,7 @@
if (!mpResult) {
LOGE("Unable to allocate ScriptCached object.\n");
- return NULL;
+ return false;
}
bool result = checkFileSize()
@@ -79,15 +94,9 @@
&& checkStringPool()
&& readDependencyTable()
&& checkDependency()
- && readPragmaList()
- && readObjectSlotList()
- && readObjFile()
- && readVarNameList()
- && readFuncNameList()
- //&& relocate()
;
- return result ? mpResult.take() : NULL;
+ return result;
}
diff --git a/lib/ExecutionEngine/MCCacheReader.h b/lib/ExecutionEngine/MCCacheReader.h
index d9e4027..7fcbe41 100644
--- a/lib/ExecutionEngine/MCCacheReader.h
+++ b/lib/ExecutionEngine/MCCacheReader.h
@@ -75,6 +75,7 @@
}
ScriptCached *readCacheFile(FileHandle *objFile, FileHandle *infoFile, Script *s);
+ bool checkCacheFile(FileHandle *objFile, FileHandle *infoFile, Script *S);
bool isContextSlotNotAvail() const {
return mIsContextSlotNotAvail;
diff --git a/lib/ExecutionEngine/Script.cpp b/lib/ExecutionEngine/Script.cpp
index 26929fd..e67fd61 100644
--- a/lib/ExecutionEngine/Script.cpp
+++ b/lib/ExecutionEngine/Script.cpp
@@ -178,6 +178,32 @@
return 0;
}
+int Script::prepareSharedObject(char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags) {
+#if USE_CACHE
+ 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 '/'
+ }
+
+ // Check Cache File
+ if (internalLoadCache(true) == 0) {
+ return 0;
+ }
+ }
+#endif
+ int status = internalCompile(true);
+ if (status != 0) {
+ LOGE("LLVM error message: %s\n", getCompilerErrorMessage());
+ }
+ return status;
+}
+
int Script::prepareExecutable(char const *cacheDir,
char const *cacheName,
@@ -199,13 +225,13 @@
}
// Load Cache File
- if (internalLoadCache() == 0) {
+ if (internalLoadCache(false) == 0) {
return 0;
}
}
#endif
- int status = internalCompile();
+ int status = internalCompile(false);
if (status != 0) {
LOGE("LLVM error message: %s\n", getCompilerErrorMessage());
}
@@ -214,7 +240,7 @@
#if USE_CACHE
-int Script::internalLoadCache() {
+int Script::internalLoadCache(bool checkOnly) {
if (getBooleanProp("debug.bcc.nocache")) {
// Android system environment property disable the cache mechanism by
// setting "debug.bcc.nocache". So we will not load the cache file any
@@ -270,6 +296,9 @@
}
}
+ if (checkOnly)
+ return reader.checkCacheFile(&objFile, &infoFile, this);
+
// Read cache file
ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
@@ -291,7 +320,7 @@
}
#endif
-int Script::internalCompile() {
+int Script::internalCompile(bool compileOnly) {
// Create the ScriptCompiled object
mCompiled = new (std::nothrow) ScriptCompiled(this);
@@ -337,7 +366,7 @@
}
// Compile and JIT the code
- if (mCompiled->compile() != 0) {
+ if (mCompiled->compile(compileOnly) != 0) {
LOGE("Unable to compile.\n");
return 1;
}
diff --git a/lib/ExecutionEngine/Script.h b/lib/ExecutionEngine/Script.h
index 921af8c..46b385f 100644
--- a/lib/ExecutionEngine/Script.h
+++ b/lib/ExecutionEngine/Script.h
@@ -103,6 +103,10 @@
char const *cacheName,
unsigned long flags);
+ int prepareSharedObject(char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags);
+
char const *getCompilerErrorMessage();
void *lookup(const char *name);
@@ -159,9 +163,9 @@
private:
#if USE_CACHE
- int internalLoadCache();
+ int internalLoadCache(bool checkOnly);
#endif
- int internalCompile();
+ int internalCompile(bool compileOnly);
};
diff --git a/lib/ExecutionEngine/ScriptCompiled.h b/lib/ExecutionEngine/ScriptCompiled.h
index 9593be8..5972ddf 100644
--- a/lib/ExecutionEngine/ScriptCompiled.h
+++ b/lib/ExecutionEngine/ScriptCompiled.h
@@ -88,8 +88,8 @@
return mCompiler.linkModule(module);
}
- int compile() {
- return mCompiler.compile();
+ int compile(bool compileOnly) {
+ return mCompiler.compile(compileOnly);
}
char const *getCompilerErrorMessage() {
diff --git a/lib/ExecutionEngine/bcc.cpp b/lib/ExecutionEngine/bcc.cpp
index 1d2bc8f..1686cb2 100644
--- a/lib/ExecutionEngine/bcc.cpp
+++ b/lib/ExecutionEngine/bcc.cpp
@@ -117,6 +117,14 @@
}
+extern "C" int bccPrepareSharedObject(BCCScriptRef script,
+ char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags) {
+ return unwrap(script)->prepareSharedObject(cacheDir, cacheName, flags);
+}
+
+
extern "C" int bccPrepareExecutable(BCCScriptRef script,
char const *cacheDir,
char const *cacheName,