Revert "Make libbcc public."
This reverts commit 80232dd16c0affb2afae01cde6c94abf23ac1ba8.
diff --git a/lib/ExecutionEngine/bcc.cpp b/lib/ExecutionEngine/bcc.cpp
new file mode 100644
index 0000000..b830ec2
--- /dev/null
+++ b/lib/ExecutionEngine/bcc.cpp
@@ -0,0 +1,442 @@
+/*
+ * 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 "DebugHelper.h"
+#include "Initialization.h"
+#include "RSExecutable.h"
+#include "RSScript.h"
+#include "Sha1Helper.h"
+#include "Source.h"
+
+#include "bcc_internal.h"
+#include <bcinfo/BitcodeWrapper.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() {
+ BCC_FUNC_LOGGER();
+ 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) {
+ BCC_FUNC_LOGGER();
+ 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) {
+ BCC_FUNC_LOGGER();
+ unwrap(script)->driver.setRSRuntimeLookupFunction(pFn);
+ unwrap(script)->driver.setRSRuntimeLookupContext(pContext);
+ return BCC_NO_ERROR;
+}
+
+
+extern "C" int bccGetError(BCCScriptRef script) {
+ BCC_FUNC_LOGGER();
+ 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[20];
+ calcSHA1(sha1, pBitcode, pBitcodeSize);
+ if (!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[20];
+ calcFileSHA1(sha1, pPath);
+ if (!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) {
+ BCC_FUNC_LOGGER();
+ 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) {
+ BCC_FUNC_LOGGER();
+ return (helper_add_source(unwrap(script), unwrap(module),
+ /* pIsLink */false) == false);
+}
+
+
+extern "C" int bccReadFile(BCCScriptRef script,
+ char const *path,
+ unsigned long flags) {
+ BCC_FUNC_LOGGER();
+ 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) {
+ BCC_FUNC_LOGGER();
+ 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) {
+ BCC_FUNC_LOGGER();
+ return (helper_add_source(unwrap(script), path,
+ flags, /* pIsLink */true) == false);
+}
+
+
+extern "C" void bccMarkExternalSymbol(BCCScriptRef script, char const *name) {
+ BCC_FUNC_LOGGER();
+ return /* BCC_DEPRECATED_API */;
+}
+
+
+extern "C" int bccPrepareRelocatable(BCCScriptRef script,
+ char const *objPath,
+ bccRelocModelEnum RelocModel,
+ unsigned long flags) {
+ BCC_FUNC_LOGGER();
+ return BCC_DEPRECATED_API;
+}
+
+
+extern "C" int bccPrepareSharedObject(BCCScriptRef script,
+ char const *objPath,
+ char const *dsoPath,
+ unsigned long flags) {
+ BCC_FUNC_LOGGER();
+ return BCC_DEPRECATED_API;
+}
+
+
+extern "C" int bccPrepareExecutable(BCCScriptRef script,
+ char const *cacheDir,
+ char const *cacheName,
+ unsigned long flags) {
+ BCC_FUNC_LOGGER();
+
+ 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) {
+ BCC_FUNC_LOGGER();
+
+ 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) {
+ BCC_FUNC_LOGGER();
+
+ 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) {
+ BCC_FUNC_LOGGER();
+
+ 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) {
+ BCC_FUNC_LOGGER();
+
+ 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
+ }
+}