Add BCCContext.

Convention:
  * namespace bcc {
    /* no space here */class [ClassName] {
      ...
    };

    } // end namespace bcc
  * Instance variables are prefixed with "m";
  * Class variable/method are captialized;
  * Local variables in the function are in lower case with underscore;
  * Parameters to the function are prefixed with "p";
  * Include guard in the header will look like
    #ifndef BCC_<sub folder>_<class>_H
  * The order of implementation in .cpp is in the order of their
    declaration with the following constraints:
    i.   Class methods go first
    ii.  Recursively apply this rule to the sub-class
    iii. Then the constructor and destructor of the class
    iv.  And then the instance methods
  * The order of includes in Foo.cpp should be:
    i.   Foo.h should always go first
    ii.  C headers
    iii. C++ headers
    iv.  LLVM headers
    iv.  Other headers from the project other than libbcc and Android
         frameworks (i.e., f/b/include/utils/)
    v.   Header files defined in libbcc
    vi.  Header files from Android frameworks (f/b/include/utils/)

    Android frameworks should be included in the last since it
    implicitly includes cutils/log.h which may cause LOG_TAG be
    defined to NULL if no LOG_TAG hasn't been defined ever before
    include it.

  * Avoid including STL and LLVM headers in the BCC headers. Some
    clients (e.g., RenderScript) may prefer not include the C++ STL
    support and don't want to associate with LLVM directly.

BCCContext manages the global data across the libbcc infrastructure.
This includes LLVMContext object required by materialize bitcode into
llvm::Module and LLVM compilation infrastructure.

Furthermore, BCCContext is escalated to be managed in Script instead
of in the SourceInfo.

Change-Id: I60b9da7b5c61f6c684dcf981ba5abaf066e3c883
diff --git a/lib/ExecutionEngine/Android.mk b/lib/ExecutionEngine/Android.mk
index c015bcc..78850dd 100644
--- a/lib/ExecutionEngine/Android.mk
+++ b/lib/ExecutionEngine/Android.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2011 The Android Open Source Project
+# Copyright (C) 2011-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.
@@ -23,6 +23,7 @@
 #=====================================================================
 
 libbcc_executionengine_SRC_FILES := \
+  BCCContext.cpp \
   Compiler.cpp \
   FileHandle.cpp \
   GDBJIT.cpp \
diff --git a/lib/ExecutionEngine/BCCContext.cpp b/lib/ExecutionEngine/BCCContext.cpp
new file mode 100644
index 0000000..6d0c5b9
--- /dev/null
+++ b/lib/ExecutionEngine/BCCContext.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 "BCCContext.h"
+
+#include <new>
+
+#include "BCCContextImpl.h"
+#include "DebugHelper.h"
+
+using namespace bcc;
+
+static BCCContext *GlobalContext = NULL;
+
+BCCContext *BCCContext::GetOrCreateGlobalContext() {
+  if (GlobalContext == NULL) {
+    GlobalContext = new (std::nothrow) BCCContext();
+    if (GlobalContext == NULL) {
+      ALOGE("Out of memory when allocate global BCCContext!");
+    }
+  }
+  return GlobalContext;
+}
+
+void BCCContext::DestroyGlobalContext() {
+  delete GlobalContext;
+  GlobalContext = NULL;
+}
+
+BCCContext::BCCContext() : mImpl(new BCCContextImpl(*this)) { }
+
+BCCContext::~BCCContext() {
+  delete mImpl;
+  if (this == GlobalContext) {
+    // We're deleting the context returned from GetOrCreateGlobalContext().
+    // Reset the GlobalContext.
+    GlobalContext = NULL;
+  }
+  return;
+}
+
+llvm::LLVMContext &BCCContext::getLLVMContext()
+{ return mImpl->mLLVMContext; }
+
+const llvm::LLVMContext &BCCContext::getLLVMContext() const
+{ return mImpl->mLLVMContext; }
diff --git a/lib/ExecutionEngine/BCCContext.h b/lib/ExecutionEngine/BCCContext.h
new file mode 100644
index 0000000..3e58acc
--- /dev/null
+++ b/lib/ExecutionEngine/BCCContext.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#ifndef BCC_EXECUTION_ENGINE_CONTEXT_H
+#define BCC_EXECUTION_ENGINE_CONTEXT_H
+
+namespace llvm {
+  class LLVMContext;
+}
+
+namespace bcc {
+
+class BCCContextImpl;
+
+/*
+ * class BCCContext manages the global data across the libbcc infrastructure.
+ */
+class BCCContext {
+public:
+  BCCContextImpl *const mImpl;
+
+  BCCContext();
+  ~BCCContext();
+
+  llvm::LLVMContext &getLLVMContext();
+  const llvm::LLVMContext &getLLVMContext() const;
+
+  // Global BCCContext
+  static BCCContext *GetOrCreateGlobalContext();
+  static void DestroyGlobalContext();
+};
+
+} // namespace bcc
+
+#endif  // BCC_EXECUTION_ENGINE_CONTEXT_H
diff --git a/lib/ExecutionEngine/BCCContextImpl.h b/lib/ExecutionEngine/BCCContextImpl.h
new file mode 100644
index 0000000..b23d798
--- /dev/null
+++ b/lib/ExecutionEngine/BCCContextImpl.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#ifndef BCC_EXECUTION_ENGINE_CONTEXT_IMPL_H
+#define BCC_EXECUTION_ENGINE_CONTEXT_IMPL_H
+
+#include <llvm/LLVMContext.h>
+
+namespace bcc {
+
+class BCCContext;
+
+/*
+ * class BCCContextImpl contains the implementation of BCCCotext.
+ */
+class BCCContextImpl {
+public:
+  llvm::LLVMContext mLLVMContext;
+
+  BCCContextImpl(BCCContext &pContext) { }
+  ~BCCContextImpl() { }
+};
+
+} // namespace bcc
+
+#endif  // BCC_EXECUTION_ENGINE_CONTEXT_IMPL_H
diff --git a/lib/ExecutionEngine/Script.cpp b/lib/ExecutionEngine/Script.cpp
index 11ef0e1..2dbdf40 100644
--- a/lib/ExecutionEngine/Script.cpp
+++ b/lib/ExecutionEngine/Script.cpp
@@ -23,6 +23,7 @@
 #include "MCCacheWriter.h"
 #include "CompilerOption.h"
 
+#include "BCCContextImpl.h"
 #include "DebugHelper.h"
 #include "FileHandle.h"
 #include "GDBJITRegistrar.h"
@@ -347,14 +348,14 @@
   }
 
   // Parse Source bitcode file (if necessary)
-  if (mSourceList[0]->prepareModule() != 0) {
+  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(mSourceList[0]->getContext()) != 0) {
+    if (mSourceList[1]->prepareModule(mContext.mImpl->mLLVMContext) != 0) {
       ALOGE("Unable to setup library module\n");
       return 1;
     }
diff --git a/lib/ExecutionEngine/Script.h b/lib/ExecutionEngine/Script.h
index e95cf8a..4534951 100644
--- a/lib/ExecutionEngine/Script.h
+++ b/lib/ExecutionEngine/Script.h
@@ -20,6 +20,7 @@
 #include <bcc/bcc.h>
 #include "bcc_internal.h"
 
+#include "BCCContext.h"
 #include "Compiler.h"
 
 #include <llvm/Support/CodeGen.h>
@@ -59,6 +60,8 @@
 
   class Script {
   private:
+    BCCContext mContext;
+
     int mErrorCode;
 
     ScriptStatus::StatusType mStatus;
diff --git a/lib/ExecutionEngine/SourceInfo.cpp b/lib/ExecutionEngine/SourceInfo.cpp
index c069462..5477514 100644
--- a/lib/ExecutionEngine/SourceInfo.cpp
+++ b/lib/ExecutionEngine/SourceInfo.cpp
@@ -27,7 +27,6 @@
 
 #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>
@@ -121,7 +120,7 @@
 }
 
 
-int SourceInfo::prepareModule(llvm::LLVMContext *context) {
+int SourceInfo::prepareModule(llvm::LLVMContext &context) {
   if (module)
     return 0;
 
@@ -157,28 +156,16 @@
     break;
   }
 
-  if (context)
-    shared_context = true;
-  else
-    context = new llvm::LLVMContext();
-
-  module = llvm::ParseBitcodeFile(mem.get(), *context, &errmsg);
+  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() {
-  if (module != NULL) {
-    llvm::LLVMContext *context = &module->getContext();
-    delete module;
-    if (!shared_context)
-      delete context;
-  }
+  delete module;
 }
 
 template <typename T> void SourceInfo::introDependency(T &checker) {
diff --git a/lib/ExecutionEngine/SourceInfo.h b/lib/ExecutionEngine/SourceInfo.h
index 080d3b4..f838f71 100644
--- a/lib/ExecutionEngine/SourceInfo.h
+++ b/lib/ExecutionEngine/SourceInfo.h
@@ -23,10 +23,6 @@
 
 #include <stddef.h>
 
-namespace llvm {
-  class LLVMContext;
-}
-
 namespace bcc {
   namespace SourceKind {
     enum SourceType {
@@ -43,9 +39,6 @@
     // 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 {
@@ -64,7 +57,7 @@
     unsigned char sha1[20];
 
   private:
-    SourceInfo() : module(NULL), shared_context(false) { }
+    SourceInfo() : module(NULL) { }
 
   public:
     static SourceInfo *createFromBuffer(char const *resName,
@@ -82,12 +75,8 @@
       return module;
     }
 
-    inline llvm::LLVMContext *getContext() const {
-      return (module) ? &module->getContext() : NULL;
-    }
-
     // Share with the given context if it's provided.
-    int prepareModule(llvm::LLVMContext *context = NULL);
+    int prepareModule(llvm::LLVMContext &context);
 
     template <typename T> void introDependency(T &checker);