Merge "Changing rsg to rs because functions don't rely on graphics. Renaming one of the includes for clarity."
diff --git a/Android.mk b/Android.mk
index e3948c8..213cc45 100644
--- a/Android.mk
+++ b/Android.mk
@@ -22,10 +22,6 @@
 # Whole Static Library to Be Linked In
 #=====================================================================
 
-ifeq ($(libbcc_USE_OLD_JIT),1)
-libbcc_WHOLE_STATIC_LIBRARIES += libbccCodeGen
-endif
-
 ifeq ($(libbcc_USE_DISASSEMBLER),1)
 libbcc_WHOLE_STATIC_LIBRARIES += libbccDisassembler
 endif
@@ -80,9 +76,7 @@
 LOCAL_WHOLE_STATIC_LIBRARIES += libbccCompilerRT
 endif
 
-ifeq ($(libbcc_USE_MCJIT),1)
-  LOCAL_STATIC_LIBRARIES += librsloader
-endif
+LOCAL_STATIC_LIBRARIES += librsloader
 
 ifeq ($(libbcc_USE_DISASSEMBLER),1)
   ifeq ($(TARGET_ARCH),arm)
@@ -192,9 +186,7 @@
 
 LOCAL_WHOLE_STATIC_LIBRARIES += $(libbcc_WHOLE_STATIC_LIBRARIES)
 
-ifeq ($(libbcc_USE_MCJIT),1)
-  LOCAL_STATIC_LIBRARIES += librsloader
-endif
+LOCAL_STATIC_LIBRARIES += librsloader
 
 ifeq ($(libbcc_USE_DISASSEMBLER),1)
   LOCAL_STATIC_LIBRARIES += \
diff --git a/Config.h b/Config.h
index ebe0044..b1ea833 100644
--- a/Config.h
+++ b/Config.h
@@ -4,62 +4,22 @@
 #include "ConfigFromMk.h"
 
 //---------------------------------------------------------------------------
-// Configuration for JIT & MC Assembler
-//---------------------------------------------------------------------------
-#if !USE_OLD_JIT && !USE_MCJIT
-#error "You should choose at least one code generation method."
-#endif
-
-//---------------------------------------------------------------------------
 // Configuration for Disassembler
 //---------------------------------------------------------------------------
 
-#if !USE_OLD_JIT
-#undef DEBUG_OLD_JIT_DISASSEMBLER
-#define DEBUG_OLD_JIT_DISASSEMBLER 0
-#endif
-
-#if !USE_MCJIT
-#undef DEBUG_MCJIT_DISASSEMBLER
-#define DEBUG_MCJIT_DISASSEMBLER 0
-#endif
-
-#if DEBUG_OLD_JIT_DISASSEMBLER || DEBUG_MCJIT_DISASSEMBLER
+#if DEBUG_MC_DISASSEMBLER
 #define USE_DISASSEMBLER 1
 #else
 #define USE_DISASSEMBLER 0
 #endif
 
 #if defined(__HOST__)
-#define DEBUG_OLD_JIT_DISASSEMBLER_FILE "/tmp/oldjit-dis.s"
-#define DEBUG_MCJIT_DISASSEMBLER_FILE "/tmp/mcjit-dis.s"
+#define DEBUG_MC_DISASSEMBLER_FILE "/tmp/mc-dis.s"
 #else
-#define DEBUG_OLD_JIT_DISASSEMBLER_FILE "/data/local/tmp/oldjit-dis.s"
-#define DEBUG_MCJIT_DISASSEMBLER_FILE "/data/local/tmp/mcjit-dis.s"
+#define DEBUG_MC_DISASSEMBLER_FILE "/data/local/tmp/mc-dis.s"
 #endif // defined(__HOST__)
 
 //---------------------------------------------------------------------------
-// Configuration for ContextManager
-//---------------------------------------------------------------------------
-
-#if USE_OLD_JIT
-
-// Note: Most of the code should NOT use these constants.  Use the public
-// static member of ContextManager instead, which is type-safe.  For example,
-// if you need BCC_CONTEXT_FIXED_ADDR_, then you should write:
-// ContextManager::ContextFixedAddr
-
-#define BCC_CONTEXT_FIXED_ADDR_ reinterpret_cast<char *>(0x7e000000)
-
-#define BCC_CONTEXT_SLOT_COUNT_ 8
-
-#define BCC_CONTEXT_CODE_SIZE_ (128 * 1024)
-
-#define BCC_CONTEXT_DATA_SIZE_ (128 * 1024)
-
-#endif // USE_OLD_JIT
-
-//---------------------------------------------------------------------------
 // Configuration for CodeGen and CompilerRT
 //---------------------------------------------------------------------------
 
diff --git a/README.html b/README.html
index 0b8b447..447312a 100644
--- a/README.html
+++ b/README.html
@@ -419,24 +419,24 @@
 table, and bcc context.  Every section should be aligned to a word size.
 Here is the brief description of each sections:</p>
 <ul class="simple">
-<li><strong>Header</strong> (OBCC_Header) - The header of a cache file. It contains the
+<li><strong>Header</strong> (MCO_Header) - The header of a cache file. It contains the
 magic word, version, machine integer type information (the endianness,
 the size of off_t, size_t, and ptr_t), and the size
 and offset of other sections.  The header section is guaranteed
 to be at the beginning of the cache file.</li>
-<li><strong>String Pool</strong> (OBCC_StringPool) - A collection of serialized variable
+<li><strong>String Pool</strong> (MCO_StringPool) - A collection of serialized variable
 length strings.  The strp_index in the other part of the cache file
 represents the index of such string in this string pool.</li>
-<li><strong>Dependencies Table</strong> (OBCC_DependencyTable) - The dependencies table.
+<li><strong>Dependencies Table</strong> (MCO_DependencyTable) - The dependencies table.
 This table stores the resource name (or file path), the resource
 type (rather in APK or on the file system), and the SHA1 checksum.</li>
-<li><strong>Relocation Table</strong> (OBCC_RelocationTable) - <em>not enabled</em></li>
-<li><strong>Exported Variable List</strong> (OBCC_ExportVarList) -
+<li><strong>Relocation Table</strong> (MCO_RelocationTable) - <em>not enabled</em></li>
+<li><strong>Exported Variable List</strong> (MCO_ExportVarList) -
 The list of the addresses of exported variables.</li>
-<li><strong>Exported Function List</strong> (OBCC_ExportFuncList) -
+<li><strong>Exported Function List</strong> (MCO_ExportFuncList) -
 The list of the addresses of exported functions.</li>
-<li><strong>Pragma List</strong> (OBCC_PragmaList) - The list of pragma key-value pair.</li>
-<li><strong>Function Information Table</strong> (OBCC_FuncTable) - This is a table of
+<li><strong>Pragma List</strong> (MCO_PragmaList) - The list of pragma key-value pair.</li>
+<li><strong>Function Information Table</strong> (MCO_FuncTable) - This is a table of
 function information, such as function name, function entry address,
 and function binary size.  Besides, the table should be ordered by
 function name.</li>
diff --git a/README.rst b/README.rst
index cf40138..97070c0 100644
--- a/README.rst
+++ b/README.rst
@@ -138,31 +138,31 @@
 table, and bcc context.  Every section should be aligned to a word size.
 Here is the brief description of each sections:
 
-* **Header** (OBCC_Header) - The header of a cache file. It contains the
+* **Header** (MCO_Header) - The header of a cache file. It contains the
   magic word, version, machine integer type information (the endianness,
   the size of off_t, size_t, and ptr_t), and the size
   and offset of other sections.  The header section is guaranteed
   to be at the beginning of the cache file.
 
-* **String Pool** (OBCC_StringPool) - A collection of serialized variable
+* **String Pool** (MCO_StringPool) - A collection of serialized variable
   length strings.  The strp_index in the other part of the cache file
   represents the index of such string in this string pool.
 
-* **Dependencies Table** (OBCC_DependencyTable) - The dependencies table.
+* **Dependencies Table** (MCO_DependencyTable) - The dependencies table.
   This table stores the resource name (or file path), the resource
   type (rather in APK or on the file system), and the SHA1 checksum.
 
-* **Relocation Table** (OBCC_RelocationTable) - *not enabled*
+* **Relocation Table** (MCO_RelocationTable) - *not enabled*
 
-* **Exported Variable List** (OBCC_ExportVarList) -
+* **Exported Variable List** (MCO_ExportVarList) -
   The list of the addresses of exported variables.
 
-* **Exported Function List** (OBCC_ExportFuncList) -
+* **Exported Function List** (MCO_ExportFuncList) -
   The list of the addresses of exported functions.
 
-* **Pragma List** (OBCC_PragmaList) - The list of pragma key-value pair.
+* **Pragma List** (MCO_PragmaList) - The list of pragma key-value pair.
 
-* **Function Information Table** (OBCC_FuncTable) - This is a table of
+* **Function Information Table** (MCO_FuncTable) - This is a table of
   function information, such as function name, function entry address,
   and function binary size.  Besides, the table should be ordered by
   function name.
diff --git a/bcinfo/Android.mk b/bcinfo/Android.mk
index f813e77..5a53e07 100644
--- a/bcinfo/Android.mk
+++ b/bcinfo/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.
@@ -38,6 +38,7 @@
 
 libbcinfo_C_INCLUDES := $(LOCAL_PATH)/../include
 libbcinfo_STATIC_LIBRARIES := \
+  libLLVMWrap \
   libLLVMBitReader \
   libLLVMBitWriter \
   libLLVMCore \
diff --git a/bcinfo/BitcodeTranslator.cpp b/bcinfo/BitcodeTranslator.cpp
index 3dcddfc..bd4cd4b 100644
--- a/bcinfo/BitcodeTranslator.cpp
+++ b/bcinfo/BitcodeTranslator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011, The Android Open Source Project
+ * Copyright 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.
@@ -16,6 +16,8 @@
 
 #include "bcinfo/BitcodeTranslator.h"
 
+#include "bcinfo/BitcodeWrapper.h"
+
 #include "BitReader_2_7/BitReader_2_7.h"
 #include "BitReader_3_0/BitReader_3_0.h"
 
@@ -88,6 +90,12 @@
     return false;
   }
 
+  BitcodeWrapper BCWrapper(mBitcode, mBitcodeSize);
+  if (BCWrapper.getTargetAPI() != mVersion) {
+    ALOGE("Bitcode wrapper (%u) and translator (%u) disagree about target API",
+          BCWrapper.getTargetAPI(), mVersion);
+  }
+
   if ((mVersion != kCurrentAPIVersion) &&
       ((mVersion < kMinimumAPIVersion) ||
        (mVersion > kMaximumAPIVersion))) {
@@ -136,11 +144,21 @@
   llvm::WriteBitcodeToFile(module, OS);
   OS.flush();
 
-  char *c = new char[Buffer.size()];
-  memcpy(c, Buffer.c_str(), Buffer.size());
+  AndroidBitcodeWrapper wrapper;
+  size_t actualWrapperLen = writeAndroidBitcodeWrapper(
+      &wrapper, Buffer.size(), BCWrapper.getTargetAPI(),
+      BCWrapper.getCompilerVersion(), BCWrapper.getOptimizationLevel());
+  if (!actualWrapperLen) {
+    ALOGE("Couldn't produce bitcode wrapper!");
+    return false;
+  }
+
+  mTranslatedBitcodeSize = actualWrapperLen + Buffer.size();
+  char *c = new char[mTranslatedBitcodeSize];
+  memcpy(c, &wrapper, actualWrapperLen);
+  memcpy(c + actualWrapperLen, Buffer.c_str(), Buffer.size());
 
   mTranslatedBitcode = c;
-  mTranslatedBitcodeSize = Buffer.size();
 
   return true;
 }
diff --git a/bcinfo/BitcodeWrapper.cpp b/bcinfo/BitcodeWrapper.cpp
index c6f9c04..67f95b8 100644
--- a/bcinfo/BitcodeWrapper.cpp
+++ b/bcinfo/BitcodeWrapper.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011, The Android Open Source Project
+ * Copyright 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.
@@ -15,6 +15,8 @@
  */
 
 #include "bcinfo/BitcodeWrapper.h"
+#include "bcinfo/Wrap/bitcode_wrapperer.h"
+#include "bcinfo/Wrap/in_memory_wrapper_input.h"
 
 #define LOG_TAG "bcinfo"
 #include <cutils/log.h>
@@ -28,8 +30,19 @@
 
 BitcodeWrapper::BitcodeWrapper(const char *bitcode, size_t bitcodeSize)
     : mFileType(BC_NOT_BC), mBitcode(bitcode),
-      mBitcodeEnd(bitcode + bitcodeSize - 1), mBitcodeSize(bitcodeSize) {
-  memset(&mBCHeader, 0, sizeof(mBCHeader));
+      mBitcodeEnd(bitcode + bitcodeSize - 1), mBitcodeSize(bitcodeSize),
+      mHeaderVersion(0), mTargetAPI(0) {
+  InMemoryWrapperInput inMem(mBitcode, mBitcodeSize);
+  BitcodeWrapperer wrapperer(&inMem, NULL);
+  if (wrapperer.IsInputBitcodeWrapper()) {
+    mFileType = BC_WRAPPER;
+    mHeaderVersion = wrapperer.getAndroidHeaderVersion();
+    mTargetAPI = wrapperer.getAndroidTargetAPI();
+    mCompilerVersion = wrapperer.getAndroidCompilerVersion();
+    mOptimizationLevel = wrapperer.getAndroidOptimizationLevel();
+  } else if (wrapperer.IsInputBitcodeFile()) {
+    mFileType = BC_RAW;
+  }
 }
 
 
@@ -39,30 +52,7 @@
 
 
 bool BitcodeWrapper::unwrap() {
-  if (!mBitcode || !mBitcodeSize) {
-    ALOGE("Invalid/empty bitcode");
-    return false;
-  }
-
-  if (llvm::isBitcodeWrapper((const unsigned char*) mBitcode,
-                             (const unsigned char*) mBitcodeEnd)) {
-    if (mBitcodeSize < sizeof(mBCHeader)) {
-      ALOGE("Invalid bitcode size");
-      return false;
-    }
-
-    mFileType = BC_WRAPPER;
-    memcpy(&mBCHeader, mBitcode, sizeof(mBCHeader));
-    return true;
-  } else if (llvm::isRawBitcode((const unsigned char*) mBitcode,
-                                (const unsigned char*) mBitcodeEnd)) {
-    mFileType = BC_RAW;
-    return true;
-  } else {
-    ALOGE("Not bitcode");
-    mFileType = BC_NOT_BC;
-    return false;
-  }
+  return mFileType != BC_NOT_BC;
 }
 
 }  // namespace bcinfo
diff --git a/bcinfo/Wrap/Android.mk b/bcinfo/Wrap/Android.mk
new file mode 100644
index 0000000..adc306a
--- /dev/null
+++ b/bcinfo/Wrap/Android.mk
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+LLVM_ROOT_PATH := $(LOCAL_PATH)/../../../../../external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+
+llvm_wrap_SRC_FILES := \
+  bitcode_wrapperer.cpp \
+  file_wrapper_input.cpp \
+  file_wrapper_output.cpp \
+  in_memory_wrapper_input.cpp \
+  wrapper_output.cpp
+
+llvm_wrap_C_INCLUDES := $(LOCAL_PATH)/../../include
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libLLVMWrap
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(llvm_wrap_SRC_FILES)
+LOCAL_CFLAGS += -D__HOST__
+LOCAL_C_INCLUDES := $(llvm_wrap_C_INCLUDES)
+
+include $(LLVM_HOST_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libLLVMWrap
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(llvm_wrap_SRC_FILES)
+LOCAL_C_INCLUDES := $(llvm_wrap_C_INCLUDES)
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(LLVM_GEN_INTRINSICS_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/bcinfo/Wrap/LLVMBuild.txt b/bcinfo/Wrap/LLVMBuild.txt
new file mode 100644
index 0000000..8750711
--- /dev/null
+++ b/bcinfo/Wrap/LLVMBuild.txt
@@ -0,0 +1,21 @@
+;===- ./lib/Wrap/LLVMBuild.txt ------------------------------*- Conf -*--===;
+;
+;                     The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = Wrap
+parent = Libraries
diff --git a/bcinfo/Wrap/Makefile b/bcinfo/Wrap/Makefile
new file mode 100644
index 0000000..79aa2b3
--- /dev/null
+++ b/bcinfo/Wrap/Makefile
@@ -0,0 +1,14 @@
+##===- lib/Linker/Makefile ---------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+LIBRARYNAME = LLVMWrap
+BUILD_ARCHIVE := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/bcinfo/Wrap/bitcode_wrapperer.cpp b/bcinfo/Wrap/bitcode_wrapperer.cpp
new file mode 100644
index 0000000..c8b7d26
--- /dev/null
+++ b/bcinfo/Wrap/bitcode_wrapperer.cpp
@@ -0,0 +1,380 @@
+/*
+ * 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 "bcinfo/Wrap/bitcode_wrapperer.h"
+
+#define LOG_TAG "bcinfo"
+#include <cutils/log.h>
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+using std::vector;
+
+// The number of bytes in a 32 bit integer.
+static const uint32_t kWordSize = 4;
+
+// Number of LLVM-defined fixed fields in the header.
+static const uint32_t kLLVMFields = 4;
+
+// Total number of fixed fields in the header.
+static const uint32_t kFixedFields = 7;
+
+// The magic number that must exist for bitcode wrappers.
+static const uint32_t kWrapperMagicNumber = 0x0B17C0DE;
+
+// The version number associated with a wrapper file.
+// Note: llvm currently only allows the value 0. When this changes,
+// we should consider making this a command line option.
+static const uint32_t kLLVMVersionNumber = 0;
+
+// Fields defined by Android bitcode header.
+static const uint32_t kAndroidHeaderVersion = 0;
+static const uint32_t kAndroidTargetAPI = 0;
+static const uint32_t kAndroidDefaultCompilerVersion = 0;
+static const uint32_t kAndroidDefaultOptimizationLevel = 3;
+
+// PNaCl bitcode version number.
+static const uint32_t kPnaclBitcodeVersion = 0;
+
+// Max size for variable fields. Currently only used for writing them
+// out to files (the parsing works for arbitrary sizes).
+static const size_t kMaxVariableFieldSize = 256;
+
+BitcodeWrapperer::BitcodeWrapperer(WrapperInput* infile, WrapperOutput* outfile)
+    : infile_(infile),
+      outfile_(outfile),
+      buffer_size_(0),
+      cursor_(0),
+      infile_at_eof_(false),
+      infile_bc_offset_(0),
+      wrapper_bc_offset_(0),
+      wrapper_bc_size_(0),
+      android_header_version_(kAndroidHeaderVersion),
+      android_target_api_(kAndroidTargetAPI),
+      android_compiler_version_(kAndroidDefaultCompilerVersion),
+      android_optimization_level_(kAndroidDefaultOptimizationLevel),
+      pnacl_bc_version_(0),
+      error_(false) {
+  buffer_.resize(kBitcodeWrappererBufferSize);
+  if (IsInputBitcodeWrapper()) {
+    ParseWrapperHeader();
+  } else if (IsInputBitcodeFile()) {
+    wrapper_bc_offset_ = kWordSize * kFixedFields;
+    wrapper_bc_size_ = GetInFileSize();
+  } else {
+    ALOGE("Error: input file is not a bitcode file.\n");
+    error_ = true;
+  }
+}
+
+BitcodeWrapperer::~BitcodeWrapperer() {
+  for(size_t i = 0; i < variable_field_data_.size(); i++) {
+    delete [] variable_field_data_[i];
+  }
+}
+
+
+void BitcodeWrapperer::ClearBuffer() {
+  buffer_size_ = 0;
+  cursor_ = 0;
+  infile_at_eof_ = false;
+}
+
+bool BitcodeWrapperer::Seek(uint32_t pos) {
+  if (infile_->Seek(pos)) {
+    ClearBuffer();
+    return true;
+  }
+  return false;
+}
+
+bool BitcodeWrapperer::CanReadWord() {
+  if (GetBufferUnreadBytes() < kWordSize) {
+    FillBuffer();
+    return GetBufferUnreadBytes() >= kWordSize;
+  } else {
+    return true;
+  }
+}
+
+void BitcodeWrapperer::FillBuffer() {
+  if (cursor_ > 0) {
+    // Before filling, move any remaining bytes to the
+    // front of the buffer. This allows us to assume
+    // that after the call to FillBuffer, readable
+    // text is contiguous.
+    if (cursor_ < buffer_size_) {
+      size_t i = 0;
+      while (cursor_ < buffer_size_) {
+        buffer_[i++] = buffer_[cursor_++];
+      }
+      cursor_ = 0;
+      buffer_size_ = i;
+    }
+  } else {
+    // Assume the buffer contents have been used,
+    // and we want to completely refill it.
+    buffer_size_ = 0;
+  }
+
+  // Now fill in remaining space.
+  size_t needed = buffer_.size() - buffer_size_;
+
+  while (buffer_.size() > buffer_size_) {
+    int actually_read = infile_->Read(&buffer_[buffer_size_], needed);
+    if (infile_->AtEof()) {
+      infile_at_eof_ = true;
+    }
+    if (actually_read) {
+      buffer_size_ += actually_read;
+      needed -= actually_read;
+    } else if (infile_at_eof_) {
+      break;
+    }
+  }
+}
+
+bool BitcodeWrapperer::ReadWord(uint32_t& word) {
+  if (!CanReadWord()) return false;
+  word = (((uint32_t) BufferLookahead(0)) << 0)
+      | (((uint32_t) BufferLookahead(1)) << 8)
+      | (((uint32_t) BufferLookahead(2)) << 16)
+      | (((uint32_t) BufferLookahead(3)) << 24);
+  cursor_ += kWordSize;
+  return true;
+}
+
+bool BitcodeWrapperer::WriteWord(uint32_t value) {
+  uint8_t buffer[kWordSize];
+  buffer[3] = (value >> 24) & 0xFF;
+  buffer[2] = (value >> 16) & 0xFF;
+  buffer[1] = (value >> 8)  & 0xFF;
+  buffer[0] = (value >> 0)  & 0xFF;
+  return outfile_->Write(buffer, kWordSize);
+}
+
+bool BitcodeWrapperer::WriteVariableFields() {
+  // This buffer may have to be bigger if we start using the fields
+  // for larger things.
+  uint8_t buffer[kMaxVariableFieldSize];
+  for (vector<BCHeaderField>::iterator it = header_fields_.begin();
+       it != header_fields_.end(); ++it) {
+    if (!it->Write(buffer, kMaxVariableFieldSize) ||
+        !outfile_->Write(buffer, it->GetTotalSize())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool BitcodeWrapperer::ParseWrapperHeader() {
+  // Make sure LLVM-defined fields have been parsed
+  if (!IsInputBitcodeWrapper()) return false;
+  // Check the android/pnacl fields
+  if (!ReadWord(android_header_version_) ||
+      !ReadWord(android_target_api_) || !ReadWord(pnacl_bc_version_)) {
+    ALOGW("Error: file not long enough to contain header\n");
+    return false;
+  }
+  if (pnacl_bc_version_ != kPnaclBitcodeVersion) {
+    ALOGW("Error: bad PNaCl Bitcode version\n");
+    return false;
+  }
+  int field_data_total = wrapper_bc_offset_ - kWordSize * kFixedFields;
+  if (field_data_total > 0) {
+    // Read in the variable fields. We need to allocate space for the data.
+    int field_data_read = 0;
+
+    while (field_data_read < field_data_total) {
+      FillBuffer();
+      size_t buffer_needed = BCHeaderField::GetDataSizeFromSerialized(
+          &buffer_[cursor_]);
+      if (buffer_needed > buffer_.size()) {
+        buffer_.resize(buffer_needed +
+                       sizeof(BCHeaderField::FixedSubfield) * 2);
+        FillBuffer();
+      }
+      variable_field_data_.push_back(new uint8_t[buffer_needed]);
+
+      BCHeaderField field(BCHeaderField::kInvalid, 0,
+                          variable_field_data_.back());
+      field.Read(&buffer_[cursor_], buffer_size_);
+      header_fields_.push_back(field);
+      size_t field_size = field.GetTotalSize();
+      cursor_ += field_size;
+      field_data_read += field_size;
+      if (field_data_read > field_data_total) {
+        // We read too much data, the header is corrupted
+        ALOGE("Error: raw bitcode offset inconsistent with "
+              "variable field data\n");
+        return false;
+      }
+
+      struct IntFieldHelper {
+        BCHeaderField::FixedSubfield tag;
+        uint16_t len;
+        uint32_t val;
+      };
+      IntFieldHelper tempIntField;
+
+      switch (field.getID()) {
+        case BCHeaderField::kAndroidCompilerVersion:
+          if (field.Write((uint8_t*)&tempIntField,
+                          sizeof(tempIntField))) {
+            android_compiler_version_ = tempIntField.val;
+          }
+          break;
+        case BCHeaderField::kAndroidOptimizationLevel:
+          if (field.Write((uint8_t*)&tempIntField,
+                          sizeof(tempIntField))) {
+            android_optimization_level_ = tempIntField.val;
+          }
+          break;
+        default:
+          // Ignore other field types for now
+          break;
+      }
+    }
+    Seek(0);
+  }
+  return true;
+}
+
+bool BitcodeWrapperer::IsInputBitcodeWrapper() {
+  ResetCursor();
+  // First make sure that there are enough words (LLVM header)
+  // to peek at.
+  if (GetBufferUnreadBytes() < kLLVMFields * kWordSize) {
+    FillBuffer();
+    if (GetBufferUnreadBytes() < kLLVMFields * kWordSize) return false;
+  }
+
+  // Now make sure the magic number is right.
+  uint32_t first_word;
+  if ((!ReadWord(first_word)) ||
+      (kWrapperMagicNumber != first_word)) return false;
+
+  // Make sure the version is right.
+  uint32_t second_word;
+  if ((!ReadWord(second_word)) ||
+      (kLLVMVersionNumber != second_word)) return false;
+
+  // Make sure that the offset and size (for llvm) is defined.
+  uint32_t bc_offset;
+  uint32_t bc_size;
+  if (ReadWord(bc_offset) &&
+      ReadWord(bc_size)) {
+    // Before returning, save the extracted values.
+    wrapper_bc_offset_ = bc_offset;
+    infile_bc_offset_ = bc_offset;
+    wrapper_bc_size_ = bc_size;
+    return true;
+  }
+  // If reached, unable to read wrapped header.
+  return false;
+}
+
+bool BitcodeWrapperer::IsInputBitcodeFile() {
+  ResetCursor();
+  // First make sure that there are four bytes to peek at.
+  if (GetBufferUnreadBytes() < kWordSize) {
+    FillBuffer();
+    if (GetBufferUnreadBytes() < kWordSize) return false;
+  }
+  // If reached, Check if first 4 bytes match bitcode
+  // file magic number.
+  return (BufferLookahead(0) == 'B') &&
+      (BufferLookahead(1) == 'C') &&
+      (BufferLookahead(2) == 0xc0) &&
+      (BufferLookahead(3) == 0xde);
+}
+
+bool BitcodeWrapperer::BufferCopyInToOut(uint32_t size) {
+  while (size > 0) {
+    // Be sure buffer is non-empty before writing.
+    if (0 == buffer_size_) {
+      FillBuffer();
+      if (0 == buffer_size_) {
+        return false;
+      }
+    }
+    // copy the buffer to the output file.
+    size_t block = (buffer_size_ < size) ? buffer_size_ : size;
+    if (!outfile_->Write(&buffer_[cursor_], block)) return false;
+    size -= block;
+    buffer_size_ = 0;
+  }
+  // Be sure that there isn't more bytes on the input stream.
+  FillBuffer();
+  return buffer_size_ == 0;
+}
+
+void BitcodeWrapperer::AddHeaderField(BCHeaderField* field) {
+  header_fields_.push_back(*field);
+  wrapper_bc_offset_ += field->GetTotalSize();
+}
+
+bool BitcodeWrapperer::WriteBitcodeWrapperHeader() {
+  return
+      // Note: This writes out the 4 word header required by llvm wrapped
+      // bitcode.
+      WriteWord(kWrapperMagicNumber) &&
+      WriteWord(kLLVMVersionNumber) &&
+      WriteWord(wrapper_bc_offset_) &&
+      WriteWord(wrapper_bc_size_) &&
+      // 2 fixed fields defined by Android
+      WriteWord(android_header_version_) &&
+      WriteWord(android_target_api_) &&
+      // PNaClBitcode version
+      WriteWord(kPnaclBitcodeVersion) &&
+      // Common variable-length fields
+      WriteVariableFields();
+}
+
+void BitcodeWrapperer::PrintWrapperHeader() {
+  if (error_) {
+    fprintf(stderr, "Error condition exists: the following"
+            "data may not be reliable\n");
+  }
+  fprintf(stderr, "Wrapper magic:\t\t%x\n", kWrapperMagicNumber);
+  fprintf(stderr, "LLVM Bitcode version:\t%d\n", kLLVMVersionNumber);
+  fprintf(stderr, "Raw bitcode offset:\t%d\n", wrapper_bc_offset_);
+  fprintf(stderr, "Raw bitcode size:\t%d\n", wrapper_bc_size_);
+  fprintf(stderr, "Android header version:\t%d\n", android_header_version_);
+  fprintf(stderr, "Android target API:\t%d\n", android_target_api_);
+  fprintf(stderr, "PNaCl bitcode version:\t%d\n", kPnaclBitcodeVersion);
+  for (size_t i = 0; i < header_fields_.size(); i++) header_fields_[i].Print();
+}
+
+bool BitcodeWrapperer::GenerateWrappedBitcodeFile() {
+  if (!error_ &&
+      WriteBitcodeWrapperHeader() &&
+      Seek(infile_bc_offset_) &&
+      BufferCopyInToOut(wrapper_bc_size_)) {
+    off_t dangling = wrapper_bc_size_ & 3;
+    if (dangling) {
+      return outfile_->Write((const uint8_t*) "\0\0\0\0", 4 - dangling);
+    }
+    return true;
+  }
+  return false;
+}
+
+bool BitcodeWrapperer::GenerateRawBitcodeFile() {
+  return !error_ && Seek(infile_bc_offset_) &&
+      BufferCopyInToOut(wrapper_bc_size_);
+}
diff --git a/bcinfo/Wrap/file_wrapper_input.cpp b/bcinfo/Wrap/file_wrapper_input.cpp
new file mode 100644
index 0000000..08212c2
--- /dev/null
+++ b/bcinfo/Wrap/file_wrapper_input.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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 <sys/stat.h>
+#include <stdlib.h>
+
+#include "bcinfo/Wrap/file_wrapper_input.h"
+
+FileWrapperInput::FileWrapperInput(const char* name) :
+    _name(name), _at_eof(false), _size_found(false), _size(0) {
+  _file = fopen(name, "rb");
+  if (NULL == _file) {
+    fprintf(stderr, "Unable to open: %s\n", name);
+    exit(1);
+  }
+}
+
+FileWrapperInput::~FileWrapperInput() {
+  fclose(_file);
+}
+
+size_t FileWrapperInput::Read(uint8_t* buffer, size_t wanted) {
+  size_t found = fread((char*) buffer, 1, wanted, _file);
+  if (feof(_file) || ferror(_file)) {
+    _at_eof = true;
+  }
+  return found;
+}
+
+bool FileWrapperInput::AtEof() {
+  return _at_eof;
+}
+
+off_t FileWrapperInput::Size() {
+  if (_size_found) return _size;
+  struct stat st;
+  if (0 == stat(_name, &st)) {
+    _size_found = true;
+    _size = st.st_size;
+    return _size;
+  } else {
+    fprintf(stderr, "Unable to compute file size: %s\n", _name);
+    exit(1);
+  }
+  // NOT REACHABLE.
+  return 0;
+}
+
+bool FileWrapperInput::Seek(uint32_t pos) {
+  return 0 == fseek(_file, (long) pos, SEEK_SET);
+}
diff --git a/bcinfo/Wrap/file_wrapper_output.cpp b/bcinfo/Wrap/file_wrapper_output.cpp
new file mode 100644
index 0000000..4cdc54e
--- /dev/null
+++ b/bcinfo/Wrap/file_wrapper_output.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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 <stdlib.h>
+
+#include "bcinfo/Wrap/file_wrapper_output.h"
+
+FileWrapperOutput::FileWrapperOutput(const char* name)
+    : _name(name) {
+  _file = fopen(name, "wb");
+  if (NULL == _file) {
+    fprintf(stderr, "Unable to open: %s\n", name);
+    exit(1);
+  }
+}
+
+FileWrapperOutput::~FileWrapperOutput() {
+  fclose(_file);
+}
+
+bool FileWrapperOutput::Write(uint8_t byte) {
+  return EOF != fputc(byte, _file);
+}
+
+bool FileWrapperOutput::Write(const uint8_t* buffer, size_t buffer_size) {
+  if (buffer_size > 0) {
+    return buffer_size == fwrite(buffer, 1, buffer_size, _file);
+  } else {
+    return true;
+  }
+}
diff --git a/bcinfo/Wrap/in_memory_wrapper_input.cpp b/bcinfo/Wrap/in_memory_wrapper_input.cpp
new file mode 100644
index 0000000..3f91f01
--- /dev/null
+++ b/bcinfo/Wrap/in_memory_wrapper_input.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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 <sys/stat.h>
+#include <stdlib.h>
+
+#include "bcinfo/Wrap/in_memory_wrapper_input.h"
+
+InMemoryWrapperInput::InMemoryWrapperInput(const char* buffer, size_t size) :
+    _buffer(buffer), _pos(0), _size(size) {
+}
+
+InMemoryWrapperInput::~InMemoryWrapperInput() {
+}
+
+size_t InMemoryWrapperInput::Read(uint8_t* buffer, size_t wanted) {
+  size_t found = 0;
+  while (found < wanted) {
+    if (_pos >= _size) {
+      return found;
+    }
+    buffer[found++] = _buffer[_pos++];
+  }
+  return found;
+}
+
+bool InMemoryWrapperInput::AtEof() {
+  return (_pos >= _size);
+}
+
+off_t InMemoryWrapperInput::Size() {
+  return _size;
+}
+
+bool InMemoryWrapperInput::Seek(uint32_t pos) {
+  if (pos < _size) {
+    _pos = pos;
+    return true;
+  } else {
+    return false;
+  }
+}
diff --git a/bcinfo/Wrap/wrapper_output.cpp b/bcinfo/Wrap/wrapper_output.cpp
new file mode 100644
index 0000000..3c72422
--- /dev/null
+++ b/bcinfo/Wrap/wrapper_output.cpp
@@ -0,0 +1,25 @@
+/*
+ * 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 "bcinfo/Wrap/wrapper_output.h"
+
+bool WrapperOutput::Write(const uint8_t* buffer, size_t buffer_size) {
+  // Default implementation that uses the byte write routine.
+  for (size_t i = 0; i < buffer_size; ++i) {
+    if (!Write(buffer[i])) return false;
+  }
+  return true;
+}
diff --git a/bcinfo/tools/main.cpp b/bcinfo/tools/main.cpp
index 6ecded0..bed24aa 100644
--- a/bcinfo/tools/main.cpp
+++ b/bcinfo/tools/main.cpp
@@ -120,8 +120,6 @@
   }
   printf("\n");
 
-  printf("optimizationLevel: %u\n", ME->getOptimizationLevel());
-
   return;
 }
 
@@ -184,11 +182,6 @@
   unsigned int version = 0;
 
   bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeSize);
-  if (!bcWrapper.unwrap()) {
-    fprintf(stderr, "failed to unwrap bitcode wrapper\n");
-    return 2;
-  }
-
   if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) {
     version = bcWrapper.getTargetAPI();
     printf("Found bitcodeWrapper\n");
@@ -196,7 +189,9 @@
     version = 12;
   }
 
-  printf("bitcodeVersion: %u\n", version);
+  printf("targetAPI: %u\n", version);
+  printf("compilerVersion: %u\n", bcWrapper.getCompilerVersion());
+  printf("optimizationLevel: %u\n\n", bcWrapper.getOptimizationLevel());
 
   bcinfo::BitcodeTranslator *BT =
       new bcinfo::BitcodeTranslator(bitcode, bitcodeSize, version);
diff --git a/include/bcc/bcc_cache.h b/include/bcc/bcc_cache.h
deleted file mode 100644
index 6809cce..0000000
--- a/include/bcc/bcc_cache.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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_CACHE_H
-#define BCC_CACHE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-/* BCC Cache File Magic Word */
-#define OBCC_MAGIC "\0bcc"
-
-/* BCC Cache File Version, encoded in 4 bytes of ASCII */
-#define OBCC_VERSION "001\0"
-
-/* BCC Cache Header Structure */
-struct OBCC_Header {
-  /* magic and version */
-  uint8_t magic[4];
-  uint8_t version[4];
-
-  /* machine-dependent integer type size */
-  uint8_t endianness;
-  uint8_t sizeof_off_t;
-  uint8_t sizeof_size_t;
-  uint8_t sizeof_ptr_t;
-
-  /* string pool section */
-  off_t str_pool_offset;
-  size_t str_pool_size;
-
-  /* dependancy table */
-  off_t depend_tab_offset;
-  size_t depend_tab_size;
-
-  /* relocation table section */
-  off_t reloc_tab_offset;
-  size_t reloc_tab_size;
-
-  /* export variable list section */
-  off_t export_var_list_offset;
-  size_t export_var_list_size;
-
-  /* export function list section */
-  off_t export_func_list_offset;
-  size_t export_func_list_size;
-
-  /* pragma list section */
-  off_t pragma_list_offset;
-  size_t pragma_list_size;
-
-  /* function table */
-  off_t func_table_offset;
-  size_t func_table_size;
-
-  /* function table */
-  off_t object_slot_list_offset;
-  size_t object_slot_list_size;
-
-  /* context section */
-  char *context_cached_addr;
-  uint32_t context_parity_checksum;
-
-  /* dirty hack for libRS */
-  /* TODO: This should be removed in the future */
-  uint32_t libRS_threadable;
-
-  /* export foreach list section */
-  off_t export_foreach_list_offset;
-  size_t export_foreach_list_size;
-};
-
-struct OBCC_String {
-  size_t length; /* String length, without ending '\0' */
-  off_t offset; /* Note: Offset related to string_pool_offset. */
-};
-
-struct OBCC_StringPool {
-  size_t count;
-  struct OBCC_String list[];
-};
-
-enum OBCC_ResourceType {
-  BCC_APK_RESOURCE = 0,
-  BCC_FILE_RESOURCE = 1,
-};
-
-struct OBCC_Dependency {
-  size_t res_name_strp_index;
-  uint32_t res_type; /* BCC_APK_RESOURCE or BCC_FILE_RESOURCE */
-  unsigned char sha1[20];
-};
-
-struct OBCC_DependencyTable {
-  size_t count;
-  struct OBCC_Dependency table[];
-};
-
-struct OBCC_RelocationTable {
-/* TODO: Implement relocation table. */
-};
-
-struct OBCC_ExportVarList {
-  size_t count;
-  void *cached_addr_list[];
-};
-
-struct OBCC_ExportFuncList {
-  size_t count;
-  void *cached_addr_list[];
-};
-
-struct OBCC_ExportForEachList {
-  size_t count;
-  void *cached_addr_list[];
-};
-
-struct OBCC_Pragma {
-  size_t key_strp_index;
-  size_t value_strp_index;
-};
-
-struct OBCC_PragmaList {
-  size_t count;
-  struct OBCC_Pragma list[];
-};
-
-struct OBCC_ObjectSlotList {
-  size_t count;
-  uint32_t object_slot_list[];
-};
-
-struct OBCC_FuncInfo {
-  size_t name_strp_index;
-  void *cached_addr;
-  size_t size;
-};
-
-struct OBCC_FuncTable {
-  size_t count;
-  struct OBCC_FuncInfo table[];
-};
-
-struct OBCC_String_Ptr {
-  size_t count;
-  size_t strp_indexs[];
-};
-
-
-#endif /* BCC_CACHE_H */
diff --git a/include/bcc/bcc_mccache.h b/include/bcc/bcc_mccache.h
index 292165d..a214831 100644
--- a/include/bcc/bcc_mccache.h
+++ b/include/bcc/bcc_mccache.h
@@ -20,8 +20,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include "bcc_cache.h"
-
 /* BCC Cache File Magic Word */
 #define MCO_MAGIC "\0bcc"
 
@@ -81,5 +79,77 @@
   size_t export_foreach_name_list_size;
 };
 
+struct MCO_String {
+  size_t length; /* String length, without ending '\0' */
+  off_t offset; /* Note: Offset related to string_pool_offset. */
+};
+
+struct MCO_StringPool {
+  size_t count;
+  struct MCO_String list[];
+};
+
+enum MCO_ResourceType {
+  BCC_APK_RESOURCE = 0,
+  BCC_FILE_RESOURCE = 1,
+};
+
+struct MCO_Dependency {
+  size_t res_name_strp_index;
+  uint32_t res_type; /* BCC_APK_RESOURCE or BCC_FILE_RESOURCE */
+  unsigned char sha1[20];
+};
+
+struct MCO_DependencyTable {
+  size_t count;
+  struct MCO_Dependency table[];
+};
+
+struct MCO_ExportVarList {
+  size_t count;
+  void *cached_addr_list[];
+};
+
+struct MCO_ExportFuncList {
+  size_t count;
+  void *cached_addr_list[];
+};
+
+struct MCO_ExportForEachList {
+  size_t count;
+  void *cached_addr_list[];
+};
+
+struct MCO_Pragma {
+  size_t key_strp_index;
+  size_t value_strp_index;
+};
+
+struct MCO_PragmaList {
+  size_t count;
+  struct MCO_Pragma list[];
+};
+
+struct MCO_ObjectSlotList {
+  size_t count;
+  uint32_t object_slot_list[];
+};
+
+struct MCO_FuncInfo {
+  size_t name_strp_index;
+  void *cached_addr;
+  size_t size;
+};
+
+struct MCO_FuncTable {
+  size_t count;
+  struct MCO_FuncInfo table[];
+};
+
+struct MCO_String_Ptr {
+  size_t count;
+  size_t strp_indexs[];
+};
+
 
 #endif /* BCC_MCCACHE_H */
diff --git a/include/bcinfo/BitcodeWrapper.h b/include/bcinfo/BitcodeWrapper.h
index cde0a91..3e9ed52 100644
--- a/include/bcinfo/BitcodeWrapper.h
+++ b/include/bcinfo/BitcodeWrapper.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011, The Android Open Source Project
+ * Copyright 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.
@@ -17,18 +17,27 @@
 #ifndef __ANDROID_BCINFO_BITCODEWRAPPER_H__
 #define __ANDROID_BCINFO_BITCODEWRAPPER_H__
 
+#include "bcinfo/Wrap/BCHeaderField.h"
+
 #include <cstddef>
 #include <stdint.h>
 
 namespace bcinfo {
 
-struct BCWrapperHeader {
+struct AndroidBitcodeWrapper {
   uint32_t Magic;
   uint32_t Version;
   uint32_t BitcodeOffset;
   uint32_t BitcodeSize;
   uint32_t HeaderVersion;
   uint32_t TargetAPI;
+  uint32_t PNaClVersion;
+  uint16_t CompilerVersionTag;
+  uint16_t CompilerVersionLen;
+  uint32_t CompilerVersion;
+  uint16_t OptimizationLevelTag;
+  uint16_t OptimizationLevelLen;
+  uint32_t OptimizationLevel;
 };
 
 enum BCFileType {
@@ -44,7 +53,10 @@
   const char *mBitcodeEnd;
   size_t mBitcodeSize;
 
-  struct BCWrapperHeader mBCHeader;
+  uint32_t mHeaderVersion;
+  uint32_t mTargetAPI;
+  uint32_t mCompilerVersion;
+  uint32_t mOptimizationLevel;
 
  public:
   /**
@@ -58,7 +70,7 @@
   ~BitcodeWrapper();
 
   /**
-   * Attempt to unwrap the target bitcode.
+   * Attempt to unwrap the target bitcode. This function is \deprecated.
    *
    * \return true on success and false if an error occurred.
    */
@@ -72,20 +84,71 @@
   }
 
   /**
-   * \return header version of bitcode wrapper. This can only be 0 currently.
+   * \return header version of bitcode wrapper.
    */
   uint32_t getHeaderVersion() const {
-    return mBCHeader.HeaderVersion;
+    return mHeaderVersion;
   }
 
   /**
-   * \return target API version of this script.
+   * \return target API version for this bitcode.
    */
   uint32_t getTargetAPI() const {
-    return mBCHeader.TargetAPI;
+    return mTargetAPI;
   }
+
+  /**
+   * \return compiler version that generated this bitcode.
+   */
+  uint32_t getCompilerVersion() const {
+    return mCompilerVersion;
+  }
+
+  /**
+   * \return compiler optimization level for this bitcode.
+   */
+  uint32_t getOptimizationLevel() const {
+    return mOptimizationLevel;
+  }
+
 };
 
+/**
+ * Helper function to emit just the bitcode wrapper returning the number of
+ * bytes that were written.
+ *
+ * \param wrapper - where to write header information into.
+ * \param bitcodeSize - size of bitcode in bytes.
+ * \param targetAPI - target API version for this bitcode.
+ * \param compilerVersion - compiler version that generated this bitcode.
+ * \param optimizationLevel - compiler optimization level for this bitcode.
+ *
+ * \return number of wrapper bytes written into the \p buffer.
+ */
+static inline size_t writeAndroidBitcodeWrapper(AndroidBitcodeWrapper *wrapper,
+    size_t bitcodeSize, uint32_t targetAPI, uint32_t compilerVersion,
+    uint32_t optimizationLevel) {
+  if (!wrapper) {
+    return 0;
+  }
+
+  wrapper->Magic = 0x0B17C0DE;
+  wrapper->Version = 0;
+  wrapper->BitcodeOffset = sizeof(*wrapper);
+  wrapper->BitcodeSize = bitcodeSize;
+  wrapper->HeaderVersion = 0;
+  wrapper->TargetAPI = targetAPI;
+  wrapper->PNaClVersion = 0;
+  wrapper->CompilerVersionTag = BCHeaderField::kAndroidCompilerVersion;
+  wrapper->CompilerVersionLen = 4;
+  wrapper->CompilerVersion = compilerVersion;
+  wrapper->OptimizationLevelTag = BCHeaderField::kAndroidOptimizationLevel;
+  wrapper->OptimizationLevelLen = 4;
+  wrapper->OptimizationLevel = optimizationLevel;
+
+  return sizeof(*wrapper);
+}
+
 }  // namespace bcinfo
 
 #endif  // __ANDROID_BCINFO_BITCODEWRAPPER_H__
diff --git a/include/bcinfo/Wrap/BCHeaderField.h b/include/bcinfo/Wrap/BCHeaderField.h
new file mode 100644
index 0000000..8652d78
--- /dev/null
+++ b/include/bcinfo/Wrap/BCHeaderField.h
@@ -0,0 +1,118 @@
+/*
+ * 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 LLVM_WRAP_BCHEADER_FIELD_H__
+#define LLVM_WRAP_BCHEADER_FIELD_H__
+
+#include <limits>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+// Class representing a variable-size metadata field in the bitcode header.
+// Also contains the list of known Tag IDs.
+// Contains a pointer to the data but does not own the data, so it can be
+// copied with the trivial copy constructor/assignment operator.
+
+// The serialized format has 2 fixed subfields (ID and length) and the
+// variable-length data subfield
+class BCHeaderField {
+ public:
+  typedef enum {
+    kInvalid = 0,
+    kBitcodeHash = 1,
+    kAndroidCompilerVersion = 0x4001,
+    kAndroidOptimizationLevel = 0x4002
+  } Tag;
+  typedef uint16_t FixedSubfield;
+
+  BCHeaderField(Tag ID, size_t len, uint8_t* data) :
+      ID_(ID), len_(len), data_(data) {}
+  size_t GetTotalSize() {
+    // Round up to 4 byte alignment
+    return (kTagLenSize + len_ + 3) & ~3;
+  }
+
+  bool Write(uint8_t* buf, size_t buf_len) {
+    size_t fields_len = kTagLenSize + len_;
+    size_t pad_len = (4 - (fields_len & 3)) & 3;
+    // Ensure buffer is large enough and that length can be represented
+    // in 16 bits
+    if (buf_len < fields_len + pad_len ||
+        len_ > std::numeric_limits<FixedSubfield>::max()) return false;
+
+    WriteFixedSubfield(static_cast<FixedSubfield>(ID_), buf);
+    WriteFixedSubfield(static_cast<FixedSubfield>(len_),
+                       buf + sizeof(FixedSubfield));
+    memcpy(buf + kTagLenSize, data_, len_);
+    // Pad out to 4 byte alignment
+    if (pad_len) {
+      memset(buf + fields_len, 0, pad_len);
+    }
+    return true;
+  }
+
+  bool Read(const uint8_t* buf, size_t buf_len) {
+    if (buf_len < kTagLenSize) return false;
+    FixedSubfield field;
+    ReadFixedSubfield(&field, buf);
+    ID_ = static_cast<Tag>(field);
+    ReadFixedSubfield(&field, buf + sizeof(FixedSubfield));
+    len_ = static_cast<size_t>(field);
+    if (buf_len < kTagLenSize + len_) return false;
+    memcpy(data_, buf + kTagLenSize, len_);
+    return true;
+  }
+
+  void Print() {
+    fprintf(stderr, "Field ID: %d, data length %d, total length %d\n",
+            ID_, static_cast<int>(len_), static_cast<int>(GetTotalSize()));
+    fprintf(stderr, "Data:");
+    for (size_t i = 0; i < len_; i++) fprintf(stderr, "0x%x ", data_[i]);
+    fprintf(stderr, "\n");
+  }
+
+  // Get the data size from a serialized field to allow allocation
+  static size_t GetDataSizeFromSerialized(const uint8_t* buf) {
+    FixedSubfield len;
+    ReadFixedSubfield(&len, buf + sizeof(FixedSubfield));
+    return len;
+  }
+
+  Tag getID() const {
+    return ID_;
+  }
+
+  size_t getLen() const {
+    return len_;
+  }
+
+ private:
+ // Combined size of the fixed subfields
+ const static size_t kTagLenSize = 2 * sizeof(FixedSubfield);
+  static void WriteFixedSubfield(FixedSubfield value, uint8_t* buf) {
+    buf[0] = value & 0xFF;
+    buf[1] = (value >> 8) & 0xFF;
+  }
+  static void ReadFixedSubfield(FixedSubfield* value, const uint8_t* buf) {
+    *value = buf[0] | buf[1] << 8;
+  }
+  Tag ID_;
+  size_t len_;
+  uint8_t *data_;
+};
+
+#endif  // LLVM_WRAP_BCHEADER_FIELD_H__
diff --git a/include/bcinfo/Wrap/bitcode_wrapperer.h b/include/bcinfo/Wrap/bitcode_wrapperer.h
new file mode 100644
index 0000000..2fbce21
--- /dev/null
+++ b/include/bcinfo/Wrap/bitcode_wrapperer.h
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+// Define utility class to wrap/unwrap bitcode files. Does wrapping/unwrapping
+// in such a way that the wrappered bitcode file is still a bitcode file.
+
+#ifndef LLVM_WRAP_BITCODE_WRAPPERER_H__
+#define LLVM_WRAP_BITCODE_WRAPPERER_H__
+
+#include <stdint.h>
+#include <stddef.h>
+#include <vector>
+
+#include "bcinfo/Wrap/support_macros.h"
+#include "bcinfo/Wrap/BCHeaderField.h"
+#include "bcinfo/Wrap/wrapper_input.h"
+#include "bcinfo/Wrap/wrapper_output.h"
+
+// The bitcode wrapper header is the following 7 fixed 4-byte fields:
+//      1) 0B17C0DE - The magic number expected by llvm for wrapped bitcodes
+//      2) Version # 0 - The current version of wrapped bitcode files
+//      3) (raw) bitcode offset
+//      4) (raw) bitcode size
+//      5) Android header version
+//      6) Android target API
+//      7) PNaCl Bitcode version
+//      plus 0 or more variable-length fields (consisting of ID, length, data)
+
+// Initial buffer size. It is expanded if needed to hold large variable-size
+// fields.
+static const size_t kBitcodeWrappererBufferSize = 1024;
+
+// Support class for outputting a wrapped bitcode file from a raw bitcode
+// file (and optionally additional header fields), or for outputting a raw
+// bitcode file from a wrapped one.
+class BitcodeWrapperer {
+ public:
+  // Create a bitcode wrapperer using the following
+  // input and output files.
+  BitcodeWrapperer(WrapperInput* infile, WrapperOutput* outfile);
+
+  // Returns true if the input file begins with a bitcode
+  // wrapper magic number. As a side effect, _wrapper_ fields are set.
+  bool IsInputBitcodeWrapper();
+
+  // Returns true if the input file begins with a bitcode
+  // file magic number.
+  bool IsInputBitcodeFile();
+
+  // Add a variable-length field to the header. The caller is responsible
+  // for freeing the data pointed to by the BCHeaderField.
+  void AddHeaderField(BCHeaderField* field);
+
+  // Generate a wrapped bitcode file from the input bitcode file
+  // and the current header data. Return true on success.
+  bool GenerateWrappedBitcodeFile();
+
+  // Unwrap the wrapped bitcode file, to the corresponding
+  // outfile. Return true on success.
+  bool GenerateRawBitcodeFile();
+
+  // Print current wrapper header fields to stderr for debugging.
+  void PrintWrapperHeader();
+
+  uint32_t getAndroidHeaderVersion() {
+    return android_header_version_;
+  }
+
+  uint32_t getAndroidTargetAPI() {
+    return android_target_api_;
+  }
+
+  uint32_t getAndroidCompilerVersion() {
+    return android_compiler_version_;
+  }
+
+  uint32_t getAndroidOptimizationLevel() {
+    return android_optimization_level_;
+  }
+
+  ~BitcodeWrapperer();
+
+ private:
+  DISALLOW_CLASS_COPY_AND_ASSIGN(BitcodeWrapperer);
+
+  // Refills the buffer with more bytes. Does this in a way
+  // such that it is maximally filled.
+  void FillBuffer();
+
+  // Returns the number of bytes in infile.
+  off_t GetInFileSize() { return infile_->Size(); }
+
+  // Returns the offset of bitcode (i.e. the size of the wrapper header)
+  // if the output file were to be written now.
+  size_t BitcodeOffset();
+
+  // Returns true if we can read a word. If necessary, fills the buffer
+  // with enough characters so that there are at least a 32-bit value
+  // in the buffer. Returns false if there isn't a 32-bit value
+  // to read from the input file.
+  bool CanReadWord();
+
+  // Read a (32-bit) word from the input. Return true
+  // if able to read the word.
+  bool ReadWord(uint32_t& word);
+
+  // Write a (32-bit) word to the output. Return true if successful
+  bool WriteWord(uint32_t word);
+
+  // Write all variable-sized header fields to the output. Return true
+  // if successful.
+  bool WriteVariableFields();
+
+  // Parse the bitcode wrapper header in the infile, if any. Return true
+  // if successful.
+  bool ParseWrapperHeader();
+
+  // Returns the i-th character in front of the cursor in the buffer.
+  uint8_t BufferLookahead(int i) { return buffer_[cursor_ + i]; }
+
+  // Returns how many unread bytes are in the buffer.
+  size_t GetBufferUnreadBytes() { return buffer_size_ - cursor_; }
+
+
+  // Backs up the read cursor to the beginning of the input buffer.
+  void ResetCursor() {
+    cursor_ = 0;
+  }
+
+  // Generates the header sequence for the wrapped bitcode being
+  // generated.
+  bool WriteBitcodeWrapperHeader();
+
+  // Copies size bytes of infile to outfile, using the buffer.
+  bool BufferCopyInToOut(uint32_t size);
+
+  // Discards the old infile and replaces it with the given file.
+  void ReplaceInFile(WrapperInput* new_infile);
+
+  // Discards the old outfile and replaces it with the given file.
+  void ReplaceOutFile(WrapperOutput* new_outfile);
+
+  // Moves to the given position in the input file. Returns false
+  // if unsuccessful.
+  bool Seek(uint32_t pos);
+
+  // Clear the buffer of all contents.
+  void ClearBuffer();
+
+  // The input file being processed. Can be either
+  // a bitcode file, a wrappered bitcode file, or a secondary
+  // file to be wrapped.
+  WrapperInput* infile_;
+
+  // The output file being generated. Can be either
+  // a bitcode file, a wrappered bitcode file, or a secondary
+  // unwrapped file.
+  WrapperOutput* outfile_;
+
+  // A buffer of bytes read from the input file.
+  std::vector<uint8_t> buffer_;
+
+  // The number of bytes that were read from the input file
+  // into the buffer.
+  size_t buffer_size_;
+
+  // The index to the current read point within the buffer.
+  size_t cursor_;
+
+  // True when eof of input is reached.
+  bool infile_at_eof_;
+
+  // The 32-bit value defining the offset of the raw bitcode in the input file.
+  uint32_t infile_bc_offset_;
+
+  // The 32-bit value defining the generated offset of the wrapped bitcode.
+  // This value changes as new fields are added with AddHeaderField
+  uint32_t wrapper_bc_offset_;
+
+  // The 32-bit value defining the size of the raw wrapped bitcode.
+  uint32_t wrapper_bc_size_;
+
+  // Android header version and target API
+  uint32_t android_header_version_;
+  uint32_t android_target_api_;
+  uint32_t android_compiler_version_;
+  uint32_t android_optimization_level_;
+
+  // PNaCl bitcode version
+  uint32_t pnacl_bc_version_;
+
+  // Vector of variable header fields
+  std::vector<BCHeaderField> header_fields_;
+  // If any bufferdata from header fields is owned, it is stored here and
+  // freed on destruction.
+  std::vector<uint8_t*> variable_field_data_;
+
+  // True if there was an error condition (e.g. the file is not bitcode)
+  bool error_;
+};
+
+#endif  // LLVM_WRAP_BITCODE_WRAPPERER_H__
diff --git a/include/bcinfo/Wrap/file_wrapper_input.h b/include/bcinfo/Wrap/file_wrapper_input.h
new file mode 100644
index 0000000..2ff955f
--- /dev/null
+++ b/include/bcinfo/Wrap/file_wrapper_input.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+// Defines utility allowing files for bitcode input wrapping.
+
+#ifndef FILE_WRAPPER_INPUT_H__
+#define FILE_WRAPPER_INPUT_H__
+
+#include <stdio.h>
+
+#include "bcinfo/Wrap/support_macros.h"
+#include "bcinfo/Wrap/wrapper_input.h"
+
+// Define a class to wrap named files.
+class FileWrapperInput : public WrapperInput {
+ public:
+  FileWrapperInput(const char* _name);
+  ~FileWrapperInput();
+  // Tries to read the requested number of bytes into the buffer. Returns the
+  // actual number of bytes read.
+  virtual size_t Read(uint8_t* buffer, size_t wanted);
+  // Returns true if at end of file. Note: May return false
+  // until Read is called, and returns 0.
+  virtual bool AtEof();
+  // Returns the size of the file (in bytes).
+  virtual off_t Size();
+  // Moves to the given offset within the file. Returns
+  // false if unable to move to that position.
+  virtual bool Seek(uint32_t pos);
+ private:
+  // The name of the file.
+  const char* _name;
+  // True once eof has been encountered.
+  bool _at_eof;
+  // True if size has been computed.
+  bool _size_found;
+  // The size of the file.
+  off_t _size;
+  // The corresponding (opened) file.
+  FILE* _file;
+ private:
+  DISALLOW_CLASS_COPY_AND_ASSIGN(FileWrapperInput);
+};
+
+#endif // FILE_WRAPPER_INPUT_H__
diff --git a/include/bcinfo/Wrap/file_wrapper_output.h b/include/bcinfo/Wrap/file_wrapper_output.h
new file mode 100644
index 0000000..fa01c93
--- /dev/null
+++ b/include/bcinfo/Wrap/file_wrapper_output.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+// Defines utility allowing files for bitcode output wrapping.
+
+#ifndef FILE_WRAPPER_OUTPUT_H__
+#define FILE_WRAPPER_OUTPUT_H__
+
+#include <stdio.h>
+
+#include "bcinfo/Wrap/support_macros.h"
+#include "bcinfo/Wrap/wrapper_output.h"
+
+// Define a class to wrap named files. */
+class FileWrapperOutput : public WrapperOutput {
+ public:
+  FileWrapperOutput(const char* name);
+  ~FileWrapperOutput();
+  // Writes a single byte, returning false if unable to write.
+  virtual bool Write(uint8_t byte);
+  // Writes the specified number of bytes in the buffer to
+  // output. Returns false if unable to write.
+  virtual bool Write(const uint8_t* buffer, size_t buffer_size);
+ private:
+  // The name of the file
+  const char* _name;
+  // The corresponding (opened) file.
+  FILE* _file;
+ private:
+  DISALLOW_CLASS_COPY_AND_ASSIGN(FileWrapperOutput);
+};
+#endif  // FILE_WRAPPER_OUTPUT_H__
diff --git a/include/bcinfo/Wrap/in_memory_wrapper_input.h b/include/bcinfo/Wrap/in_memory_wrapper_input.h
new file mode 100644
index 0000000..634dd40
--- /dev/null
+++ b/include/bcinfo/Wrap/in_memory_wrapper_input.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+// Defines utility allowing in-memory buffers for bitcode input wrapping.
+
+#ifndef IN_MEMORY_WRAPPER_INPUT_H__
+#define IN_MEMORY_WRAPPER_INPUT_H__
+
+#include <stdio.h>
+
+#include "bcinfo/Wrap/support_macros.h"
+#include "bcinfo/Wrap/wrapper_input.h"
+
+// Define a class to wrap named files.
+class InMemoryWrapperInput : public WrapperInput {
+ public:
+  InMemoryWrapperInput(const char* buffer, size_t size);
+  ~InMemoryWrapperInput();
+  // Tries to read the requested number of bytes into the buffer. Returns the
+  // actual number of bytes read.
+  virtual size_t Read(uint8_t* buffer, size_t wanted);
+  // Returns true if at end of buffer. Note: May return false
+  // until Read is called, and returns 0.
+  virtual bool AtEof();
+  // Returns the size of the buffer (in bytes).
+  virtual off_t Size();
+  // Moves to the given offset within the buffer. Returns
+  // false if unable to move to that position.
+  virtual bool Seek(uint32_t pos);
+ private:
+  // The actual in-memory buffer
+  const char* _buffer;
+  // The position in the buffer
+  size_t _pos;
+  // True once eof has been encountered.
+  bool _at_eof;
+  // The size of the buffer.
+  size_t _size;
+ private:
+  DISALLOW_CLASS_COPY_AND_ASSIGN(InMemoryWrapperInput);
+};
+
+#endif // IN_MEMORY_WRAPPER_INPUT_H__
diff --git a/include/bcinfo/Wrap/support_macros.h b/include/bcinfo/Wrap/support_macros.h
new file mode 100644
index 0000000..5d3b8ce
--- /dev/null
+++ b/include/bcinfo/Wrap/support_macros.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+// Define support macros for defining classes, etc.
+
+#ifndef LLVM_SUPPORT_SUPPORT_MACROS_H__
+#define LLVM_SUPPORT_SUPPORT_MACROS_H__
+
+// Define macro, to use within a class declaration,  to disallow constructor
+// copy. Defines copy constructor declaration under the assumption that it
+// is never defined.
+#define DISALLOW_CLASS_COPY(class_name) \
+  class_name(class_name& arg)  // Do not implement
+
+// Define macro, to use within a class declaration,  to disallow assignment.
+// Defines assignment operation declaration under the assumption that it
+// is never defined.
+#define DISALLOW_CLASS_ASSIGN(class_name) \
+  void operator=(class_name& arg)  // Do not implement
+
+// Define macro to add copy and assignment declarations to a class file,
+// for which no bodies will be defined, effectively disallowing these from
+// being defined in the class.
+#define DISALLOW_CLASS_COPY_AND_ASSIGN(class_name) \
+  DISALLOW_CLASS_COPY(class_name); \
+  DISALLOW_CLASS_ASSIGN(class_name)
+
+#endif  // LLVM_SUPPORT_SUPPORT_MACROS_H__
diff --git a/include/bcinfo/Wrap/wrapper_input.h b/include/bcinfo/Wrap/wrapper_input.h
new file mode 100644
index 0000000..d3330df
--- /dev/null
+++ b/include/bcinfo/Wrap/wrapper_input.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+// Define a generic interface to a file/memory region that contains
+// a bitcode file, a wrapped bitcode file, or a data file to wrap.
+
+#ifndef LLVM_WRAP_WRAPPER_INPUT_H__
+#define LLVM_WRAP_WRAPPER_INPUT_H__
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "support_macros.h"
+
+// The following is a generic interface to a file/memory region that contains
+// a bitcode file, a wrapped bitcode file, or data file to wrap.
+class WrapperInput {
+ public:
+  WrapperInput() {}
+  virtual ~WrapperInput() {}
+  // Tries to read the requested number of bytes into the buffer. Returns the
+  // actual number of bytes read.
+  virtual size_t Read(uint8_t* buffer, size_t wanted) = 0;
+  // Returns true if at end of input. Note: May return false until
+  // Read is called, and returns 0.
+  virtual bool AtEof() = 0;
+  // Returns the size of the input (in bytes).
+  virtual off_t Size() = 0;
+  // Moves to the given offset within the input region. Returns false
+  // if unable to move to that position.
+  virtual bool Seek(uint32_t pos) = 0;
+ private:
+  DISALLOW_CLASS_COPY_AND_ASSIGN(WrapperInput);
+};
+
+#endif  // LLVM_WRAP_WRAPPER_INPUT_H__
diff --git a/include/bcinfo/Wrap/wrapper_output.h b/include/bcinfo/Wrap/wrapper_output.h
new file mode 100644
index 0000000..6498805
--- /dev/null
+++ b/include/bcinfo/Wrap/wrapper_output.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+// Defines a generic interface to a file/memory region that
+// contains a generated wrapped bitcode file, bitcode file,
+// or data file.
+
+#ifndef LLVM_WRAP_WRAPPER_OUTPUT_H__
+#define LLVM_WRAP_WRAPPER_OUTPUT_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "bcinfo/Wrap/support_macros.h"
+
+// The following is a generic interface to a file/memory region
+// that contains a generated bitcode file, wrapped bitcode file,
+// or a data file.
+class WrapperOutput {
+ public:
+  WrapperOutput() {}
+  virtual ~WrapperOutput() {}
+  // Writes a single byte, returning false if unable to write.
+  virtual bool Write(uint8_t byte) = 0;
+  // Writes the specified number of bytes in the buffer to
+  // output. Returns false if unable to write.
+  virtual bool Write(const uint8_t* buffer, size_t buffer_size);
+ private:
+  DISALLOW_CLASS_COPY_AND_ASSIGN(WrapperOutput);
+};
+
+#endif  // LLVM_WRAP_WRAPPER_OUTPUT_H__
diff --git a/lib/CodeGen/Android.mk b/lib/CodeGen/Android.mk
deleted file mode 100644
index 0eacfa1..0000000
--- a/lib/CodeGen/Android.mk
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Copyright (C) 2011 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.
-#
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../../libbcc-config.mk
-
-ifeq ($(libbcc_USE_OLD_JIT),1)
-
-#=====================================================================
-# Common: libbccCodeGen
-#=====================================================================
-
-libbcc_codegen_SRC_FILES := \
-  CodeEmitter.cpp \
-  CodeMemoryManager.cpp
-
-
-#=====================================================================
-# Device Static Library: libbccCodeGen
-#=====================================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libbccCodeGen
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-LOCAL_CFLAGS += $(libbcc_CFLAGS)
-LOCAL_C_INCLUDES += $(libbcc_C_INCLUDES)
-LOCAL_SRC_FILES := $(libbcc_codegen_SRC_FILES)
-
-include $(LIBBCC_ROOT_PATH)/libbcc-gen-config-from-mk.mk
-include $(LIBBCC_ROOT_PATH)/libbcc-build-rules.mk
-include $(LLVM_ROOT_PATH)/llvm-device-build.mk
-include $(BUILD_STATIC_LIBRARY)
-
-
-#=====================================================================
-# Host Static Library: libbccCodeGen
-#=====================================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libbccCodeGen
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-LOCAL_IS_HOST_MODULE := true
-
-LOCAL_CFLAGS += $(libbcc_CFLAGS)
-LOCAL_CFLAGS += -D__HOST__
-LOCAL_C_INCLUDES += $(libbcc_C_INCLUDES)
-
-LOCAL_SRC_FILES := $(libbcc_codegen_SRC_FILES)
-
-include $(LIBBCC_ROOT_PATH)/libbcc-gen-config-from-mk.mk
-include $(LIBBCC_ROOT_PATH)/libbcc-build-rules.mk
-include $(LLVM_ROOT_PATH)/llvm-host-build.mk
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-endif # $(libbcc_USE_OLD_JIT)
diff --git a/lib/CodeGen/CodeEmitter.cpp b/lib/CodeGen/CodeEmitter.cpp
deleted file mode 100644
index c3f37e1..0000000
--- a/lib/CodeGen/CodeEmitter.cpp
+++ /dev/null
@@ -1,1442 +0,0 @@
-//===-- CodeEmitter.cpp - CodeEmitter Class -------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See external/llvm/LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the CodeEmitter class.
-//
-//===----------------------------------------------------------------------===//
-
-#define LOG_TAG "bcc"
-#include <cutils/log.h>
-
-#include "CodeEmitter.h"
-
-#include "Config.h"
-
-#if DEBUG_OLD_JIT_DISASSEMBLER
-#include "Disassembler/Disassembler.h"
-#endif
-
-#include "CodeMemoryManager.h"
-#include "ExecutionEngine/Runtime.h"
-#include "ExecutionEngine/ScriptCompiled.h"
-
-#include <bcc/bcc.h>
-#include <bcc/bcc_cache.h>
-#include "ExecutionEngine/bcc_internal.h"
-
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineRelocation.h"
-#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/CodeGen/JITCodeEmitter.h"
-
-#include "llvm/ExecutionEngine/GenericValue.h"
-
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include "llvm/Support/Host.h"
-
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Target/TargetJITInfo.h"
-
-#include "llvm/Constant.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalAlias.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Instruction.h"
-#include "llvm/Type.h"
-
-#include <algorithm>
-#include <vector>
-#include <set>
-#include <string>
-
-#include <stddef.h>
-
-
-namespace bcc {
-
-// Will take the ownership of @MemMgr
-CodeEmitter::CodeEmitter(ScriptCompiled *result, CodeMemoryManager *pMemMgr)
-    : mpResult(result),
-      mpMemMgr(pMemMgr),
-      mpTarget(NULL),
-      mpTJI(NULL),
-      mpTD(NULL),
-      mpCurEmitFunction(NULL),
-      mpConstantPool(NULL),
-      mpJumpTable(NULL),
-      mpMMI(NULL),
-      mpSymbolLookupFn(NULL),
-      mpSymbolLookupContext(NULL) {
-}
-
-
-CodeEmitter::~CodeEmitter() {
-}
-
-
-// Once you finish the compilation on a translation unit, you can call this
-// function to recycle the memory (which is used at compilation time and not
-// needed for runtime).
-//
-//  NOTE: You should not call this funtion until the code-gen passes for a
-//        given module is done. Otherwise, the results is undefined and may
-//        cause the system crash!
-void CodeEmitter::releaseUnnecessary() {
-  mMBBLocations.clear();
-  mLabelLocations.clear();
-  mGlobalAddressMap.clear();
-  mFunctionToLazyStubMap.clear();
-  GlobalToIndirectSymMap.clear();
-  ExternalFnToStubMap.clear();
-  PendingFunctions.clear();
-}
-
-
-void CodeEmitter::reset() {
-  releaseUnnecessary();
-
-  mpResult = NULL;
-
-  mpSymbolLookupFn = NULL;
-  mpSymbolLookupContext = NULL;
-
-  mpTJI = NULL;
-  mpTD = NULL;
-
-  mpMemMgr->reset();
-}
-
-
-void *CodeEmitter::UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
-  if (Addr == NULL) {
-    // Removing mapping
-    GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
-    void *OldVal;
-
-    if (I == mGlobalAddressMap.end()) {
-      OldVal = NULL;
-    } else {
-      OldVal = I->second;
-      mGlobalAddressMap.erase(I);
-    }
-
-    return OldVal;
-  }
-
-  void *&CurVal = mGlobalAddressMap[GV];
-  void *OldVal = CurVal;
-
-  CurVal = Addr;
-
-  return OldVal;
-}
-
-
-unsigned int CodeEmitter::GetConstantPoolSizeInBytes(
-                                    llvm::MachineConstantPool *MCP) {
-  const std::vector<llvm::MachineConstantPoolEntry> &Constants =
-      MCP->getConstants();
-
-  if (Constants.empty())
-    return 0;
-
-  unsigned int Size = 0;
-  for (int i = 0, e = Constants.size(); i != e; i++) {
-    llvm::MachineConstantPoolEntry CPE = Constants[i];
-    unsigned int AlignMask = CPE.getAlignment() - 1;
-    Size = (Size + AlignMask) & ~AlignMask;
-    llvm::Type *Ty = CPE.getType();
-    Size += mpTD->getTypeAllocSize(Ty);
-  }
-
-  return Size;
-}
-
-// This function converts a Constant* into a GenericValue. The interesting
-// part is if C is a ConstantExpr.
-void CodeEmitter::GetConstantValue(const llvm::Constant *C,
-                                   llvm::GenericValue &Result) {
-  if (C->getValueID() == llvm::Value::UndefValueVal)
-    return;
-  else if (C->getValueID() == llvm::Value::ConstantExprVal) {
-    const llvm::ConstantExpr *CE = (llvm::ConstantExpr*) C;
-    const llvm::Constant *Op0 = CE->getOperand(0);
-
-    switch (CE->getOpcode()) {
-      case llvm::Instruction::GetElementPtr: {
-        // Compute the index
-        llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
-                                                   CE->op_end());
-        uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(), Indices);
-
-        GetConstantValue(Op0, Result);
-        Result.PointerVal =
-            static_cast<uint8_t*>(Result.PointerVal) + Offset;
-
-        return;
-      }
-      case llvm::Instruction::Trunc: {
-        uint32_t BitWidth =
-            llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
-
-        GetConstantValue(Op0, Result);
-        Result.IntVal = Result.IntVal.trunc(BitWidth);
-
-        return;
-      }
-      case llvm::Instruction::ZExt: {
-        uint32_t BitWidth =
-            llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
-
-        GetConstantValue(Op0, Result);
-        Result.IntVal = Result.IntVal.zext(BitWidth);
-
-        return;
-      }
-      case llvm::Instruction::SExt: {
-        uint32_t BitWidth =
-            llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
-
-        GetConstantValue(Op0, Result);
-        Result.IntVal = Result.IntVal.sext(BitWidth);
-
-        return;
-      }
-      case llvm::Instruction::FPTrunc: {
-        // TODO(all): fixme: long double
-        GetConstantValue(Op0, Result);
-        Result.FloatVal = static_cast<float>(Result.DoubleVal);
-        return;
-      }
-      case llvm::Instruction::FPExt: {
-        // TODO(all): fixme: long double
-        GetConstantValue(Op0, Result);
-        Result.DoubleVal = static_cast<double>(Result.FloatVal);
-        return;
-      }
-      case llvm::Instruction::UIToFP: {
-        GetConstantValue(Op0, Result);
-        if (CE->getType()->isFloatTy())
-          Result.FloatVal =
-              static_cast<float>(Result.IntVal.roundToDouble());
-        else if (CE->getType()->isDoubleTy())
-          Result.DoubleVal = Result.IntVal.roundToDouble();
-        else if (CE->getType()->isX86_FP80Ty()) {
-          const uint64_t zero[] = { 0, 0 };
-          llvm::APFloat apf(llvm::APInt(80, 2, zero));
-          apf.convertFromAPInt(Result.IntVal,
-                               false,
-                               llvm::APFloat::rmNearestTiesToEven);
-          Result.IntVal = apf.bitcastToAPInt();
-        }
-        return;
-      }
-      case llvm::Instruction::SIToFP: {
-        GetConstantValue(Op0, Result);
-        if (CE->getType()->isFloatTy())
-          Result.FloatVal =
-              static_cast<float>(Result.IntVal.signedRoundToDouble());
-        else if (CE->getType()->isDoubleTy())
-          Result.DoubleVal = Result.IntVal.signedRoundToDouble();
-        else if (CE->getType()->isX86_FP80Ty()) {
-          const uint64_t zero[] = { 0, 0 };
-          llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
-          apf.convertFromAPInt(Result.IntVal,
-                               true,
-                               llvm::APFloat::rmNearestTiesToEven);
-          Result.IntVal = apf.bitcastToAPInt();
-        }
-        return;
-      }
-      // double->APInt conversion handles sign
-      case llvm::Instruction::FPToUI:
-      case llvm::Instruction::FPToSI: {
-        uint32_t BitWidth =
-            llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
-
-        GetConstantValue(Op0, Result);
-        if (Op0->getType()->isFloatTy())
-          Result.IntVal =
-           llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
-        else if (Op0->getType()->isDoubleTy())
-          Result.IntVal =
-              llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal,
-                                                 BitWidth);
-        else if (Op0->getType()->isX86_FP80Ty()) {
-          llvm::APFloat apf = llvm::APFloat(Result.IntVal);
-          uint64_t V;
-          bool Ignored;
-          apf.convertToInteger(&V,
-                               BitWidth,
-                               CE->getOpcode() == llvm::Instruction::FPToSI,
-                               llvm::APFloat::rmTowardZero,
-                               &Ignored);
-          Result.IntVal = V;  // endian?
-        }
-        return;
-      }
-      case llvm::Instruction::PtrToInt: {
-        uint32_t PtrWidth = mpTD->getPointerSizeInBits();
-
-        GetConstantValue(Op0, Result);
-        Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
-                                    (Result.PointerVal));
-
-        return;
-      }
-      case llvm::Instruction::IntToPtr: {
-        uint32_t PtrWidth = mpTD->getPointerSizeInBits();
-
-        GetConstantValue(Op0, Result);
-        if (PtrWidth != Result.IntVal.getBitWidth())
-          Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
-        bccAssert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
-
-        Result.PointerVal =
-            llvm::PointerTy(
-                static_cast<uintptr_t>(Result.IntVal.getZExtValue()));
-
-        return;
-      }
-      case llvm::Instruction::BitCast: {
-        GetConstantValue(Op0, Result);
-        const llvm::Type *DestTy = CE->getType();
-
-        switch (Op0->getType()->getTypeID()) {
-          case llvm::Type::IntegerTyID: {
-            bccAssert(DestTy->isFloatingPointTy() && "invalid bitcast");
-            if (DestTy->isFloatTy())
-              Result.FloatVal = Result.IntVal.bitsToFloat();
-            else if (DestTy->isDoubleTy())
-              Result.DoubleVal = Result.IntVal.bitsToDouble();
-            break;
-          }
-          case llvm::Type::FloatTyID: {
-            bccAssert(DestTy->isIntegerTy(32) && "Invalid bitcast");
-            Result.IntVal.floatToBits(Result.FloatVal);
-            break;
-          }
-          case llvm::Type::DoubleTyID: {
-            bccAssert(DestTy->isIntegerTy(64) && "Invalid bitcast");
-            Result.IntVal.doubleToBits(Result.DoubleVal);
-            break;
-          }
-          case llvm::Type::PointerTyID: {
-            bccAssert(DestTy->isPointerTy() && "Invalid bitcast");
-            break;  // getConstantValue(Op0) above already converted it
-          }
-          default: {
-            llvm_unreachable("Invalid bitcast operand");
-          }
-        }
-        return;
-      }
-      case llvm::Instruction::Add:
-      case llvm::Instruction::FAdd:
-      case llvm::Instruction::Sub:
-      case llvm::Instruction::FSub:
-      case llvm::Instruction::Mul:
-      case llvm::Instruction::FMul:
-      case llvm::Instruction::UDiv:
-      case llvm::Instruction::SDiv:
-      case llvm::Instruction::URem:
-      case llvm::Instruction::SRem:
-      case llvm::Instruction::And:
-      case llvm::Instruction::Or:
-      case llvm::Instruction::Xor: {
-        llvm::GenericValue LHS, RHS;
-        GetConstantValue(Op0, LHS);
-        GetConstantValue(CE->getOperand(1), RHS);
-
-        switch (Op0->getType()->getTypeID()) {
-          case llvm::Type::IntegerTyID: {
-            switch (CE->getOpcode()) {
-              case llvm::Instruction::Add: {
-                Result.IntVal = LHS.IntVal + RHS.IntVal;
-                break;
-              }
-              case llvm::Instruction::Sub: {
-                Result.IntVal = LHS.IntVal - RHS.IntVal;
-                break;
-              }
-              case llvm::Instruction::Mul: {
-                Result.IntVal = LHS.IntVal * RHS.IntVal;
-                break;
-              }
-              case llvm::Instruction::UDiv: {
-                Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
-                break;
-              }
-              case llvm::Instruction::SDiv: {
-                Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
-                break;
-              }
-              case llvm::Instruction::URem: {
-                Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
-                break;
-              }
-              case llvm::Instruction::SRem: {
-                Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
-                break;
-              }
-              case llvm::Instruction::And: {
-                Result.IntVal = LHS.IntVal & RHS.IntVal;
-                break;
-              }
-              case llvm::Instruction::Or: {
-                Result.IntVal = LHS.IntVal | RHS.IntVal;
-                break;
-              }
-              case llvm::Instruction::Xor: {
-                Result.IntVal = LHS.IntVal ^ RHS.IntVal;
-                break;
-              }
-              default: {
-                llvm_unreachable("Invalid integer opcode");
-              }
-            }
-            break;
-          }
-          case llvm::Type::FloatTyID: {
-            switch (CE->getOpcode()) {
-              case llvm::Instruction::FAdd: {
-                Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
-                break;
-              }
-              case llvm::Instruction::FSub: {
-                Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
-                break;
-              }
-              case llvm::Instruction::FMul: {
-                Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
-                break;
-              }
-              case llvm::Instruction::FDiv: {
-                Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
-                break;
-              }
-              case llvm::Instruction::FRem: {
-                Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
-                break;
-              }
-              default: {
-                llvm_unreachable("Invalid float opcode");
-              }
-            }
-            break;
-          }
-          case llvm::Type::DoubleTyID: {
-            switch (CE->getOpcode()) {
-              case llvm::Instruction::FAdd: {
-                Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
-                break;
-              }
-              case llvm::Instruction::FSub: {
-                Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
-                break;
-              }
-              case llvm::Instruction::FMul: {
-                Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
-                break;
-              }
-              case llvm::Instruction::FDiv: {
-                Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
-                break;
-              }
-              case llvm::Instruction::FRem: {
-                Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
-                break;
-              }
-              default: {
-                llvm_unreachable("Invalid double opcode");
-              }
-            }
-            break;
-          }
-          case llvm::Type::X86_FP80TyID:
-          case llvm::Type::PPC_FP128TyID:
-          case llvm::Type::FP128TyID: {
-            llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
-            switch (CE->getOpcode()) {
-              case llvm::Instruction::FAdd: {
-                apfLHS.add(llvm::APFloat(RHS.IntVal),
-                           llvm::APFloat::rmNearestTiesToEven);
-                break;
-              }
-              case llvm::Instruction::FSub: {
-                apfLHS.subtract(llvm::APFloat(RHS.IntVal),
-                                llvm::APFloat::rmNearestTiesToEven);
-                break;
-              }
-              case llvm::Instruction::FMul: {
-                apfLHS.multiply(llvm::APFloat(RHS.IntVal),
-                                llvm::APFloat::rmNearestTiesToEven);
-                break;
-              }
-              case llvm::Instruction::FDiv: {
-                apfLHS.divide(llvm::APFloat(RHS.IntVal),
-                              llvm::APFloat::rmNearestTiesToEven);
-                break;
-              }
-              case llvm::Instruction::FRem: {
-                apfLHS.mod(llvm::APFloat(RHS.IntVal),
-                           llvm::APFloat::rmNearestTiesToEven);
-                break;
-              }
-              default: {
-                llvm_unreachable("Invalid long double opcode");
-              }
-            }
-            Result.IntVal = apfLHS.bitcastToAPInt();
-            break;
-          }
-          default: {
-            llvm_unreachable("Bad add type!");
-          }
-        }  // End switch (Op0->getType()->getTypeID())
-        return;
-      }
-      default: {
-        break;
-      }
-    }   // End switch (CE->getOpcode())
-
-    std::string msg;
-    llvm::raw_string_ostream Msg(msg);
-    Msg << "ConstantExpr not handled: " << *CE;
-    llvm::report_fatal_error(Msg.str());
-  }  // C->getValueID() == llvm::Value::ConstantExprVal
-
-  switch (C->getType()->getTypeID()) {
-    case llvm::Type::FloatTyID: {
-      Result.FloatVal =
-          llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToFloat();
-      break;
-    }
-    case llvm::Type::DoubleTyID: {
-      Result.DoubleVal =
-          llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToDouble();
-      break;
-    }
-    case llvm::Type::X86_FP80TyID:
-    case llvm::Type::FP128TyID:
-    case llvm::Type::PPC_FP128TyID: {
-      Result.IntVal =
-          llvm::cast<llvm::ConstantFP>(C)->getValueAPF().bitcastToAPInt();
-      break;
-    }
-    case llvm::Type::IntegerTyID: {
-      Result.IntVal =
-          llvm::cast<llvm::ConstantInt>(C)->getValue();
-      break;
-    }
-    case llvm::Type::PointerTyID: {
-      switch (C->getValueID()) {
-        case llvm::Value::ConstantPointerNullVal: {
-          Result.PointerVal = NULL;
-          break;
-        }
-        case llvm::Value::FunctionVal: {
-          const llvm::Function *F = static_cast<const llvm::Function*>(C);
-          Result.PointerVal =
-              GetPointerToFunctionOrStub(const_cast<llvm::Function*>(F));
-          break;
-        }
-        case llvm::Value::GlobalVariableVal: {
-          const llvm::GlobalVariable *GV =
-              static_cast<const llvm::GlobalVariable*>(C);
-          Result.PointerVal =
-            GetOrEmitGlobalVariable(const_cast<llvm::GlobalVariable*>(GV));
-          break;
-        }
-        case llvm::Value::BlockAddressVal: {
-          bccAssert(false && "JIT does not support address-of-label yet!");
-        }
-        default: {
-          llvm_unreachable("Unknown constant pointer type!");
-        }
-      }
-      break;
-    }
-    default: {
-      std::string msg;
-      llvm::raw_string_ostream Msg(msg);
-      Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
-      llvm::report_fatal_error(Msg.str());
-      break;
-    }
-  }
-  return;
-}
-
-
-// Stores the data in @Val of type @Ty at address @Addr.
-void CodeEmitter::StoreValueToMemory(const llvm::GenericValue &Val,
-                                     void *Addr,
-                                     llvm::Type *Ty) {
-  const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
-
-  switch (Ty->getTypeID()) {
-    case llvm::Type::IntegerTyID: {
-      const llvm::APInt &IntVal = Val.IntVal;
-      bccAssert(((IntVal.getBitWidth() + 7) / 8 >= StoreBytes) &&
-          "Integer too small!");
-
-      const uint8_t *Src =
-        reinterpret_cast<const uint8_t*>(IntVal.getRawData());
-
-      if (llvm::sys::isLittleEndianHost()) {
-        // Little-endian host - the source is ordered from LSB to MSB.
-        // Order the destination from LSB to MSB: Do a straight copy.
-        memcpy(Addr, Src, StoreBytes);
-      } else {
-        // Big-endian host - the source is an array of 64 bit words
-        // ordered from LSW to MSW.
-        //
-        // Each word is ordered from MSB to LSB.
-        //
-        // Order the destination from MSB to LSB:
-        //  Reverse the word order, but not the bytes in a word.
-        unsigned int i = StoreBytes;
-        while (i > sizeof(uint64_t)) {
-          i -= sizeof(uint64_t);
-          ::memcpy(reinterpret_cast<uint8_t*>(Addr) + i,
-              Src,
-              sizeof(uint64_t));
-          Src += sizeof(uint64_t);
-        }
-        ::memcpy(Addr, Src + sizeof(uint64_t) - i, i);
-      }
-      break;
-    }
-    case llvm::Type::FloatTyID: {
-      *reinterpret_cast<float*>(Addr) = Val.FloatVal;
-      break;
-    }
-    case llvm::Type::DoubleTyID: {
-      *reinterpret_cast<double*>(Addr) = Val.DoubleVal;
-      break;
-    }
-    case llvm::Type::X86_FP80TyID: {
-      memcpy(Addr, Val.IntVal.getRawData(), 10);
-      break;
-    }
-    case llvm::Type::PointerTyID: {
-      // Ensure 64 bit target pointers are fully initialized on 32 bit
-      // hosts.
-      if (StoreBytes != sizeof(llvm::PointerTy))
-        memset(Addr, 0, StoreBytes);
-      *((llvm::PointerTy*) Addr) = Val.PointerVal;
-      break;
-    }
-    default: {
-      break;
-    }
-  }
-
-  if (llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
-    std::reverse(reinterpret_cast<uint8_t*>(Addr),
-        reinterpret_cast<uint8_t*>(Addr) + StoreBytes);
-
-  return;
-}
-
-
-// Recursive function to apply a @Constant value into the specified memory
-// location @Addr.
-void CodeEmitter::InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
-  switch (C->getValueID()) {
-    case llvm::Value::UndefValueVal: {
-      // Nothing to do
-      break;
-    }
-    case llvm::Value::ConstantVectorVal: {
-      // dynamic cast may hurt performance
-      const llvm::ConstantVector *CP = (llvm::ConstantVector*) C;
-
-      unsigned int ElementSize = mpTD->getTypeAllocSize
-        (CP->getType()->getElementType());
-
-      for (int i = 0, e = CP->getNumOperands(); i != e;i++)
-        InitializeConstantToMemory(
-            CP->getOperand(i),
-            reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
-      break;
-    }
-    case llvm::Value::ConstantAggregateZeroVal: {
-      memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
-      break;
-    }
-    case llvm::Value::ConstantArrayVal: {
-      const llvm::ConstantArray *CPA = (llvm::ConstantArray*) C;
-      unsigned int ElementSize = mpTD->getTypeAllocSize
-        (CPA->getType()->getElementType());
-
-      for (int i = 0, e = CPA->getNumOperands(); i != e; i++)
-        InitializeConstantToMemory(
-            CPA->getOperand(i),
-            reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
-      break;
-    }
-    case llvm::Value::ConstantStructVal: {
-      const llvm::ConstantStruct *CPS =
-          static_cast<const llvm::ConstantStruct*>(C);
-      const llvm::StructLayout *SL = mpTD->getStructLayout
-        (llvm::cast<llvm::StructType>(CPS->getType()));
-
-      for (int i = 0, e = CPS->getNumOperands(); i != e; i++)
-        InitializeConstantToMemory(
-            CPS->getOperand(i),
-            reinterpret_cast<uint8_t*>(Addr) + SL->getElementOffset(i));
-      break;
-    }
-    default: {
-      if (C->getType()->isFirstClassType()) {
-        llvm::GenericValue Val;
-        GetConstantValue(C, Val);
-        StoreValueToMemory(Val, Addr, C->getType());
-      } else {
-        llvm_unreachable("Unknown constant type to initialize memory "
-                         "with!");
-      }
-      break;
-    }
-  }
-  return;
-}
-
-
-void CodeEmitter::emitConstantPool(llvm::MachineConstantPool *MCP) {
-  if (mpTJI->hasCustomConstantPool())
-    return;
-
-  // Constant pool address resolution is handled by the target itself in ARM
-  // (TargetJITInfo::hasCustomConstantPool() returns true).
-#if !defined(PROVIDE_ARM_CODEGEN)
-  const std::vector<llvm::MachineConstantPoolEntry> &Constants =
-    MCP->getConstants();
-
-  if (Constants.empty())
-    return;
-
-  unsigned Size = GetConstantPoolSizeInBytes(MCP);
-  unsigned Align = MCP->getConstantPoolAlignment();
-
-  mpConstantPoolBase = allocateSpace(Size, Align);
-  mpConstantPool = MCP;
-
-  if (mpConstantPoolBase == NULL)
-    return;  // out of memory
-
-  unsigned Offset = 0;
-  for (int i = 0, e = Constants.size(); i != e; i++) {
-    llvm::MachineConstantPoolEntry CPE = Constants[i];
-    unsigned AlignMask = CPE.getAlignment() - 1;
-    Offset = (Offset + AlignMask) & ~AlignMask;
-
-    uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
-    mConstPoolAddresses.push_back(CAddr);
-
-    if (CPE.isMachineConstantPoolEntry())
-      llvm::report_fatal_error
-        ("Initialize memory with machine specific constant pool"
-         " entry has not been implemented!");
-
-    InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
-
-    llvm::Type *Ty = CPE.Val.ConstVal->getType();
-    Offset += mpTD->getTypeAllocSize(Ty);
-  }
-#endif
-  return;
-}
-
-
-void CodeEmitter::initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
-  if (mpTJI->hasCustomJumpTables())
-    return;
-
-  const std::vector<llvm::MachineJumpTableEntry> &JT =
-    MJTI->getJumpTables();
-  if (JT.empty())
-    return;
-
-  unsigned NumEntries = 0;
-  for (int i = 0, e = JT.size(); i != e; i++)
-    NumEntries += JT[i].MBBs.size();
-
-  unsigned EntrySize = MJTI->getEntrySize(*mpTD);
-
-  mpJumpTable = MJTI;
-  mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
-      MJTI->getEntryAlignment(*mpTD));
-
-  return;
-}
-
-
-void CodeEmitter::emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
-  if (mpTJI->hasCustomJumpTables())
-    return;
-
-  const std::vector<llvm::MachineJumpTableEntry> &JT =
-    MJTI->getJumpTables();
-  if (JT.empty() || mpJumpTableBase == 0)
-    return;
-
-  bccAssert(mpTargetMachine->getRelocationModel() == llvm::Reloc::Static &&
-            (MJTI->getEntrySize(*mpTD) == sizeof(mpTD /* a pointer type */)) &&
-            "Cross JIT'ing?");
-
-  // For each jump table, map each target in the jump table to the
-  // address of an emitted MachineBasicBlock.
-  intptr_t *SlotPtr = reinterpret_cast<intptr_t*>(mpJumpTableBase);
-  for (int i = 0, ie = JT.size(); i != ie; i++) {
-    const std::vector<llvm::MachineBasicBlock*> &MBBs = JT[i].MBBs;
-    // Store the address of the basic block for this jump table slot in the
-    // memory we allocated for the jump table in 'initJumpTableInfo'
-    for (int j = 0, je = MBBs.size(); j != je; j++)
-      *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
-  }
-}
-
-
-void *CodeEmitter::GetPointerToGlobal(llvm::GlobalValue *V,
-                                      void *Reference,
-                                      bool MayNeedFarStub) {
-  switch (V->getValueID()) {
-    case llvm::Value::FunctionVal: {
-      llvm::Function *F = (llvm::Function*) V;
-
-      // If we have code, go ahead and return that.
-      if (void *ResultPtr = GetPointerToGlobalIfAvailable(F))
-        return ResultPtr;
-
-      if (void *FnStub = GetLazyFunctionStubIfAvailable(F))
-        // Return the function stub if it's already created.
-        // We do this first so that:
-        //   we're returning the same address for the function as any
-        //   previous call.
-        //
-        // TODO(llvm.org): Yes, this is wrong. The lazy stub isn't
-        //                 guaranteed to be close enough to call.
-        return FnStub;
-
-      // If we know the target can handle arbitrary-distance calls, try to
-      //  return a direct pointer.
-      if (!MayNeedFarStub) {
-        //
-        // x86_64 architecture may encounter the bug:
-        //   http://llvm.org/bugs/show_bug.cgi?id=5201
-        // which generate instruction "call" instead of "callq".
-        //
-        // And once the real address of stub is greater than 64-bit
-        // long, the replacement will truncate to 32-bit resulting a
-        // serious problem.
-#if !defined(__x86_64__)
-        // If this is an external function pointer, we can force the JIT
-        // to 'compile' it, which really just adds it to the map.
-        if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
-          return GetPointerToFunction(F, /* AbortOnFailure = */false);
-          // Changing to false because wanting to allow later calls to
-          // mpTJI->relocate() without aborting. For caching purpose
-        }
-#endif
-      }
-
-      // Otherwise, we may need a to emit a stub, and, conservatively, we
-      // always do so.
-      return GetLazyFunctionStub(F);
-      break;
-    }
-    case llvm::Value::GlobalVariableVal: {
-      return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
-      break;
-    }
-    case llvm::Value::GlobalAliasVal: {
-      llvm::GlobalAlias *GA = (llvm::GlobalAlias*) V;
-      const llvm::GlobalValue *GV = GA->resolveAliasedGlobal(false);
-
-      switch (GV->getValueID()) {
-        case llvm::Value::FunctionVal: {
-          // TODO(all): is there's any possibility that the function is not
-          // code-gen'd?
-          return GetPointerToFunction(
-              static_cast<const llvm::Function*>(GV),
-              /* AbortOnFailure = */false);
-          // Changing to false because wanting to allow later calls to
-          // mpTJI->relocate() without aborting. For caching purpose
-          break;
-        }
-        case llvm::Value::GlobalVariableVal: {
-          if (void *P = mGlobalAddressMap[GV])
-            return P;
-
-          llvm::GlobalVariable *GVar = (llvm::GlobalVariable*) GV;
-          EmitGlobalVariable(GVar);
-
-          return mGlobalAddressMap[GV];
-          break;
-        }
-        case llvm::Value::GlobalAliasVal: {
-          bccAssert(false && "Alias should be resolved ultimately!");
-        }
-      }
-      break;
-    }
-    default: {
-      break;
-    }
-  }
-  llvm_unreachable("Unknown type of global value!");
-}
-
-
-// If the specified function has been code-gen'd, return a pointer to the
-// function. If not, compile it, or use a stub to implement lazy compilation
-// if available.
-void *CodeEmitter::GetPointerToFunctionOrStub(llvm::Function *F) {
-  // If we have already code generated the function, just return the
-  // address.
-  if (void *Addr = GetPointerToGlobalIfAvailable(F))
-    return Addr;
-
-  // Get a stub if the target supports it.
-  return GetLazyFunctionStub(F);
-}
-
-
-void *CodeEmitter::GetLazyFunctionStub(llvm::Function *F) {
-  // If we already have a lazy stub for this function, recycle it.
-  void *&Stub = mFunctionToLazyStubMap[F];
-  if (Stub)
-    return Stub;
-
-  // In any cases, we should NOT resolve function at runtime (though we are
-  // able to). We resolve this right now.
-  void *Actual = NULL;
-  if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
-    Actual = GetPointerToFunction(F, /* AbortOnFailure = */false);
-    // Changing to false because wanting to allow later calls to
-    // mpTJI->relocate() without aborting. For caching purpose
-  }
-
-  // Codegen a new stub, calling the actual address of the external
-  // function, if it was resolved.
-  llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
-  startGVStub(F, SL.Size, SL.Alignment);
-  Stub = mpTJI->emitFunctionStub(F, Actual, *this);
-  finishGVStub();
-
-  // We really want the address of the stub in the GlobalAddressMap for the
-  // JIT, not the address of the external function.
-  UpdateGlobalMapping(F, Stub);
-
-  if (!Actual) {
-    PendingFunctions.insert(F);
-  } else {
-#if DEBUG_OLD_JIT_DISASSEMBLER
-    Disassemble(DEBUG_OLD_JIT_DISASSEMBLER_FILE,
-                mpTarget, mpTargetMachine, F->getName(),
-                (unsigned char const *)Stub, SL.Size);
-#endif
-  }
-
-  return Stub;
-}
-
-
-void *CodeEmitter::GetPointerToFunction(const llvm::Function *F,
-                                        bool AbortOnFailure) {
-  void *Addr = GetPointerToGlobalIfAvailable(F);
-  if (Addr)
-    return Addr;
-
-  bccAssert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
-            "Internal error: only external defined function routes here!");
-
-  // Handle the failure resolution by ourselves.
-  Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
-                                 /* AbortOnFailure = */ false);
-
-  // If we resolved the symbol to a null address (eg. a weak external)
-  // return a null pointer let the application handle it.
-  if (Addr == NULL) {
-    if (AbortOnFailure)
-      llvm::report_fatal_error("Could not resolve external function "
-                               "address: " + F->getName());
-    else
-      return NULL;
-  }
-
-  AddGlobalMapping(F, Addr);
-
-  return Addr;
-}
-
-
-void *CodeEmitter::GetPointerToNamedSymbol(const std::string &Name,
-                                           bool AbortOnFailure) {
-  if (void *Addr = FindRuntimeFunction(Name.c_str()))
-    return Addr;
-
-  if (mpSymbolLookupFn)
-    if (void *Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
-      return Addr;
-
-  if (AbortOnFailure)
-    llvm::report_fatal_error("Program used external symbol '" + Name +
-                            "' which could not be resolved!");
-
-  return NULL;
-}
-
-
-// Return the address of the specified global variable, possibly emitting it
-// to memory if needed. This is used by the Emitter.
-void *CodeEmitter::GetOrEmitGlobalVariable(llvm::GlobalVariable *GV) {
-  void *Ptr = GetPointerToGlobalIfAvailable(GV);
-  if (Ptr)
-    return Ptr;
-
-  if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
-    // If the global is external, just remember the address.
-    Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
-    AddGlobalMapping(GV, Ptr);
-  } else {
-    // If the global hasn't been emitted to memory yet, allocate space and
-    // emit it into memory.
-    Ptr = GetMemoryForGV(GV);
-    AddGlobalMapping(GV, Ptr);
-    EmitGlobalVariable(GV);
-  }
-
-  return Ptr;
-}
-
-
-// This method abstracts memory allocation of global variable so that the
-// JIT can allocate thread local variables depending on the target.
-void *CodeEmitter::GetMemoryForGV(llvm::GlobalVariable *GV) {
-  void *Ptr;
-
-  llvm::Type *GlobalType = GV->getType()->getElementType();
-  size_t S = mpTD->getTypeAllocSize(GlobalType);
-  size_t A = mpTD->getPreferredAlignment(GV);
-
-  if (GV->isThreadLocal()) {
-    // We can support TLS by
-    //
-    //  Ptr = TJI.allocateThreadLocalMemory(S);
-    //
-    // But I tend not to.
-    // (should we disable this in the front-end (i.e., slang)?).
-    llvm::report_fatal_error
-        ("Compilation of Thread Local Storage (TLS) is disabled!");
-
-  } else if (mpTJI->allocateSeparateGVMemory()) {
-    if (A <= 8) {
-      Ptr = malloc(S);
-    } else {
-      // Allocate (S + A) bytes of memory, then use an aligned pointer
-      // within that space.
-      Ptr = malloc(S + A);
-      unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
-      Ptr = reinterpret_cast<uint8_t*>(Ptr) +
-                (MisAligned ? (A - MisAligned) : 0);
-    }
-  } else {
-    Ptr = allocateGlobal(S, A);
-  }
-
-  return Ptr;
-}
-
-
-void CodeEmitter::EmitGlobalVariable(llvm::GlobalVariable *GV) {
-  void *GA = GetPointerToGlobalIfAvailable(GV);
-
-  if (GV->isThreadLocal())
-    llvm::report_fatal_error
-        ("We don't support Thread Local Storage (TLS)!");
-
-  if (GA == NULL) {
-    // If it's not already specified, allocate memory for the global.
-    GA = GetMemoryForGV(GV);
-    AddGlobalMapping(GV, GA);
-  }
-
-  InitializeConstantToMemory(GV->getInitializer(), GA);
-
-  // You can do some statistics on global variable here.
-  return;
-}
-
-
-void *CodeEmitter::GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
-  // Make sure GV is emitted first, and create a stub containing the fully
-  // resolved address.
-  void *GVAddress = GetPointerToGlobal(V, Reference, false);
-
-  // If we already have a stub for this global variable, recycle it.
-  void *&IndirectSym = GlobalToIndirectSymMap[V];
-  // Otherwise, codegen a new indirect symbol.
-  if (!IndirectSym)
-    IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
-
-  return IndirectSym;
-}
-
-
-// Return a stub for the function at the specified address.
-void *CodeEmitter::GetExternalFunctionStub(void *FnAddr) {
-  void *&Stub = ExternalFnToStubMap[FnAddr];
-  if (Stub)
-    return Stub;
-
-  llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
-  startGVStub(0, SL.Size, SL.Alignment);
-  Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
-  finishGVStub();
-
-  return Stub;
-}
-
-
-void CodeEmitter::setTargetMachine(llvm::TargetMachine &TM) {
-  mpTargetMachine = &TM;
-
-  // Set Target
-  mpTarget = &TM.getTarget();
-  // Set TargetJITInfo
-  mpTJI = TM.getJITInfo();
-  // set TargetData
-  mpTD = TM.getTargetData();
-
-  bccAssert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
-
-  return;
-}
-
-
-// This callback is invoked when the specified function is about to be code
-// generated.  This initializes the BufferBegin/End/Ptr fields.
-void CodeEmitter::startFunction(llvm::MachineFunction &F) {
-  uintptr_t ActualSize = 0;
-
-  mpMemMgr->setMemoryWritable();
-
-  // BufferBegin, BufferEnd and CurBufferPtr are all inherited from class
-  // MachineCodeEmitter, which is the super class of the class
-  // JITCodeEmitter.
-  //
-  // BufferBegin/BufferEnd - Pointers to the start and end of the memory
-  //                         allocated for this code buffer.
-  //
-  // CurBufferPtr - Pointer to the next byte of memory to fill when emitting
-  //                code. This is guranteed to be in the range
-  //                [BufferBegin, BufferEnd].  If this pointer is at
-  //                BufferEnd, it will never move due to code emission, and
-  //                all code emission requests will be ignored (this is the
-  //                buffer overflow condition).
-  BufferBegin = CurBufferPtr =
-      mpMemMgr->startFunctionBody(F.getFunction(), ActualSize);
-  BufferEnd = BufferBegin + ActualSize;
-
-  if (mpCurEmitFunction == NULL) {
-    mpCurEmitFunction = new FuncInfo(); // TODO(all): Allocation check!
-    mpCurEmitFunction->name = NULL;
-    mpCurEmitFunction->addr = NULL;
-    mpCurEmitFunction->size = 0;
-  }
-
-  // Ensure the constant pool/jump table info is at least 4-byte aligned.
-  emitAlignment(16);
-
-  emitConstantPool(F.getConstantPool());
-  if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
-    initJumpTableInfo(MJTI);
-
-  // About to start emitting the machine code for the function.
-  emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
-
-  UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
-
-  mpCurEmitFunction->addr = CurBufferPtr;
-
-  mMBBLocations.clear();
-}
-
-
-// This callback is invoked when the specified function has finished code
-// generation. If a buffer overflow has occurred, this method returns true
-// (the callee is required to try again).
-bool CodeEmitter::finishFunction(llvm::MachineFunction &F) {
-  if (CurBufferPtr == BufferEnd) {
-    // No enough memory
-    mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
-    return false;
-  }
-
-  if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
-    emitJumpTableInfo(MJTI);
-
-  if (!mRelocations.empty()) {
-    //ptrdiff_t BufferOffset = BufferBegin - mpMemMgr->getCodeMemBase();
-
-    // Resolve the relocations to concrete pointers.
-    for (int i = 0, e = mRelocations.size(); i != e; i++) {
-      llvm::MachineRelocation &MR = mRelocations[i];
-      void *ResultPtr = NULL;
-
-      if (!MR.letTargetResolve()) {
-        if (MR.isExternalSymbol()) {
-          ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
-
-          if (MR.mayNeedFarStub()) {
-            ResultPtr = GetExternalFunctionStub(ResultPtr);
-          }
-
-        } else if (MR.isGlobalValue()) {
-          ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
-                                         BufferBegin
-                                           + MR.getMachineCodeOffset(),
-                                         MR.mayNeedFarStub());
-        } else if (MR.isIndirectSymbol()) {
-          ResultPtr =
-              GetPointerToGVIndirectSym(
-                  MR.getGlobalValue(),
-                  BufferBegin + MR.getMachineCodeOffset());
-        } else if (MR.isBasicBlock()) {
-          ResultPtr =
-              (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
-        } else if (MR.isConstantPoolIndex()) {
-          ResultPtr =
-             (void*) getConstantPoolEntryAddress(MR.getConstantPoolIndex());
-        } else {
-          bccAssert(MR.isJumpTableIndex() && "Unknown type of relocation");
-          ResultPtr =
-              (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
-        }
-
-        if (!MR.isExternalSymbol() || MR.mayNeedFarStub()) {
-          // TODO(logan): Cache external symbol relocation entry.
-          // Currently, we are not caching them.  But since Android
-          // system is using prelink, it is not a problem.
-#if 0
-          // Cache the relocation result address
-          mCachingRelocations.push_back(
-            oBCCRelocEntry(MR.getRelocationType(),
-                           MR.getMachineCodeOffset() + BufferOffset,
-                           ResultPtr));
-#endif
-        }
-
-        MR.setResultPointer(ResultPtr);
-      }
-    }
-
-    mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
-                    mpMemMgr->getGOTBase());
-  }
-
-  mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
-  // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
-  // global variables that were referenced in the relocations.
-  if (CurBufferPtr == BufferEnd)
-    return false;
-
-  // Now that we've succeeded in emitting the function.
-  mpCurEmitFunction->size = CurBufferPtr - BufferBegin;
-
-#if DEBUG_OLD_JIT_DISASSEMBLER
-  // FnStart is the start of the text, not the start of the constant pool
-  // and other per-function data.
-  uint8_t *FnStart =
-      reinterpret_cast<uint8_t*>(
-          GetPointerToGlobalIfAvailable(F.getFunction()));
-
-  // FnEnd is the end of the function's machine code.
-  uint8_t *FnEnd = CurBufferPtr;
-#endif
-
-  BufferBegin = CurBufferPtr = 0;
-
-  if (F.getFunction()->hasName()) {
-    std::string const &name = F.getFunction()->getNameStr();
-    mpResult->mEmittedFunctions[name] = mpCurEmitFunction;
-    mpCurEmitFunction = NULL;
-  }
-
-  mRelocations.clear();
-  mConstPoolAddresses.clear();
-
-  if (mpMMI)
-    mpMMI->EndFunction();
-
-  updateFunctionStub(F.getFunction());
-
-  // Mark code region readable and executable if it's not so already.
-  mpMemMgr->setMemoryExecutable();
-
-#if DEBUG_OLD_JIT_DISASSEMBLER
-  Disassemble(DEBUG_OLD_JIT_DISASSEMBLER_FILE,
-              mpTarget, mpTargetMachine, F.getFunction()->getName(),
-              (unsigned char const *)FnStart, FnEnd - FnStart);
-#endif
-
-  return false;
-}
-
-
-void CodeEmitter::startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
-                 unsigned Alignment) {
-  mpSavedBufferBegin = BufferBegin;
-  mpSavedBufferEnd = BufferEnd;
-  mpSavedCurBufferPtr = CurBufferPtr;
-
-  BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
-                                                      Alignment);
-  BufferEnd = BufferBegin + StubSize + 1;
-
-  return;
-}
-
-
-void CodeEmitter::startGVStub(void *Buffer, unsigned StubSize) {
-  mpSavedBufferBegin = BufferBegin;
-  mpSavedBufferEnd = BufferEnd;
-  mpSavedCurBufferPtr = CurBufferPtr;
-
-  BufferBegin = CurBufferPtr = reinterpret_cast<uint8_t *>(Buffer);
-  BufferEnd = BufferBegin + StubSize + 1;
-
-  return;
-}
-
-
-void CodeEmitter::finishGVStub() {
-  bccAssert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
-
-  // restore
-  BufferBegin = mpSavedBufferBegin;
-  BufferEnd = mpSavedBufferEnd;
-  CurBufferPtr = mpSavedCurBufferPtr;
-}
-
-
-// Allocates and fills storage for an indirect GlobalValue, and returns the
-// address.
-void *CodeEmitter::allocIndirectGV(const llvm::GlobalValue *GV,
-                      const uint8_t *Buffer, size_t Size,
-                      unsigned Alignment) {
-  uint8_t *IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
-  memcpy(IndGV, Buffer, Size);
-  return IndGV;
-}
-
-
-// Allocate memory for a global. Unlike allocateSpace, this method does not
-// allocate memory in the current output buffer, because a global may live
-// longer than the current function.
-void *CodeEmitter::allocateGlobal(uintptr_t Size, unsigned Alignment) {
-  // Delegate this call through the memory manager.
-  return mpMemMgr->allocateGlobal(Size, Alignment);
-}
-
-
-// This should be called by the target when a new basic block is about to be
-// emitted. This way the MCE knows where the start of the block is, and can
-// implement getMachineBasicBlockAddress.
-void CodeEmitter::StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
-  if (mMBBLocations.size() <= (unsigned) MBB->getNumber())
-    mMBBLocations.resize((MBB->getNumber() + 1) * 2);
-  mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
-  return;
-}
-
-
-// Return the address of the jump table with index @Index in the function
-// that last called initJumpTableInfo.
-uintptr_t CodeEmitter::getJumpTableEntryAddress(unsigned Index) const {
-  const std::vector<llvm::MachineJumpTableEntry> &JT =
-      mpJumpTable->getJumpTables();
-
-  bccAssert((Index < JT.size()) && "Invalid jump table index!");
-
-  unsigned int Offset = 0;
-  unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
-
-  for (unsigned i = 0; i < Index; i++)
-    Offset += JT[i].MBBs.size();
-  Offset *= EntrySize;
-
-  return (uintptr_t)(reinterpret_cast<uint8_t*>(mpJumpTableBase) + Offset);
-}
-
-
-// Return the address of the specified MachineBasicBlock, only usable after
-// the label for the MBB has been emitted.
-uintptr_t CodeEmitter::getMachineBasicBlockAddress(
-                                        llvm::MachineBasicBlock *MBB) const {
-  bccAssert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
-            mMBBLocations[MBB->getNumber()] &&
-            "MBB not emitted!");
-  return mMBBLocations[MBB->getNumber()];
-}
-
-
-void CodeEmitter::updateFunctionStub(const llvm::Function *F) {
-  // Get the empty stub we generated earlier.
-  void *Stub;
-  std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
-  if (I != PendingFunctions.end())
-    Stub = mFunctionToLazyStubMap[F];
-  else
-    return;
-
-  void *Addr = GetPointerToGlobalIfAvailable(F);
-
-  bccAssert(Addr != Stub &&
-            "Function must have non-stub address to be updated.");
-
-  // Tell the target jit info to rewrite the stub at the specified address,
-  // rather than creating a new one.
-  llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
-  startGVStub(Stub, SL.Size);
-  mpTJI->emitFunctionStub(F, Addr, *this);
-  finishGVStub();
-
-#if DEBUG_OLD_JIT_DISASSEMBLER
-  Disassemble(DEBUG_OLD_JIT_DISASSEMBLER_FILE,
-              mpTarget, mpTargetMachine, F->getName(),
-              (unsigned char const *)Stub, SL.Size);
-#endif
-
-  PendingFunctions.erase(I);
-}
-
-
-} // namespace bcc
diff --git a/lib/CodeGen/CodeEmitter.h b/lib/CodeGen/CodeEmitter.h
deleted file mode 100644
index fc6dab1..0000000
--- a/lib/CodeGen/CodeEmitter.h
+++ /dev/null
@@ -1,339 +0,0 @@
-//===-- CodeEmitter.h - CodeEmitter Class -----------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See external/llvm/LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the CodeEmitter class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef BCC_CODEEMITTER_H
-#define BCC_CODEEMITTER_H
-
-#include <bcc/bcc.h>
-#include <bcc/bcc_assert.h>
-#include <bcc/bcc_cache.h>
-#include "ExecutionEngine/bcc_internal.h"
-
-#include "Config.h"
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineRelocation.h"
-#include "llvm/CodeGen/JITCodeEmitter.h"
-#include "llvm/Support/ValueHandle.h"
-
-#include <map>
-#include <vector>
-#include <set>
-
-#include <stdint.h>
-
-namespace llvm {
-  class Constant;
-  class GenericValue;
-  class GlobalVariable;
-  class GlobalValue;
-  class Function;
-  class MachineBasicBlock;
-  class MachineFunction;
-  class MachineJumpTableInfo;
-  class MachineModuleInfo;
-  class MCSymbol;
-  class Target;
-  class TargetData;
-  class TargetJITInfo;
-  class TargetMachine;
-  class Type;
-}
-
-namespace bcc {
-  class CodeMemoryManager;
-  class ScriptCompiled;
-
-  class CodeEmitter : public llvm::JITCodeEmitter {
-  private:
-    typedef llvm::DenseMap<const llvm::GlobalValue *, void *>
-      GlobalAddressMapTy;
-
-    typedef llvm::DenseMap<const llvm::Function *, void*>
-      FunctionToLazyStubMapTy;
-
-    typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void *>
-      GlobalToIndirectSymMapTy;
-
-  public:
-    typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
-
-
-  private:
-    ScriptCompiled *mpResult;
-
-    CodeMemoryManager *mpMemMgr;
-
-    llvm::TargetMachine *mpTargetMachine;
-
-    // The JITInfo for the target we are compiling to
-    const llvm::Target *mpTarget;
-
-    llvm::TargetJITInfo *mpTJI;
-
-    const llvm::TargetData *mpTD;
-
-
-    FuncInfo *mpCurEmitFunction;
-
-    GlobalAddressMapTy mGlobalAddressMap;
-
-    // This vector is a mapping from MBB ID's to their address. It is filled in
-    // by the StartMachineBasicBlock callback and queried by the
-    // getMachineBasicBlockAddress callback.
-    std::vector<uintptr_t> mMBBLocations;
-
-    // The constant pool for the current function.
-    llvm::MachineConstantPool *mpConstantPool;
-
-    // A pointer to the first entry in the constant pool.
-    void *mpConstantPoolBase;
-
-    // Addresses of individual constant pool entries.
-    llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
-
-    // The jump tables for the current function.
-    llvm::MachineJumpTableInfo *mpJumpTable;
-
-    // A pointer to the first entry in the jump table.
-    void *mpJumpTableBase;
-
-    // When outputting a function stub in the context of some other function, we
-    // save BufferBegin/BufferEnd/CurBufferPtr here.
-    uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
-
-    // These are the relocations that the function needs, as emitted.
-    std::vector<llvm::MachineRelocation> mRelocations;
-
-#if 0
-    std::vector<oBCCRelocEntry> mCachingRelocations;
-#endif
-
-    // This vector is a mapping from Label ID's to their address.
-    llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
-
-    // Machine module info for exception informations
-    llvm::MachineModuleInfo *mpMMI;
-
-
-    FunctionToLazyStubMapTy mFunctionToLazyStubMap;
-
-    std::set<const llvm::Function*> PendingFunctions;
-
-    GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
-
-    std::map<void*, void*> ExternalFnToStubMap;
-
-  public:
-    // Resolver to undefined symbol in CodeEmitter
-    BCCSymbolLookupFn mpSymbolLookupFn;
-    void *mpSymbolLookupContext;
-
-    // Will take the ownership of @MemMgr
-    explicit CodeEmitter(ScriptCompiled *result, CodeMemoryManager *pMemMgr);
-
-    virtual ~CodeEmitter();
-
-    global_addresses_const_iterator global_address_begin() const {
-      return mGlobalAddressMap.begin();
-    }
-
-    global_addresses_const_iterator global_address_end() const {
-      return mGlobalAddressMap.end();
-    }
-
-#if 0
-    std::vector<oBCCRelocEntry> const &getCachingRelocations() const {
-      return mCachingRelocations;
-    }
-#endif
-
-    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
-      mpSymbolLookupFn = pFn;
-      mpSymbolLookupContext = pContext;
-    }
-
-    void setTargetMachine(llvm::TargetMachine &TM);
-
-    // This callback is invoked when the specified function is about to be code
-    // generated.  This initializes the BufferBegin/End/Ptr fields.
-    virtual void startFunction(llvm::MachineFunction &F);
-
-    // This callback is invoked when the specified function has finished code
-    // generation. If a buffer overflow has occurred, this method returns true
-    // (the callee is required to try again).
-    virtual bool finishFunction(llvm::MachineFunction &F);
-
-    // Allocates and fills storage for an indirect GlobalValue, and returns the
-    // address.
-    virtual void *allocIndirectGV(const llvm::GlobalValue *GV,
-                                  const uint8_t *Buffer, size_t Size,
-                                  unsigned Alignment);
-
-    // Emits a label
-    virtual void emitLabel(llvm::MCSymbol *Label) {
-      mLabelLocations[Label] = getCurrentPCValue();
-    }
-
-    // Allocate memory for a global. Unlike allocateSpace, this method does not
-    // allocate memory in the current output buffer, because a global may live
-    // longer than the current function.
-    virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment);
-
-    // This should be called by the target when a new basic block is about to be
-    // emitted. This way the MCE knows where the start of the block is, and can
-    // implement getMachineBasicBlockAddress.
-    virtual void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB);
-
-    // Whenever a relocatable address is needed, it should be noted with this
-    // interface.
-    virtual void addRelocation(const llvm::MachineRelocation &MR) {
-      mRelocations.push_back(MR);
-    }
-
-    // Return the address of the @Index entry in the constant pool that was
-    // last emitted with the emitConstantPool method.
-    virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
-      bccAssert(Index < mpConstantPool->getConstants().size() &&
-                "Invalid constant pool index!");
-      return mConstPoolAddresses[Index];
-    }
-
-    // Return the address of the jump table with index @Index in the function
-    // that last called initJumpTableInfo.
-    virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const;
-
-    // Return the address of the specified MachineBasicBlock, only usable after
-    // the label for the MBB has been emitted.
-    virtual uintptr_t getMachineBasicBlockAddress(
-                                        llvm::MachineBasicBlock *MBB) const;
-
-    // Return the address of the specified LabelID, only usable after the
-    // LabelID has been emitted.
-    virtual uintptr_t getLabelAddress(llvm::MCSymbol *Label) const {
-      bccAssert(mLabelLocations.count(Label) && "Label not emitted!");
-      return mLabelLocations.find(Label)->second;
-    }
-
-    // Specifies the MachineModuleInfo object. This is used for exception
-    // handling purposes.
-    virtual void setModuleInfo(llvm::MachineModuleInfo *Info) {
-      mpMMI = Info;
-    }
-
-    void releaseUnnecessary();
-
-    void reset();
-
-  private:
-    void startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
-                     unsigned Alignment);
-
-    void startGVStub(void *Buffer, unsigned StubSize);
-
-    void finishGVStub();
-
-    // Replace an existing mapping for GV with a new address. This updates both
-    // maps as required. If Addr is null, the entry for the global is removed
-    // from the mappings.
-    void *UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr);
-
-    // Tell the execution engine that the specified global is at the specified
-    // location. This is used internally as functions are JIT'd and as global
-    // variables are laid out in memory.
-    void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
-       void *&CurVal = mGlobalAddressMap[GV];
-       assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
-       CurVal = Addr;
-    }
-
-    // This returns the address of the specified global value if it is has
-    // already been codegen'd, otherwise it returns null.
-    void *GetPointerToGlobalIfAvailable(const llvm::GlobalValue *GV) {
-      GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
-      return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
-    }
-
-    unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool *MCP);
-
-    // This function converts a Constant* into a GenericValue. The interesting
-    // part is if C is a ConstantExpr.
-    void GetConstantValue(const llvm::Constant *C, llvm::GenericValue &Result);
-
-    // Stores the data in @Val of type @Ty at address @Addr.
-    void StoreValueToMemory(const llvm::GenericValue &Val, void *Addr,
-                            llvm::Type *Ty);
-
-    // Recursive function to apply a @Constant value into the specified memory
-    // location @Addr.
-    void InitializeConstantToMemory(const llvm::Constant *C, void *Addr);
-
-    void emitConstantPool(llvm::MachineConstantPool *MCP);
-
-    void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI);
-
-    void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI);
-
-    void *GetPointerToGlobal(llvm::GlobalValue *V,
-                             void *Reference,
-                             bool MayNeedFarStub);
-
-    // If the specified function has been code-gen'd, return a pointer to the
-    // function. If not, compile it, or use a stub to implement lazy compilation
-    // if available.
-    void *GetPointerToFunctionOrStub(llvm::Function *F);
-
-    void *GetLazyFunctionStubIfAvailable(llvm::Function *F) {
-      return mFunctionToLazyStubMap.lookup(F);
-    }
-
-    void *GetLazyFunctionStub(llvm::Function *F);
-
-    void updateFunctionStub(const llvm::Function *F);
-
-    void *GetPointerToFunction(const llvm::Function *F, bool AbortOnFailure);
-
-    void *GetPointerToNamedSymbol(const std::string &Name,
-                                  bool AbortOnFailure);
-
-    // Return the address of the specified global variable, possibly emitting it
-    // to memory if needed. This is used by the Emitter.
-    void *GetOrEmitGlobalVariable(llvm::GlobalVariable *GV);
-
-    // This method abstracts memory allocation of global variable so that the
-    // JIT can allocate thread local variables depending on the target.
-    void *GetMemoryForGV(llvm::GlobalVariable *GV);
-
-    void EmitGlobalVariable(llvm::GlobalVariable *GV);
-
-    void *GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference);
-
-    // This is the equivalent of FunctionToLazyStubMap for external functions.
-    //
-    // TODO(llvm.org): Of course, external functions don't need a lazy stub.
-    //                 It's actually here to make it more likely that far calls
-    //                 succeed, but no single stub can guarantee that. I'll
-    //                 remove this in a subsequent checkin when I actually fix
-    //                 far calls.
-
-    // Return a stub for the function at the specified address.
-    void *GetExternalFunctionStub(void *FnAddr);
-
-  };
-
-} // namespace bcc
-
-#endif // BCC_CODEEMITTER_H
diff --git a/lib/CodeGen/CodeMemoryManager.cpp b/lib/CodeGen/CodeMemoryManager.cpp
deleted file mode 100644
index 5f015cc..0000000
--- a/lib/CodeGen/CodeMemoryManager.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-//===-- CodeMemoryManager.cpp - CodeMemoryManager Class -------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See external/llvm/LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the CodeMemoryManager class.
-//
-//===----------------------------------------------------------------------===//
-
-#define LOG_TAG "bcc"
-#include <bcc/bcc_assert.h>
-
-#include <cutils/log.h>
-
-#include "CodeMemoryManager.h"
-#include "ExecutionEngine/OldJIT/ContextManager.h"
-
-#include "llvm/Support/ErrorHandling.h"
-
-#include <sys/mman.h>
-
-#include <stddef.h>
-
-#include <map>
-#include <string>
-#include <utility>
-
-
-namespace bcc {
-
-
-const unsigned int MaxCodeSize = ContextManager::ContextCodeSize;
-const unsigned int MaxGOTSize = 1 * 1024;
-const unsigned int MaxGlobalVarSize = ContextManager::ContextDataSize;
-
-
-CodeMemoryManager::CodeMemoryManager()
-  : mpCodeMem(NULL), mpGVMem(NULL), mpGOTBase(NULL) {
-
-  reset();
-  std::string ErrMsg;
-
-  mpCodeMem = ContextManager::get().allocateContext();
-
-  if (!mpCodeMem) {
-    ALOGE("Unable to allocate mpCodeMem\n");
-    llvm::report_fatal_error("Failed to allocate memory for emitting "
-                             "codes\n" + ErrMsg);
-  }
-
-  // Set global variable pool
-  mpGVMem = mpCodeMem + MaxCodeSize;
-
-  return;
-}
-
-
-CodeMemoryManager::~CodeMemoryManager() {
-  mpCodeMem = 0;
-  mpGVMem = 0;
-}
-
-
-uint8_t *CodeMemoryManager::allocateSGMemory(uintptr_t Size,
-                                             unsigned Alignment) {
-
-  intptr_t FreeMemSize = getFreeCodeMemSize();
-  if ((FreeMemSize < 0) || (static_cast<uintptr_t>(FreeMemSize) < Size))
-    // The code size excesses our limit
-    return NULL;
-
-  if (Alignment == 0)
-    Alignment = 1;
-
-  uint8_t *result = getCodeMemBase() + mCurSGMemIdx - Size;
-  result = (uint8_t*) (((intptr_t) result) & ~(intptr_t) (Alignment - 1));
-
-  mCurSGMemIdx = result - getCodeMemBase();
-
-  return result;
-}
-
-
-// setMemoryWritable - When code generation is in progress, the code pages
-//                     may need permissions changed.
-void CodeMemoryManager::setMemoryWritable() {
-  mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC);
-}
-
-
-// When code generation is done and we're ready to start execution, the
-// code pages may need permissions changed.
-void CodeMemoryManager::setMemoryExecutable() {
-  mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_EXEC);
-}
-
-
-// Setting this flag to true makes the memory manager garbage values over
-// freed memory.  This is useful for testing and debugging, and is to be
-// turned on by default in debug mode.
-void CodeMemoryManager::setPoisonMemory(bool poison) {
-  // no effect
-}
-
-
-// Global Offset Table Management
-
-// If the current table requires a Global Offset Table, this method is
-// invoked to allocate it.  This method is required to set HasGOT to true.
-void CodeMemoryManager::AllocateGOT() {
-  bccAssert(mpGOTBase != NULL && "Cannot allocate the GOT multiple times");
-  mpGOTBase = allocateSGMemory(MaxGOTSize);
-  HasGOT = true;
-}
-
-
-// Main Allocation Functions
-
-// When we start JITing a function, the JIT calls this method to allocate a
-// block of free RWX memory, which returns a pointer to it. If the JIT wants
-// to request a block of memory of at least a certain size, it passes that
-// value as ActualSize, and this method returns a block with at least that
-// much space. If the JIT doesn't know ahead of time how much space it will
-// need to emit the function, it passes 0 for the ActualSize. In either
-// case, this method is required to pass back the size of the allocated
-// block through ActualSize. The JIT will be careful to not write more than
-// the returned ActualSize bytes of memory.
-uint8_t *CodeMemoryManager::startFunctionBody(const llvm::Function *F,
-                                              uintptr_t &ActualSize) {
-  intptr_t FreeMemSize = getFreeCodeMemSize();
-  if ((FreeMemSize < 0) ||
-      (static_cast<uintptr_t>(FreeMemSize) < ActualSize))
-    // The code size excesses our limit
-    return NULL;
-
-  ActualSize = getFreeCodeMemSize();
-  return (getCodeMemBase() + mCurFuncMemIdx);
-}
-
-// This method is called when the JIT is done codegen'ing the specified
-// function. At this point we know the size of the JIT compiled function.
-// This passes in FunctionStart (which was returned by the startFunctionBody
-// method) and FunctionEnd which is a pointer to the actual end of the
-// function. This method should mark the space allocated and remember where
-// it is in case the client wants to deallocate it.
-void CodeMemoryManager::endFunctionBody(const llvm::Function *F,
-                                        uint8_t *FunctionStart,
-                                        uint8_t *FunctionEnd) {
-  bccAssert(FunctionEnd > FunctionStart);
-  bccAssert(FunctionStart == (getCodeMemBase() + mCurFuncMemIdx) &&
-            "Mismatched function start/end!");
-
-  // Advance the pointer
-  intptr_t FunctionCodeSize = FunctionEnd - FunctionStart;
-  bccAssert(FunctionCodeSize <= getFreeCodeMemSize() &&
-            "Code size excess the limitation!");
-  mCurFuncMemIdx += FunctionCodeSize;
-
-  // Record there's a function in our memory start from @FunctionStart
-  bccAssert(mFunctionMap.find(F) == mFunctionMap.end() &&
-            "Function already emitted!");
-  mFunctionMap.insert(
-      std::make_pair<const llvm::Function*, std::pair<void*, void*> >(
-          F, std::make_pair(FunctionStart, FunctionEnd)));
-
-  return;
-}
-
-// Allocate a (function code) memory block of the given size. This method
-// cannot be called between calls to startFunctionBody and endFunctionBody.
-uint8_t *CodeMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) {
-  if (getFreeCodeMemSize() < Size) {
-    // The code size excesses our limit
-    return NULL;
-  }
-
-  if (Alignment == 0)
-    Alignment = 1;
-
-  uint8_t *result = getCodeMemBase() + mCurFuncMemIdx;
-  result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
-                       ~(intptr_t) (Alignment - 1));
-
-  mCurFuncMemIdx = (result + Size) - getCodeMemBase();
-
-  return result;
-}
-
-// Allocate memory for a global variable.
-uint8_t *CodeMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) {
-  if (getFreeGVMemSize() < Size) {
-    // The code size excesses our limit
-    ALOGE("No Global Memory");
-    return NULL;
-  }
-
-  if (Alignment == 0)
-    Alignment = 1;
-
-  uint8_t *result = getGVMemBase() + mCurGVMemIdx;
-  result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
-                       ~(intptr_t) (Alignment - 1));
-
-  mCurGVMemIdx = (result + Size) - getGVMemBase();
-
-  return result;
-}
-
-// Free the specified function body. The argument must be the return value
-// from a call to startFunctionBody() that hasn't been deallocated yet. This
-// is never called when the JIT is currently emitting a function.
-void CodeMemoryManager::deallocateFunctionBody(void *Body) {
-  // linear search
-  uint8_t *FunctionStart = NULL, *FunctionEnd = NULL;
-  for (FunctionMapTy::iterator I = mFunctionMap.begin(),
-          E = mFunctionMap.end(); I != E; I++) {
-    if (I->second.first == Body) {
-      FunctionStart = reinterpret_cast<uint8_t*>(I->second.first);
-      FunctionEnd = reinterpret_cast<uint8_t*>(I->second.second);
-      break;
-    }
-  }
-
-  bccAssert((FunctionStart == NULL) && "Memory is never allocated!");
-
-  // free the memory
-  intptr_t SizeNeedMove = (getCodeMemBase() + mCurFuncMemIdx) - FunctionEnd;
-
-  bccAssert(SizeNeedMove >= 0 &&
-            "Internal error: CodeMemoryManager::mCurFuncMemIdx may not"
-            " be correctly calculated!");
-
-  if (SizeNeedMove > 0) {
-    // there's data behind deallocating function
-    memmove(FunctionStart, FunctionEnd, SizeNeedMove);
-  }
-
-  mCurFuncMemIdx -= (FunctionEnd - FunctionStart);
-}
-
-// Below are the methods we create
-void CodeMemoryManager::reset() {
-  mpGOTBase = NULL;
-  HasGOT = false;
-
-  mCurFuncMemIdx = 0;
-  mCurSGMemIdx = MaxCodeSize - 1;
-  mCurGVMemIdx = 0;
-
-  mFunctionMap.clear();
-}
-
-} // namespace bcc
diff --git a/lib/CodeGen/CodeMemoryManager.h b/lib/CodeGen/CodeMemoryManager.h
deleted file mode 100644
index ed003ec..0000000
--- a/lib/CodeGen/CodeMemoryManager.h
+++ /dev/null
@@ -1,246 +0,0 @@
-//===-- CodeMemoryManager.h - CodeMemoryManager Class -----------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See external/llvm/LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the CodeMemoryManager class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef BCC_CODEMEMORYMANAGER_H
-#define BCC_CODEMEMORYMANAGER_H
-
-#include "ExecutionEngine/Compiler.h"
-
-#include "llvm/ExecutionEngine/JITMemoryManager.h"
-
-#include <bcc/bcc_assert.h>
-
-#include <map>
-#include <utility>
-
-#include <stddef.h>
-#include <stdint.h>
-
-
-namespace llvm {
-  // Forward Declaration
-  class Function;
-  class GlobalValue;
-};
-
-
-namespace bcc {
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Memory manager for the code reside in memory
-  //
-  // The memory for our code emitter is very simple and is conforming to the
-  // design decisions of Android RenderScript's Exection Environment:
-  //   The code, data, and symbol sizes are limited (currently 100KB.)
-  //
-  // It's very different from typical compiler, which has no limitation
-  // on the code size. How does code emitter know the size of the code
-  // it is about to emit? It does not know beforehand. We want to solve
-  // this without complicating the code emitter too much.
-  //
-  // We solve this by pre-allocating a certain amount of memory,
-  // and then start the code emission. Once the buffer overflows, the emitter
-  // simply discards all the subsequent emission but still has a counter
-  // on how many bytes have been emitted.
-  //
-  // So once the whole emission is done, if there's a buffer overflow,
-  // it re-allocates the buffer with enough size (based on the
-  //  counter from previous emission) and re-emit again.
-
-  extern const unsigned int MaxCodeSize;
-  extern const unsigned int MaxGOTSize;
-  extern const unsigned int MaxGlobalVarSize;
-
-
-  class CodeMemoryManager : public llvm::JITMemoryManager {
-  private:
-    typedef std::map<const llvm::Function*,
-                     std::pair<void * /* start address */,
-                               void * /* end address */> > FunctionMapTy;
-
-
-  private:
-    //
-    // Our memory layout is as follows:
-    //
-    //  The direction of arrows (-> and <-) shows memory's growth direction
-    //  when more space is needed.
-    //
-    // @mpCodeMem:
-    //  +--------------------------------------------------------------+
-    //  | Function Memory ... ->                <- ...        Stub/GOT |
-    //  +--------------------------------------------------------------+
-    //  |<------------------ Total: @MaxCodeSize KiB ----------------->|
-    //
-    //  Where size of GOT is @MaxGOTSize KiB.
-    //
-    // @mpGVMem:
-    //  +--------------------------------------------------------------+
-    //  | Global variable ... ->                                       |
-    //  +--------------------------------------------------------------+
-    //  |<--------------- Total: @MaxGlobalVarSize KiB --------------->|
-    //
-    //
-    // @mCurFuncMemIdx: The current index (starting from 0) of the last byte
-    //                    of function code's memory usage
-    // @mCurSGMemIdx: The current index (starting from tail) of the last byte
-    //                    of stub/GOT's memory usage
-    // @mCurGVMemIdx: The current index (starting from tail) of the last byte
-    //                    of global variable's memory usage
-    //
-    uintptr_t mCurFuncMemIdx;
-    uintptr_t mCurSGMemIdx;
-    uintptr_t mCurGVMemIdx;
-    char *mpCodeMem;
-    char *mpGVMem;
-
-    // GOT Base
-    uint8_t *mpGOTBase;
-
-    FunctionMapTy mFunctionMap;
-
-
-  public:
-    CodeMemoryManager();
-
-    virtual ~CodeMemoryManager();
-
-    uint8_t *getCodeMemBase() const {
-      return reinterpret_cast<uint8_t*>(mpCodeMem);
-    }
-
-    // setMemoryWritable - When code generation is in progress, the code pages
-    //                     may need permissions changed.
-    virtual void setMemoryWritable();
-
-    // When code generation is done and we're ready to start execution, the
-    // code pages may need permissions changed.
-    virtual void setMemoryExecutable();
-
-    // Setting this flag to true makes the memory manager garbage values over
-    // freed memory.  This is useful for testing and debugging, and is to be
-    // turned on by default in debug mode.
-    virtual void setPoisonMemory(bool poison);
-
-
-    // Global Offset Table Management
-
-    // If the current table requires a Global Offset Table, this method is
-    // invoked to allocate it.  This method is required to set HasGOT to true.
-    virtual void AllocateGOT();
-
-    // If this is managing a Global Offset Table, this method should return a
-    // pointer to its base.
-    virtual uint8_t *getGOTBase() const {
-      return mpGOTBase;
-    }
-
-    // Main Allocation Functions
-
-    // When we start JITing a function, the JIT calls this method to allocate a
-    // block of free RWX memory, which returns a pointer to it. If the JIT wants
-    // to request a block of memory of at least a certain size, it passes that
-    // value as ActualSize, and this method returns a block with at least that
-    // much space. If the JIT doesn't know ahead of time how much space it will
-    // need to emit the function, it passes 0 for the ActualSize. In either
-    // case, this method is required to pass back the size of the allocated
-    // block through ActualSize. The JIT will be careful to not write more than
-    // the returned ActualSize bytes of memory.
-    virtual uint8_t *startFunctionBody(const llvm::Function *F,
-                                       uintptr_t &ActualSize);
-
-    // This method is called by the JIT to allocate space for a function stub
-    // (used to handle limited branch displacements) while it is JIT compiling a
-    // function. For example, if foo calls bar, and if bar either needs to be
-    // lazily compiled or is a native function that exists too far away from the
-    // call site to work, this method will be used to make a thunk for it. The
-    // stub should be "close" to the current function body, but should not be
-    // included in the 'actualsize' returned by startFunctionBody.
-    virtual uint8_t *allocateStub(const llvm::GlobalValue *F,
-                                  unsigned StubSize,
-                                  unsigned Alignment) {
-      return allocateSGMemory(StubSize, Alignment);
-    }
-
-    // This method is called when the JIT is done codegen'ing the specified
-    // function. At this point we know the size of the JIT compiled function.
-    // This passes in FunctionStart (which was returned by the startFunctionBody
-    // method) and FunctionEnd which is a pointer to the actual end of the
-    // function. This method should mark the space allocated and remember where
-    // it is in case the client wants to deallocate it.
-    virtual void endFunctionBody(const llvm::Function *F,
-                                 uint8_t *FunctionStart,
-                                 uint8_t *FunctionEnd);
-
-    // Allocate a (function code) memory block of the given size. This method
-    // cannot be called between calls to startFunctionBody and endFunctionBody.
-    virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
-
-    // Allocate memory for a global variable.
-    virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
-
-    // Free the specified function body. The argument must be the return value
-    // from a call to startFunctionBody() that hasn't been deallocated yet. This
-    // is never called when the JIT is currently emitting a function.
-    virtual void deallocateFunctionBody(void *Body);
-
-    // When we finished JITing the function, if exception handling is set, we
-    // emit the exception table.
-    virtual uint8_t *startExceptionTable(const llvm::Function *F,
-                                         uintptr_t &ActualSize) {
-      bccAssert(false &&
-                "Exception is not allowed in our language specification");
-      return NULL;
-    }
-
-    // This method is called when the JIT is done emitting the exception table.
-    virtual void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
-                                   uint8_t *TableEnd, uint8_t *FrameRegister) {
-      bccAssert(false &&
-                "Exception is not allowed in our language specification");
-    }
-
-    // Free the specified exception table's memory. The argument must be the
-    // return value from a call to startExceptionTable() that hasn't been
-    // deallocated yet. This is never called when the JIT is currently emitting
-    // an exception table.
-    virtual void deallocateExceptionTable(void *ET) {
-      bccAssert(false &&
-                "Exception is not allowed in our language specification");
-    }
-
-    // Below are the methods we create
-    void reset();
-
-
-  private:
-    intptr_t getFreeCodeMemSize() const {
-      return mCurSGMemIdx - mCurFuncMemIdx;
-    }
-
-    uint8_t *allocateSGMemory(uintptr_t Size,
-                              unsigned Alignment = 1 /* no alignment */);
-
-    uintptr_t getFreeGVMemSize() const {
-      return MaxGlobalVarSize - mCurGVMemIdx;
-    }
-
-    uint8_t *getGVMemBase() const {
-      return reinterpret_cast<uint8_t*>(mpGVMem);
-    }
-
-  };
-
-} // namespace bcc
-
-#endif  // BCC_CODEMEMORYMANAGER_H
diff --git a/lib/ExecutionEngine/Android.mk b/lib/ExecutionEngine/Android.mk
index 2e2a4fa..c015bcc 100644
--- a/lib/ExecutionEngine/Android.mk
+++ b/lib/ExecutionEngine/Android.mk
@@ -27,34 +27,15 @@
   FileHandle.cpp \
   GDBJIT.cpp \
   GDBJITRegistrar.cpp \
+  MCCacheWriter.cpp \
+  MCCacheReader.cpp \
   Runtime.c \
   RuntimeStub.c \
   Script.cpp \
-  ScriptCompiled.cpp \
-  SourceInfo.cpp
-
-ifeq ($(libbcc_USE_OLD_JIT),1)
-libbcc_executionengine_SRC_FILES += \
-  OldJIT/ContextManager.cpp
-endif
-
-ifeq ($(libbcc_USE_CACHE),1)
-ifeq ($(libbcc_USE_OLD_JIT),1)
-libbcc_executionengine_SRC_FILES += \
-  OldJIT/CacheReader.cpp \
-  OldJIT/CacheWriter.cpp
-endif
-
-ifeq ($(libbcc_USE_MCJIT),1)
-libbcc_executionengine_SRC_FILES += \
-  MCCacheWriter.cpp \
-  MCCacheReader.cpp
-endif
-
-libbcc_executionengine_SRC_FILES += \
   ScriptCached.cpp \
-  Sha1Helper.cpp
-endif
+  ScriptCompiled.cpp \
+  Sha1Helper.cpp \
+  SourceInfo.cpp
 
 
 #=====================================================================
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index e7bdd52..8a55e38 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -19,10 +19,6 @@
 #include "Config.h"
 #include <bcinfo/MetadataExtractor.h>
 
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
-
 #if USE_DISASSEMBLER
 #include "Disassembler/Disassembler.h"
 #endif
@@ -34,9 +30,7 @@
 #include "Sha1Helper.h"
 #include "CompilerOption.h"
 
-#if USE_MCJIT
 #include "librsloader.h"
-#endif
 
 #include "Transforms/BCCTransforms.h"
 
@@ -210,12 +204,10 @@
   // Register the scheduler
   llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
 
-#if USE_CACHE
   // Read in SHA1 checksum of libbcc and libRS.
   readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
 
   calcFileSHA1(sha1LibRS, pathLibRS);
-#endif
 
   GlobalInitialized = true;
 }
@@ -229,27 +221,9 @@
 }
 
 
-#if USE_OLD_JIT
-CodeMemoryManager *Compiler::createCodeMemoryManager() {
-  mCodeMemMgr.reset(new CodeMemoryManager());
-  return mCodeMemMgr.get();
-}
-#endif
-
-
-#if USE_OLD_JIT
-CodeEmitter *Compiler::createCodeEmitter() {
-  mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
-  return mCodeEmitter.get();
-}
-#endif
-
-
 Compiler::Compiler(ScriptCompiled *result)
   : mpResult(result),
-#if USE_MCJIT
     mRSExecutable(NULL),
-#endif
     mpSymbolLookupFn(NULL),
     mpSymbolLookupContext(NULL),
     mModule(NULL),
@@ -413,14 +387,6 @@
   }
 
   // Perform code generation
-#if USE_OLD_JIT
-  if (runCodeGen(new llvm::TargetData(*TD), TM,
-                 ExportVarMetadata, ExportFuncMetadata) != 0) {
-    goto on_bcc_compile_error;
-  }
-#endif
-
-#if USE_MCJIT
   if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
     goto on_bcc_compile_error;
   }
@@ -468,7 +434,7 @@
     }
   }
 
-#if DEBUG_MCJIT_DISASSEMBLER
+#if DEBUG_MC_DISASSEMBLER
   {
     // Get MC codegen emitted function name list
     size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
@@ -480,13 +446,12 @@
       void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
       if (func) {
         size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
-        Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
+        Disassemble(DEBUG_MC_DISASSEMBLER_FILE,
                     Target, TM, func_list[i], (unsigned char const *)func, size);
       }
     }
   }
 #endif
-#endif
 
 on_bcc_compile_error:
   // ALOGE("on_bcc_compiler_error");
@@ -507,133 +472,6 @@
 }
 
 
-#if USE_OLD_JIT
-int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
-                         llvm::NamedMDNode const *ExportVarMetadata,
-                         llvm::NamedMDNode const *ExportFuncMetadata) {
-  // Create memory manager for creation of code emitter later.
-  if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
-    setError("Failed to startup memory management for further compilation");
-    return 1;
-  }
-
-  mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
-
-  // Create code emitter
-  if (!mCodeEmitter.get()) {
-    if (!createCodeEmitter()) {
-      setError("Failed to create machine code emitter for compilation");
-      return 1;
-    }
-  } else {
-    // Reuse the code emitter
-    mCodeEmitter->reset();
-  }
-
-  mCodeEmitter->setTargetMachine(*TM);
-  mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
-                                       mpSymbolLookupContext);
-
-  // Create code-gen pass to run the code emitter
-  llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
-    new llvm::FunctionPassManager(mModule));
-
-  // Add TargetData to code generation pass manager
-  CodeGenPasses->add(TD);
-
-  // Add code emit passes
-  if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
-                                     *mCodeEmitter,
-                                     CodeGenOptLevel)) {
-    setError("The machine code emission is not supported on '" + Triple + "'");
-    return 1;
-  }
-
-  // Run the code emitter on every non-declaration function in the module
-  CodeGenPasses->doInitialization();
-  for (llvm::Module::iterator
-       I = mModule->begin(), E = mModule->end(); I != E; I++) {
-    if (!I->isDeclaration()) {
-      CodeGenPasses->run(*I);
-    }
-  }
-
-  CodeGenPasses->doFinalization();
-
-  // Copy the global address mapping from code emitter and remapping
-  if (ExportVarMetadata) {
-    ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
-
-    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
-      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
-      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
-        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
-        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
-          llvm::StringRef ExportVarName =
-            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
-
-          CodeEmitter::global_addresses_const_iterator I, E;
-          for (I = mCodeEmitter->global_address_begin(),
-               E = mCodeEmitter->global_address_end();
-               I != E; I++) {
-            if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
-              continue;
-            if (ExportVarName == I->first->getName()) {
-              varList.push_back(I->second);
-#if DEBUG_BCC_REFLECT
-              ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
-#endif
-              break;
-            }
-          }
-          if (I != mCodeEmitter->global_address_end())
-            continue;  // found
-
-#if DEBUG_BCC_REFLECT
-          ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
-               ExportVarName.str().c_str(), (void *)0);
-#endif
-        }
-      }
-      // if reaching here, we know the global variable record in metadata is
-      // not found. So we make an empty slot
-      varList.push_back(NULL);
-    }
-
-    bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
-              "Number of slots doesn't match the number of export variables!");
-  }
-
-  if (ExportFuncMetadata) {
-    ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
-
-    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
-      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
-      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
-        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
-        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
-          llvm::StringRef ExportFuncName =
-            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
-          funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
-#if DEBUG_BCC_REFLECT
-          ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
-               funcList.back());
-#endif
-        }
-      }
-    }
-  }
-
-  // Tell code emitter now can release the memory using during the JIT since
-  // we have done the code emission
-  mCodeEmitter->releaseUnnecessary();
-
-  return 0;
-}
-#endif // USE_OLD_JIT
-
-
-#if USE_MCJIT
 int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
   // Decorate mEmittedELFExecutable with formatted ostream
   llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
@@ -658,7 +496,6 @@
   OutSVOS.flush();
   return 0;
 }
-#endif // USE_MCJIT
 
 int Compiler::runInternalPasses(std::vector<std::string>& Names,
                                 std::vector<uint32_t>& Signatures) {
@@ -804,14 +641,11 @@
 }
 
 
-#if USE_MCJIT
 void *Compiler::getSymbolAddress(char const *name) {
   return rsloaderGetSymbolAddress(mRSExecutable, name);
 }
-#endif
 
 
-#if USE_MCJIT
 void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
   Compiler *self = reinterpret_cast<Compiler *>(context);
 
@@ -828,13 +662,10 @@
   ALOGE("Unable to resolve symbol: %s\n", name);
   return NULL;
 }
-#endif
 
 
 Compiler::~Compiler() {
-#if USE_MCJIT
   rsloaderDisposeExec(mRSExecutable);
-#endif
 
   // llvm::llvm_shutdown();
 }
diff --git a/lib/ExecutionEngine/Compiler.h b/lib/ExecutionEngine/Compiler.h
index eebe550..863cda6 100644
--- a/lib/ExecutionEngine/Compiler.h
+++ b/lib/ExecutionEngine/Compiler.h
@@ -19,12 +19,9 @@
 
 #include <bcc/bcc.h>
 
-#include "CodeGen/CodeEmitter.h"
-#include "CodeGen/CodeMemoryManager.h"
+#include <Config.h>
 
-#if USE_MCJIT
 #include "librsloader.h"
-#endif
 
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
@@ -85,21 +82,11 @@
 
     std::string mError;
 
-#if USE_OLD_JIT
-    // The memory manager for code emitter
-    llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
-
-    // The CodeEmitter
-    llvm::OwningPtr<CodeEmitter> mCodeEmitter;
-#endif
-
-#if USE_MCJIT
-    // Compilation buffer for MCJIT
+    // Compilation buffer for MC
     llvm::SmallVector<char, 1024> mEmittedELFExecutable;
 
     // Loaded and relocated executable
     RSExecRef mRSExecutable;
-#endif
 
     BCCSymbolLookupFn mpSymbolLookupFn;
     void *mpSymbolLookupContext;
@@ -126,19 +113,11 @@
       mpSymbolLookupContext = pContext;
     }
 
-#if USE_OLD_JIT
-    CodeMemoryManager *createCodeMemoryManager();
-
-    CodeEmitter *createCodeEmitter();
-#endif
-
-#if USE_MCJIT
     void *getSymbolAddress(char const *name);
 
     const llvm::SmallVector<char, 1024> &getELF() const {
       return mEmittedELFExecutable;
     }
-#endif
 
     int readModule(llvm::Module *module) {
       mModule = module;
@@ -167,9 +146,8 @@
 
     int runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM);
 
-#if USE_MCJIT
     static void *resolveSymbolAdapter(void *context, char const *name);
-#endif
+
     int runInternalPasses(std::vector<std::string>& Names,
                           std::vector<uint32_t>& Signatures);
 
diff --git a/lib/ExecutionEngine/MCCacheReader.cpp b/lib/ExecutionEngine/MCCacheReader.cpp
index 5beff88..6005536 100644
--- a/lib/ExecutionEngine/MCCacheReader.cpp
+++ b/lib/ExecutionEngine/MCCacheReader.cpp
@@ -39,8 +39,6 @@
 
 using namespace std;
 
-
-#if USE_MCJIT
 namespace bcc {
 
 MCCacheReader::~MCCacheReader() {
@@ -148,15 +146,15 @@
 
 
 bool MCCacheReader::checkHeader() {
-  if (memcmp(mpHeader->magic, OBCC_MAGIC, 4) != 0) {
+  if (memcmp(mpHeader->magic, MCO_MAGIC, 4) != 0) {
     ALOGE("Bad magic word\n");
     return false;
   }
 
-  if (memcmp(mpHeader->version, OBCC_VERSION, 4) != 0) {
+  if (memcmp(mpHeader->version, MCO_VERSION, 4) != 0) {
     mpHeader->version[4 - 1] = '\0'; // ensure c-style string terminated
     ALOGI("Cache file format version mismatch: now %s cached %s\n",
-         OBCC_VERSION, mpHeader->version);
+         MCO_VERSION, mpHeader->version);
     return false;
   }
   return true;
@@ -242,7 +240,7 @@
 
 
 bool MCCacheReader::readStringPool() {
-  CACHE_READER_READ_SECTION(OBCC_StringPool,
+  CACHE_READER_READ_SECTION(MCO_StringPool,
                             mpResult->mpStringPoolRaw, str_pool);
 
   char *str_base = reinterpret_cast<char *>(str_pool_raw);
@@ -258,7 +256,7 @@
 
 
 bool MCCacheReader::checkStringPool() {
-  OBCC_StringPool *poolR = mpResult->mpStringPoolRaw;
+  MCO_StringPool *poolR = mpResult->mpStringPoolRaw;
   vector<char const *> &pool = mpResult->mStringPool;
 
   // Ensure that every c-style string is ended with '\0'
@@ -274,7 +272,7 @@
 
 
 bool MCCacheReader::readDependencyTable() {
-  CACHE_READER_READ_SECTION(OBCC_DependencyTable, mpCachedDependTable,
+  CACHE_READER_READ_SECTION(MCO_DependencyTable, mpCachedDependTable,
                             depend_tab);
   return true;
 }
@@ -297,7 +295,7 @@
     uint32_t depType = dep->second.first;
     unsigned char const *depSHA1 = dep->second.second;
 
-    OBCC_Dependency *depCached =&mpCachedDependTable->table[i];
+    MCO_Dependency *depCached =&mpCachedDependTable->table[i];
     char const *depCachedName = strPool[depCached->res_name_strp_index];
     uint32_t depCachedType = depCached->res_type;
     unsigned char const *depCachedSHA1 = depCached->sha1;
@@ -337,10 +335,10 @@
 }
 
 bool MCCacheReader::readVarNameList() {
-  CACHE_READER_READ_SECTION(OBCC_String_Ptr, mpVarNameList, export_var_name_list);
+  CACHE_READER_READ_SECTION(MCO_String_Ptr, mpVarNameList, export_var_name_list);
   vector<char const *> const &strPool = mpResult->mStringPool;
 
-  mpResult->mpExportVars = (OBCC_ExportVarList*)
+  mpResult->mpExportVars = (MCO_ExportVarList*)
                             malloc(sizeof(size_t) +
                                    sizeof(void*) * export_var_name_list_raw->count);
   if (!mpResult->mpExportVars) {
@@ -352,7 +350,7 @@
   for (size_t i = 0; i < export_var_name_list_raw->count; ++i) {
     mpResult->mpExportVars->cached_addr_list[i] =
       rsloaderGetSymbolAddress(mpResult->mRSExecutable, strPool[export_var_name_list_raw->strp_indexs[i]]);
-#if DEBUG_MCJIT_REFLECT
+#if DEBUG_MC_REFLECT
     ALOGD("Get symbol address: %s -> %p",
       strPool[export_var_name_list_raw->strp_indexs[i]], mpResult->mpExportVars->cached_addr_list[i]);
 #endif
@@ -361,10 +359,10 @@
 }
 
 bool MCCacheReader::readFuncNameList() {
-  CACHE_READER_READ_SECTION(OBCC_String_Ptr, mpFuncNameList, export_func_name_list);
+  CACHE_READER_READ_SECTION(MCO_String_Ptr, mpFuncNameList, export_func_name_list);
   vector<char const *> const &strPool = mpResult->mStringPool;
 
-  mpResult->mpExportFuncs = (OBCC_ExportFuncList*)
+  mpResult->mpExportFuncs = (MCO_ExportFuncList*)
                             malloc(sizeof(size_t) +
                                    sizeof(void*) * export_func_name_list_raw->count);
   if (!mpResult->mpExportFuncs) {
@@ -376,7 +374,7 @@
   for (size_t i = 0; i < export_func_name_list_raw->count; ++i) {
     mpResult->mpExportFuncs->cached_addr_list[i] =
       rsloaderGetSymbolAddress(mpResult->mRSExecutable, strPool[export_func_name_list_raw->strp_indexs[i]]);
-#if DEBUG_MCJIT_REFLECT
+#if DEBUG_MC_REFLECT
     ALOGD("Get function address: %s -> %p",
       strPool[export_func_name_list_raw->strp_indexs[i]], mpResult->mpExportFuncs->cached_addr_list[i]);
 #endif
@@ -385,10 +383,10 @@
 }
 
 bool MCCacheReader::readForEachNameList() {
-  CACHE_READER_READ_SECTION(OBCC_String_Ptr, mpForEachNameList, export_foreach_name_list);
+  CACHE_READER_READ_SECTION(MCO_String_Ptr, mpForEachNameList, export_foreach_name_list);
   vector<char const *> const &strPool = mpResult->mStringPool;
 
-  mpResult->mpExportForEach = (OBCC_ExportForEachList*)
+  mpResult->mpExportForEach = (MCO_ExportForEachList*)
                               malloc(sizeof(size_t) +
                                      sizeof(void*) * export_foreach_name_list_raw->count);
   if (!mpResult->mpExportForEach) {
@@ -400,7 +398,7 @@
   for (size_t i = 0; i < export_foreach_name_list_raw->count; ++i) {
     mpResult->mpExportForEach->cached_addr_list[i] =
       rsloaderGetSymbolAddress(mpResult->mRSExecutable, strPool[export_foreach_name_list_raw->strp_indexs[i]]);
-#if DEBUG_MCJIT_REFLECT
+#if DEBUG_MC_REFLECT
     ALOGE("Get foreach function address: %s -> %p",
       strPool[export_foreach_name_list_raw->strp_indexs[i]], mpResult->mpExportForEach->cached_addr_list[i]);
 #endif
@@ -409,13 +407,13 @@
 }
 
 bool MCCacheReader::readPragmaList() {
-  CACHE_READER_READ_SECTION(OBCC_PragmaList, mpPragmaList, pragma_list);
+  CACHE_READER_READ_SECTION(MCO_PragmaList, mpPragmaList, pragma_list);
 
   vector<char const *> const &strPool = mpResult->mStringPool;
   ScriptCached::PragmaList &pragmas = mpResult->mPragmas;
 
   for (size_t i = 0; i < pragma_list_raw->count; ++i) {
-    OBCC_Pragma *pragma = &pragma_list_raw->list[i];
+    MCO_Pragma *pragma = &pragma_list_raw->list[i];
     pragmas.push_back(make_pair(strPool[pragma->key_strp_index],
                                 strPool[pragma->value_strp_index]));
   }
@@ -425,7 +423,7 @@
 
 
 bool MCCacheReader::readObjectSlotList() {
-  CACHE_READER_READ_SECTION(OBCC_ObjectSlotList,
+  CACHE_READER_READ_SECTION(MCO_ObjectSlotList,
                             mpResult->mpObjectSlotList, object_slot_list);
   return true;
 }
@@ -484,4 +482,3 @@
 }
 
 } // namespace bcc
-#endif
diff --git a/lib/ExecutionEngine/MCCacheReader.h b/lib/ExecutionEngine/MCCacheReader.h
index 1e59111..df4aca3 100644
--- a/lib/ExecutionEngine/MCCacheReader.h
+++ b/lib/ExecutionEngine/MCCacheReader.h
@@ -40,13 +40,13 @@
     off_t mInfoFileSize;
 
     MCO_Header *mpHeader;
-    OBCC_DependencyTable *mpCachedDependTable;
-    OBCC_PragmaList *mpPragmaList;
-    OBCC_FuncTable *mpFuncTable;
+    MCO_DependencyTable *mpCachedDependTable;
+    MCO_PragmaList *mpPragmaList;
+    MCO_FuncTable *mpFuncTable;
 
-    OBCC_String_Ptr *mpVarNameList;
-    OBCC_String_Ptr *mpFuncNameList;
-    OBCC_String_Ptr *mpForEachNameList;
+    MCO_String_Ptr *mpVarNameList;
+    MCO_String_Ptr *mpFuncNameList;
+    MCO_String_Ptr *mpForEachNameList;
 
     llvm::OwningPtr<ScriptCached> mpResult;
 
@@ -68,7 +68,7 @@
 
     ~MCCacheReader();
 
-    void addDependency(OBCC_ResourceType resType,
+    void addDependency(MCO_ResourceType resType,
                        std::string const &resName,
                        unsigned char const *sha1) {
       mDependencies.insert(std::make_pair(resName,
diff --git a/lib/ExecutionEngine/MCCacheWriter.cpp b/lib/ExecutionEngine/MCCacheWriter.cpp
index cca724e..b0bf117 100644
--- a/lib/ExecutionEngine/MCCacheWriter.cpp
+++ b/lib/ExecutionEngine/MCCacheWriter.cpp
@@ -31,7 +31,6 @@
 
 using namespace std;
 
-#if USE_MCJIT
 namespace bcc {
 
 MCCacheWriter::~MCCacheWriter() {
@@ -88,8 +87,8 @@
   memset(header, '\0', sizeof(MCO_Header));
 
   // Magic word and version
-  memcpy(header->magic, OBCC_MAGIC, 4);
-  memcpy(header->version, OBCC_VERSION, 4);
+  memcpy(header->magic, MCO_MAGIC, 4);
+  memcpy(header->version, MCO_VERSION, 4);
 
   // Machine Integer Type
   uint32_t number = 0x00000001;
@@ -107,10 +106,10 @@
 
 
 bool MCCacheWriter::prepareDependencyTable() {
-  size_t tableSize = sizeof(OBCC_DependencyTable) +
-                     sizeof(OBCC_Dependency) * mDependencies.size();
+  size_t tableSize = sizeof(MCO_DependencyTable) +
+                     sizeof(MCO_Dependency) * mDependencies.size();
 
-  OBCC_DependencyTable *tab = (OBCC_DependencyTable *)malloc(tableSize);
+  MCO_DependencyTable *tab = (MCO_DependencyTable *)malloc(tableSize);
 
   if (!tab) {
     ALOGE("Unable to allocate for dependency table section.\n");
@@ -125,7 +124,7 @@
   size_t i = 0;
   for (map<string, pair<uint32_t, unsigned char const *> >::iterator
        I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) {
-    OBCC_Dependency *dep = &tab->table[i];
+    MCO_Dependency *dep = &tab->table[i];
 
     dep->res_name_strp_index = addString(I->first.c_str(), I->first.size());
     dep->res_type = I->second.first;
@@ -138,10 +137,10 @@
 bool MCCacheWriter::preparePragmaList() {
   size_t pragmaCount = mpOwner->getPragmaCount();
 
-  size_t listSize = sizeof(OBCC_PragmaList) +
-                    sizeof(OBCC_Pragma) * pragmaCount;
+  size_t listSize = sizeof(MCO_PragmaList) +
+                    sizeof(MCO_Pragma) * pragmaCount;
 
-  OBCC_PragmaList *list = (OBCC_PragmaList *)malloc(listSize);
+  MCO_PragmaList *list = (MCO_PragmaList *)malloc(listSize);
 
   if (!list) {
     ALOGE("Unable to allocate for pragma list\n");
@@ -164,7 +163,7 @@
     size_t keyLen = strlen(key);
     size_t valueLen = strlen(value);
 
-    OBCC_Pragma *pragma = &list->list[i];
+    MCO_Pragma *pragma = &list->list[i];
     pragma->key_strp_index = addString(key, keyLen);
     pragma->value_strp_index = addString(value, valueLen);
   }
@@ -174,8 +173,8 @@
 
 bool MCCacheWriter::prepareStringPool() {
   // Calculate string pool size
-  size_t size = sizeof(OBCC_StringPool) +
-                sizeof(OBCC_String) * mStringPool.size();
+  size_t size = sizeof(MCO_StringPool) +
+                sizeof(MCO_String) * mStringPool.size();
 
   off_t strOffset = size;
 
@@ -184,7 +183,7 @@
   }
 
   // Create string pool
-  OBCC_StringPool *pool = (OBCC_StringPool *)malloc(size);
+  MCO_StringPool *pool = (MCO_StringPool *)malloc(size);
 
   if (!pool) {
     ALOGE("Unable to allocate string pool.\n");
@@ -199,7 +198,7 @@
   char *strPtr = reinterpret_cast<char *>(pool) + strOffset;
 
   for (size_t i = 0; i < mStringPool.size(); ++i) {
-    OBCC_String *str = &pool->list[i];
+    MCO_String *str = &pool->list[i];
 
     str->length = mStringPool[i].second;
     str->offset = strOffset;
@@ -217,9 +216,9 @@
 
 bool MCCacheWriter::prepareExportVarNameList() {
   size_t varCount = mpOwner->getExportVarCount();
-  size_t listSize = sizeof(OBCC_String_Ptr) + sizeof(size_t) * varCount;
+  size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * varCount;
 
-  OBCC_String_Ptr *list = (OBCC_String_Ptr*)malloc(listSize);
+  MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
 
   if (!list) {
     ALOGE("Unable to allocate for export variable name list\n");
@@ -241,9 +240,9 @@
 
 bool MCCacheWriter::prepareExportFuncNameList() {
   size_t funcCount = mpOwner->getExportFuncCount();
-  size_t listSize = sizeof(OBCC_String_Ptr) + sizeof(size_t) * funcCount;
+  size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * funcCount;
 
-  OBCC_String_Ptr *list = (OBCC_String_Ptr*)malloc(listSize);
+  MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
 
   if (!list) {
     ALOGE("Unable to allocate for export function name list\n");
@@ -265,9 +264,9 @@
 
 bool MCCacheWriter::prepareExportForEachNameList() {
   size_t forEachCount = mpOwner->getExportForEachCount();
-  size_t listSize = sizeof(OBCC_String_Ptr) + sizeof(size_t) * forEachCount;
+  size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * forEachCount;
 
-  OBCC_String_Ptr *list = (OBCC_String_Ptr*)malloc(listSize);
+  MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
 
   if (!list) {
     ALOGE("Unable to allocate for export forEach name list\n");
@@ -290,10 +289,10 @@
 bool MCCacheWriter::prepareObjectSlotList() {
   size_t objectSlotCount = mpOwner->getObjectSlotCount();
 
-  size_t listSize = sizeof(OBCC_ObjectSlotList) +
+  size_t listSize = sizeof(MCO_ObjectSlotList) +
                     sizeof(uint32_t) * objectSlotCount;
 
-  OBCC_ObjectSlotList *list = (OBCC_ObjectSlotList *)malloc(listSize);
+  MCO_ObjectSlotList *list = (MCO_ObjectSlotList *)malloc(listSize);
 
   if (!list) {
     ALOGE("Unable to allocate for object slot list\n");
@@ -387,4 +386,3 @@
 }
 
 } // namespace bcc
-#endif
diff --git a/lib/ExecutionEngine/MCCacheWriter.h b/lib/ExecutionEngine/MCCacheWriter.h
index 58f6ef5..b2bcb12 100644
--- a/lib/ExecutionEngine/MCCacheWriter.h
+++ b/lib/ExecutionEngine/MCCacheWriter.h
@@ -41,14 +41,14 @@
              std::pair<uint32_t, unsigned char const *> > mDependencies;
 
     MCO_Header *mpHeaderSection;
-    OBCC_StringPool *mpStringPoolSection;
-    OBCC_DependencyTable *mpDependencyTableSection;
-    OBCC_PragmaList *mpPragmaListSection;
-    OBCC_ObjectSlotList *mpObjectSlotSection;
+    MCO_StringPool *mpStringPoolSection;
+    MCO_DependencyTable *mpDependencyTableSection;
+    MCO_PragmaList *mpPragmaListSection;
+    MCO_ObjectSlotList *mpObjectSlotSection;
 
-    OBCC_String_Ptr *mpExportVarNameListSection;
-    OBCC_String_Ptr *mpExportFuncNameListSection;
-    OBCC_String_Ptr *mpExportForEachNameListSection;
+    MCO_String_Ptr *mpExportVarNameListSection;
+    MCO_String_Ptr *mpExportFuncNameListSection;
+    MCO_String_Ptr *mpExportForEachNameListSection;
 
     std::vector<std::string> varNameList;
     std::vector<std::string> funcNameList;
@@ -66,7 +66,7 @@
     bool writeCacheFile(FileHandle *objFile, FileHandle *infoFile,
                         Script *S, uint32_t libRS_threadable);
 
-    void addDependency(OBCC_ResourceType resType,
+    void addDependency(MCO_ResourceType resType,
                        std::string const &resName,
                        unsigned char const *sha1) {
       mDependencies.insert(std::make_pair(resName,
diff --git a/lib/ExecutionEngine/OldJIT/CacheReader.cpp b/lib/ExecutionEngine/OldJIT/CacheReader.cpp
deleted file mode 100644
index 8eceb5f..0000000
--- a/lib/ExecutionEngine/OldJIT/CacheReader.cpp
+++ /dev/null
@@ -1,453 +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.
- */
-
-#include "CacheReader.h"
-
-#include "ContextManager.h"
-#include "DebugHelper.h"
-#include "FileHandle.h"
-#include "ScriptCached.h"
-
-#include <bcc/bcc_cache.h>
-
-#include <llvm/ADT/OwningPtr.h>
-
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <utility>
-#include <vector>
-
-#include <new>
-
-#include <stdlib.h>
-#include <string.h>
-
-using namespace std;
-
-
-namespace bcc {
-
-CacheReader::~CacheReader() {
-  if (mpHeader) { free(mpHeader); }
-  if (mpCachedDependTable) { free(mpCachedDependTable); }
-  if (mpPragmaList) { free(mpPragmaList); }
-  if (mpFuncTable) { free(mpFuncTable); }
-}
-
-ScriptCached *CacheReader::readCacheFile(FileHandle *objFile,
-                                         FileHandle *infoFile,
-                                         Script *S) {
-  // Check file handle
-  if (!objFile || objFile->getFD() < 0 ||
-      !infoFile || infoFile->getFD() < 0) {
-    return NULL;
-  }
-
-  mObjFile = objFile;
-  mInfoFile = infoFile;
-
-  // Allocate ScriptCached object
-  mpResult.reset(new (nothrow) ScriptCached(S));
-
-  if (!mpResult) {
-    ALOGE("Unable to allocate ScriptCached object.\n");
-    return NULL;
-  }
-
-  bool result = checkFileSize()
-             && readHeader()
-             && checkHeader()
-             && checkMachineIntType()
-             && checkSectionOffsetAndSize()
-             && readStringPool()
-             && checkStringPool()
-             && readDependencyTable()
-             && checkDependency()
-             && readExportVarList()
-             && readExportFuncList()
-             && readPragmaList()
-             && readFuncTable()
-             && readObjectSlotList()
-             && readContext()
-             && checkContext()
-             //&& readRelocationTable()
-             //&& relocate()
-             ;
-
-  return result ? mpResult.take() : NULL;
-}
-
-
-bool CacheReader::checkFileSize() {
-  struct stat stfile;
-
-  if (fstat(mInfoFile->getFD(), &stfile) < 0) {
-    ALOGE("Unable to stat metadata information file.\n");
-    return false;
-  }
-
-  mInfoFileSize = stfile.st_size;
-
-  if (mInfoFileSize < (off_t)sizeof(OBCC_Header)) {
-    ALOGE("Metadata information file is too small to be correct.\n");
-    return false;
-  }
-
-  if (fstat(mObjFile->getFD(), &stfile) < 0) {
-    ALOGE("Unable to stat executable file.\n");
-    return false;
-  }
-
-  if (stfile.st_size < (off_t)ContextManager::ContextSize) {
-    ALOGE("Executable file is too small to be correct.\n");
-    return false;
-  }
-
-  return true;
-}
-
-
-bool CacheReader::readHeader() {
-  if (mInfoFile->seek(0, SEEK_SET) != 0) {
-    ALOGE("Unable to seek to 0. (reason: %s)\n", strerror(errno));
-    return false;
-  }
-
-  mpHeader = (OBCC_Header *)malloc(sizeof(OBCC_Header));
-  if (!mpHeader) {
-    ALOGE("Unable to allocate for cache header.\n");
-    return false;
-  }
-
-  if (mInfoFile->read((char *)mpHeader, sizeof(OBCC_Header)) !=
-      (ssize_t)sizeof(OBCC_Header)) {
-    ALOGE("Unable to read cache header.\n");
-    return false;
-  }
-
-  // Dirty hack for libRS.
-  // TODO(all): This should be removed in the future.
-  if (mpHeader->libRS_threadable) {
-    mpResult->mLibRSThreadable = true;
-  }
-
-  return true;
-}
-
-
-bool CacheReader::checkHeader() {
-  if (memcmp(mpHeader->magic, OBCC_MAGIC, 4) != 0) {
-    ALOGE("Bad magic word\n");
-    return false;
-  }
-
-  if (memcmp(mpHeader->version, OBCC_VERSION, 4) != 0) {
-    mpHeader->version[4 - 1] = '\0'; // ensure c-style string terminated
-    ALOGI("Cache file format version mismatch: now %s cached %s\n",
-         OBCC_VERSION, mpHeader->version);
-    return false;
-  }
-  return true;
-}
-
-
-bool CacheReader::checkMachineIntType() {
-  uint32_t number = 0x00000001;
-
-  bool isLittleEndian = (*reinterpret_cast<char *>(&number) == 1);
-  if ((isLittleEndian && mpHeader->endianness != 'e') ||
-      (!isLittleEndian && mpHeader->endianness != 'E')) {
-    ALOGE("Machine endianness mismatch.\n");
-    return false;
-  }
-
-  if ((unsigned int)mpHeader->sizeof_off_t != sizeof(off_t) ||
-      (unsigned int)mpHeader->sizeof_size_t != sizeof(size_t) ||
-      (unsigned int)mpHeader->sizeof_ptr_t != sizeof(void *)) {
-    ALOGE("Machine integer size mismatch.\n");
-    return false;
-  }
-
-  return true;
-}
-
-
-bool CacheReader::checkSectionOffsetAndSize() {
-#define CHECK_SECTION_OFFSET(NAME)                                          \
-  do {                                                                      \
-    off_t offset = mpHeader-> NAME##_offset;                                \
-    off_t size = (off_t)mpHeader-> NAME##_size;                             \
-                                                                            \
-    if (mInfoFileSize < offset || mInfoFileSize < offset + size) {          \
-      ALOGE(#NAME " section overflow.\n");                                   \
-      return false;                                                         \
-    }                                                                       \
-                                                                            \
-    if (offset % sizeof(int) != 0) {                                        \
-      ALOGE(#NAME " offset must aligned to %d.\n", (int)sizeof(int));        \
-      return false;                                                         \
-    }                                                                       \
-                                                                            \
-    if (size < static_cast<off_t>(sizeof(size_t))) {                        \
-      ALOGE(#NAME " size is too small to be correct.\n");                    \
-      return false;                                                         \
-    }                                                                       \
-  } while (0)
-
-  CHECK_SECTION_OFFSET(str_pool);
-  CHECK_SECTION_OFFSET(depend_tab);
-  //CHECK_SECTION_OFFSET(reloc_tab);
-  CHECK_SECTION_OFFSET(export_var_list);
-  CHECK_SECTION_OFFSET(export_func_list);
-  CHECK_SECTION_OFFSET(pragma_list);
-
-#undef CHECK_SECTION_OFFSET
-
-  // TODO(logan): Move this to some where else.
-  long pagesize = sysconf(_SC_PAGESIZE);
-  if ((uintptr_t)mpHeader->context_cached_addr % pagesize != 0) {
-    ALOGE("cached address is not aligned to pagesize.\n");
-    return false;
-  }
-
-  return true;
-}
-
-
-#define CACHE_READER_READ_SECTION(TYPE, AUTO_MANAGED_HOLDER, NAME)          \
-  TYPE *NAME##_raw = (TYPE *)malloc(mpHeader->NAME##_size);                 \
-                                                                            \
-  if (!NAME##_raw) {                                                        \
-    ALOGE("Unable to allocate for " #NAME "\n");                             \
-    return false;                                                           \
-  }                                                                         \
-                                                                            \
-  /* We have to ensure that some one will deallocate NAME##_raw */          \
-  AUTO_MANAGED_HOLDER = NAME##_raw;                                         \
-                                                                            \
-  if (mInfoFile->seek(mpHeader->NAME##_offset, SEEK_SET) == -1) {           \
-    ALOGE("Unable to seek to " #NAME " section\n");                          \
-    return false;                                                           \
-  }                                                                         \
-                                                                            \
-  if (mInfoFile->read(reinterpret_cast<char *>(NAME##_raw),                 \
-                  mpHeader->NAME##_size) != (ssize_t)mpHeader->NAME##_size) \
-  {                                                                         \
-    ALOGE("Unable to read " #NAME ".\n");                                    \
-    return false;                                                           \
-  }
-
-
-bool CacheReader::readStringPool() {
-  CACHE_READER_READ_SECTION(OBCC_StringPool,
-                            mpResult->mpStringPoolRaw, str_pool);
-
-  char *str_base = reinterpret_cast<char *>(str_pool_raw);
-
-  vector<char const *> &pool = mpResult->mStringPool;
-  for (size_t i = 0; i < str_pool_raw->count; ++i) {
-    char *str = str_base + str_pool_raw->list[i].offset;
-    pool.push_back(str);
-  }
-
-  return true;
-}
-
-
-bool CacheReader::checkStringPool() {
-  OBCC_StringPool *poolR = mpResult->mpStringPoolRaw;
-  vector<char const *> &pool = mpResult->mStringPool;
-
-  // Ensure that every c-style string is ended with '\0'
-  for (size_t i = 0; i < poolR->count; ++i) {
-    if (pool[i][poolR->list[i].length] != '\0') {
-      ALOGE("The %lu-th string does not end with '\\0'.\n", (unsigned long)i);
-      return false;
-    }
-  }
-
-  return true;
-}
-
-
-bool CacheReader::readDependencyTable() {
-  CACHE_READER_READ_SECTION(OBCC_DependencyTable, mpCachedDependTable,
-                            depend_tab);
-  return true;
-}
-
-
-bool CacheReader::checkDependency() {
-  if (mDependencies.size() != mpCachedDependTable->count) {
-    ALOGE("Dependencies count mismatch. (%lu vs %lu)\n",
-         (unsigned long)mDependencies.size(),
-         (unsigned long)mpCachedDependTable->count);
-    return false;
-  }
-
-  vector<char const *> &strPool = mpResult->mStringPool;
-  map<string, pair<uint32_t, unsigned char const *> >::iterator dep;
-
-  dep = mDependencies.begin();
-  for (size_t i = 0; i < mpCachedDependTable->count; ++i, ++dep) {
-    string const &depName = dep->first;
-    uint32_t depType = dep->second.first;
-    unsigned char const *depSHA1 = dep->second.second;
-
-    OBCC_Dependency *depCached =&mpCachedDependTable->table[i];
-    char const *depCachedName = strPool[depCached->res_name_strp_index];
-    uint32_t depCachedType = depCached->res_type;
-    unsigned char const *depCachedSHA1 = depCached->sha1;
-
-    if (depName != depCachedName) {
-      ALOGE("Cache dependency name mismatch:\n");
-      ALOGE("  given:  %s\n", depName.c_str());
-      ALOGE("  cached: %s\n", depCachedName);
-
-      return false;
-    }
-
-    if (memcmp(depSHA1, depCachedSHA1, 20) != 0) {
-      ALOGE("Cache dependency %s sha1 mismatch:\n", depCachedName);
-
-#define PRINT_SHA1(PREFIX, X, POSTFIX) \
-      ALOGE(PREFIX "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \
-                  "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" POSTFIX, \
-           X[0], X[1], X[2], X[3], X[4], X[5], X[6], X[7], X[8], X[9], \
-           X[10],X[11],X[12],X[13],X[14],X[15],X[16],X[17],X[18],X[19]);
-
-      PRINT_SHA1("  given:  ", depSHA1, "\n");
-      PRINT_SHA1("  cached: ", depCachedSHA1, "\n");
-
-#undef PRINT_SHA1
-
-      return false;
-    }
-
-    if (depType != depCachedType) {
-      ALOGE("Cache dependency %s resource type mismatch.\n", depCachedName);
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool CacheReader::readExportVarList() {
-  CACHE_READER_READ_SECTION(OBCC_ExportVarList,
-                            mpResult->mpExportVars, export_var_list);
-  return true;
-}
-
-
-bool CacheReader::readExportFuncList() {
-  CACHE_READER_READ_SECTION(OBCC_ExportFuncList,
-                            mpResult->mpExportFuncs, export_func_list);
-  return true;
-}
-
-
-bool CacheReader::readPragmaList() {
-  CACHE_READER_READ_SECTION(OBCC_PragmaList, mpPragmaList, pragma_list);
-
-  vector<char const *> const &strPool = mpResult->mStringPool;
-  ScriptCached::PragmaList &pragmas = mpResult->mPragmas;
-
-  for (size_t i = 0; i < pragma_list_raw->count; ++i) {
-    OBCC_Pragma *pragma = &pragma_list_raw->list[i];
-    pragmas.push_back(make_pair(strPool[pragma->key_strp_index],
-                                strPool[pragma->value_strp_index]));
-  }
-
-  return true;
-}
-
-
-bool CacheReader::readObjectSlotList() {
-  CACHE_READER_READ_SECTION(OBCC_ObjectSlotList,
-                            mpResult->mpObjectSlotList, object_slot_list);
-  return true;
-}
-
-
-bool CacheReader::readFuncTable() {
-  CACHE_READER_READ_SECTION(OBCC_FuncTable, mpFuncTable, func_table);
-
-  vector<char const *> &strPool = mpResult->mStringPool;
-  ScriptCached::FuncTable &table = mpResult->mFunctions;
-  for (size_t i = 0; i < func_table_raw->count; ++i) {
-    OBCC_FuncInfo *func = &func_table_raw->table[i];
-    table.insert(make_pair(strPool[func->name_strp_index],
-                           make_pair(func->cached_addr, func->size)));
-  }
-
-  return true;
-}
-
-#undef CACHE_READER_READ_SECTION
-
-
-bool CacheReader::readContext() {
-  mpResult->mContext =
-    ContextManager::get().allocateContext(mpHeader->context_cached_addr,
-                                          mObjFile->getFD(), 0);
-
-  if (!mpResult->mContext) {
-    // Unable to allocate at cached address.  Give up.
-    mIsContextSlotNotAvail = true;
-    return false;
-
-    // TODO(logan): If relocation is fixed, we should try to allocate the
-    // code in different location, and relocate the context.
-  }
-
-  return true;
-}
-
-
-bool CacheReader::checkContext() {
-  uint32_t sum = mpHeader->context_parity_checksum;
-  uint32_t *ptr = reinterpret_cast<uint32_t *>(mpResult->mContext);
-
-  for (size_t i = 0; i < ContextManager::ContextSize / sizeof(uint32_t); ++i) {
-    sum ^= *ptr++;
-  }
-
-  if (sum != 0) {
-    ALOGE("Checksum check failed\n");
-    return false;
-  }
-
-  ALOGI("Passed checksum even parity verification.\n");
-  return true;
-}
-
-
-bool CacheReader::readRelocationTable() {
-  // TODO(logan): Not finished.
-  return true;
-}
-
-
-bool CacheReader::relocate() {
-  // TODO(logan): Not finished.
-  return true;
-}
-
-
-} // namespace bcc
diff --git a/lib/ExecutionEngine/OldJIT/CacheReader.h b/lib/ExecutionEngine/OldJIT/CacheReader.h
deleted file mode 100644
index a208ed6..0000000
--- a/lib/ExecutionEngine/OldJIT/CacheReader.h
+++ /dev/null
@@ -1,104 +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_CACHEREADER_H
-#define BCC_CACHEREADER_H
-
-#include "ScriptCached.h"
-
-#include <llvm/ADT/OwningPtr.h>
-
-#include <map>
-#include <string>
-#include <utility>
-
-#include <stddef.h>
-#include <stdint.h>
-
-struct OBCC_Header;
-
-namespace bcc {
-  class FileHandle;
-  class Script;
-
-  class CacheReader {
-  private:
-    FileHandle *mObjFile;
-    FileHandle *mInfoFile;
-    off_t mInfoFileSize;
-
-    OBCC_Header *mpHeader;
-    OBCC_DependencyTable *mpCachedDependTable;
-    OBCC_PragmaList *mpPragmaList;
-    OBCC_FuncTable *mpFuncTable;
-
-    llvm::OwningPtr<ScriptCached> mpResult;
-
-    std::map<std::string,
-             std::pair<uint32_t, unsigned char const *> > mDependencies;
-
-    bool mIsContextSlotNotAvail;
-
-  public:
-    CacheReader()
-      : mObjFile(NULL), mInfoFile(NULL), mInfoFileSize(0), mpHeader(NULL),
-        mpCachedDependTable(NULL), mpPragmaList(NULL), mpFuncTable(NULL),
-        mIsContextSlotNotAvail(false) {
-    }
-
-    ~CacheReader();
-
-    void addDependency(OBCC_ResourceType resType,
-                       std::string const &resName,
-                       unsigned char const *sha1) {
-      mDependencies.insert(std::make_pair(resName,
-                           std::make_pair((uint32_t)resType, sha1)));
-    }
-
-    ScriptCached *readCacheFile(FileHandle *objFile,
-                                FileHandle *infoFile,
-                                Script *s);
-
-    bool isContextSlotNotAvail() const {
-      return mIsContextSlotNotAvail;
-    }
-
-  private:
-    bool readHeader();
-    bool readStringPool();
-    bool readDependencyTable();
-    bool readExportVarList();
-    bool readExportFuncList();
-    bool readPragmaList();
-    bool readFuncTable();
-    bool readObjectSlotList();
-    bool readContext();
-    bool readRelocationTable();
-
-    bool checkFileSize();
-    bool checkHeader();
-    bool checkMachineIntType();
-    bool checkSectionOffsetAndSize();
-    bool checkStringPool();
-    bool checkDependency();
-    bool checkContext();
-
-    bool relocate();
-  };
-
-} // namespace bcc
-
-#endif // BCC_CACHEREADER_H
diff --git a/lib/ExecutionEngine/OldJIT/CacheWriter.cpp b/lib/ExecutionEngine/OldJIT/CacheWriter.cpp
deleted file mode 100644
index 36bf281..0000000
--- a/lib/ExecutionEngine/OldJIT/CacheWriter.cpp
+++ /dev/null
@@ -1,427 +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.
- */
-
-#include "CacheWriter.h"
-
-#include "ContextManager.h"
-#include "DebugHelper.h"
-#include "FileHandle.h"
-#include "Script.h"
-
-#include <map>
-#include <string>
-#include <vector>
-#include <utility>
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-using namespace std;
-
-namespace bcc {
-
-CacheWriter::~CacheWriter() {
-#define CHECK_AND_FREE(VAR) if (VAR) { free(VAR); }
-
-  CHECK_AND_FREE(mpHeaderSection);
-  CHECK_AND_FREE(mpStringPoolSection);
-  CHECK_AND_FREE(mpDependencyTableSection);
-  //CHECK_AND_FREE(mpRelocationTableSection);
-  CHECK_AND_FREE(mpExportVarListSection);
-  CHECK_AND_FREE(mpExportFuncListSection);
-  CHECK_AND_FREE(mpPragmaListSection);
-  CHECK_AND_FREE(mpFuncTableSection);
-  CHECK_AND_FREE(mpObjectSlotSection);
-
-#undef CHECK_AND_FREE
-}
-
-bool CacheWriter::writeCacheFile(FileHandle *objFile,
-                                 FileHandle *infoFile,
-                                 Script *S,
-                                 uint32_t libRS_threadable) {
-  if (!objFile || objFile->getFD() < 0 ||
-      !infoFile || infoFile->getFD() < 0) {
-    return false;
-  }
-
-  mObjFile = objFile;
-  mInfoFile = infoFile;
-  mpOwner = S;
-
-  bool result = prepareHeader(libRS_threadable)
-             && prepareDependencyTable()
-             && prepareFuncTable()
-             && preparePragmaList()
-             //&& prepareRelocationTable()
-             && prepareStringPool()
-             && prepareExportVarList()
-             && prepareExportFuncList()
-             && prepareObjectSlotList()
-             && calcSectionOffset()
-             && calcContextChecksum()
-             && writeAll()
-             ;
-
-  return result;
-}
-
-
-bool CacheWriter::prepareHeader(uint32_t libRS_threadable) {
-  OBCC_Header *header = (OBCC_Header *)malloc(sizeof(OBCC_Header));
-
-  if (!header) {
-    ALOGE("Unable to allocate for header.\n");
-    return false;
-  }
-
-  mpHeaderSection = header;
-
-  // Initialize
-  memset(header, '\0', sizeof(OBCC_Header));
-
-  // Magic word and version
-  memcpy(header->magic, OBCC_MAGIC, 4);
-  memcpy(header->version, OBCC_VERSION, 4);
-
-  // Machine Integer Type
-  uint32_t number = 0x00000001;
-  header->endianness = (*reinterpret_cast<char *>(&number) == 1) ? 'e' : 'E';
-  header->sizeof_off_t = sizeof(off_t);
-  header->sizeof_size_t = sizeof(size_t);
-  header->sizeof_ptr_t = sizeof(void *);
-
-  // Context
-  header->context_cached_addr = mpOwner->getContext();
-
-  // libRS is threadable dirty hack
-  // TODO: This should be removed in the future
-  header->libRS_threadable = libRS_threadable;
-
-  return true;
-}
-
-
-bool CacheWriter::prepareDependencyTable() {
-  size_t tableSize = sizeof(OBCC_DependencyTable) +
-                     sizeof(OBCC_Dependency) * mDependencies.size();
-
-  OBCC_DependencyTable *tab = (OBCC_DependencyTable *)malloc(tableSize);
-
-  if (!tab) {
-    ALOGE("Unable to allocate for dependency table section.\n");
-    return false;
-  }
-
-  mpDependencyTableSection = tab;
-  mpHeaderSection->depend_tab_size = tableSize;
-
-  tab->count = mDependencies.size();
-
-  size_t i = 0;
-  for (map<string, pair<uint32_t, unsigned char const *> >::iterator
-       I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) {
-    OBCC_Dependency *dep = &tab->table[i];
-
-    dep->res_name_strp_index = addString(I->first.c_str(), I->first.size());
-    dep->res_type = I->second.first;
-    memcpy(dep->sha1, I->second.second, 20);
-  }
-
-  return true;
-}
-
-
-bool CacheWriter::prepareFuncTable() {
-  size_t funcCount = mpOwner->getFuncCount();
-
-  size_t tableSize = sizeof(OBCC_FuncTable) +
-                     sizeof(OBCC_FuncInfo) * funcCount;
-
-  OBCC_FuncTable *tab = (OBCC_FuncTable *)malloc(tableSize);
-
-  if (!tab) {
-    ALOGE("Unable to allocate for function table section.\n");
-    return false;
-  }
-
-  mpFuncTableSection = tab;
-  mpHeaderSection->func_table_size = tableSize;
-
-  tab->count = static_cast<size_t>(funcCount);
-
-  // Get the function informations
-  vector<FuncInfo> funcInfoList(funcCount);
-  mpOwner->getFuncInfoList(funcCount, &*funcInfoList.begin());
-
-  for (size_t i = 0; i < funcCount; ++i) {
-    FuncInfo *info = &funcInfoList[i];
-    OBCC_FuncInfo *outputInfo = &tab->table[i];
-
-    outputInfo->name_strp_index = addString(info->name, strlen(info->name));
-    outputInfo->cached_addr = info->addr;
-    outputInfo->size = info->size;
-  }
-
-  return true;
-}
-
-
-bool CacheWriter::preparePragmaList() {
-  size_t pragmaCount = mpOwner->getPragmaCount();
-
-  size_t listSize = sizeof(OBCC_PragmaList) +
-                    sizeof(OBCC_Pragma) * pragmaCount;
-
-  OBCC_PragmaList *list = (OBCC_PragmaList *)malloc(listSize);
-
-  if (!list) {
-    ALOGE("Unable to allocate for pragma list\n");
-    return false;
-  }
-
-  mpPragmaListSection = list;
-  mpHeaderSection->pragma_list_size = listSize;
-
-  list->count = pragmaCount;
-
-  vector<char const *> keyList(pragmaCount);
-  vector<char const *> valueList(pragmaCount);
-  mpOwner->getPragmaList(pragmaCount, &*keyList.begin(), &*valueList.begin());
-
-  for (size_t i = 0; i < pragmaCount; ++i) {
-    char const *key = keyList[i];
-    char const *value = valueList[i];
-
-    size_t keyLen = strlen(key);
-    size_t valueLen = strlen(value);
-
-    OBCC_Pragma *pragma = &list->list[i];
-    pragma->key_strp_index = addString(key, keyLen);
-    pragma->value_strp_index = addString(value, valueLen);
-  }
-
-  return true;
-}
-
-
-bool CacheWriter::prepareRelocationTable() {
-  // TODO(logan): Implement relocation table cache write.
-  return false;
-}
-
-
-bool CacheWriter::prepareStringPool() {
-  // Calculate string pool size
-  size_t size = sizeof(OBCC_StringPool) +
-                sizeof(OBCC_String) * mStringPool.size();
-
-  off_t strOffset = size;
-
-  for (size_t i = 0; i < mStringPool.size(); ++i) {
-    size += mStringPool[i].second + 1;
-  }
-
-  // Create string pool
-  OBCC_StringPool *pool = (OBCC_StringPool *)malloc(size);
-
-  if (!pool) {
-    ALOGE("Unable to allocate string pool.\n");
-    return false;
-  }
-
-  mpStringPoolSection = pool;
-  mpHeaderSection->str_pool_size = size;
-
-  pool->count = mStringPool.size();
-
-  char *strPtr = reinterpret_cast<char *>(pool) + strOffset;
-
-  for (size_t i = 0; i < mStringPool.size(); ++i) {
-    OBCC_String *str = &pool->list[i];
-
-    str->length = mStringPool[i].second;
-    str->offset = strOffset;
-    memcpy(strPtr, mStringPool[i].first, str->length);
-
-    strPtr += str->length;
-    *strPtr++ = '\0';
-
-    strOffset += str->length + 1;
-  }
-
-  return true;
-}
-
-
-bool CacheWriter::prepareExportVarList() {
-  size_t varCount = mpOwner->getExportVarCount();
-  size_t listSize = sizeof(OBCC_ExportVarList) + sizeof(void *) * varCount;
-
-  OBCC_ExportVarList *list = (OBCC_ExportVarList *)malloc(listSize);
-
-  if (!list) {
-    ALOGE("Unable to allocate for export variable list\n");
-    return false;
-  }
-
-  mpExportVarListSection = list;
-  mpHeaderSection->export_var_list_size = listSize;
-
-  list->count = static_cast<size_t>(varCount);
-
-  mpOwner->getExportVarList(varCount, list->cached_addr_list);
-  return true;
-}
-
-
-bool CacheWriter::prepareExportFuncList() {
-  size_t funcCount = mpOwner->getExportFuncCount();
-  size_t listSize = sizeof(OBCC_ExportFuncList) + sizeof(void *) * funcCount;
-
-  OBCC_ExportFuncList *list = (OBCC_ExportFuncList *)malloc(listSize);
-
-  if (!list) {
-    ALOGE("Unable to allocate for export function list\n");
-    return false;
-  }
-
-  mpExportFuncListSection = list;
-  mpHeaderSection->export_func_list_size = listSize;
-
-  list->count = static_cast<size_t>(funcCount);
-
-  mpOwner->getExportFuncList(funcCount, list->cached_addr_list);
-  return true;
-}
-
-
-bool CacheWriter::prepareObjectSlotList() {
-  size_t objectSlotCount = mpOwner->getObjectSlotCount();
-
-  size_t listSize = sizeof(OBCC_ObjectSlotList) +
-                    sizeof(uint32_t) * objectSlotCount;
-
-  OBCC_ObjectSlotList *list = (OBCC_ObjectSlotList *)malloc(listSize);
-
-  if (!list) {
-    ALOGE("Unable to allocate for object slot list\n");
-    return false;
-  }
-
-  mpObjectSlotSection = list;
-  mpHeaderSection->object_slot_list_size = listSize;
-
-  list->count = objectSlotCount;
-
-  mpOwner->getObjectSlotList(objectSlotCount, list->object_slot_list);
-  return true;
-}
-
-
-bool CacheWriter::calcSectionOffset() {
-  size_t offset = sizeof(OBCC_Header);
-
-#define OFFSET_INCREASE(NAME)                                               \
-  do {                                                                      \
-    /* Align to a word */                                                   \
-    size_t rem = offset % sizeof(int);                                      \
-    if (rem > 0) {                                                          \
-      offset += sizeof(int) - rem;                                          \
-    }                                                                       \
-                                                                            \
-    /* Save the offset and increase it */                                   \
-    mpHeaderSection->NAME##_offset = offset;                                \
-    offset += mpHeaderSection->NAME##_size;                                 \
-  } while (0)
-
-  OFFSET_INCREASE(str_pool);
-  OFFSET_INCREASE(depend_tab);
-  //OFFSET_INCREASE(reloc_tab);
-  OFFSET_INCREASE(export_var_list);
-  OFFSET_INCREASE(export_func_list);
-  OFFSET_INCREASE(pragma_list);
-  OFFSET_INCREASE(func_table);
-  OFFSET_INCREASE(object_slot_list);
-
-#undef OFFSET_INCREASE
-  return true;
-}
-
-
-bool CacheWriter::calcContextChecksum() {
-  uint32_t sum = 0;
-  uint32_t *ptr = reinterpret_cast<uint32_t *>(mpOwner->getContext());
-
-  for (size_t i = 0; i < ContextManager::ContextSize / sizeof(uint32_t); ++i) {
-    sum ^= *ptr++;
-  }
-
-  mpHeaderSection->context_parity_checksum = sum;
-  return true;
-}
-
-
-bool CacheWriter::writeAll() {
-#define WRITE_SECTION(NAME, OFFSET, SIZE, SECTION)                          \
-  do {                                                                      \
-    if (mInfoFile->seek(OFFSET, SEEK_SET) == -1) {                          \
-      ALOGE("Unable to seek to " #NAME " section for writing.\n");           \
-      return false;                                                         \
-    }                                                                       \
-                                                                            \
-    if (mInfoFile->write(reinterpret_cast<char *>(SECTION), (SIZE)) !=      \
-        static_cast<ssize_t>(SIZE)) {                                       \
-      ALOGE("Unable to write " #NAME " section to cache file.\n");           \
-      return false;                                                         \
-    }                                                                       \
-  } while (0)
-
-#define WRITE_SECTION_SIMPLE(NAME, SECTION)                                 \
-  WRITE_SECTION(NAME,                                                       \
-                mpHeaderSection->NAME##_offset,                             \
-                mpHeaderSection->NAME##_size,                               \
-                SECTION)
-
-  WRITE_SECTION(header, 0, sizeof(OBCC_Header), mpHeaderSection);
-
-  WRITE_SECTION_SIMPLE(str_pool, mpStringPoolSection);
-  WRITE_SECTION_SIMPLE(depend_tab, mpDependencyTableSection);
-  //WRITE_SECTION_SIMPLE(reloc_tab, mpRelocationTableSection);
-  WRITE_SECTION_SIMPLE(export_var_list, mpExportVarListSection);
-  WRITE_SECTION_SIMPLE(export_func_list, mpExportFuncListSection);
-  WRITE_SECTION_SIMPLE(pragma_list, mpPragmaListSection);
-  WRITE_SECTION_SIMPLE(func_table, mpFuncTableSection);
-  WRITE_SECTION_SIMPLE(object_slot_list, mpObjectSlotSection);
-
-#undef WRITE_SECTION_SIMPLE
-#undef WRITE_SECTION
-
-
-  // Write Context to Executable File
-  char const *context = (char const *)mpOwner->getContext();
-  size_t context_size = ContextManager::ContextSize;
-  if (mObjFile->write(context, context_size) != (ssize_t)context_size) {
-    ALOGE("Unable to write context image to executable file\n");
-    return false;
-  }
-
-  return true;
-}
-
-
-} // namespace bcc
diff --git a/lib/ExecutionEngine/OldJIT/CacheWriter.h b/lib/ExecutionEngine/OldJIT/CacheWriter.h
deleted file mode 100644
index d492d4a..0000000
--- a/lib/ExecutionEngine/OldJIT/CacheWriter.h
+++ /dev/null
@@ -1,101 +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_CACHEWRITER_H
-#define BCC_CACHEWRITER_H
-
-#include <bcc/bcc_cache.h>
-
-#include "FileHandle.h"
-
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace bcc {
-  class Script;
-
-  class CacheWriter {
-  private:
-    Script *mpOwner;
-
-    FileHandle *mObjFile;
-    FileHandle *mInfoFile;
-
-    std::vector<std::pair<char const *, size_t> > mStringPool;
-
-    std::map<std::string,
-             std::pair<uint32_t, unsigned char const *> > mDependencies;
-
-    OBCC_Header *mpHeaderSection;
-    OBCC_StringPool *mpStringPoolSection;
-    OBCC_DependencyTable *mpDependencyTableSection;
-    //OBCC_RelocationTable *mpRelocationTableSection;
-    OBCC_ExportVarList *mpExportVarListSection;
-    OBCC_ExportFuncList *mpExportFuncListSection;
-    OBCC_PragmaList *mpPragmaListSection;
-    OBCC_FuncTable *mpFuncTableSection;
-    OBCC_ObjectSlotList *mpObjectSlotSection;
-
-  public:
-    CacheWriter()
-      : mpHeaderSection(NULL), mpStringPoolSection(NULL),
-        mpDependencyTableSection(NULL), mpExportVarListSection(NULL),
-        mpExportFuncListSection(NULL), mpPragmaListSection(NULL),
-        mpFuncTableSection(NULL), mpObjectSlotSection(NULL) {
-    }
-
-    ~CacheWriter();
-
-    bool writeCacheFile(FileHandle *objFile,
-                        FileHandle *infoFile,
-                        Script *S,
-                        uint32_t libRS_threadable);
-
-    void addDependency(OBCC_ResourceType resType,
-                       std::string const &resName,
-                       unsigned char const *sha1) {
-      mDependencies.insert(std::make_pair(resName,
-                           std::make_pair((uint32_t)resType, sha1)));
-    }
-
-  private:
-    bool prepareHeader(uint32_t libRS_threadable);
-    bool prepareStringPool();
-    bool prepareDependencyTable();
-    bool prepareRelocationTable();
-    bool prepareExportVarList();
-    bool prepareExportFuncList();
-    bool preparePragmaList();
-    bool prepareFuncTable();
-    bool prepareObjectSlotList();
-
-    bool writeAll();
-
-    bool calcSectionOffset();
-    bool calcContextChecksum();
-
-    size_t addString(char const *str, size_t size) {
-      mStringPool.push_back(std::make_pair(str, size));
-      return mStringPool.size() - 1;
-    }
-
-  };
-
-} // namespace bcc
-
-#endif // BCC_CACHEWRITER_H
diff --git a/lib/ExecutionEngine/OldJIT/ContextManager.cpp b/lib/ExecutionEngine/OldJIT/ContextManager.cpp
deleted file mode 100644
index 5dca382..0000000
--- a/lib/ExecutionEngine/OldJIT/ContextManager.cpp
+++ /dev/null
@@ -1,197 +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.
- */
-
-#include "ContextManager.h"
-
-#include "DebugHelper.h"
-
-#include <llvm/Support/Mutex.h>
-#include <llvm/Support/MutexGuard.h>
-
-#include <errno.h>
-#include <sys/mman.h>
-#include <utils/threads.h>
-
-#include <stddef.h>
-#include <string.h>
-
-
-namespace bcc {
-
-// Starting address for context slots
-char * const ContextManager::ContextFixedAddr = BCC_CONTEXT_FIXED_ADDR_;
-
-// ContextManager singleton object
-ContextManager ContextManager::TheContextManager;
-
-
-ContextManager::ContextManager() {
-  // Initialize context slot occupation table to false
-  for (size_t i = 0; i < ContextSlotCount; ++i) {
-    mContextSlotOccupied[i] = false;
-  }
-}
-
-char *ContextManager::allocateContext() {
-  {
-    // Acquire mContextSlotOccupiedLock
-    llvm::MutexGuard Locked(mContextSlotOccupiedLock);
-
-    // Try to allocate context on the managed context slot.
-    for (size_t i = 0; i < ContextSlotCount; ++i) {
-      if (mContextSlotOccupied[i]) {
-        continue;
-      }
-
-      void *addr = ContextFixedAddr + ContextSize * i;
-      void *result = mmap(addr, ContextSize,
-                          PROT_READ | PROT_WRITE | PROT_EXEC,
-                          MAP_PRIVATE | MAP_ANON, -1, 0);
-
-      if (result == addr) {
-        ALOGI("Allocate bcc context. addr=%p\n", result);
-        mContextSlotOccupied[i] = true;
-        return static_cast<char *>(result);
-      }
-
-      if (result && result != MAP_FAILED) {
-        ALOGE("Unable to allocate. suggested=%p, result=%p\n", addr, result);
-        munmap(result, ContextSize);
-      }
-
-      ALOGE("Unable to allocate. addr=%p.  Retry ...\n", addr);
-    }
-    // Release mContextSlotOccupiedLock
-  }
-
-  // No slot available, allocate at arbitary address.
-  void *result = mmap(0, ContextSize, PROT_READ | PROT_WRITE | PROT_EXEC,
-                      MAP_PRIVATE | MAP_ANON, -1, 0);
-
-  if (!result || result == MAP_FAILED) {
-    ALOGE("Unable to mmap. (reason: %s)\n", strerror(errno));
-    return NULL;
-  }
-
-  ALOGI("Allocate bcc context. addr=%p\n", result);
-  return static_cast<char *>(result);
-}
-
-
-char *ContextManager::allocateContext(char *addr,
-                                      int imageFd, off_t imageOffset) {
-  // This function should only allocate context when address is an context
-  // slot address.  And the image offset is aligned to the pagesize.
-
-  if (imageFd < 0) {
-    ALOGE("Invalid file descriptor for bcc context image\n");
-    return NULL;
-  }
-
-  unsigned long pagesize = (unsigned long)sysconf(_SC_PAGESIZE);
-
-  if (imageOffset % pagesize > 0) {
-    ALOGE("BCC context image offset is not aligned to page size\n");
-    return NULL;
-  }
-
-  ssize_t slot = getSlotIndexFromAddress(addr);
-  if (slot < 0) {
-    ALOGE("Suggested address is not a bcc context slot address\n");
-    return NULL;
-  }
-
-  llvm::MutexGuard Locked(mContextSlotOccupiedLock);
-  if (mContextSlotOccupied[slot]) {
-    ALOGW("Suggested bcc context slot has been occupied.\n");
-    return NULL;
-  }
-
-  // ALOGI("addr=%x, imageFd=%d, imageOffset=%x", addr, imageFd, imageOffset);
-  void *result = mmap(addr, ContextSize,
-                      PROT_READ | PROT_WRITE | PROT_EXEC,
-                      MAP_PRIVATE, imageFd, imageOffset);
-
-  if (!result || result == MAP_FAILED) {
-    ALOGE("Unable to allocate. addr=%p\n", addr);
-    return NULL;
-  }
-
-  if (result != addr) {
-    ALOGE("Unable to allocate at suggested=%p, result=%p\n", addr, result);
-    munmap(result, ContextSize);
-    return NULL;
-  }
-
-  ALOGI("Allocate bcc context. addr=%p\n", addr);
-  mContextSlotOccupied[slot] = true;
-  return static_cast<char *>(result);
-}
-
-
-void ContextManager::deallocateContext(char *addr) {
-  if (!addr) {
-    return;
-  }
-
-  llvm::MutexGuard Locked(mContextSlotOccupiedLock);
-
-  ALOGI("Deallocate bcc context. addr=%p\n", addr);
-
-  // Unmap
-  if (munmap(addr, ContextSize) < 0) {
-    ALOGE("Unable to unmap. addr=%p (reason: %s)\n", addr, strerror(errno));
-    return;
-  }
-
-  // If the address is one of the context slot, then mark such slot
-  // freely available as well.
-  ssize_t slot = getSlotIndexFromAddress(addr);
-  if (slot >= 0) {
-    // Give the context slot back.
-    mContextSlotOccupied[slot] = false;
-  }
-}
-
-
-bool ContextManager::isManagingContext(char *addr) const {
-  ssize_t slot = getSlotIndexFromAddress(addr);
-
-  if (slot < 0) {
-    return false;
-  }
-
-  llvm::MutexGuard Locked(mContextSlotOccupiedLock);
-  return mContextSlotOccupied[slot];
-}
-
-
-ssize_t ContextManager::getSlotIndexFromAddress(char *addr) {
-  if (addr >= ContextFixedAddr) {
-    size_t offset = (size_t)(addr - ContextFixedAddr);
-    if (offset % ContextSize == 0) {
-      size_t slot = offset / ContextSize;
-      if (slot < ContextSlotCount) {
-        return slot;
-      }
-    }
-  }
-  return -1;
-}
-
-
-
-} // namespace bcc
diff --git a/lib/ExecutionEngine/OldJIT/ContextManager.h b/lib/ExecutionEngine/OldJIT/ContextManager.h
deleted file mode 100644
index f23c4a1..0000000
--- a/lib/ExecutionEngine/OldJIT/ContextManager.h
+++ /dev/null
@@ -1,74 +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_CONTEXTMANAGER_H
-#define BCC_CONTEXTMANAGER_H
-
-#include <Config.h>
-
-#include <llvm/Support/Mutex.h>
-
-#include <unistd.h>
-#include <stddef.h>
-
-
-namespace bcc {
-
-  class ContextManager {
-  public:
-    // Starting address of context slot address space
-    static char * const ContextFixedAddr;
-
-    // Number of the context slots
-    static size_t const ContextSlotCount = BCC_CONTEXT_SLOT_COUNT_;
-
-    // Context size
-    static size_t const ContextCodeSize = BCC_CONTEXT_CODE_SIZE_;
-    static size_t const ContextDataSize = BCC_CONTEXT_DATA_SIZE_;
-    static size_t const ContextSize = ContextCodeSize + ContextDataSize;
-
-  private:
-    // Context manager singleton
-    static ContextManager TheContextManager;
-
-  private:
-    // Mutex lock for context slot occupation table
-    mutable llvm::sys::Mutex mContextSlotOccupiedLock;
-
-    // Context slot occupation table
-    bool mContextSlotOccupied[ContextSlotCount];
-
-    ContextManager();
-
-  public:
-    static ContextManager &get() {
-      return TheContextManager;
-    }
-
-    char *allocateContext();
-    char *allocateContext(char *addr, int imageFd, off_t imageOffset);
-    void deallocateContext(char *addr);
-
-    bool isManagingContext(char *addr) const;
-
-  private:
-    static ssize_t getSlotIndexFromAddress(char *addr);
-
-  };
-
-} // namespace bcc
-
-#endif // BCC_CONTEXTMANAGER_H
diff --git a/lib/ExecutionEngine/Script.cpp b/lib/ExecutionEngine/Script.cpp
index 4b0b406..445d075 100644
--- a/lib/ExecutionEngine/Script.cpp
+++ b/lib/ExecutionEngine/Script.cpp
@@ -18,19 +18,10 @@
 
 #include "Config.h"
 
-#if USE_OLD_JIT
-#include "OldJIT/CacheReader.h"
-#include "OldJIT/CacheWriter.h"
-#endif
-
 #include "MCCacheReader.h"
 #include "MCCacheWriter.h"
 #include "CompilerOption.h"
 
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
-
 #include "DebugHelper.h"
 #include "FileHandle.h"
 #include "GDBJITRegistrar.h"
@@ -66,11 +57,9 @@
     delete mCompiled;
     break;
 
-#if USE_CACHE
   case ScriptStatus::Cached:
     delete mCached;
     break;
-#endif
 
   default:
     break;
@@ -230,10 +219,7 @@
     return 1;
   }
 
-  int status = -1;
-#if USE_CACHE
-  status = internalLoadCache(cacheDir, cacheName, /* checkOnly */ false);
-#endif
+  int status = internalLoadCache(cacheDir, cacheName, /* checkOnly */ false);
 
   if (status != 0) {
     CompilerOption option;
@@ -259,7 +245,6 @@
   return status;
 }
 
-#if USE_CACHE
 int Script::internalLoadCache(char const *cacheDir, char const *cacheName,
                               bool checkOnly) {
   if ((cacheDir == NULL) || (cacheName == NULL)) {
@@ -294,9 +279,6 @@
     return 1;
   }
 
-#if USE_OLD_JIT
-  CacheReader reader;
-#elif USE_MCJIT
   MCCacheReader reader;
 
   // Register symbol lookup function
@@ -304,7 +286,6 @@
     reader.registerSymbolCallback(mpExtSymbolLookupFn,
                                       mpExtSymbolLookupFnContext);
   }
-#endif
 
   // Dependencies
   reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
@@ -338,7 +319,6 @@
 
   return 0;
 }
-#endif
 
 int Script::internalCompile(const CompilerOption &option) {
   // Create the ScriptCompiled object
@@ -406,19 +386,13 @@
       (getCompilerErrorMessage() == NULL))
     return 1;
 
-#if USE_CACHE
   // Note: If we re-compile the script because the cached context slot not
   // available, then we don't have to write the cache.
 
   // Note: If the address of the context is not in the context slot, then
   // we don't have to cache it.
 
-  if (
-#if USE_OLD_JIT
-      !mIsContextSlotNotAvail &&
-      ContextManager::get().isManagingContext(getContext()) &&
-#endif
-      isCacheable()) {
+  if (isCacheable()) {
 
     std::string objPath = getCachedObjectPath();
     std::string infoPath = getCacheInfoPath();
@@ -428,9 +402,7 @@
     // to modify its contents.  (The same script may be running concurrently in
     // the same process or a different process!)
     ::unlink(objPath.c_str());
-#if !USE_OLD_JIT && USE_MCJIT
     ::unlink(infoPath.c_str());
-#endif
 
     FileHandle objFile;
     FileHandle infoFile;
@@ -438,11 +410,7 @@
     if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
         infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
 
-#if USE_OLD_JIT
-      CacheWriter writer;
-#elif USE_MCJIT
       MCCacheWriter writer;
-#endif
 
 #ifdef TARGET_BUILD
       // Dependencies
@@ -484,7 +452,6 @@
       }
     }
   }
-#endif // USE_CACHE
 
   return 0;
 }
@@ -506,11 +473,9 @@
       return mCompiled->lookup(name);
     }
 
-#if USE_CACHE
     case ScriptStatus::Cached: {
       return mCached->lookup(name);
     }
-#endif
 
     default: {
       mErrorCode = BCC_INVALID_OPERATION;
@@ -526,11 +491,9 @@
       return mCompiled->getExportVarCount();
     }
 
-#if USE_CACHE
     case ScriptStatus::Cached: {
       return mCached->getExportVarCount();
     }
-#endif
 
     default: {
       return 0;
@@ -545,11 +508,9 @@
       return mCompiled->getExportFuncCount();
     }
 
-#if USE_CACHE
     case ScriptStatus::Cached: {
       return mCached->getExportFuncCount();
     }
-#endif
 
     default: {
       return 0;
@@ -564,11 +525,9 @@
       return mCompiled->getExportForEachCount();
     }
 
-#if USE_CACHE
     case ScriptStatus::Cached: {
       return mCached->getExportForEachCount();
     }
-#endif
 
     default: {
       return 0;
@@ -583,11 +542,9 @@
       return mCompiled->getPragmaCount();
     }
 
-#if USE_CACHE
     case ScriptStatus::Cached: {
       return mCached->getPragmaCount();
     }
-#endif
 
     default: {
       return 0;
@@ -602,11 +559,9 @@
       return mCompiled->getFuncCount();
     }
 
-#if USE_CACHE
     case ScriptStatus::Cached: {
       return mCached->getFuncCount();
     }
-#endif
 
     default: {
       return 0;
@@ -621,11 +576,9 @@
       return mCompiled->getObjectSlotCount();
     }
 
-#if USE_CACHE
     case ScriptStatus::Cached: {
       return mCached->getObjectSlotCount();
     }
-#endif
 
     default: {
       return 0;
@@ -641,9 +594,7 @@
       m##STATUS->getExportVarList(varListSize, varList); \
       break;
 
-#if USE_CACHE
     DELEGATE(Cached);
-#endif
 
     DELEGATE(Compiled);
 #undef DELEGATE
@@ -674,9 +625,7 @@
       m##STATUS->getExportFuncList(funcListSize, funcList); \
       break;
 
-#if USE_CACHE
     DELEGATE(Cached);
-#endif
 
     DELEGATE(Compiled);
 #undef DELEGATE
@@ -706,9 +655,7 @@
       m##STATUS->getExportForEachList(funcListSize, funcList); \
       break;
 
-#if USE_CACHE
     DELEGATE(Cached);
-#endif
 
     DELEGATE(Compiled);
 #undef DELEGATE
@@ -740,9 +687,7 @@
       m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
       break;
 
-#if USE_CACHE
     DELEGATE(Cached);
-#endif
 
     DELEGATE(Compiled);
 #undef DELEGATE
@@ -762,9 +707,7 @@
       m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
       break;
 
-#if USE_CACHE
     DELEGATE(Cached);
-#endif
 
     DELEGATE(Compiled);
 #undef DELEGATE
@@ -784,9 +727,7 @@
       m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
       break;
 
-#if USE_CACHE
     DELEGATE(Cached);
-#endif
 
     DELEGATE(Compiled);
 #undef DELEGATE
@@ -798,29 +739,6 @@
 }
 
 
-#if USE_OLD_JIT
-char *Script::getContext() {
-  switch (mStatus) {
-
-#if USE_CACHE
-    case ScriptStatus::Cached: {
-      return mCached->getContext();
-    }
-#endif
-
-    case ScriptStatus::Compiled: {
-      return mCompiled->getContext();
-    }
-
-    default: {
-      mErrorCode = BCC_INVALID_OPERATION;
-      return NULL;
-    }
-  }
-}
-#endif
-
-
 int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
   mpExtSymbolLookupFn = pFn;
   mpExtSymbolLookupFnContext = pContext;
@@ -834,7 +752,6 @@
 }
 
 bool Script::isCacheable() const {
-#if USE_CACHE
   if (getBooleanProp("debug.bcc.nocache")) {
     // Android system environment property: Disables the cache mechanism by
     // setting "debug.bcc.nocache".  So we will not load the cache file any
@@ -849,22 +766,18 @@
   }
 
   return true;
-#else
-  return false;
-#endif
 }
 
-#if USE_MCJIT
 size_t Script::getELFSize() const {
   switch (mStatus) {
     case ScriptStatus::Compiled: {
       return mCompiled->getELFSize();
     }
-#if USE_CACHE
+
     case ScriptStatus::Cached: {
       return mCached->getELFSize();
     }
-#endif
+
     default: {
       return 0;
     }
@@ -876,16 +789,15 @@
     case ScriptStatus::Compiled: {
       return mCompiled->getELF();
     }
-#if USE_CACHE
+
     case ScriptStatus::Cached: {
       return mCached->getELF();
     }
-#endif
+
     default: {
       return NULL;
     }
   }
 }
-#endif
 
 } // namespace bcc
diff --git a/lib/ExecutionEngine/Script.h b/lib/ExecutionEngine/Script.h
index b05fc07..16a453c 100644
--- a/lib/ExecutionEngine/Script.h
+++ b/lib/ExecutionEngine/Script.h
@@ -44,9 +44,7 @@
     enum StatusType {
       Unknown,
       Compiled,
-#if USE_CACHE
-      Cached,
-#endif
+      Cached
     };
   }
 
@@ -71,31 +69,19 @@
 
     union {
       ScriptCompiled *mCompiled;
-#if USE_CACHE
       ScriptCached *mCached;
-#endif
     };
 
-#if USE_CACHE
     std::string mCacheDir;
     std::string mCacheName;
 
     inline std::string getCachedObjectPath() const {
-#if USE_OLD_JIT
-      return std::string(mCacheDir + mCacheName + ".jit-image");
-#elif USE_MCJIT
       return std::string(mCacheDir + mCacheName + ".o");
-#endif
     }
 
     inline std::string getCacheInfoPath() const {
-#if USE_OLD_JIT
-      return getCachedObjectPath().append(".oBCC");
-#elif USE_MCJIT
       return getCachedObjectPath().append(".info");
-#endif
     }
-#endif
 
     bool mIsContextSlotNotAvail;
 
@@ -217,10 +203,6 @@
 
     int registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext);
 
-#if USE_OLD_JIT
-    char *getContext();
-#endif
-
     bool isCacheable() const;
 
     void setError(int error) {
@@ -236,14 +218,13 @@
     }
 
   private:
-#if USE_CACHE
     //
     // It returns 0 if there's a cache hit.
     //
     // Side effect: it will set mCacheDir, mCacheName.
     int internalLoadCache(char const *cacheDir, char const *cacheName,
                           bool checkOnly);
-#endif
+
     int internalCompile(const CompilerOption&);
   };
 
diff --git a/lib/ExecutionEngine/ScriptCached.cpp b/lib/ExecutionEngine/ScriptCached.cpp
index 30fc3fd..bbfac2b 100644
--- a/lib/ExecutionEngine/ScriptCached.cpp
+++ b/lib/ExecutionEngine/ScriptCached.cpp
@@ -18,12 +18,6 @@
 
 #include "ScriptCached.h"
 
-#include <bcc/bcc_cache.h>
-
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
-
 #include "DebugHelper.h"
 
 #include <stdlib.h>
@@ -31,13 +25,6 @@
 namespace bcc {
 
 ScriptCached::~ScriptCached() {
-  // Deallocate the bcc script context
-#if USE_OLD_JIT
-  if (mContext) {
-    ContextManager::get().deallocateContext(mContext);
-  }
-#endif
-
   // Deallocate string pool, exported var list, exported func list
   if (mpStringPoolRaw) { free(mpStringPoolRaw); }
   if (mpExportVars) { free(mpExportVars); }
@@ -127,11 +114,7 @@
 
 
 void *ScriptCached::lookup(const char *name) {
-#if USE_MCJIT
   return rsloaderGetSymbolAddress(mRSExecutable, name);
-#endif
-  FuncTable::const_iterator I = mFunctions.find(name);
-  return (I == mFunctions.end()) ? NULL : I->second.first;
 }
 
 void ScriptCached::getFuncInfoList(size_t funcInfoListSize,
diff --git a/lib/ExecutionEngine/ScriptCached.h b/lib/ExecutionEngine/ScriptCached.h
index f18cb88..e24a714 100644
--- a/lib/ExecutionEngine/ScriptCached.h
+++ b/lib/ExecutionEngine/ScriptCached.h
@@ -20,13 +20,10 @@
 #include "Config.h"
 
 #include <bcc/bcc.h>
-#include <bcc/bcc_cache.h>
 #include <bcc/bcc_mccache.h>
 #include "bcc_internal.h"
 
-#if USE_MCJIT
 #include "librsloader.h"
-#endif
 
 #include <llvm/ADT/SmallVector.h>
 
@@ -59,24 +56,18 @@
   private:
     Script *mpOwner;
 
-    OBCC_ExportVarList *mpExportVars;
-    OBCC_ExportFuncList *mpExportFuncs;
-    OBCC_ExportForEachList *mpExportForEach;
+    MCO_ExportVarList *mpExportVars;
+    MCO_ExportFuncList *mpExportFuncs;
+    MCO_ExportForEachList *mpExportForEach;
     PragmaList mPragmas;
-    OBCC_ObjectSlotList *mpObjectSlotList;
+    MCO_ObjectSlotList *mpObjectSlotList;
 
     FuncTable mFunctions;
 
-#if USE_OLD_JIT
-    char *mContext;
-#endif
-
-#if USE_MCJIT
     RSExecRef mRSExecutable;
     llvm::SmallVector<char, 1024> mCachedELFExecutable;
-#endif
 
-    OBCC_StringPool *mpStringPoolRaw;
+    MCO_StringPool *mpStringPoolRaw;
     std::vector<char const *> mStringPool;
 
     bool mLibRSThreadable;
@@ -88,9 +79,6 @@
         mpExportFuncs(NULL),
         mpExportForEach(NULL),
         mpObjectSlotList(NULL),
-#if USE_OLD_JIT
-        mContext(NULL),
-#endif
         mpStringPoolRaw(NULL),
         mLibRSThreadable(false) {
     }
@@ -139,13 +127,6 @@
     void getObjectSlotList(size_t objectSlotListSize,
                            uint32_t *objectSlotList);
 
-#if USE_OLD_JIT
-    char *getContext() {
-      return mContext;
-    }
-#endif
-
-#if USE_MCJIT
     const char *getELF() const {
       return &*mCachedELFExecutable.begin();
     }
@@ -153,7 +134,7 @@
     size_t getELFSize() const {
       return mCachedELFExecutable.size();
     }
-#endif
+
     // Dirty hack for libRS.
     // TODO(all): This should be removed in the future.
     bool isLibRSThreadable() const {
diff --git a/lib/ExecutionEngine/ScriptCompiled.cpp b/lib/ExecutionEngine/ScriptCompiled.cpp
index 47f2bb4..4f2bb1b 100644
--- a/lib/ExecutionEngine/ScriptCompiled.cpp
+++ b/lib/ExecutionEngine/ScriptCompiled.cpp
@@ -17,28 +17,11 @@
 #include "ScriptCompiled.h"
 
 #include "bcc_internal.h"
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
 #include "DebugHelper.h"
 
 namespace bcc {
 
 ScriptCompiled::~ScriptCompiled() {
-#if USE_OLD_JIT
-  // Deallocate the BCC context
-  if (mContext) {
-    ContextManager::get().deallocateContext(mContext);
-  }
-
-  // Delete the emitted function information
-  for (FuncInfoMap::iterator I = mEmittedFunctions.begin(),
-       E = mEmittedFunctions.end(); I != E; I++) {
-    if (I->second != NULL) {
-      delete I->second;
-    }
-  }
-#endif
 }
 
 void ScriptCompiled::getExportVarList(size_t varListSize, void **varList) {
@@ -126,16 +109,7 @@
 
 
 void *ScriptCompiled::lookup(const char *name) {
-#if USE_OLD_JIT
-  FuncInfoMap::const_iterator I = mEmittedFunctions.find(name);
-  return (I == mEmittedFunctions.end()) ? NULL : I->second->addr;
-#endif
-
-#if USE_MCJIT
   return mCompiler.getSymbolAddress(name);
-#endif
-
-  return NULL;
 }
 
 
diff --git a/lib/ExecutionEngine/ScriptCompiled.h b/lib/ExecutionEngine/ScriptCompiled.h
index 4498f1a..d945024 100644
--- a/lib/ExecutionEngine/ScriptCompiled.h
+++ b/lib/ExecutionEngine/ScriptCompiled.h
@@ -65,16 +65,9 @@
 
     FuncInfoMap mEmittedFunctions;
 
-#if USE_OLD_JIT
-    char *mContext; // Context of BCC script (code and data)
-#endif
-
   public:
     ScriptCompiled(Script *owner)
       : mpOwner(owner), mCompiler(this)
-#if USE_OLD_JIT
-        , mContext(NULL)
-#endif
     {
     }
 
@@ -149,13 +142,6 @@
       return mpOwner->getUserDefinedExternalSymbols();
     }
 
-#if USE_OLD_JIT
-    char *getContext() {
-      return mContext;
-    }
-#endif
-
-#if USE_MCJIT
     const char *getELF() const {
       return &*mCompiler.getELF().begin();
     }
@@ -163,7 +149,6 @@
     size_t getELFSize() const {
       return mCompiler.getELF().size();
     }
-#endif
 
     void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
       mCompiler.registerSymbolCallback(pFn, pContext);
diff --git a/lib/ExecutionEngine/SourceInfo.cpp b/lib/ExecutionEngine/SourceInfo.cpp
index 25c53e8..c069462 100644
--- a/lib/ExecutionEngine/SourceInfo.cpp
+++ b/lib/ExecutionEngine/SourceInfo.cpp
@@ -16,23 +16,14 @@
 
 #include "SourceInfo.h"
 
-#if USE_CACHE
-#if USE_OLD_JIT
-#include "OldJIT/CacheReader.h"
-#include "OldJIT/CacheWriter.h"
-#endif
-#if USE_MCJIT
 #include "MCCacheWriter.h"
 #include "MCCacheReader.h"
-#endif
-#endif
 
 #include "DebugHelper.h"
 #include "ScriptCompiled.h"
 #include "Sha1Helper.h"
 
 #include <bcc/bcc.h>
-#include <bcc/bcc_cache.h>
 
 #include <llvm/Bitcode/ReaderWriter.h>
 #include <llvm/Module.h>
@@ -64,7 +55,6 @@
   result->buffer.bitcodeSize = bitcodeSize;
   result->flags = flags;
 
-#if USE_CACHE
   if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) {
     result->flags |= BCC_SKIP_DEP_SHA1;
 
@@ -78,7 +68,6 @@
   } else {
     calcSHA1(result->sha1, bitcode, bitcodeSize);
   }
-#endif
 
   return result;
 }
@@ -96,13 +85,11 @@
   result->file.path = path;
   result->flags = flags;
 
-#if USE_CACHE
   memset(result->sha1, '\0', 20);
 
   if (!(result->flags & BCC_SKIP_DEP_SHA1)) {
     calcFileSHA1(result->sha1, path);
   }
-#endif
 
   return result;
 }
@@ -120,7 +107,6 @@
   result->module = module;
   result->flags = flags;
 
-#if USE_CACHE
   if (! (flags & BCC_SKIP_DEP_SHA1)) {
     result->flags |= BCC_SKIP_DEP_SHA1;
 
@@ -130,7 +116,6 @@
   }
 
   memset(result->sha1, '\0', 20);
-#endif
 
   return result;
 }
@@ -196,7 +181,6 @@
   }
 }
 
-#if USE_CACHE
 template <typename T> void SourceInfo::introDependency(T &checker) {
   if (flags & BCC_SKIP_DEP_SHA1) {
     return;
@@ -216,16 +200,8 @@
   }
 }
 
-#if USE_OLD_JIT
-template void SourceInfo::introDependency<CacheReader>(CacheReader &);
-template void SourceInfo::introDependency<CacheWriter>(CacheWriter &);
-#endif
-
-#if USE_MCJIT
 template void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &);
 template void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &);
-#endif
-#endif // USE_CACHE
 
 
 } // namespace bcc
diff --git a/lib/ExecutionEngine/SourceInfo.h b/lib/ExecutionEngine/SourceInfo.h
index 9026f1c..080d3b4 100644
--- a/lib/ExecutionEngine/SourceInfo.h
+++ b/lib/ExecutionEngine/SourceInfo.h
@@ -61,9 +61,7 @@
 
     unsigned long flags;
 
-#if USE_CACHE
     unsigned char sha1[20];
-#endif
 
   private:
     SourceInfo() : module(NULL), shared_context(false) { }
@@ -91,9 +89,7 @@
     // 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();
   };
diff --git a/libbcc-config.mk b/libbcc-config.mk
index dc3ab33..37cc848 100644
--- a/libbcc-config.mk
+++ b/libbcc-config.mk
@@ -28,33 +28,19 @@
 # Configurations
 #=====================================================================
 
-libbcc_USE_OLD_JIT                  := 0
-libbcc_USE_MCJIT                    := 1
-
-libbcc_USE_CACHE                    := 1
-
-libbcc_DEBUG_OLD_JIT_DISASSEMBLER   := 0
-libbcc_DEBUG_MCJIT_DISASSEMBLER     := 0
+libbcc_DEBUG_MC_DISASSEMBLER        := 0
 
 libbcc_USE_LOGGER                   := 1
 libbcc_USE_FUNC_LOGGER              := 0
 libbcc_DEBUG_BCC_REFLECT            := 0
-libbcc_DEBUG_MCJIT_REFLECT          := 0
+libbcc_DEBUG_MC_REFLECT             := 0
 
 
 #=====================================================================
 # Automatic Configurations
 #=====================================================================
 
-ifeq ($(libbcc_USE_OLD_JIT),0)
-libbcc_DEBUG_OLD_JIT_DISASSEMBLER := 0
-endif
-
-ifeq ($(libbcc_USE_MCJIT),0)
-libbcc_DEBUG_MCJIT_DISASSEMBLER := 0
-endif
-
-ifeq ($(libbcc_DEBUG_OLD_JIT_DISASSEMBLER)$(libbcc_DEBUG_MCJIT_DISASSEMBLER),00)
+ifeq ($(libbcc_DEBUG_MC_DISASSEMBLER),0)
 libbcc_USE_DISASSEMBLER := 0
 else
 libbcc_USE_DISASSEMBLER := 1