am ead5ccba: Revert "Refactor SourceInfo into Source."
* commit 'ead5ccba05af33df1a061b39847a9be137c00143':
Revert "Refactor SourceInfo into Source."
diff --git a/lib/ExecutionEngine/Android.mk b/lib/ExecutionEngine/Android.mk
index 855d055..78850dd 100644
--- a/lib/ExecutionEngine/Android.mk
+++ b/lib/ExecutionEngine/Android.mk
@@ -24,7 +24,6 @@
libbcc_executionengine_SRC_FILES := \
BCCContext.cpp \
- BCCContextImpl.cpp \
Compiler.cpp \
FileHandle.cpp \
GDBJIT.cpp \
@@ -37,7 +36,7 @@
ScriptCached.cpp \
ScriptCompiled.cpp \
Sha1Helper.cpp \
- Source.cpp
+ SourceInfo.cpp
#=====================================================================
diff --git a/lib/ExecutionEngine/BCCContext.cpp b/lib/ExecutionEngine/BCCContext.cpp
index 892fd5a..6d0c5b9 100644
--- a/lib/ExecutionEngine/BCCContext.cpp
+++ b/lib/ExecutionEngine/BCCContext.cpp
@@ -19,9 +19,7 @@
#include <new>
#include "BCCContextImpl.h"
-#include "Compiler.h"
#include "DebugHelper.h"
-#include "Source.h"
using namespace bcc;
@@ -42,10 +40,7 @@
GlobalContext = NULL;
}
-BCCContext::BCCContext() : mImpl(new BCCContextImpl(*this)) {
- // Initialize the LLVM compiler infrastructure.
- Compiler::GlobalInitialization();
-}
+BCCContext::BCCContext() : mImpl(new BCCContextImpl(*this)) { }
BCCContext::~BCCContext() {
delete mImpl;
@@ -54,14 +49,9 @@
// Reset the GlobalContext.
GlobalContext = NULL;
}
+ return;
}
-void BCCContext::addSource(Source &pSource)
-{ mImpl->mOwnSources.insert(&pSource); }
-
-void BCCContext::removeSource(Source &pSource)
-{ mImpl->mOwnSources.erase(&pSource); }
-
llvm::LLVMContext &BCCContext::getLLVMContext()
{ return mImpl->mLLVMContext; }
diff --git a/lib/ExecutionEngine/BCCContext.h b/lib/ExecutionEngine/BCCContext.h
index 56962fe..3e58acc 100644
--- a/lib/ExecutionEngine/BCCContext.h
+++ b/lib/ExecutionEngine/BCCContext.h
@@ -24,7 +24,6 @@
namespace bcc {
class BCCContextImpl;
-class Source;
/*
* class BCCContext manages the global data across the libbcc infrastructure.
@@ -39,9 +38,6 @@
llvm::LLVMContext &getLLVMContext();
const llvm::LLVMContext &getLLVMContext() const;
- void addSource(Source &pSource);
- void removeSource(Source &pSource);
-
// Global BCCContext
static BCCContext *GetOrCreateGlobalContext();
static void DestroyGlobalContext();
diff --git a/lib/ExecutionEngine/BCCContextImpl.cpp b/lib/ExecutionEngine/BCCContextImpl.cpp
deleted file mode 100644
index ec865fa..0000000
--- a/lib/ExecutionEngine/BCCContextImpl.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include "BCCContextImpl.h"
-
-#include <vector>
-
-#include <llvm/ADT/STLExtras.h>
-
-#include "Source.h"
-
-using namespace bcc;
-
-BCCContextImpl::~BCCContextImpl() {
- // Another temporary container is needed to store the Source objects that we
- // are going to detroy. Since the destruction of Source object will call
- // removeSource() and change the content of OwnSources.
- std::vector<Source *> Sources(mOwnSources.begin(), mOwnSources.end());
- llvm::DeleteContainerPointers(Sources);
-}
diff --git a/lib/ExecutionEngine/BCCContextImpl.h b/lib/ExecutionEngine/BCCContextImpl.h
index 446eb36..b23d798 100644
--- a/lib/ExecutionEngine/BCCContextImpl.h
+++ b/lib/ExecutionEngine/BCCContextImpl.h
@@ -17,13 +17,11 @@
#ifndef BCC_EXECUTION_ENGINE_CONTEXT_IMPL_H
#define BCC_EXECUTION_ENGINE_CONTEXT_IMPL_H
-#include <llvm/ADT/SmallPtrSet.h>
#include <llvm/LLVMContext.h>
namespace bcc {
class BCCContext;
-class Source;
/*
* class BCCContextImpl contains the implementation of BCCCotext.
@@ -32,12 +30,8 @@
public:
llvm::LLVMContext mLLVMContext;
- // The set of sources that initialized in this context. They will be destroyed
- // automatically when this context is gone.
- llvm::SmallPtrSet<Source *, 2> mOwnSources;
-
BCCContextImpl(BCCContext &pContext) { }
- ~BCCContextImpl();
+ ~BCCContextImpl() { }
};
} // namespace bcc
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index 100f54b..58a49c5 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -226,27 +226,27 @@
mRSExecutable(NULL),
mpSymbolLookupFn(NULL),
mpSymbolLookupContext(NULL),
- mModule(NULL) {
+ mModule(NULL),
+ mHasLinked(false) /* Turn off linker */ {
llvm::remove_fatal_error_handler();
llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
return;
}
-int Compiler::readModule(llvm::Module &pModule) {
- mModule = &pModule;
- if (pModule.getMaterializer() != NULL) {
- // A module with non-null materializer means that it is a lazy-load module.
- // Materialize it now via invoking MaterializeAllPermanently(). This
- // function returns false when the materialization is successful.
- if (pModule.MaterializeAllPermanently(&mError)) {
- setError("Failed to materialize the module `" +
- pModule.getModuleIdentifier() + "'! (" + mError + ")");
- mModule = NULL;
- }
+
+int Compiler::linkModule(llvm::Module *moduleWith) {
+ if (llvm::Linker::LinkModules(mModule, moduleWith,
+ llvm::Linker::PreserveSource,
+ &mError) != 0) {
+ return hasError();
}
+
+ // Everything for linking should be settled down here with no error occurs
+ mHasLinked = true;
return hasError();
}
+
int Compiler::compile(const CompilerOption &option) {
llvm::Target const *Target = NULL;
llvm::TargetData *TD = NULL;
@@ -390,7 +390,7 @@
runInternalPasses(ForEachNameList, ForEachSigList);
// Perform link-time optimization if we have multiple modules
- if (option.RunLTO) {
+ if (mHasLinked) {
runLTO(new llvm::TargetData(*TD), ExportSymbols, CodeGenOptLevel);
}
diff --git a/lib/ExecutionEngine/Compiler.h b/lib/ExecutionEngine/Compiler.h
index 8fee17c..863cda6 100644
--- a/lib/ExecutionEngine/Compiler.h
+++ b/lib/ExecutionEngine/Compiler.h
@@ -93,6 +93,8 @@
llvm::Module *mModule;
+ bool mHasLinked;
+
public:
Compiler(ScriptCompiled *result);
@@ -117,7 +119,12 @@
return mEmittedELFExecutable;
}
- int readModule(llvm::Module &pModule);
+ int readModule(llvm::Module *module) {
+ mModule = module;
+ return hasError();
+ }
+
+ int linkModule(llvm::Module *module);
int compile(const CompilerOption &option);
diff --git a/lib/ExecutionEngine/CompilerOption.h b/lib/ExecutionEngine/CompilerOption.h
index f7c1e50..75278c7 100644
--- a/lib/ExecutionEngine/CompilerOption.h
+++ b/lib/ExecutionEngine/CompilerOption.h
@@ -82,9 +82,6 @@
CodeModelOpt = llvm::CodeModel::Small;
#endif
- //-- Run LTO passes --//
- RunLTO = true;
-
//-- Load the result object after successful compilation --//
LoadAfterCompile = true;
}
@@ -92,7 +89,6 @@
llvm::TargetOptions TargetOpt;
llvm::CodeModel::Model CodeModelOpt;
llvm::Reloc::Model RelocModelOpt;
- bool RunLTO;
bool LoadAfterCompile;
};
diff --git a/lib/ExecutionEngine/Script.cpp b/lib/ExecutionEngine/Script.cpp
index 7c79254..2dbdf40 100644
--- a/lib/ExecutionEngine/Script.cpp
+++ b/lib/ExecutionEngine/Script.cpp
@@ -16,19 +16,8 @@
#include "Script.h"
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <new>
-#include <cstring>
-
-#include <llvm/ADT/STLExtras.h>
-
-#include <cutils/properties.h>
-
#include "Config.h"
+#include "bcinfo/BitcodeWrapper.h"
#include "MCCacheReader.h"
#include "MCCacheWriter.h"
@@ -41,7 +30,16 @@
#include "ScriptCompiled.h"
#include "ScriptCached.h"
#include "Sha1Helper.h"
-#include "Source.h"
+#include "SourceInfo.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <new>
+#include <string.h>
+#include <cutils/properties.h>
namespace {
@@ -55,14 +53,6 @@
namespace bcc {
-Script::Script(Source &pSource)
- : mSource(&pSource),
- mpExtSymbolLookupFn(NULL),
- mpExtSymbolLookupFnContext(NULL) {
- resetState();
- return;
-}
-
Script::~Script() {
switch (mStatus) {
case ScriptStatus::Compiled:
@@ -76,62 +66,111 @@
default:
break;
}
- llvm::DeleteContainerPointers(mDependencyInfos);
-}
-void Script::resetState() {
- mErrorCode = BCC_NO_ERROR;
- mStatus = ScriptStatus::Unknown;
- mObjectType = ScriptObject::Unknown;
- mIsContextSlotNotAvail = false;
- // FIXME: mpExtSymbolLookupFn and mpExtSymbolLookupFnContext should be assign
- // to NULL during state resetting.
- //mpExtSymbolLookupFn = NULL;
- //mpExtSymbolLookupFnContext = NULL;
- llvm::DeleteContainerPointers(mDependencyInfos);
- return;
+ for (size_t i = 0; i < 2; ++i) {
+ delete mSourceList[i];
+ }
}
-Script::DependencyInfo::DependencyInfo(MCO_ResourceType pSourceType,
- const std::string &pSourceName,
- const uint8_t *pSHA1)
- : mSourceType(pSourceType), mSourceName(pSourceName) {
- ::memcpy(mSHA1, pSHA1, sizeof(mSHA1));
- return;
-}
+int Script::addSourceBC(size_t idx,
+ char const *resName,
+ const char *bitcode,
+ size_t bitcodeSize,
+ unsigned long flags) {
-bool Script::reset(Source &pSource, bool pPreserveCurrent) {
- if (mSource == &pSource) {
- return false;
+ if (!resName) {
+ mErrorCode = BCC_INVALID_VALUE;
+ ALOGE("Invalid argument: resName = NULL\n");
+ return 1;
}
- if (!pPreserveCurrent) {
- delete mSource;
- }
- mSource = &pSource;
- resetState();
- return true;
-}
-
-bool Script::mergeSource(Source &pSource, bool pPreserveSource) {
- return mSource->merge(pSource, pPreserveSource);
-}
-
-bool Script::addSourceDependencyInfo(MCO_ResourceType pSourceType,
- const std::string &pSourceName,
- const uint8_t *pSHA1) {
- DependencyInfo *dep_info = new (std::nothrow) DependencyInfo(pSourceType,
- pSourceName,
- pSHA1);
- if (dep_info == NULL) {
- ALOGE("Out of memory when record dependency information of `%s'!",
- pSourceName.c_str());
- return false;
+ if (mStatus != ScriptStatus::Unknown) {
+ mErrorCode = BCC_INVALID_OPERATION;
+ ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
+ return 1;
}
- mDependencyInfos.push_back(dep_info);
- return true;
+ if (!bitcode) {
+ mErrorCode = BCC_INVALID_VALUE;
+ ALOGE("Invalid argument: bitcode = NULL\n");
+ return 1;
+ }
+
+ bcinfo::BitcodeWrapper wrapper(bitcode, bitcodeSize);
+
+ mSourceList[idx] = SourceInfo::createFromBuffer(resName,
+ bitcode, bitcodeSize,
+ flags);
+
+ if (!mSourceList[idx]) {
+ mErrorCode = BCC_OUT_OF_MEMORY;
+ ALOGE("Out of memory while adding source bitcode\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int Script::addSourceModule(size_t idx,
+ llvm::Module *module,
+ unsigned long flags) {
+ if (mStatus != ScriptStatus::Unknown) {
+ mErrorCode = BCC_INVALID_OPERATION;
+ ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
+ return 1;
+ }
+
+ if (!module) {
+ mErrorCode = BCC_INVALID_VALUE;
+ ALOGE("Invalid argument: module = NULL\n");
+ return 1;
+ }
+
+ mSourceList[idx] = SourceInfo::createFromModule(module, flags);
+
+ if (!mSourceList[idx]) {
+ mErrorCode = BCC_OUT_OF_MEMORY;
+ ALOGE("Out of memory when add source module\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int Script::addSourceFile(size_t idx,
+ char const *path,
+ unsigned long flags) {
+ if (mStatus != ScriptStatus::Unknown) {
+ mErrorCode = BCC_INVALID_OPERATION;
+ ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
+ return 1;
+ }
+
+ if (!path) {
+ mErrorCode = BCC_INVALID_VALUE;
+ ALOGE("Invalid argument: path = NULL\n");
+ return 1;
+ }
+
+ struct stat sb;
+ if (stat(path, &sb) != 0) {
+ mErrorCode = BCC_INVALID_VALUE;
+ ALOGE("File not found: %s\n", path);
+ return 1;
+ }
+
+ mSourceList[idx] = SourceInfo::createFromFile(path, flags);
+
+ if (!mSourceList[idx]) {
+ mErrorCode = BCC_OUT_OF_MEMORY;
+ ALOGE("Out of memory while adding source file\n");
+ return 1;
+ }
+
+ return 0;
}
int Script::prepareRelocatable(char const *objPath,
@@ -139,7 +178,6 @@
unsigned long flags) {
CompilerOption option;
option.RelocModelOpt = RelocModel;
- option.RunLTO = false;
option.LoadAfterCompile = false;
int status = internalCompile(option);
@@ -257,11 +295,10 @@
reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
- for (unsigned i = 0; i < mDependencyInfos.size(); i++) {
- const DependencyInfo *dep_info = mDependencyInfos[i];
- reader.addDependency(dep_info->getSourceType(),
- dep_info->getSourceName(),
- dep_info->getSHA1Checksum());
+ for (size_t i = 0; i < 2; ++i) {
+ if (mSourceList[i]) {
+ mSourceList[i]->introDependency(reader);
+ }
}
if (checkOnly)
@@ -305,12 +342,39 @@
mpExtSymbolLookupFnContext);
}
+ if (!mSourceList[0]) {
+ ALOGE("Source bitcode is not set.\n");
+ return 1;
+ }
+
+ // Parse Source bitcode file (if necessary)
+ if (mSourceList[0]->prepareModule(mContext.mImpl->mLLVMContext) != 0) {
+ ALOGE("Unable to setup source module\n");
+ return 1;
+ }
+
+ // Parse Library bitcode file (if necessary)
+ if (mSourceList[1]) {
+ if (mSourceList[1]->prepareModule(mContext.mImpl->mLLVMContext) != 0) {
+ ALOGE("Unable to setup library module\n");
+ return 1;
+ }
+ }
+
// Set the main source module
- if (mCompiled->readModule(mSource->getModule()) != 0) {
+ if (mCompiled->readModule(mSourceList[0]->getModule()) != 0) {
ALOGE("Unable to read source module\n");
return 1;
}
+ // Link the source module with the library module
+ if (mSourceList[1]) {
+ if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
+ ALOGE("Unable to link library module\n");
+ return 1;
+ }
+ }
+
// Compile and JIT the code
if (mCompiled->compile(option) != 0) {
ALOGE("Unable to compile.\n");
@@ -358,14 +422,12 @@
writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
#endif
- for (unsigned i = 0; i < mDependencyInfos.size(); i++) {
- const DependencyInfo *dep_info = mDependencyInfos[i];
- writer.addDependency(dep_info->getSourceType(),
- dep_info->getSourceName(),
- dep_info->getSHA1Checksum());
+ for (size_t i = 0; i < 2; ++i) {
+ if (mSourceList[i]) {
+ mSourceList[i]->introDependency(writer);
+ }
}
-
// libRS is threadable dirty hack
// TODO: This should be removed in the future
uint32_t libRS_threadable = 0;
diff --git a/lib/ExecutionEngine/Script.h b/lib/ExecutionEngine/Script.h
index b654797..4534951 100644
--- a/lib/ExecutionEngine/Script.h
+++ b/lib/ExecutionEngine/Script.h
@@ -17,20 +17,19 @@
#ifndef BCC_SCRIPT_H
#define BCC_SCRIPT_H
+#include <bcc/bcc.h>
+#include "bcc_internal.h"
+
+#include "BCCContext.h"
+#include "Compiler.h"
+
+#include <llvm/Support/CodeGen.h>
+
#include <vector>
#include <string>
-#include <stdint.h>
#include <stddef.h>
-#include <llvm/ADT/SmallVector.h>
-
-#include <bcc/bcc.h>
-#include <bcc/bcc_mccache.h>
-#include "bcc_internal.h"
-
-#include "Compiler.h"
-
namespace llvm {
class Module;
class GDBJITRegistrar;
@@ -39,7 +38,7 @@
namespace bcc {
class ScriptCompiled;
class ScriptCached;
- class Source;
+ class SourceInfo;
struct CompilerOption;
namespace ScriptStatus {
@@ -61,6 +60,8 @@
class Script {
private:
+ BCCContext mContext;
+
int mErrorCode;
ScriptStatus::StatusType mStatus;
@@ -87,31 +88,11 @@
bool mIsContextSlotNotAvail;
- // This is the source associated with this object and is going to be
- // compiled.
- Source *mSource;
-
- class DependencyInfo {
- private:
- MCO_ResourceType mSourceType;
- std::string mSourceName;
- uint8_t mSHA1[20];
-
- public:
- DependencyInfo(MCO_ResourceType pSourceType,
- const std::string &pSourceName,
- const uint8_t *pSHA1);
-
- inline MCO_ResourceType getSourceType() const
- { return mSourceType; }
-
- inline const std::string getSourceName() const
- { return mSourceName; }
-
- inline const uint8_t *getSHA1Checksum() const
- { return mSHA1; }
- };
- llvm::SmallVector<DependencyInfo *, 2> mDependencyInfos;
+ // Source List
+ SourceInfo *mSourceList[2];
+ // Note: mSourceList[0] (main source)
+ // Note: mSourceList[1] (library source)
+ // TODO(logan): Generalize this, use vector or SmallVector instead!
// External Function List
std::vector<char const *> mUserDefinedExternalSymbols;
@@ -120,31 +101,32 @@
BCCSymbolLookupFn mpExtSymbolLookupFn;
void *mpExtSymbolLookupFnContext;
- // Reset the state of this script object
- void resetState();
-
public:
- Script(Source &pSource);
+ Script() : mErrorCode(BCC_NO_ERROR), mStatus(ScriptStatus::Unknown),
+ mObjectType(ScriptObject::Unknown),
+ mIsContextSlotNotAvail(false),
+ mpExtSymbolLookupFn(NULL), mpExtSymbolLookupFnContext(NULL) {
+ Compiler::GlobalInitialization();
+
+ mSourceList[0] = NULL;
+ mSourceList[1] = NULL;
+ }
~Script();
- // Reset this object with the new source supplied. Return false if this
- // object remains unchanged after the call (e.g., the supplied source is
- // the same with the one contain in this object.) If pPreserveCurrent is
- // false, the current containing source will be destroyed after successfully
- // reset.
- bool reset(Source &pSource, bool pPreserveCurrent = false);
+ int addSourceBC(size_t idx,
+ char const *resName,
+ const char *bitcode,
+ size_t bitcodeSize,
+ unsigned long flags);
- // Merge (or link) another source into the current source associated with
- // this Script object. Return false on error.
- bool mergeSource(Source &pSource, bool pPreserveSource = false);
+ int addSourceModule(size_t idx,
+ llvm::Module *module,
+ unsigned long flags);
- // 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 addSourceDependencyInfo(MCO_ResourceType pSourceType,
- const std::string &pSourceName,
- const uint8_t *pSHA1);
+ int addSourceFile(size_t idx,
+ char const *path,
+ unsigned long flags);
void markExternalSymbol(char const *name) {
mUserDefinedExternalSymbols.push_back(name);
@@ -160,7 +142,7 @@
int writeCache();
/*
- * Link the given bitcodes in mSource to shared object (.so).
+ * Link the given bitcodes in mSourceList to shared object (.so).
*
* Currently, it requires one to provide the relocatable object files with
* given bitcodes to output a shared object.
@@ -171,7 +153,7 @@
* you haven't done that yet) and then link the output relocatable object
* file to .so in dsoPath.
*
- * TODO: Currently, we only support to link a bitcode (i.e., mSource.)
+ * TODO: Currently, we only support to link the bitcodes in mSourceList[0].
*
*/
int prepareSharedObject(char const *objPath,
diff --git a/lib/ExecutionEngine/ScriptCompiled.h b/lib/ExecutionEngine/ScriptCompiled.h
index 8752aa3..7b7b62a 100644
--- a/lib/ExecutionEngine/ScriptCompiled.h
+++ b/lib/ExecutionEngine/ScriptCompiled.h
@@ -17,17 +17,17 @@
#ifndef BCC_SCRIPTCOMPILED_H
#define BCC_SCRIPTCOMPILED_H
+#include "Compiler.h"
+#include "Script.h"
+
+#include <bcc/bcc.h>
+
#include <list>
#include <map>
#include <string>
#include <utility>
#include <vector>
-#include <bcc/bcc.h>
-
-#include "Compiler.h"
-#include "Script.h"
-
namespace llvm {
class Module;
}
@@ -73,8 +73,12 @@
~ScriptCompiled();
- int readModule(llvm::Module &pModule) {
- return mCompiler.readModule(pModule);
+ int readModule(llvm::Module *module) {
+ return mCompiler.readModule(module);
+ }
+
+ int linkModule(llvm::Module *module) {
+ return mCompiler.linkModule(module);
}
int compile(const CompilerOption &option) {
diff --git a/lib/ExecutionEngine/Source.cpp b/lib/ExecutionEngine/Source.cpp
deleted file mode 100644
index 754f3e5..0000000
--- a/lib/ExecutionEngine/Source.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include "Source.h"
-
-#include <new>
-
-#include <llvm/Bitcode/ReaderWriter.h>
-#include <llvm/LLVMContext.h>
-#include <llvm/Linker.h>
-#include <llvm/Module.h>
-#include <llvm/Support/MemoryBuffer.h>
-#include <llvm/Support/system_error.h>
-
-#include "BCCContext.h"
-#include "BCCContextImpl.h"
-#include "DebugHelper.h"
-
-namespace {
-
-// Helper function to load the bitcode. This uses "bitcode lazy load" feature to
-// reduce the startup time. On success, return the LLVM module object created
-// and take the ownership of input memory buffer (i.e., pInput). On error,
-// return NULL and will NOT take the ownership of pInput.
-static inline llvm::Module *helper_load_bitcode(llvm::LLVMContext &pContext,
- llvm::MemoryBuffer *pInput) {
- std::string error;
- llvm::Module *module = llvm::getLazyBitcodeModule(pInput, pContext, &error);
-
- if (module == NULL) {
- ALOGE("Unable to parse the given bitcode file `%s'! (%s)",
- pInput->getBufferIdentifier(), error.c_str());
- }
-
- return module;
-}
-
-} // end anonymous namespace
-
-namespace bcc {
-
-Source *Source::CreateFromBuffer(BCCContext &pContext,
- const char *pName,
- const char *pBitcode,
- size_t pBitcodeSize) {
- llvm::StringRef input_data(pBitcode, pBitcodeSize);
- llvm::MemoryBuffer *input_memory =
- llvm::MemoryBuffer::getMemBuffer(input_data, pName);
-
- if (input_memory == NULL) {
- ALOGE("Unable to load bitcode `%s' from buffer!", pName);
- return NULL;
- }
-
- llvm::Module *module = helper_load_bitcode(pContext.mImpl->mLLVMContext,
- input_memory);
- if (module == NULL) {
- delete input_memory;
- return NULL;
- }
-
- Source *result = CreateFromModule(pContext, *module, /* pNoDelete */false);
- if (result == NULL) {
- delete module;
- }
-
- return result;
-}
-
-
-Source *Source::CreateFromFile(BCCContext &pContext, const std::string &pPath) {
- llvm::OwningPtr<llvm::MemoryBuffer> input_data;
-
- llvm::error_code ec = llvm::MemoryBuffer::getFile(pPath, input_data);
- if (ec != llvm::error_code::success()) {
- ALOGE("Failed to load bitcode from path %s! (%s)", pPath.c_str(),
- ec.message().c_str());
- return NULL;
- }
-
- llvm::MemoryBuffer *input_memory = input_data.take();
- llvm::Module *module = helper_load_bitcode(pContext.mImpl->mLLVMContext,
- input_memory);
- if (module == NULL) {
- delete input_memory;
- return NULL;
- }
-
- Source *result = CreateFromModule(pContext, *module, /* pNoDelete */false);
- if (result == NULL) {
- delete module;
- }
-
- return result;
-}
-
-
-Source *Source::CreateFromModule(BCCContext &pContext, llvm::Module &pModule,
- bool pNoDelete) {
- Source *result = new (std::nothrow) Source(pContext, pModule, pNoDelete);
- if (result == NULL) {
- ALOGE("Out of memory during Source object allocation for `%s'!",
- pModule.getModuleIdentifier().c_str());
- }
- return result;
-}
-
-Source::Source(BCCContext &pContext, llvm::Module &pModule, bool pNoDelete)
- : mContext(pContext), mModule(&pModule), mNoDelete(pNoDelete) {
- pContext.addSource(*this);
-}
-
-Source::~Source() {
- mContext.removeSource(*this);
- if (!mNoDelete)
- delete mModule;
-}
-
-bool Source::merge(Source &pSource, bool pPreserveSource) {
- std::string error;
- llvm::Linker::LinkerMode mode =
- ((pPreserveSource) ? llvm::Linker::PreserveSource :
- llvm::Linker::DestroySource);
-
- if (llvm::Linker::LinkModules(mModule, &pSource.getModule(),
- mode, &error) != 0) {
- ALOGE("Failed to link source `%s' with `%s' (%s)!",
- getIdentifier().c_str(),
- pSource.getIdentifier().c_str(),
- error.c_str());
- return false;
- }
-
- if (!pPreserveSource) {
- pSource.mNoDelete = true;
- delete &pSource;
- }
-
- return true;
-}
-
-Source *Source::CreateEmpty(BCCContext &pContext, const std::string &pName) {
- // Create an empty module
- llvm::Module *module =
- new (std::nothrow) llvm::Module(pName, pContext.mImpl->mLLVMContext);
-
- if (module == NULL) {
- ALOGE("Out of memory when creating empty LLVM module `%s'!", pName.c_str());
- return NULL;
- }
-
- Source *result = CreateFromModule(pContext, *module, /* pNoDelete */false);
- if (result == NULL) {
- delete module;
- }
-
- return result;
-}
-
-const std::string &Source::getIdentifier() const {
- return mModule->getModuleIdentifier();
-}
-
-} // namespace bcc
diff --git a/lib/ExecutionEngine/Source.h b/lib/ExecutionEngine/Source.h
deleted file mode 100644
index b9a98e8..0000000
--- a/lib/ExecutionEngine/Source.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2010, 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_EXECUTION_ENGINE_SOURCE_H
-#define BCC_EXECUTION_ENGINE_SOURCE_H
-
-#include <string>
-
-namespace llvm {
- class Module;
-}
-
-namespace bcc {
-
-class BCCContext;
-
-class Source {
-private:
- BCCContext &mContext;
- llvm::Module *mModule;
-
- // If true, destructor won't destroy the mModule.
- bool mNoDelete;
-
-private:
- Source(BCCContext &pContext, llvm::Module &pModule, bool pNoDelete = false);
-
-public:
- static Source *CreateFromBuffer(BCCContext &pContext,
- const char *pName,
- const char *pBitcode,
- size_t pBitcodeSize);
-
- static Source *CreateFromFile(BCCContext &pContext,
- const std::string &pPath);
-
- // Create a Source object from an existing module. If pNoDelete
- // is true, destructor won't call delete on the given module.
- static Source *CreateFromModule(BCCContext &pContext,
- llvm::Module &pModule,
- bool pNoDelete = false);
-
- static Source *CreateEmpty(BCCContext &pContext, const std::string &pName);
-
- // Merge the current source with pSource. If pPreserveSource is false, pSource
- // will be destroyed after successfully merged. Return false on error.
- bool merge(Source &pSource, bool pPreserveSource = false);
-
- inline BCCContext &getContext()
- { return mContext; }
- inline const BCCContext &getContext() const
- { return mContext; }
-
- inline llvm::Module &getModule()
- { return *mModule; }
- inline const llvm::Module &getModule() const
- { return *mModule; }
-
- // Get the "identifier" of the bitcode. This will return the value of pName
- // when it's created using CreateFromBuffer and pPath if CreateFromFile().
- const std::string &getIdentifier() const;
-
- ~Source();
-};
-
-} // namespace bcc
-
-#endif // BCC_EXECUTION_ENGINE_SOURCE_H
diff --git a/lib/ExecutionEngine/SourceInfo.cpp b/lib/ExecutionEngine/SourceInfo.cpp
new file mode 100644
index 0000000..5477514
--- /dev/null
+++ b/lib/ExecutionEngine/SourceInfo.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2010, 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.
+ */
+
+#include "SourceInfo.h"
+
+#include "MCCacheWriter.h"
+#include "MCCacheReader.h"
+
+#include "DebugHelper.h"
+#include "ScriptCompiled.h"
+#include "Sha1Helper.h"
+
+#include <bcc/bcc.h>
+
+#include <llvm/Bitcode/ReaderWriter.h>
+#include <llvm/Module.h>
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/MemoryBuffer.h>
+#include <llvm/Support/system_error.h>
+
+#include <stddef.h>
+#include <string.h>
+
+namespace bcc {
+
+
+SourceInfo *SourceInfo::createFromBuffer(char const *resName,
+ char const *bitcode,
+ size_t bitcodeSize,
+ unsigned long flags) {
+ SourceInfo *result = new SourceInfo();
+
+ if (!result) {
+ return NULL;
+ }
+
+ result->type = SourceKind::Buffer;
+ result->buffer.resName = resName;
+ result->buffer.bitcode = bitcode;
+ result->buffer.bitcodeSize = bitcodeSize;
+ result->flags = flags;
+
+ if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) {
+ result->flags |= 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");
+ }
+
+ if (result->flags & BCC_SKIP_DEP_SHA1) {
+ memset(result->sha1, '\0', 20);
+ } else {
+ calcSHA1(result->sha1, bitcode, bitcodeSize);
+ }
+
+ return result;
+}
+
+
+SourceInfo *SourceInfo::createFromFile(char const *path,
+ unsigned long flags) {
+ SourceInfo *result = new SourceInfo();
+
+ if (!result) {
+ return NULL;
+ }
+
+ result->type = SourceKind::File;
+ result->file.path = path;
+ result->flags = flags;
+
+ memset(result->sha1, '\0', 20);
+
+ if (!(result->flags & BCC_SKIP_DEP_SHA1)) {
+ calcFileSHA1(result->sha1, path);
+ }
+
+ return result;
+}
+
+
+SourceInfo *SourceInfo::createFromModule(llvm::Module *module,
+ unsigned long flags) {
+ SourceInfo *result = new SourceInfo();
+
+ if (!result) {
+ return NULL;
+ }
+
+ result->type = SourceKind::Module;
+ result->module = module;
+ result->flags = flags;
+
+ if (! (flags & BCC_SKIP_DEP_SHA1)) {
+ result->flags |= BCC_SKIP_DEP_SHA1;
+
+ ALOGW("Unable to calculate sha1sum for llvm::Module.\n");
+ ALOGW("Sha1sum dependency check will be skipped.\n");
+ ALOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
+ }
+
+ memset(result->sha1, '\0', 20);
+
+ return result;
+}
+
+
+int SourceInfo::prepareModule(llvm::LLVMContext &context) {
+ if (module)
+ return 0;
+
+ llvm::OwningPtr<llvm::MemoryBuffer> mem;
+ std::string errmsg;
+
+ switch (type) {
+ case SourceKind::Buffer:
+ {
+ mem.reset(llvm::MemoryBuffer::getMemBuffer(
+ llvm::StringRef(buffer.bitcode, buffer.bitcodeSize)));
+
+ if (!mem.get()) {
+ ALOGE("Unable to MemoryBuffer::getMemBuffer(addr=%p, size=%lu)\n",
+ buffer.bitcode, (unsigned long)buffer.bitcodeSize);
+ return 1;
+ }
+ }
+ break;
+
+ case SourceKind::File:
+ {
+ if (llvm::error_code ec = llvm::MemoryBuffer::getFile(file.path, mem)) {
+ ALOGE("Unable to MemoryBuffer::getFile(path=%s, %s)\n",
+ file.path, ec.message().c_str());
+ return 1;
+ }
+ }
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+
+ module = llvm::ParseBitcodeFile(mem.get(), context, &errmsg);
+ if (module == NULL) {
+ ALOGE("Unable to ParseBitcodeFile: %s\n", errmsg.c_str());
+ }
+
+ return (module == NULL);
+}
+
+SourceInfo::~SourceInfo() {
+ delete module;
+}
+
+template <typename T> void SourceInfo::introDependency(T &checker) {
+ if (flags & BCC_SKIP_DEP_SHA1) {
+ return;
+ }
+
+ switch (type) {
+ case SourceKind::Buffer:
+ checker.addDependency(BCC_APK_RESOURCE, buffer.resName, sha1);
+ break;
+
+ case SourceKind::File:
+ checker.addDependency(BCC_FILE_RESOURCE, file.path, sha1);
+ break;
+
+ default:
+ break;
+ }
+}
+
+template void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &);
+template void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &);
+
+
+} // namespace bcc
diff --git a/lib/ExecutionEngine/SourceInfo.h b/lib/ExecutionEngine/SourceInfo.h
new file mode 100644
index 0000000..f838f71
--- /dev/null
+++ b/lib/ExecutionEngine/SourceInfo.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010, 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_SOURCEINFO_H
+#define BCC_SOURCEINFO_H
+
+#include "Config.h"
+
+#include <llvm/Module.h>
+
+#include <stddef.h>
+
+namespace bcc {
+ namespace SourceKind {
+ enum SourceType {
+ File,
+ Buffer,
+ Module,
+ };
+ }
+
+ class SourceInfo {
+ private:
+ SourceKind::SourceType type;
+
+ // Note: module should not be a part of union. Since, we are going to
+ // use module to store the pointer to parsed bitcode.
+ llvm::Module *module;
+
+ union {
+ struct {
+ char const *resName;
+ char const *bitcode;
+ size_t bitcodeSize;
+ } buffer;
+
+ struct {
+ char const *path;
+ } file;
+ };
+
+ unsigned long flags;
+
+ unsigned char sha1[20];
+
+ private:
+ SourceInfo() : module(NULL) { }
+
+ public:
+ static SourceInfo *createFromBuffer(char const *resName,
+ char const *bitcode,
+ size_t bitcodeSize,
+ unsigned long flags);
+
+ static SourceInfo *createFromFile(char const *path,
+ unsigned long flags);
+
+ static SourceInfo *createFromModule(llvm::Module *module,
+ unsigned long flags);
+
+ inline llvm::Module *getModule() const {
+ return module;
+ }
+
+ // Share with the given context if it's provided.
+ int prepareModule(llvm::LLVMContext &context);
+
+ template <typename T> void introDependency(T &checker);
+
+ ~SourceInfo();
+ };
+
+
+} // namespace bcc
+
+#endif // BCC_SOURCEINFO_H
diff --git a/lib/ExecutionEngine/bcc.cpp b/lib/ExecutionEngine/bcc.cpp
index ee6efaa..01ef32f 100644
--- a/lib/ExecutionEngine/bcc.cpp
+++ b/lib/ExecutionEngine/bcc.cpp
@@ -18,22 +18,19 @@
// This is an eager-compilation JIT running on Android.
#include <bcc/bcc.h>
+#include "bcc_internal.h"
+
+#include "Config.h"
+
+#include "Compiler.h"
+#include "DebugHelper.h"
+#include "Script.h"
#include <string>
#include <utils/StopWatch.h>
-#include "Config.h"
-
-#include <bcc/bcc_mccache.h>
-#include "bcc_internal.h"
-
-#include "BCCContext.h"
-#include "Compiler.h"
-#include "DebugHelper.h"
-#include "Script.h"
-#include "Sha1Helper.h"
-#include "Source.h"
+#include <llvm/Support/CodeGen.h>
using namespace bcc;
@@ -54,15 +51,7 @@
extern "C" BCCScriptRef bccCreateScript() {
BCC_FUNC_LOGGER();
bccPrintBuildStamp();
- // FIXME: This is a workaround for this API: use global BCC context and
- // create an empty source to create a Script object.
- BCCContext *context = BCCContext::GetOrCreateGlobalContext();
- if (context == NULL) {
- return NULL;
- }
-
- Source *source = Source::CreateEmpty(*context, "empty");
- return wrap(new Script(*source));
+ return wrap(new bcc::Script());
}
@@ -85,102 +74,13 @@
return unwrap(script)->getError();
}
-static bool helper_add_source(Script *pScript,
- 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");
- }
-
- BCCContext *context = BCCContext::GetOrCreateGlobalContext();
- if (context == NULL) {
- return false;
- }
-
- Source *source = Source::CreateFromBuffer(*context, pName,
- pBitcode, pBitcodeSize);
- if (source == NULL) {
- return false;
- }
-
- if (need_dependency_check) {
- uint8_t sha1[20];
- calcSHA1(sha1, pBitcode, pBitcodeSize);
- if (!pScript->addSourceDependencyInfo(BCC_APK_RESOURCE, pName, sha1)) {
- return false;
- }
- }
-
- return ((pIsLink) ? pScript->mergeSource(*source) : pScript->reset(*source));
-}
-
-static bool helper_add_source(Script *pScript,
- llvm::Module *pModule,
- bool pIsLink) {
- if (pModule == NULL)
- return false;
-
- BCCContext *context = BCCContext::GetOrCreateGlobalContext();
- if (context == NULL) {
- return false;
- }
-
- if (pModule == NULL) {
- ALOGE("Cannot add null module to script!");
- return false;
- }
-
- Source *source = Source::CreateFromModule(*context, *pModule, true);
- if (source == NULL) {
- return false;
- }
-
- return ((pIsLink) ? pScript->mergeSource(*source) : pScript->reset(*source));
-}
-
-static bool helper_add_source(Script *pScript,
- char const *pPath,
- unsigned long pFlags,
- bool pIsLink) {
- bool need_dependency_check = !(pFlags & BCC_SKIP_DEP_SHA1);
- BCCContext *context = BCCContext::GetOrCreateGlobalContext();
- if (context == NULL) {
- return false;
- }
-
- Source *source = Source::CreateFromFile(*context, pPath);
- if (source == NULL) {
- return false;
- }
-
- if (need_dependency_check) {
- uint8_t sha1[20];
- calcFileSHA1(sha1, pPath);
- if (!pScript->addSourceDependencyInfo(BCC_APK_RESOURCE, pPath, sha1)) {
- return false;
- }
- }
-
- return ((pIsLink) ? pScript->mergeSource(*source) : pScript->reset(*source));
-}
-
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);
+ return unwrap(script)->addSourceBC(0, resName, bitcode, bitcodeSize, flags);
}
@@ -189,8 +89,7 @@
LLVMModuleRef module,
unsigned long flags) {
BCC_FUNC_LOGGER();
- return (helper_add_source(unwrap(script), unwrap(module),
- /* pIsLink */false) == false);
+ return unwrap(script)->addSourceModule(0, unwrap(module), flags);
}
@@ -198,8 +97,7 @@
char const *path,
unsigned long flags) {
BCC_FUNC_LOGGER();
- return (helper_add_source(unwrap(script), path,
- flags, /* pIsLink */false) == false);
+ return unwrap(script)->addSourceFile(0, path, flags);
}
@@ -209,9 +107,7 @@
size_t bitcodeSize,
unsigned long flags) {
BCC_FUNC_LOGGER();
- return (helper_add_source(unwrap(script), resName,
- bitcode, bitcodeSize,
- flags, /* pIsLink */true) == false);
+ return unwrap(script)->addSourceBC(1, resName, bitcode, bitcodeSize, flags);
}
@@ -219,8 +115,7 @@
char const *path,
unsigned long flags) {
BCC_FUNC_LOGGER();
- return (helper_add_source(unwrap(script), path,
- flags, /* pIsLink */true) == false);
+ return unwrap(script)->addSourceFile(1, path, flags);
}