Let SourceInfo take charage of and LLVM module.
I.e., a module never escapes from its associated SourceInfo object.
Change-Id: Ib7fe914052e8b1b06b879737f57828739d54e0f0
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index a299806..4545c0e 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -44,8 +44,6 @@
#include "llvm/Analysis/Passes.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
@@ -60,7 +58,6 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
@@ -277,28 +274,14 @@
#endif
mpSymbolLookupFn(NULL),
mpSymbolLookupContext(NULL),
- mContext(NULL),
mModule(NULL),
mHasLinked(false) /* Turn off linker */ {
llvm::remove_fatal_error_handler();
llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
- mContext = new llvm::LLVMContext();
return;
}
-llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
- llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
-
- if (!result) {
- ALOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
- return NULL;
- }
-
- return result;
-}
-
-
int Compiler::linkModule(llvm::Module *moduleWith) {
if (llvm::Linker::LinkModules(mModule, moduleWith,
llvm::Linker::DestroySource,
@@ -916,9 +899,6 @@
Compiler::~Compiler() {
- delete mModule;
- delete mContext;
-
#if USE_MCJIT
rsloaderDisposeExec(mRSExecutable);
#endif
diff --git a/lib/ExecutionEngine/Compiler.h b/lib/ExecutionEngine/Compiler.h
index 2d4faf7..5082d9e 100644
--- a/lib/ExecutionEngine/Compiler.h
+++ b/lib/ExecutionEngine/Compiler.h
@@ -40,9 +40,7 @@
namespace llvm {
- class LLVMContext;
class Module;
- class MemoryBuffer;
class NamedMDNode;
class TargetData;
}
@@ -110,7 +108,6 @@
BCCSymbolLookupFn mpSymbolLookupFn;
void *mpSymbolLookupContext;
- llvm::LLVMContext *mContext;
llvm::Module *mModule;
bool mHasLinked;
@@ -143,8 +140,6 @@
}
#endif
- llvm::Module *parseBitcodeFile(llvm::MemoryBuffer *MEM);
-
int readModule(llvm::Module *module) {
mModule = module;
return hasError();
diff --git a/lib/ExecutionEngine/Script.cpp b/lib/ExecutionEngine/Script.cpp
index 2751299..9e59495 100644
--- a/lib/ExecutionEngine/Script.cpp
+++ b/lib/ExecutionEngine/Script.cpp
@@ -76,9 +76,8 @@
break;
}
- for (size_t i = 0; i < 2; ++i) {
+ for (size_t i = 0; i < 2; ++i)
delete mSourceList[i];
- }
}
@@ -346,28 +345,25 @@
mpExtSymbolLookupFnContext);
}
- // Parse Bitcode File (if necessary)
- for (size_t i = 0; i < 2; ++i) {
- if (mSourceList[i] && mSourceList[i]->prepareModule(mCompiled) != 0) {
- ALOGE("Unable to parse bitcode for source[%lu]\n", (unsigned long)i);
- return 1;
- }
- }
-
- // Set the main source module
- if (!mSourceList[0] || !mSourceList[0]->getModule()) {
- ALOGE("Source bitcode is not setted.\n");
+ if (!mSourceList[0]) {
+ ALOGE("Source bitcode is not set.\n");
return 1;
}
- if (mCompiled->readModule(mSourceList[0]->takeModule()) != 0) {
+ // Parse Bitcode File (if necessary)
+ if (mSourceList[0]->prepareModule() != 0)
+ return 1;
+
+ // Set the main source module
+ 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]->takeModule()) != 0) {
+ if (mSourceList[1] &&
+ mSourceList[1]->prepareModule(mSourceList[0]->getContext())) {
+ if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
ALOGE("Unable to link library module\n");
return 1;
}
diff --git a/lib/ExecutionEngine/ScriptCompiled.h b/lib/ExecutionEngine/ScriptCompiled.h
index e4acc16..f7bf48b 100644
--- a/lib/ExecutionEngine/ScriptCompiled.h
+++ b/lib/ExecutionEngine/ScriptCompiled.h
@@ -77,10 +77,6 @@
~ScriptCompiled();
- llvm::Module *parseBitcodeFile(llvm::MemoryBuffer *MEM) {
- return mCompiler.parseBitcodeFile(MEM);
- }
-
int readModule(llvm::Module *module) {
return mCompiler.readModule(module);
}
diff --git a/lib/ExecutionEngine/SourceInfo.cpp b/lib/ExecutionEngine/SourceInfo.cpp
index 019ecb1..9c49fcc 100644
--- a/lib/ExecutionEngine/SourceInfo.cpp
+++ b/lib/ExecutionEngine/SourceInfo.cpp
@@ -34,6 +34,9 @@
#include <bcc/bcc.h>
#include <bcc/bcc_cache.h>
+#include <llvm/Bitcode/ReaderWriter.h>
+#include <llvm/Module.h>
+#include <llvm/LLVMContext.h>
#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/Support/MemoryBuffer.h>
@@ -114,7 +117,7 @@
}
result->type = SourceKind::Module;
- result->module.reset(module);
+ result->module = module;
result->flags = flags;
#if USE_CACHE
@@ -133,44 +136,63 @@
}
-int SourceInfo::prepareModule(ScriptCompiled *SC) {
+int SourceInfo::prepareModule(llvm::LLVMContext *context) {
+ if (module)
+ return 0;
+
+ llvm::OwningPtr<llvm::MemoryBuffer> mem;
+ std::string errmsg;
+
switch (type) {
case SourceKind::Buffer:
{
- llvm::OwningPtr<llvm::MemoryBuffer> MEM(
- llvm::MemoryBuffer::getMemBuffer(
+ mem.reset(llvm::MemoryBuffer::getMemBuffer(
llvm::StringRef(buffer.bitcode, buffer.bitcodeSize)));
- if (!MEM.get()) {
+ if (!mem.get()) {
ALOGE("Unable to MemoryBuffer::getMemBuffer(addr=%p, size=%lu)\n",
- buffer.bitcode, (unsigned long)buffer.bitcodeSize);
+ buffer.bitcode, (unsigned long)buffer.bitcodeSize);
return 1;
}
-
- module.reset(SC->parseBitcodeFile(MEM.get()));
}
break;
case SourceKind::File:
{
- llvm::OwningPtr<llvm::MemoryBuffer> MEM;
-
- if (llvm::error_code ec = llvm::MemoryBuffer::getFile(file.path, MEM)) {
- ALOGE("Unable to MemoryBuffer::getFile(path=%s)\n", file.path);
+ 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;
}
-
- module.reset(SC->parseBitcodeFile(MEM.get()));
}
break;
default:
+ return 0;
break;
}
- return (module.get()) ? 0 : 1;
+ if (context)
+ shared_context = true;
+ else
+ context = new llvm::LLVMContext();
+
+ module = llvm::ParseBitcodeFile(mem.get(), *context, &errmsg);
+ if (module == NULL) {
+ ALOGE("Unable to ParseBitcodeFile: %s\n", errmsg.c_str());
+ if (!shared_context)
+ delete context;
+ }
+
+ return (module == NULL);
}
+SourceInfo::~SourceInfo() {
+ llvm::LLVMContext *context = &module->getContext();
+ delete module;
+ if (!shared_context)
+ delete context;
+}
#if USE_CACHE
template <typename T> void SourceInfo::introDependency(T &checker) {
diff --git a/lib/ExecutionEngine/SourceInfo.h b/lib/ExecutionEngine/SourceInfo.h
index b6a4c54..9026f1c 100644
--- a/lib/ExecutionEngine/SourceInfo.h
+++ b/lib/ExecutionEngine/SourceInfo.h
@@ -19,14 +19,15 @@
#include "Config.h"
-#include <llvm/ADT/OwningPtr.h>
#include <llvm/Module.h>
#include <stddef.h>
-namespace bcc {
- class ScriptCompiled;
+namespace llvm {
+ class LLVMContext;
+}
+namespace bcc {
namespace SourceKind {
enum SourceType {
File,
@@ -39,9 +40,12 @@
private:
SourceKind::SourceType type;
- llvm::OwningPtr<llvm::Module> module;
// 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;
+ // If true, the LLVM context behind the module is shared with others.
+ // Therefore, don't try to destroy the context it when destroy the module.
+ bool shared_context;
union {
struct {
@@ -62,7 +66,7 @@
#endif
private:
- SourceInfo() { }
+ SourceInfo() : module(NULL), shared_context(false) { }
public:
static SourceInfo *createFromBuffer(char const *resName,
@@ -76,19 +80,22 @@
static SourceInfo *createFromModule(llvm::Module *module,
unsigned long flags);
- llvm::Module *takeModule() {
- return module.take();
+ inline llvm::Module *getModule() const {
+ return module;
}
- llvm::Module *getModule() const {
- return module.get();
+ inline llvm::LLVMContext *getContext() const {
+ return (module) ? &module->getContext() : NULL;
}
- int prepareModule(ScriptCompiled *);
+ // Share with the given context if it's provided.
+ int prepareModule(llvm::LLVMContext *context = NULL);
#if USE_CACHE
template <typename T> void introDependency(T &checker);
#endif
+
+ ~SourceInfo();
};