diff --git a/Android.mk b/Android.mk
index e3948c8..1e2d2c3 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
diff --git a/Config.h b/Config.h
index ebe0044..500bddf 100644
--- a/Config.h
+++ b/Config.h
@@ -6,7 +6,7 @@
 //---------------------------------------------------------------------------
 // Configuration for JIT & MC Assembler
 //---------------------------------------------------------------------------
-#if !USE_OLD_JIT && !USE_MCJIT
+#if !USE_MCJIT
 #error "You should choose at least one code generation method."
 #endif
 
@@ -14,52 +14,24 @@
 // 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_MCJIT_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"
 #else
-#define DEBUG_OLD_JIT_DISASSEMBLER_FILE "/data/local/tmp/oldjit-dis.s"
 #define DEBUG_MCJIT_DISASSEMBLER_FILE "/data/local/tmp/mcjit-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/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..ffc6088 100644
--- a/lib/ExecutionEngine/Android.mk
+++ b/lib/ExecutionEngine/Android.mk
@@ -33,18 +33,7 @@
   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 \
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index e7bdd52..8f29e27 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
@@ -229,22 +225,6 @@
 }
 
 
-#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
@@ -413,13 +393,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;
@@ -507,132 +480,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
diff --git a/lib/ExecutionEngine/Compiler.h b/lib/ExecutionEngine/Compiler.h
index eebe550..301daed 100644
--- a/lib/ExecutionEngine/Compiler.h
+++ b/lib/ExecutionEngine/Compiler.h
@@ -19,8 +19,7 @@
 
 #include <bcc/bcc.h>
 
-#include "CodeGen/CodeEmitter.h"
-#include "CodeGen/CodeMemoryManager.h"
+#include <Config.h>
 
 #if USE_MCJIT
 #include "librsloader.h"
@@ -85,14 +84,6 @@
 
     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
     llvm::SmallVector<char, 1024> mEmittedELFExecutable;
@@ -126,12 +117,6 @@
       mpSymbolLookupContext = pContext;
     }
 
-#if USE_OLD_JIT
-    CodeMemoryManager *createCodeMemoryManager();
-
-    CodeEmitter *createCodeEmitter();
-#endif
-
 #if USE_MCJIT
     void *getSymbolAddress(char const *name);
 
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..3b67e04 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"
@@ -294,9 +285,7 @@
     return 1;
   }
 
-#if USE_OLD_JIT
-  CacheReader reader;
-#elif USE_MCJIT
+#if USE_MCJIT
   MCCacheReader reader;
 
   // Register symbol lookup function
@@ -413,12 +402,7 @@
   // 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,7 +412,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
+#if USE_MCJIT
     ::unlink(infoPath.c_str());
 #endif
 
@@ -438,9 +422,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
+#if USE_MCJIT
       MCCacheWriter writer;
 #endif
 
@@ -798,29 +780,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;
diff --git a/lib/ExecutionEngine/Script.h b/lib/ExecutionEngine/Script.h
index b05fc07..9253871 100644
--- a/lib/ExecutionEngine/Script.h
+++ b/lib/ExecutionEngine/Script.h
@@ -81,17 +81,13 @@
     std::string mCacheName;
 
     inline std::string getCachedObjectPath() const {
-#if USE_OLD_JIT
-      return std::string(mCacheDir + mCacheName + ".jit-image");
-#elif USE_MCJIT
+#if 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
+#if USE_MCJIT
       return getCachedObjectPath().append(".info");
 #endif
     }
@@ -217,10 +213,6 @@
 
     int registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext);
 
-#if USE_OLD_JIT
-    char *getContext();
-#endif
-
     bool isCacheable() const;
 
     void setError(int error) {
diff --git a/lib/ExecutionEngine/ScriptCached.cpp b/lib/ExecutionEngine/ScriptCached.cpp
index 30fc3fd..03a4f7a 100644
--- a/lib/ExecutionEngine/ScriptCached.cpp
+++ b/lib/ExecutionEngine/ScriptCached.cpp
@@ -20,10 +20,6 @@
 
 #include <bcc/bcc_cache.h>
 
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
-
 #include "DebugHelper.h"
 
 #include <stdlib.h>
@@ -31,13 +27,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); }
diff --git a/lib/ExecutionEngine/ScriptCached.h b/lib/ExecutionEngine/ScriptCached.h
index f18cb88..338dbdb 100644
--- a/lib/ExecutionEngine/ScriptCached.h
+++ b/lib/ExecutionEngine/ScriptCached.h
@@ -67,10 +67,6 @@
 
     FuncTable mFunctions;
 
-#if USE_OLD_JIT
-    char *mContext;
-#endif
-
 #if USE_MCJIT
     RSExecRef mRSExecutable;
     llvm::SmallVector<char, 1024> mCachedELFExecutable;
@@ -88,9 +84,6 @@
         mpExportFuncs(NULL),
         mpExportForEach(NULL),
         mpObjectSlotList(NULL),
-#if USE_OLD_JIT
-        mContext(NULL),
-#endif
         mpStringPoolRaw(NULL),
         mLibRSThreadable(false) {
     }
@@ -139,12 +132,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();
diff --git a/lib/ExecutionEngine/ScriptCompiled.cpp b/lib/ExecutionEngine/ScriptCompiled.cpp
index 47f2bb4..3de7a7f 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,11 +109,6 @@
 
 
 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
diff --git a/lib/ExecutionEngine/ScriptCompiled.h b/lib/ExecutionEngine/ScriptCompiled.h
index 4498f1a..36ef24d 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,12 +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();
diff --git a/lib/ExecutionEngine/SourceInfo.cpp b/lib/ExecutionEngine/SourceInfo.cpp
index 25c53e8..6efdf7e 100644
--- a/lib/ExecutionEngine/SourceInfo.cpp
+++ b/lib/ExecutionEngine/SourceInfo.cpp
@@ -17,10 +17,6 @@
 #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"
@@ -216,11 +212,6 @@
   }
 }
 
-#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 &);
diff --git a/libbcc-config.mk b/libbcc-config.mk
index dc3ab33..1879b10 100644
--- a/libbcc-config.mk
+++ b/libbcc-config.mk
@@ -28,12 +28,10 @@
 # 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_USE_LOGGER                   := 1
@@ -46,15 +44,11 @@
 # 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_MCJIT_DISASSEMBLER),0)
 libbcc_USE_DISASSEMBLER := 0
 else
 libbcc_USE_DISASSEMBLER := 1
