Revert "Remove all deprecated BCC C APIs."
This reverts commit 170d420231f10d5b914fde505202c58f11f43e27.
diff --git a/include/bcc/RenderScript/RSCompilerDriver.h b/include/bcc/RenderScript/RSCompilerDriver.h
index f5d48c4..60810c2 100644
--- a/include/bcc/RenderScript/RSCompilerDriver.h
+++ b/include/bcc/RenderScript/RSCompilerDriver.h
@@ -17,15 +17,15 @@
#ifndef BCC_RS_COMPILER_DRIVER_H
#define BCC_RS_COMPILER_DRIVER_H
+#include <string>
+
#include "bcc/ExecutionEngine/BCCRuntimeSymbolResolver.h"
#include "bcc/ExecutionEngine/SymbolResolvers.h"
#include "bcc/ExecutionEngine/SymbolResolverProxy.h"
-#include "bcc/RenderScript/RSInfo.h"
#include "bcc/RenderScript/RSCompiler.h"
namespace bcc {
-class BCCContext;
class CompilerConfig;
class RSExecutable;
class RSScript;
@@ -39,16 +39,15 @@
LookupFunctionSymbolResolver<void*> mRSRuntime;
SymbolResolverProxy mResolver;
- RSExecutable *loadScriptCache(const char *pOutputPath,
- const RSInfo::DependencyTableTy &pDeps);
+ RSExecutable *loadScriptCache(const RSScript &pScript,
+ const std::string &pOutputPath);
// Setup the compiler config for the given script. Return true if mConfig has
// been changed and false if it remains unchanged.
bool setupConfig(const RSScript &pScript);
RSExecutable *compileScript(RSScript &pScript,
- const char *pOutputPath,
- const RSInfo::DependencyTableTy &pDeps);
+ const std::string &pOutputPath);
public:
RSCompilerDriver();
@@ -63,9 +62,8 @@
// FIXME: This method accompany with loadScriptCache and compileScript should
// all be const-methods. They're not now because the getAddress() in
// SymbolResolverInterface is not a const-method.
- RSExecutable *build(BCCContext &pContext,
- const char *pCacheDir, const char *pResName,
- const char *pBitcode, size_t pBitcodeSize);
+ RSExecutable *build(RSScript &pScript,
+ const std::string &pOutputPath);
};
} // end namespace bcc
diff --git a/include/bcc/RenderScript/RSInfo.h b/include/bcc/RenderScript/RSInfo.h
index 766d50c..16054f5 100644
--- a/include/bcc/RenderScript/RSInfo.h
+++ b/include/bcc/RenderScript/RSInfo.h
@@ -172,7 +172,7 @@
static bool CheckDependency(const RSInfo &pInfo,
const char *pInputFilename,
- const DependencyTableTy &pDeps);
+ const RSScript::SourceDependencyListTy &pDeps);
static bool AddBuiltInDependencies(RSInfo &pInfo);
rsinfo::Header mHeader;
@@ -200,12 +200,12 @@
~RSInfo();
// Implemented in RSInfoExtractor.cpp.
- static RSInfo *ExtractFromSource(const Source &pSource,
- const DependencyTableTy &pDeps);
+ static RSInfo *ExtractFromSource(
+ const Source &pSource, const RSScript::SourceDependencyListTy &pDeps);
// Implemented in RSInfoReader.cpp.
static RSInfo *ReadFromFile(InputFile &pInput,
- const DependencyTableTy &pDeps);
+ const RSScript::SourceDependencyListTy &pDeps);
// Implemneted in RSInfoWriter.cpp
bool write(OutputFile &pOutput);
diff --git a/include/bcc/RenderScript/RSScript.h b/include/bcc/RenderScript/RSScript.h
index 4522ada..e69dcc8 100644
--- a/include/bcc/RenderScript/RSScript.h
+++ b/include/bcc/RenderScript/RSScript.h
@@ -17,6 +17,11 @@
#ifndef BCC_RS_SCRIPT_H
#define BCC_RS_SCRIPT_H
+#include <string>
+
+#include <llvm/ADT/SmallVector.h>
+#include <llvm/Support/CodeGen.h>
+
#include "bcc/Script.h"
#include "bcc/Support/Sha1Util.h"
@@ -27,6 +32,23 @@
class RSScript : public Script {
public:
+ class SourceDependency {
+ private:
+ std::string mSourceName;
+ uint8_t mSHA1[SHA1_DIGEST_LENGTH];
+
+ public:
+ SourceDependency(const std::string &pSourceName,
+ const uint8_t *pSHA1);
+
+ inline const std::string &getSourceName() const
+ { return mSourceName; }
+
+ inline const uint8_t *getSHA1Checksum() const
+ { return mSHA1; }
+ };
+ typedef llvm::SmallVectorImpl<SourceDependency *> SourceDependencyListTy;
+
// This is one-one mapping with the llvm::CodeGenOpt::Level in
// llvm/Support/CodeGen.h. Therefore, value of this type can safely cast
// to llvm::CodeGenOpt::Level. This makes RSScript LLVM-free.
@@ -38,6 +60,8 @@
};
private:
+ llvm::SmallVector<SourceDependency *, 4> mSourceDependencies;
+
const RSInfo *mInfo;
unsigned mCompilerVersion;
@@ -53,6 +77,15 @@
RSScript(Source &pSource);
+ // Add dependency information for this script given the source named
+ // pSourceName. pSHA1 is the SHA-1 checksum of the given source. Return
+ // false on error.
+ bool addSourceDependency(const std::string &pSourceName,
+ const uint8_t *pSHA1);
+
+ const SourceDependencyListTy &getSourceDependencies() const
+ { return mSourceDependencies; }
+
// Set the associated RSInfo of the script.
void setInfo(const RSInfo *pInfo)
{ mInfo = pInfo; }
@@ -71,6 +104,8 @@
OptimizationLevel getOptimizationLevel() const
{ return mOptimizationLevel; }
+
+ ~RSScript();
};
} // end namespace bcc
diff --git a/include/bcc/bcc.h b/include/bcc/bcc.h
new file mode 100644
index 0000000..6741f7d
--- /dev/null
+++ b/include/bcc/bcc.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BCC_BCC_H
+#define ANDROID_BCC_BCC_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/*-------------------------------------------------------------------------*/
+
+/* libbcc script opaque type */
+typedef struct BCCOpaqueScript *BCCScriptRef;
+
+
+/* Symbol lookup function type */
+typedef void *(*BCCSymbolLookupFn)(void *context, char const *symbolName);
+
+
+/* llvm::Module (see <llvm>/include/llvm-c/Core.h for details) */
+typedef struct LLVMOpaqueModule *LLVMModuleRef;
+
+
+/*-------------------------------------------------------------------------*/
+
+
+#define BCC_NO_ERROR 0x0000
+#define BCC_INVALID_ENUM 0x0500
+#define BCC_INVALID_OPERATION 0x0502
+#define BCC_INVALID_VALUE 0x0501
+#define BCC_OUT_OF_MEMORY 0x0505
+#define BCC_DEPRECATED_API 0x0506
+
+
+/*-------------------------------------------------------------------------*/
+
+
+/* Optional Flags for bccReadBC, bccReadFile, bccLinkBC, bccLinkFile */
+#define BCC_SKIP_DEP_SHA1 (1 << 0)
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Relocation model when prepare object, it provides 1-1 mapping to the enum
+ * llvm::Reloc::Model in llvm/Support/CodeGen.h
+ */
+typedef enum bccRelocModelEnum {
+ bccRelocDefault, // Use default target-defined relocation model
+ bccRelocStatic,
+ bccRelocPIC,
+ bccRelocDynamicNoPIC
+} bccRelocModelEnum;
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+BCCScriptRef bccCreateScript();
+
+void bccDisposeScript(BCCScriptRef script);
+
+int bccRegisterSymbolCallback(BCCScriptRef script,
+ BCCSymbolLookupFn pFn,
+ void *pContext);
+
+int bccGetError(BCCScriptRef script); /* deprecated */
+
+
+
+int bccReadBC(BCCScriptRef script,
+ char const *resName,
+ char const *bitcode,
+ size_t bitcodeSize,
+ unsigned long flags);
+
+int bccReadModule(BCCScriptRef script,
+ char const *resName,
+ LLVMModuleRef module,
+ unsigned long flags);
+
+int bccReadFile(BCCScriptRef script,
+ char const *path,
+ unsigned long flags);
+
+int bccLinkBC(BCCScriptRef script,
+ char const *resName,
+ char const *bitcode,
+ size_t bitcodeSize,
+ unsigned long flags);
+
+int bccLinkFile(BCCScriptRef script,
+ char const *path,
+ unsigned long flags);
+
+void bccMarkExternalSymbol(BCCScriptRef script, char const *name);
+
+int bccPrepareRelocatable(BCCScriptRef script,
+ char const *objPath,
+ bccRelocModelEnum RelocModel,
+ unsigned long flags);
+
+int bccPrepareSharedObject(BCCScriptRef script,
+ char const *objPath,
+ char const *dsoPath,
+ unsigned long flags);
+
+int bccPrepareExecutable(BCCScriptRef script,
+ char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags);
+
+void *bccGetFuncAddr(BCCScriptRef script, char const *funcname);
+
+void bccGetExportVarList(BCCScriptRef script,
+ size_t varListSize,
+ void **varList);
+
+void bccGetExportFuncList(BCCScriptRef script,
+ size_t funcListSize,
+ void **funcList);
+
+void bccGetExportForEachList(BCCScriptRef script,
+ size_t forEachListSize,
+ void **forEachList);
+
+char const *bccGetBuildTime();
+
+char const *bccGetBuildRev();
+
+char const *bccGetBuildSHA1();
+
+#ifdef __cplusplus
+};
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#endif
diff --git a/lib/Core/Android.mk b/lib/Core/Android.mk
index 12bb1b5..4448364 100644
--- a/lib/Core/Android.mk
+++ b/lib/Core/Android.mk
@@ -26,7 +26,8 @@
BCCContextImpl.cpp \
Compiler.cpp \
Script.cpp \
- Source.cpp
+ Source.cpp \
+ bcc.cpp
#=====================================================================
# Device Static Library: libbccCore
diff --git a/lib/Core/bcc.cpp b/lib/Core/bcc.cpp
new file mode 100644
index 0000000..451b144
--- /dev/null
+++ b/lib/Core/bcc.cpp
@@ -0,0 +1,441 @@
+/*
+ * Copyright 2010-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Bitcode compiler (bcc) for Android:
+// This is an eager-compilation JIT running on Android.
+
+#include "bcc/bcc.h"
+
+#include <llvm/Support/CodeGen.h>
+
+#include <utils/StopWatch.h>
+
+#include <bcinfo/BitcodeWrapper.h>
+
+#include "bcc/Config/BuildInfo.h"
+#include "bcc/RenderScript/RSExecutable.h"
+#include "bcc/RenderScript/RSInfo.h"
+#include "bcc/RenderScript/RSScript.h"
+#include "bcc/Source.h"
+#include "bcc/Support/Log.h"
+#include "bcc/Support/Initialization.h"
+#include "bcc/Support/Sha1Util.h"
+
+#include "bcc_internal.h"
+
+using namespace bcc;
+
+namespace llvm {
+ class Module;
+}
+
+static bool bccBuildStampPrinted = false;
+
+static void bccPrintBuildStamp() {
+ if (!bccBuildStampPrinted) {
+ ALOGI("LIBBCC build time: %s", bccGetBuildTime());
+ ALOGI("LIBBCC build revision: %s", bccGetBuildRev());
+ bccBuildStampPrinted = true;
+ }
+}
+
+extern "C" BCCScriptRef bccCreateScript() {
+ bccPrintBuildStamp();
+ init::Initialize();
+ RSScriptContext *rsctx = new (std::nothrow) RSScriptContext();
+ if (rsctx != NULL) {
+ rsctx->script = NULL;
+ rsctx->result = NULL;
+ }
+ return wrap(rsctx);
+}
+
+
+extern "C" void bccDisposeScript(BCCScriptRef script) {
+ RSScriptContext *rsctx = unwrap(script);
+ if (rsctx != NULL) {
+ delete rsctx->script;
+ delete rsctx->result;
+ }
+ delete rsctx;
+}
+
+
+extern "C" int bccRegisterSymbolCallback(BCCScriptRef script,
+ BCCSymbolLookupFn pFn,
+ void *pContext) {
+ unwrap(script)->driver.setRSRuntimeLookupFunction(pFn);
+ unwrap(script)->driver.setRSRuntimeLookupContext(pContext);
+ return BCC_NO_ERROR;
+}
+
+
+extern "C" int bccGetError(BCCScriptRef script) {
+ return BCC_DEPRECATED_API;
+}
+
+static bool helper_add_source(RSScriptContext *pCtx,
+ char const *pName,
+ char const *pBitcode,
+ size_t pBitcodeSize,
+ unsigned long pFlags,
+ bool pIsLink) {
+ bool need_dependency_check = !(pFlags & BCC_SKIP_DEP_SHA1);
+ if (!pName && need_dependency_check) {
+ pFlags |= BCC_SKIP_DEP_SHA1;
+
+ ALOGW("It is required to give resName for sha1 dependency check.\n");
+ ALOGW("Sha1sum dependency check will be skipped.\n");
+ ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
+ }
+
+ Source *source = Source::CreateFromBuffer(pCtx->context, pName,
+ pBitcode, pBitcodeSize);
+ if (source == NULL) {
+ return false;
+ }
+
+ if (pCtx->script == NULL) {
+ pCtx->script = new (std::nothrow) RSScript(*source);
+ if (pCtx->script == NULL) {
+ ALOGE("Out of memory during script creation.");
+ return false;
+ }
+ } else {
+ bool result;
+ if (pIsLink) {
+ result = pCtx->script->mergeSource(*source);
+ } else {
+ result = pCtx->script->reset(*source);
+ }
+ if (!result) {
+ return false;
+ } else {
+ bcinfo::BitcodeWrapper wrapper(pBitcode, pBitcodeSize);
+ pCtx->script->setCompilerVersion(wrapper.getCompilerVersion());
+ pCtx->script->setOptimizationLevel(
+ static_cast<RSScript::OptimizationLevel>(
+ wrapper.getOptimizationLevel()));
+ }
+ }
+
+ if (need_dependency_check) {
+ uint8_t sha1[SHA1_DIGEST_LENGTH];
+ if (!Sha1Util::GetSHA1DigestFromBuffer(sha1, pBitcode, pBitcodeSize) ||
+ !pCtx->script->addSourceDependency(pName, sha1)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool helper_add_source(RSScriptContext *pCtx,
+ llvm::Module *pModule,
+ bool pIsLink) {
+ if (pModule == NULL) {
+ ALOGE("Cannot add null module to script!");
+ return false;
+ }
+
+ Source *source = Source::CreateFromModule(pCtx->context, *pModule, true);
+ if (source == NULL) {
+ return false;
+ }
+
+ if (pCtx->script == NULL) {
+ pCtx->script = new (std::nothrow) RSScript(*source);
+ if (pCtx->script == NULL) {
+ ALOGE("Out of memory during script creation.");
+ return false;
+ }
+ } else {
+ bool result;
+ if (pIsLink) {
+ result = pCtx->script->mergeSource(*source);
+ } else {
+ result = pCtx->script->reset(*source);
+ }
+ if (!result) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool helper_add_source(RSScriptContext *pCtx,
+ char const *pPath,
+ unsigned long pFlags,
+ bool pIsLink) {
+ bool need_dependency_check = !(pFlags & BCC_SKIP_DEP_SHA1);
+
+ Source *source = Source::CreateFromFile(pCtx->context, pPath);
+ if (source == NULL) {
+ return false;
+ }
+
+ if (pCtx->script == NULL) {
+ pCtx->script = new (std::nothrow) RSScript(*source);
+ if (pCtx->script == NULL) {
+ ALOGE("Out of memory during script creation.");
+ return false;
+ }
+ } else {
+ bool result;
+ if (pIsLink) {
+ result = pCtx->script->mergeSource(*source);
+ } else {
+ result = pCtx->script->reset(*source);
+ }
+ if (!result) {
+ return false;
+ }
+ }
+
+ if (need_dependency_check) {
+ uint8_t sha1[SHA1_DIGEST_LENGTH];
+ if (!Sha1Util::GetSHA1DigestFromFile(sha1, pPath) ||
+ !pCtx->script->addSourceDependency(pPath, sha1)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+extern "C" int bccReadBC(BCCScriptRef script,
+ char const *resName,
+ char const *bitcode,
+ size_t bitcodeSize,
+ unsigned long flags) {
+ return (helper_add_source(unwrap(script), resName,
+ bitcode, bitcodeSize,
+ flags, /* pIsLink */false) == false);
+}
+
+
+extern "C" int bccReadModule(BCCScriptRef script,
+ char const *resName /* deprecated */,
+ LLVMModuleRef module,
+ unsigned long flags) {
+ return (helper_add_source(unwrap(script), unwrap(module),
+ /* pIsLink */false) == false);
+}
+
+
+extern "C" int bccReadFile(BCCScriptRef script,
+ char const *path,
+ unsigned long flags) {
+ return (helper_add_source(unwrap(script), path,
+ flags, /* pIsLink */false) == false);
+}
+
+
+extern "C" int bccLinkBC(BCCScriptRef script,
+ char const *resName,
+ char const *bitcode,
+ size_t bitcodeSize,
+ unsigned long flags) {
+ return (helper_add_source(unwrap(script), resName,
+ bitcode, bitcodeSize,
+ flags, /* pIsLink */true) == false);
+}
+
+
+extern "C" int bccLinkFile(BCCScriptRef script,
+ char const *path,
+ unsigned long flags) {
+ RSScriptContext *rsctx = unwrap(script);
+ if ((::strcmp(path, RSInfo::LibCLCorePath) == 0) &&
+ (rsctx->script != NULL)) {
+ return (RSScript::LinkRuntime(*rsctx->script) == false);
+ } else {
+ return BCC_DEPRECATED_API;
+ }
+}
+
+
+extern "C" void bccMarkExternalSymbol(BCCScriptRef script, char const *name) {
+ return /* BCC_DEPRECATED_API */;
+}
+
+
+extern "C" int bccPrepareRelocatable(BCCScriptRef script,
+ char const *objPath,
+ bccRelocModelEnum RelocModel,
+ unsigned long flags) {
+ return BCC_DEPRECATED_API;
+}
+
+
+extern "C" int bccPrepareSharedObject(BCCScriptRef script,
+ char const *objPath,
+ char const *dsoPath,
+ unsigned long flags) {
+ return BCC_DEPRECATED_API;
+}
+
+
+extern "C" int bccPrepareExecutable(BCCScriptRef script,
+ char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags) {
+ android::StopWatch compileTimer("bcc: PrepareExecutable time");
+
+ RSScriptContext *rsctx = unwrap(script);
+
+ if (rsctx->script == NULL) {
+ return 1;
+ }
+
+ // Construct the output path.
+ std::string output_path(cacheDir);
+ if (!output_path.empty() && (*output_path.rbegin() != '/')) {
+ output_path.append(1, '/');
+ }
+ output_path.append(cacheName);
+ output_path.append(".o");
+
+ // Make sure the result container is clean.
+ if (rsctx->result != NULL) {
+ delete rsctx->result;
+ rsctx->result = NULL;
+ }
+
+ rsctx->result = rsctx->driver.build(*rsctx->script, output_path);
+
+ return (rsctx->result == NULL);
+}
+
+
+extern "C" void *bccGetFuncAddr(BCCScriptRef script, char const *funcname) {
+
+ RSScriptContext *rsctx = unwrap(script);
+
+ void *addr = NULL;
+ if (rsctx->result != NULL) {
+ addr = rsctx->result->getSymbolAddress(funcname);
+ }
+
+#if DEBUG_BCC_REFLECT
+ ALOGD("Function Address: %s --> %p\n", funcname, addr);
+#endif
+
+ return addr;
+}
+
+
+extern "C" void bccGetExportVarList(BCCScriptRef script,
+ size_t varListSize,
+ void **varList) {
+ const RSScriptContext *rsctx = unwrap(script);
+ if (varList && rsctx->result) {
+ const android::Vector<void *> &export_var_addrs =
+ rsctx->result->getExportVarAddrs();
+ size_t count = export_var_addrs.size();
+
+ if (count > varListSize) {
+ count = varListSize;
+ }
+
+ for (size_t i = 0; i < count; ++i) {
+ varList[i] = export_var_addrs[i];
+ }
+
+#if DEBUG_BCC_REFLECT
+ ALOGD("ExportVarCount = %lu\n",
+ static_cast<unsigned long>(export_var_addrs.size()));
+
+ for (size_t i = 0; i < count; ++i) {
+ ALOGD("ExportVarList[%lu] = %p\n", static_cast<unsigned long>(i),
+ varList[i]);
+ }
+#endif
+ }
+}
+
+
+extern "C" void bccGetExportFuncList(BCCScriptRef script,
+ size_t funcListSize,
+ void **funcList) {
+ const RSScriptContext *rsctx = unwrap(script);
+ if (funcList && rsctx->result) {
+ const android::Vector<void *> &export_func_addrs =
+ rsctx->result->getExportFuncAddrs();
+ size_t count = export_func_addrs.size();
+
+ if (count > funcListSize) {
+ count = funcListSize;
+ }
+
+ for (size_t i = 0; i < count; ++i) {
+ funcList[i] = export_func_addrs[i];
+ }
+
+#if DEBUG_BCC_REFLECT
+ ALOGD("ExportFuncCount = %lu\n",
+ static_cast<unsigned long>(export_var_addrs.size()));
+
+ for (size_t i = 0; i < count; ++i) {
+ ALOGD("ExportFuncList[%lu] = %p\n", static_cast<unsigned long>(i),
+ varList[i]);
+ }
+#endif
+ }
+}
+
+
+extern "C" void bccGetExportForEachList(BCCScriptRef script,
+ size_t forEachListSize,
+ void **forEachList) {
+ const RSScriptContext *rsctx = unwrap(script);
+ if (forEachList && rsctx->result) {
+ const android::Vector<void *> &export_foreach_func_addrs =
+ rsctx->result->getExportForeachFuncAddrs();
+ size_t count = export_foreach_func_addrs.size();
+
+ if (count > forEachListSize) {
+ count = forEachListSize;
+ }
+
+ for (size_t i = 0; i < count; ++i) {
+ forEachList[i] = export_foreach_func_addrs[i];
+ }
+
+#if DEBUG_BCC_REFLECT
+ ALOGD("ExportForEachCount = %lu\n",
+ static_cast<unsigned long>(export_foreach_func_addrs.size()));
+
+ for (size_t i = 0; i < count; ++i) {
+ ALOGD("ExportForEachList[%lu] = %p\n", static_cast<unsigned long>(i),
+ forEachList[i]);
+ }
+#endif
+ }
+}
+
+extern "C" char const *bccGetBuildTime() {
+ return BuildInfo::GetBuildTime();
+}
+
+extern "C" char const *bccGetBuildRev() {
+ return BuildInfo::GetBuildRev();
+}
+
+extern "C" char const *bccGetBuildSHA1() {
+ return BuildInfo::GetBuildSourceBlob();
+}
diff --git a/lib/Core/bcc_internal.h b/lib/Core/bcc_internal.h
new file mode 100644
index 0000000..d7cc2cf
--- /dev/null
+++ b/lib/Core/bcc_internal.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010-2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_INTERNAL_H
+#define BCC_INTERNAL_H
+
+#include "bcc/bcc.h"
+
+#include "bcc/BCCContext.h"
+#include "bcc/RenderScript/RSCompilerDriver.h"
+
+#if defined(__cplusplus)
+
+#define BCC_OPAQUE_TYPE_CONVERSION(TRANSPARENT_TYPE, OPAQUE_TYPE) \
+ inline OPAQUE_TYPE wrap(TRANSPARENT_TYPE ptr) { \
+ return reinterpret_cast<OPAQUE_TYPE>(ptr); \
+ } \
+ \
+ inline TRANSPARENT_TYPE unwrap(OPAQUE_TYPE ptr) { \
+ return reinterpret_cast<TRANSPARENT_TYPE>(ptr); \
+ }
+
+namespace llvm {
+ class Module;
+}
+
+namespace bcc {
+
+class RSScript;
+class RSExecutable;
+
+struct RSScriptContext {
+ // The context required in libbcc.
+ BCCContext context;
+ // The compiler driver
+ RSCompilerDriver driver;
+ // The script hold the source which is about to compile.
+ RSScript *script;
+ // The compilation result.
+ RSExecutable *result;
+};
+
+BCC_OPAQUE_TYPE_CONVERSION(bcc::RSScriptContext *, BCCScriptRef);
+BCC_OPAQUE_TYPE_CONVERSION(llvm::Module *, LLVMModuleRef);
+
+} // namespace bcc
+
+#undef BCC_OPAQUE_TYPE_CONVERSION
+
+#endif // defined(__cplusplus)
+
+#endif // BCC_INTERNAL_H
diff --git a/lib/RenderScript/RSCompilerDriver.cpp b/lib/RenderScript/RSCompilerDriver.cpp
index 0ccb625..da87968 100644
--- a/lib/RenderScript/RSCompilerDriver.cpp
+++ b/lib/RenderScript/RSCompilerDriver.cpp
@@ -16,25 +16,17 @@
#include "bcc/RenderScript/RSCompilerDriver.h"
-#include <llvm/Support/Path.h>
-
-#include "bcinfo/BitcodeWrapper.h"
-
#include "bcc/RenderScript/RSExecutable.h"
-#include "bcc/RenderScript/RSScript.h"
#include "bcc/Support/CompilerConfig.h"
#include "bcc/Support/TargetCompilerConfigs.h"
-#include "bcc/Source.h"
#include "bcc/Support/FileMutex.h"
#include "bcc/Support/Log.h"
#include "bcc/Support/InputFile.h"
#include "bcc/Support/Initialization.h"
-#include "bcc/Support/Sha1Util.h"
#include "bcc/Support/OutputFile.h"
#include <cutils/properties.h>
#include <utils/String8.h>
-#include <utils/StopWatch.h>
using namespace bcc;
@@ -64,10 +56,8 @@
delete mConfig;
}
-RSExecutable *
-RSCompilerDriver::loadScriptCache(const char *pOutputPath,
- const RSInfo::DependencyTableTy &pDeps) {
- android::StopWatch load_time("bcc: RSCompilerDriver::loadScriptCache time");
+RSExecutable *RSCompilerDriver::loadScriptCache(const RSScript &pScript,
+ const std::string &pOutputPath){
RSExecutable *result = NULL;
if (is_force_recompile())
@@ -79,7 +69,7 @@
FileMutex<FileBase::kReadLock> read_output_mutex(pOutputPath);
if (read_output_mutex.hasError() || !read_output_mutex.lock()) {
- ALOGE("Unable to acquire the read lock for %s! (%s)", pOutputPath,
+ ALOGE("Unable to acquire the read lock for %s! (%s)", pOutputPath.c_str(),
read_output_mutex.getErrorMessage().c_str());
return NULL;
}
@@ -90,7 +80,7 @@
InputFile *output_file = new (std::nothrow) InputFile(pOutputPath);
if ((output_file == NULL) || output_file->hasError()) {
- ALOGE("Unable to open the %s for read! (%s)", pOutputPath,
+ ALOGE("Unable to open the %s for read! (%s)", pOutputPath.c_str(),
output_file->getErrorMessage().c_str());
delete output_file;
return NULL;
@@ -103,7 +93,7 @@
if (!output_file->lock()) {
ALOGE("Unable to acquire the read lock on %s for reading %s! (%s)",
- pOutputPath, info_path.string(),
+ pOutputPath.c_str(), info_path.string(),
output_file->getErrorMessage().c_str());
delete output_file;
return NULL;
@@ -113,7 +103,8 @@
// Open and load the RS info file.
//===--------------------------------------------------------------------===//
InputFile info_file(info_path.string());
- RSInfo *info = RSInfo::ReadFromFile(info_file, pDeps);
+ RSInfo *info = RSInfo::ReadFromFile(info_file,
+ pScript.getSourceDependencies());
// Release the lock on output_file.
output_file->unlock();
@@ -133,6 +124,12 @@
return NULL;
}
+ // TODO: Dirty hack for libRS. This can be removed once RSExecutable is public
+ // to libRS.
+ if (!result->isThreadable()) {
+ mRSRuntime.getAddress("__clearThreadable");
+ }
+
return result;
}
@@ -173,11 +170,8 @@
return changed;
}
-RSExecutable *
-RSCompilerDriver::compileScript(RSScript &pScript,
- const char *pOutputPath,
- const RSInfo::DependencyTableTy &pDeps) {
- android::StopWatch compile_time("bcc: RSCompilerDriver::compileScript time");
+RSExecutable *RSCompilerDriver::compileScript(RSScript &pScript,
+ const std::string &pOutputPath) {
RSExecutable *result = NULL;
RSInfo *info = NULL;
@@ -186,7 +180,8 @@
//===--------------------------------------------------------------------===//
// RS info may contains configuration (such as #optimization_level) to the
// compiler therefore it should be extracted before compilation.
- info = RSInfo::ExtractFromSource(pScript.getSource(), pDeps);
+ info = RSInfo::ExtractFromSource(pScript.getSource(),
+ pScript.getSourceDependencies());
if (info == NULL) {
return NULL;
}
@@ -205,7 +200,7 @@
if (write_output_mutex.hasError() || !write_output_mutex.lock()) {
ALOGE("Unable to acquire the lock for writing %s! (%s)",
- pOutputPath, write_output_mutex.getErrorMessage().c_str());
+ pOutputPath.c_str(), write_output_mutex.getErrorMessage().c_str());
return NULL;
}
@@ -215,7 +210,7 @@
OutputFile *output_file = new (std::nothrow) OutputFile(pOutputPath);
if ((output_file == NULL) || output_file->hasError()) {
- ALOGE("Unable to open the %s for write! (%s)", pOutputPath,
+ ALOGE("Unable to open the %s for write! (%s)", pOutputPath.c_str(),
output_file->getErrorMessage().c_str());
delete info;
delete output_file;
@@ -228,7 +223,8 @@
bool compiler_need_reconfigure = setupConfig(pScript);
if (mConfig == NULL) {
- ALOGE("Failed to setup config for RS compiler to compile %s!", pOutputPath);
+ ALOGE("Failed to setup config for RS compiler to compile %s!",
+ pOutputPath.c_str());
delete info;
delete output_file;
return NULL;
@@ -239,7 +235,7 @@
if (compiler_need_reconfigure) {
Compiler::ErrorCode err = mCompiler.config(*mConfig);
if (err != Compiler::kSuccess) {
- ALOGE("Failed to config the RS compiler for %s! (%s)",pOutputPath,
+ ALOGE("Failed to config the RS compiler for %s! (%s)",pOutputPath.c_str(),
Compiler::GetErrorString(err));
delete info;
delete output_file;
@@ -252,7 +248,7 @@
//===--------------------------------------------------------------------===//
Compiler::ErrorCode compile_result = mCompiler.compile(pScript, *output_file);
if (compile_result != Compiler::kSuccess) {
- ALOGE("Unable to compile the source to file %s! (%s)", pOutputPath,
+ ALOGE("Unable to compile the source to file %s! (%s)", pOutputPath.c_str(),
Compiler::GetErrorString(compile_result));
delete info;
delete output_file;
@@ -269,6 +265,10 @@
return NULL;
}
+ // TODO: Dirty hack for libRS. This can be removed once RSExecutable is public
+ // to libRS.
+ result->setThreadable(mRSRuntime.getAddress("__isThreadable") != NULL);
+
//===--------------------------------------------------------------------===//
// Write out the RS info file.
//===--------------------------------------------------------------------===//
@@ -276,107 +276,20 @@
// successfully compiled and loaded.
if (!result->syncInfo(/* pForce */true)) {
ALOGW("%s was successfully compiled and loaded but its RS info file failed "
- "to write out!", pOutputPath);
+ "to write out!", pOutputPath.c_str());
}
return result;
}
-RSExecutable *RSCompilerDriver::build(BCCContext &pContext,
- const char *pCacheDir,
- const char *pResName,
- const char *pBitcode,
- size_t pBitcodeSize) {
- android::StopWatch build_time("bcc: RSCompilerDriver::build time");
- //===--------------------------------------------------------------------===//
- // Check parameters.
- //===--------------------------------------------------------------------===//
- if ((pCacheDir == NULL) || (pResName == NULL)) {
- ALOGE("Invalid parameter passed to RSCompilerDriver::build()! (cache dir: "
- "%s, resource name: %s)", ((pCacheDir) ? pCacheDir : "(null)"),
- ((pResName) ? pResName : "(null)"));
- return NULL;
- }
-
- if ((pBitcode == NULL) || (pBitcodeSize <= 0)) {
- ALOGE("No bitcode supplied! (bitcode: %p, size of bitcode: %u)",
- pBitcode, static_cast<unsigned>(pBitcodeSize));
- return NULL;
- }
-
- //===--------------------------------------------------------------------===//
- // Prepare dependency information.
- //===--------------------------------------------------------------------===//
- RSInfo::DependencyTableTy dep_info;
- uint8_t bitcode_sha1[20];
- Sha1Util::GetSHA1DigestFromBuffer(bitcode_sha1, pBitcode, pBitcodeSize);
- dep_info.push(std::make_pair(pResName, bitcode_sha1));
-
- //===--------------------------------------------------------------------===//
- // Construct output path.
- //===--------------------------------------------------------------------===//
- llvm::sys::Path output_path(pCacheDir);
-
- // {pCacheDir}/{pResName}
- if (!output_path.appendComponent(pResName)) {
- ALOGE("Failed to construct output path %s/%s!", pCacheDir, pResName);
- return NULL;
- }
-
- // {pCacheDir}/{pResName}.o
- output_path.appendSuffix("o");
-
- //===--------------------------------------------------------------------===//
- // Load cache.
- //===--------------------------------------------------------------------===//
- RSExecutable *result = loadScriptCache(output_path.c_str(), dep_info);
+RSExecutable *RSCompilerDriver::build(RSScript &pScript,
+ const std::string &pOutputPath) {
+ RSExecutable *result = loadScriptCache(pScript, pOutputPath);
if (result != NULL) {
// Cache hit
return result;
}
- //===--------------------------------------------------------------------===//
- // Load the bitcode and create script.
- //===--------------------------------------------------------------------===//
- Source *source = Source::CreateFromBuffer(pContext, pResName,
- pBitcode, pBitcodeSize);
- if (source == NULL) {
- return NULL;
- }
-
- RSScript *script = new (std::nothrow) RSScript(*source);
- if (script == NULL) {
- ALOGE("Out of memory when create Script object for '%s'! (output: %s)",
- pResName, output_path.c_str());
- delete source;
- return NULL;
- }
-
- // Link RS script with RenderScript runtime.
- if (!RSScript::LinkRuntime(*script)) {
- ALOGE("Failed to link script '%s' with RenderScript runtime!", pResName);
- delete script;
- return NULL;
- }
-
- // Read information from bitcode wrapper.
- bcinfo::BitcodeWrapper wrapper(pBitcode, pBitcodeSize);
- script->setCompilerVersion(wrapper.getCompilerVersion());
- script->setOptimizationLevel(static_cast<RSScript::OptimizationLevel>(
- wrapper.getOptimizationLevel()));
-
- //===--------------------------------------------------------------------===//
- // Compile the script
- //===--------------------------------------------------------------------===//
- result = compileScript(*script, output_path.c_str(), dep_info);
-
- // Script is no longer used. Free it to get more memory.
- delete script;
-
- if (result == NULL) {
- return NULL;
- }
-
- return result;
+ return compileScript(pScript, pOutputPath);
}
diff --git a/lib/RenderScript/RSInfo.cpp b/lib/RenderScript/RSInfo.cpp
index 02f6f6a..6f1b309 100644
--- a/lib/RenderScript/RSInfo.cpp
+++ b/lib/RenderScript/RSInfo.cpp
@@ -73,7 +73,7 @@
bool RSInfo::CheckDependency(const RSInfo &pInfo,
const char *pInputFilename,
- const DependencyTableTy &pDeps) {
+ const RSScript::SourceDependencyListTy &pDeps) {
// Built-in dependencies are libbcc.so, libRS.so and libclcore.bc.
static const unsigned NumBuiltInDependencies = 3;
@@ -125,15 +125,19 @@
}
for (unsigned i = 0; i < pDeps.size(); i++) {
+ const RSScript::SourceDependency &in_dep = *(pDeps[i]);
const std::pair<const char *, const uint8_t *> &cache_dep =
pInfo.mDependencyTable[i + NumBuiltInDependencies];
- if ((::strcmp(pDeps[i].first, cache_dep.first) != 0) ||
- (::memcmp(pDeps[i].second, cache_dep.second,
+ if ((::strncmp(in_dep.getSourceName().c_str(),
+ cache_dep.first,
+ in_dep.getSourceName().length()) != 0) ||
+ (::memcmp(in_dep.getSHA1Checksum(), cache_dep.second,
SHA1_DIGEST_LENGTH) != 0)) {
ALOGD("Cache %s is dirty due to the source it dependends on has been "
"changed:", pInputFilename);
- PRINT_DEPENDENCY("given - ", pDeps[i].first, pDeps[i].second);
+ PRINT_DEPENDENCY("given - ", in_dep.getSourceName().c_str(),
+ in_dep.getSHA1Checksum());
PRINT_DEPENDENCY("cache - ", cache_dep.first, cache_dep.second);
return false;
}
diff --git a/lib/RenderScript/RSInfoExtractor.cpp b/lib/RenderScript/RSInfoExtractor.cpp
index dd8e580..ae1085a 100644
--- a/lib/RenderScript/RSInfoExtractor.cpp
+++ b/lib/RenderScript/RSInfoExtractor.cpp
@@ -126,7 +126,7 @@
} // end anonymous namespace
RSInfo *RSInfo::ExtractFromSource(const Source &pSource,
- const DependencyTableTy &pDeps)
+ const RSScript::SourceDependencyListTy &pDeps)
{
const llvm::Module &module = pSource.getModule();
const char *module_name = module.getModuleIdentifier().c_str();
@@ -169,10 +169,13 @@
string_pool_size += ::strlen(LibRSPath) + 1 + SHA1_DIGEST_LENGTH;
string_pool_size += ::strlen(LibCLCorePath) + 1 + SHA1_DIGEST_LENGTH;
for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
- // +1 for null-terminator
- string_pool_size += ::strlen(/* name */pDeps[i].first) + 1;
- // +SHA1_DIGEST_LENGTH for SHA-1 checksum
- string_pool_size += SHA1_DIGEST_LENGTH;
+ const RSScript::SourceDependency *source_dep = pDeps[i];
+ if (source_dep != NULL) {
+ // +1 for null-terminator
+ string_pool_size += source_dep->getSourceName().length() + 1;
+ // +SHA1_DIGEST_LENGTH for SHA-1 checksum
+ string_pool_size += SHA1_DIGEST_LENGTH;
+ }
}
// Allocate result object
@@ -379,10 +382,14 @@
// Record dependency information.
//===--------------------------------------------------------------------===//
for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
- if (!writeDependency(/* name */pDeps[i].first, /* SHA-1 */pDeps[i].second,
- result->mStringPool, &cur_string_pool_offset,
- result->mDependencyTable)) {
- goto bail;
+ const RSScript::SourceDependency *source_dep = pDeps[i];
+ if (source_dep != NULL) {
+ if (!writeDependency(source_dep->getSourceName(),
+ source_dep->getSHA1Checksum(),
+ result->mStringPool, &cur_string_pool_offset,
+ result->mDependencyTable)) {
+ goto bail;
+ }
}
}
diff --git a/lib/RenderScript/RSInfoReader.cpp b/lib/RenderScript/RSInfoReader.cpp
index 9a25c24..035209a 100644
--- a/lib/RenderScript/RSInfoReader.cpp
+++ b/lib/RenderScript/RSInfoReader.cpp
@@ -173,7 +173,8 @@
} // end anonymous namespace
-RSInfo *RSInfo::ReadFromFile(InputFile &pInput, const DependencyTableTy &pDeps) {
+RSInfo *RSInfo::ReadFromFile(InputFile &pInput,
+ const RSScript::SourceDependencyListTy &pDeps) {
android::FileMap *map = NULL;
RSInfo *result = NULL;
const uint8_t *data;
diff --git a/lib/RenderScript/RSScript.cpp b/lib/RenderScript/RSScript.cpp
index 9058ff9..0efc43b 100644
--- a/lib/RenderScript/RSScript.cpp
+++ b/lib/RenderScript/RSScript.cpp
@@ -16,12 +16,23 @@
#include "bcc/RenderScript/RSScript.h"
+#include <cstring>
+
+#include <llvm/ADT/STLExtras.h>
+
#include "bcc/RenderScript/RSInfo.h"
#include "bcc/Source.h"
#include "bcc/Support/Log.h"
using namespace bcc;
+RSScript::SourceDependency::SourceDependency(const std::string &pSourceName,
+ const uint8_t *pSHA1)
+ : mSourceName(pSourceName) {
+ ::memcpy(mSHA1, pSHA1, sizeof(mSHA1));
+ return;
+}
+
bool RSScript::LinkRuntime(RSScript &pScript) {
// Using the same context with the source in pScript.
BCCContext &context = pScript.getSource().getContext();
@@ -47,9 +58,28 @@
: Script(pSource), mInfo(NULL), mCompilerVersion(0),
mOptimizationLevel(kOptLvl3) { }
+RSScript::~RSScript() {
+ llvm::DeleteContainerPointers(mSourceDependencies);
+}
+
bool RSScript::doReset() {
mInfo = NULL;
mCompilerVersion = 0;
mOptimizationLevel = kOptLvl3;
+ llvm::DeleteContainerPointers(mSourceDependencies);
+ return true;
+}
+
+bool RSScript::addSourceDependency(const std::string &pSourceName,
+ const uint8_t *pSHA1) {
+ SourceDependency *source_dep =
+ new (std::nothrow) SourceDependency(pSourceName, pSHA1);
+ if (source_dep == NULL) {
+ ALOGE("Out of memory when record dependency information of `%s'!",
+ pSourceName.c_str());
+ return false;
+ }
+
+ mSourceDependencies.push_back(source_dep);
return true;
}
diff --git a/libbcc-gen-build-info.mk b/libbcc-gen-build-info.mk
index 679a3e0..33e1b80 100644
--- a/libbcc-gen-build-info.mk
+++ b/libbcc-gen-build-info.mk
@@ -40,6 +40,8 @@
STATIC_LIBRARIES,$(lib),$(LOCAL_IS_HOST_MODULE))/$(lib)$(a_suffix)) \
$(addprefix $($(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
$(addsuffix $(so_suffix), $(LOCAL_SHARED_LIBRARIES))) \
+ $(LIBBCC_ROOT_PATH)/lib/Core/bcc.cpp
+
# Build Rules for Automatically Generated Build Information
GEN := $(local-intermediates-dir)/BuildInfo.cpp