diff --git a/src/runtime.cc b/src/runtime.cc
index f6fdef4..3e9cd8e 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -136,18 +136,16 @@
   // Make sure all other non-daemon threads have terminated, and all daemon threads are suspended.
   delete thread_list_;
   delete monitor_list_;
-
   delete class_linker_;
   delete heap_;
-  verifier::MethodVerifier::Shutdown();
   delete intern_table_;
   delete java_vm_;
   Thread::Shutdown();
   QuasiAtomic::Shutdown();
-
   // TODO: acquire a static mutex on Runtime to avoid racing.
   CHECK(instance_ == NULL || instance_ == this);
   instance_ = NULL;
+  verifier::MethodVerifier::Shutdown();
 }
 
 struct AbortState {
@@ -810,7 +808,6 @@
   thread_list_ = new ThreadList;
   intern_table_ = new InternTable;
 
-  verifier::MethodVerifier::Init();
 
   heap_ = new Heap(options->heap_initial_size_,
                    options->heap_growth_limit_,
@@ -850,6 +847,7 @@
     class_linker_ = ClassLinker::CreateFromCompiler(*options->boot_class_path_, intern_table_);
   }
   CHECK(class_linker_ != NULL);
+  verifier::MethodVerifier::Init();
 
   method_trace_ = options->method_trace_;
   method_trace_file_ = options->method_trace_file_;
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 6018bf8..01f5466 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -3325,6 +3325,7 @@
     MutexLock mu(self, *rejected_classes_lock_);
     rejected_classes_ = new MethodVerifier::RejectedClassesTable;
   }
+  art::verifier::RegTypeCache::Init();
 }
 
 void MethodVerifier::Shutdown() {
@@ -3345,6 +3346,7 @@
   }
   delete rejected_classes_lock_;
   rejected_classes_lock_ = NULL;
+  verifier::RegTypeCache::ShutDown();
 }
 
 void MethodVerifier::AddRejectedClass(CompilerDriver::ClassReference ref) {
diff --git a/src/verifier/method_verifier.h b/src/verifier/method_verifier.h
index 49bc808..ae43162 100644
--- a/src/verifier/method_verifier.h
+++ b/src/verifier/method_verifier.h
@@ -29,7 +29,7 @@
 #include "instruction_flags.h"
 #include "mirror/object.h"
 #include "reg_type.h"
-#include "reg_type_cache.h"
+#include "reg_type_cache-inl.h"
 #include "register_line.h"
 #include "safe_map.h"
 #include "UniquePtr.h"
@@ -192,7 +192,7 @@
                                std::vector<uint32_t>& monitor_enter_dex_pcs)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  static void Init();
+  static void Init() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static void Shutdown();
 
   static bool IsClassRejected(CompilerDriver::ClassReference ref)
diff --git a/src/verifier/reg_type.cc b/src/verifier/reg_type.cc
index 0cca343..774c2b2 100644
--- a/src/verifier/reg_type.cc
+++ b/src/verifier/reg_type.cc
@@ -16,157 +16,592 @@
 
 #include "reg_type.h"
 
+
+#include "base/casts.h"
 #include "dex_file-inl.h"
 #include "mirror/class.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "object_utils.h"
-#include "reg_type_cache.h"
+#include "reg_type_cache-inl.h"
 
 #include <limits>
+#include <sstream>
 
 namespace art {
 namespace verifier {
 
-static const char* type_strings[] = {
-    "Undefined",
-    "Conflict",
-    "boolean",
-    "byte",
-    "short",
-    "char",
-    "int",
-    "float",
-    "long (Low Half)",
-    "long (High Half)",
-    "double (Low Half)",
-    "double (High Half)",
-    "Precise 32-bit Constant",
-    "Imprecise 32-bit Constant",
-    "Precise 64-bit Constant (Low Half)",
-    "Precise 64-bit Constant (High Half)",
-    "Imprecise 64-bit Constant (Low Half)",
-    "Imprecise 64-bit Constant (High Half)",
-    "Unresolved Reference",
-    "Uninitialized Reference",
-    "Uninitialized This Reference",
-    "Unresolved And Uninitialized Reference",
-    "Unresolved And Uninitialized This Reference",
-    "Unresolved Merged References",
-    "Unresolved Super Class",
-    "Reference",
-    "Precise Reference",
-};
+static const bool kIsDebugBuild = false;
+UndefinedType* UndefinedType::instance_ = NULL;
+ConflictType* ConflictType::instance_ = NULL;
+BooleanType* BooleanType::instance = NULL;
+ByteType* ByteType::instance_ = NULL;
+ShortType* ShortType::instance_ = NULL;
+CharType* CharType::instance_ = NULL;
+FloatType* FloatType::instance_ = NULL;
+LongLoType* LongLoType::instance_ = NULL;
+LongHiType* LongHiType::instance_ = NULL;
+DoubleLoType* DoubleLoType::instance_ = NULL;
+DoubleHiType* DoubleHiType::instance_ = NULL;
+IntegerType* IntegerType::instance_ = NULL;
 
-std::string RegType::Dump(const RegTypeCache* reg_types) const {
-  DCHECK(type_ >=  kRegTypeUndefined && type_ <= kRegTypePreciseReference);
-  DCHECK(arraysize(type_strings) == (kRegTypePreciseReference + 1));
-  std::string result;
-  if (IsUnresolvedMergedReference()) {
-    if (reg_types == NULL) {
-      std::pair<uint16_t, uint16_t> refs = GetTopMergedTypes();
-      result += StringPrintf("UnresolvedMergedReferences(%d, %d)", refs.first, refs.second);
-    } else {
-      std::set<uint16_t> types = GetMergedTypes(reg_types);
-      result += "UnresolvedMergedReferences(";
-      typedef std::set<uint16_t>::const_iterator It;  // TODO: C++0x auto
-      It it = types.begin();
-      result += reg_types->GetFromId(*it).Dump(reg_types);
-      for(++it; it != types.end(); ++it) {
-        result += ", ";
-        result += reg_types->GetFromId(*it).Dump(reg_types);
-      }
-      result += ")";
-    }
-  } else if (IsUnresolvedSuperClass()) {
-    uint16_t super_type_id = GetUnresolvedSuperClassChildId();
-    if (reg_types == NULL) {
-      result += StringPrintf("UnresolvedSuperClass(%d)", super_type_id);
-    } else {
-      result += "UnresolvedSuperClass(";
-      result += reg_types->GetFromId(super_type_id).Dump(reg_types);
-      result += ")";
-    }
-  } else if (IsConstant()) {
-    uint32_t val = ConstantValue();
-    if (val == 0) {
-      CHECK(IsPreciseConstant());
-      result = "Zero/null";
-    } else {
-      result = IsPreciseConstant() ? "Precise " : "Imprecise ";
-      if (IsConstantShort()) {
-        result += StringPrintf("Constant: %d", val);
-      } else {
-        result += StringPrintf("Constant: 0x%x", val);
-      }
-    }
-  } else if (IsConstantLo()) {
-    int32_t val = ConstantValueLo();
-    result = IsPreciseConstantLo() ? "Precise " : "Imprecise ";
-    if (val >= std::numeric_limits<jshort>::min() &&
-        val <= std::numeric_limits<jshort>::max()) {
-      result += StringPrintf("Low-half Constant: %d", val);
-    } else {
-      result += StringPrintf("Low-half Constant: 0x%x", val);
-    }
-  } else if (IsConstantHi()) {
-    int32_t val = ConstantValueHi();
-    result = IsPreciseConstantHi() ? "Precise " : "Imprecise ";
-    if (val >= std::numeric_limits<jshort>::min() &&
-        val <= std::numeric_limits<jshort>::max()) {
-      result += StringPrintf("High-half Constant: %d", val);
-    } else {
-      result += StringPrintf("High-half Constant: 0x%x", val);
-    }
+std::string PreciseConstType::Dump() const {
+  std::stringstream result;
+  uint32_t val = ConstantValue();
+  if (val == 0) {
+    CHECK(IsPreciseConstant());
+    result << "Zero/null";
   } else {
-    result = type_strings[type_];
-    if (IsReferenceTypes()) {
-      result += ": ";
-      if (IsUnresolvedTypes()) {
-        result += PrettyDescriptor(GetDescriptor());
-      } else {
-        result += PrettyDescriptor(GetClass());
-      }
+    result << "Precise ";
+    if (IsConstantShort()) {
+      result << StringPrintf("Constant: %d", val);
+    } else {
+      result << StringPrintf("Constant: 0x%x", val);
     }
   }
-  return result;
+  return result.str();
+}
+
+std::string BooleanType::Dump() const {
+  return "boolean";
+}
+
+std::string ConflictType::Dump() const {
+    return "Conflict";
+}
+std::string ByteType::Dump() const {
+  return "Byte";
+}
+std::string ShortType::Dump() const {
+  return "short";
+}
+std::string CharType::Dump() const {
+  return "Char";
+}
+std::string FloatType::Dump() const {
+  return "float";
+}
+std::string LongLoType::Dump() const {
+  return "long (Low Half)";
+}
+std::string LongHiType::Dump() const {
+  return "long (High Half)";
+}
+std::string DoubleLoType::Dump() const {
+  return "Double (Low Half)";
+}
+std::string DoubleHiType::Dump() const {
+  return "Double (High Half)";
+}
+std::string IntegerType::Dump() const {
+    return "Integer";
+}
+
+
+DoubleHiType* DoubleHiType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                           uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new DoubleHiType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+
+DoubleHiType* DoubleHiType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+
+void DoubleHiType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+
+DoubleLoType* DoubleLoType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                           uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new DoubleLoType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+
+DoubleLoType* DoubleLoType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+
+void DoubleLoType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+
+LongLoType* LongLoType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                       uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new LongLoType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+
+LongHiType* LongHiType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                       uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new LongHiType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+
+LongHiType* LongHiType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+
+void LongHiType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+
+LongLoType* LongLoType::GetInstance() {
+  CHECK (instance_ != NULL);
+  return instance_;
+}
+
+void LongLoType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+
+FloatType* FloatType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                     uint16_t cache_id)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  if (instance_ == NULL) {
+    instance_ = new FloatType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+FloatType* FloatType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+
+void FloatType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+
+CharType* CharType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                   uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new CharType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+CharType* CharType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+void CharType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+
+ShortType* ShortType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                     uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new ShortType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+ShortType* ShortType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+void ShortType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+ByteType* ByteType::CreateInstance(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  if (instance_ == NULL) {
+    instance_ = new ByteType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+ByteType* ByteType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+void ByteType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+IntegerType* IntegerType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                         uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new IntegerType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+IntegerType* IntegerType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+void IntegerType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+ConflictType* ConflictType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                           uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new ConflictType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+ConflictType* ConflictType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+void ConflictType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+BooleanType* BooleanType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                         uint16_t cache_id) {
+  if (BooleanType::instance == NULL) {
+    instance = new BooleanType(klass, descriptor, cache_id);
+  }
+  return BooleanType::instance;
+}
+BooleanType* BooleanType::GetInstance() {
+  CHECK(BooleanType::instance != NULL);
+  return BooleanType::instance;
+}
+
+void BooleanType::Destroy() {
+  if(BooleanType::instance != NULL) {
+    delete instance;
+    instance = NULL;
+  }
+}
+
+std::string UndefinedType::Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  return "Undefined";
+}
+UndefinedType* UndefinedType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                             uint16_t cache_id) {
+  if (instance_ == NULL) {
+    instance_ = new UndefinedType(klass, descriptor, cache_id);
+  }
+  return instance_;
+}
+UndefinedType* UndefinedType::GetInstance() {
+  CHECK(instance_ != NULL);
+  return instance_;
+}
+void UndefinedType::Destroy() {
+  if (instance_ != NULL) {
+    delete instance_;
+    instance_ = NULL;
+  }
+}
+std::string UnresolvedMergedType::Dump() const {
+  std::stringstream result;
+  std::set<uint16_t> types = GetMergedTypes();
+  result << "UnresolvedMergedReferences(";
+  typedef std::set<uint16_t>::const_iterator It;  // TODO: C++0x auto
+  It it = types.begin();
+  result << reg_type_cache_->GetFromId(*it).Dump();
+  for (++it; it != types.end(); ++it) {
+    result << ", ";
+    result << reg_type_cache_->GetFromId(*it).Dump();
+  }
+  result << ")";
+  return result.str();
+}
+std::string UnresolvedSuperClass::Dump() const {
+  std::stringstream result;
+  uint16_t super_type_id = GetUnresolvedSuperClassChildId();
+  result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")";
+  return result.str();
+}
+
+std::string UnresolvedReferenceType::Dump() const {
+  std::stringstream result;
+  result << "Unresolved Reference" << ": " << PrettyDescriptor(GetDescriptor());
+  return result.str();
+}
+
+std::string UnresolvedUninitializedRefType::Dump() const {
+  std::stringstream result;
+  result << "Unresolved And Uninitialized Reference" << ": " << PrettyDescriptor(GetDescriptor());
+  result << " Allocation PC: " << GetAllocationPc();
+  return result.str();
+}
+
+std::string UnresolvedUninitialisedThisRefType::Dump() const {
+  std::stringstream result;
+  result << "Unresolved And Uninitialized This Reference" << PrettyDescriptor(GetDescriptor());
+  return result.str();
+}
+
+std::string ReferenceType::Dump() const {
+  std::stringstream result;
+  result << "Reference" << ": " << PrettyDescriptor(GetClass());
+  return result.str();
+}
+
+std::string PreciseReferenceType::Dump() const {
+  std::stringstream result;
+  result << "Precise Reference" << ": "<< PrettyDescriptor(GetClass());
+  return result.str();
+}
+
+std::string UninitialisedReferenceType::Dump() const {
+  std::stringstream result;
+  result << "Uninitialized Reference" << ": " << PrettyDescriptor(GetClass());
+  result << " Allocation PC: " << GetAllocationPc();
+  return result.str();
+}
+std::string UninitialisedThisReferenceType::Dump() const {
+  std::stringstream result;
+  result << "Uninitialized This Reference" << ": " << PrettyDescriptor(GetClass());
+  result << "Allocation PC: " << GetAllocationPc();
+  return result.str();
+}
+
+std::string ImpreciseConstType::Dump() const {
+  std::stringstream result;
+  uint32_t val = ConstantValue();
+  if (val == 0) {
+    CHECK(IsPreciseConstant());
+    result << "Zero/null";
+  } else {
+    result << "Imprecise ";
+    if (IsConstantShort()) {
+      result << StringPrintf("Constant: %d", val);
+    } else {
+      result << StringPrintf("Constant: 0x%x", val);
+    }
+  }
+  return result.str();
+}
+std::string PreciseConstLoType::Dump() const {
+  std::stringstream result;
+
+  int32_t val = ConstantValueLo();
+  result << "Precise ";
+  if (val >= std::numeric_limits<jshort>::min() &&
+      val <= std::numeric_limits<jshort>::max()) {
+    result << StringPrintf("Low-half Constant: %d", val);
+  } else {
+    result << StringPrintf("Low-half Constant: 0x%x", val);
+  }
+  return result.str();
+}
+
+std::string ImpreciseConstLoType::Dump() const {
+  std::stringstream result;
+
+  int32_t val = ConstantValueLo();
+  result << "Imprecise ";
+  if (val >= std::numeric_limits<jshort>::min() &&
+      val <= std::numeric_limits<jshort>::max()) {
+    result << StringPrintf("Low-half Constant: %d", val);
+  } else {
+    result << StringPrintf("Low-half Constant: 0x%x", val);
+  }
+  return result.str();
+}
+
+std::string PreciseConstHiType::Dump() const {
+  std::stringstream result;
+  int32_t val = ConstantValueHi();
+  result << "Precise ";
+  if (val >= std::numeric_limits<jshort>::min() &&
+      val <= std::numeric_limits<jshort>::max()) {
+    result << StringPrintf("High-half Constant: %d", val);
+  } else {
+    result << StringPrintf("High-half Constant: 0x%x", val);
+  }
+  return result.str();
+}
+
+std::string ImpreciseConstHiType::Dump() const {
+  std::stringstream result;
+  int32_t val = ConstantValueHi();
+  result << "Imprecise ";
+  if (val >= std::numeric_limits<jshort>::min() &&
+      val <= std::numeric_limits<jshort>::max()) {
+    result << StringPrintf("High-half Constant: %d", val);
+  } else {
+    result << StringPrintf("High-half Constant: 0x%x", val);
+  }
+  return result.str();
+}
+
+BooleanType::BooleanType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      : RegType(klass, descriptor, cache_id) {
+}
+
+ConflictType::ConflictType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+ByteType::ByteType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+ShortType::ShortType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+CharType::CharType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+IntegerType::IntegerType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+ConstantType::ConstantType(uint32_t constat, uint16_t cache_id)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_): RegType(NULL, "", cache_id), constant_(constat) {
+}
+
+ReferenceType::ReferenceType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, std::string& descriptor,
+                                           uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+UnresolvedUninitialisedThisRefType::UnresolvedUninitialisedThisRefType(std::string& descriptor,
+                                                                       uint16_t cache_id)
+    : UninitializedType(NULL, descriptor, 0, cache_id) {
+}
+
+UnresolvedUninitializedRefType::UnresolvedUninitializedRefType( std::string& descriptor,
+                                                         uint32_t allocation_pc, uint16_t cache_id)
+    : UninitializedType(NULL, descriptor, allocation_pc, cache_id) {
+}
+
+UninitialisedReferenceType::UninitialisedReferenceType(mirror::Class* klass,
+                                std::string& descriptor, uint32_t allocation_pc, uint16_t cache_id)
+    : UninitializedType(klass, descriptor, allocation_pc, cache_id) {
+}
+
+LongHiType::LongHiType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+FloatType::FloatType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+DoubleLoType::DoubleLoType(mirror::Class* klass,  std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+DoubleHiType::DoubleHiType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+LongLoType::LongLoType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+const RegType& UndefinedType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  if (incoming_type.IsUndefined()) {
+    return *this;  // Undefined MERGE Undefined => Undefined
+  }
+  return reg_types->Conflict();
 }
 
 const RegType& RegType::HighHalf(RegTypeCache* cache) const {
   DCHECK(IsLowHalf());
-  if (type_ == kRegTypeLongLo) {
-    return cache->FromType(kRegTypeLongHi);
-  } else if (type_ == kRegTypeDoubleLo) {
-    return cache->FromType(kRegTypeDoubleHi);
+  if (IsLongLo()) {
+    return cache->LongHi();
+  } else if (IsDoubleLo()) {
+    return cache->DoubleHi();
   } else {
-    DCHECK_EQ(type_, kRegTypeImpreciseConstLo);
-    return cache->FromType(kRegTypeImpreciseConstHi);
+    DCHECK(IsImpreciseConstantLo());
+    return cache->FromCat2ConstHi(ConstantValue(), false);
   }
 }
 
-std::set<uint16_t> RegType::GetMergedTypes(const RegTypeCache* cache) const {
+Primitive::Type RegType::GetPrimitiveType() const {
+  if (IsNonZeroReferenceTypes()) {
+    return Primitive::kPrimNot;
+  } else if (IsBooleanTypes()) {
+    return Primitive::kPrimBoolean;
+  } else if (IsByteTypes()) {
+    return Primitive::kPrimByte;
+  } else if (IsShortTypes()) {
+    return Primitive::kPrimShort;
+  } else if (IsCharTypes()) {
+    return Primitive::kPrimChar;
+  } else if (IsFloat()) {
+    return Primitive::kPrimFloat;
+  } else if (IsIntegralTypes()) {
+    return Primitive::kPrimInt;
+  } else if (IsDoubleLo()) {
+    return Primitive::kPrimDouble;
+  } else {
+    DCHECK(IsLongTypes());
+    return Primitive::kPrimLong;
+  }
+}
+
+std::set<uint16_t> UnresolvedMergedType::GetMergedTypes() const {
   std::pair<uint16_t, uint16_t> refs = GetTopMergedTypes();
-  const RegType& left = cache->GetFromId(refs.first);
-  const RegType& right = cache->GetFromId(refs.second);
+  const RegType& _left(reg_type_cache_->GetFromId(refs.first));
+  RegType& __left(const_cast<RegType&>(_left));
+  UnresolvedMergedType* left = down_cast<UnresolvedMergedType*>(&__left);
+
+  RegType& _right(
+      const_cast<RegType&>(reg_type_cache_->GetFromId(refs.second)));
+  UnresolvedMergedType* right = down_cast<UnresolvedMergedType*>(&_right);
+
   std::set<uint16_t> types;
-  if (left.IsUnresolvedMergedReference()) {
-    types = left.GetMergedTypes(cache);
+  if (left->IsUnresolvedMergedReference()) {
+    types = left->GetMergedTypes();
   } else {
     types.insert(refs.first);
   }
-  if (right.IsUnresolvedMergedReference()) {
-    std::set<uint16_t> right_types = right.GetMergedTypes(cache);
+  if (right->IsUnresolvedMergedReference()) {
+    std::set<uint16_t> right_types = right->GetMergedTypes();
     types.insert(right_types.begin(), right_types.end());
   } else {
     types.insert(refs.second);
   }
-#ifndef NDEBUG
-  typedef std::set<uint16_t>::const_iterator It;  // TODO: C++0x auto
-  for(It it = types.begin(); it != types.end(); ++it) {
-    CHECK(!cache->GetFromId(*it).IsUnresolvedMergedReference());
+  if (kIsDebugBuild) {
+    typedef std::set<uint16_t>::const_iterator It;  // TODO: C++0x auto
+    for (It it = types.begin(); it != types.end(); ++it) {
+      CHECK(!reg_type_cache_->GetFromId(*it).IsUnresolvedMergedReference());
+    }
   }
-#endif
   return types;
 }
 
@@ -200,13 +635,13 @@
     } else if (!other_unresolved) {
       return other.GetClass()->IsPublic();  // Be conservative, only allow if other is public.
     } else {
-      return false; // More complicated test not possible on unresolved types, be conservative.
+      return false;  // More complicated test not possible on unresolved types, be conservative.
     }
   }
 }
 
 bool RegType::CanAccessMember(mirror::Class* klass, uint32_t access_flags) const {
-  if (access_flags & kAccPublic) {
+  if ((access_flags & kAccPublic) != 0) {
     return true;
   }
   if (!IsUnresolvedTypes()) {
@@ -229,23 +664,6 @@
   }
 }
 
-bool RegType::IsConstantByte() const {
-  return IsConstant() &&
-      ConstantValue() >= std::numeric_limits<jbyte>::min() &&
-      ConstantValue() <= std::numeric_limits<jbyte>::max();
-}
-
-bool RegType::IsConstantShort() const {
-  return IsConstant() &&
-      ConstantValue() >= std::numeric_limits<jshort>::min() &&
-      ConstantValue() <= std::numeric_limits<jshort>::max();
-}
-
-bool RegType::IsConstantChar() const {
-  return IsConstant() && ConstantValue() >= 0 &&
-      ConstantValue() <= std::numeric_limits<jchar>::max();
-}
-
 bool RegType::IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   return IsReference() && GetClass()->IsObjectClass();
 }
@@ -272,30 +690,41 @@
   return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
 }
 
+ImpreciseConstType::ImpreciseConstType(uint32_t constat, uint16_t cache_id)
+  : ConstantType(constat, cache_id) {
+}
+
 bool RegType::IsAssignableFrom(const RegType& src) const {
   if (Equals(src)) {
     return true;
   } else {
-    switch (GetType()) {
-      case RegType::kRegTypeBoolean:  return src.IsBooleanTypes();
-      case RegType::kRegTypeByte:     return src.IsByteTypes();
-      case RegType::kRegTypeShort:    return src.IsShortTypes();
-      case RegType::kRegTypeChar:     return src.IsCharTypes();
-      case RegType::kRegTypeInteger:  return src.IsIntegralTypes();
-      case RegType::kRegTypeFloat:    return src.IsFloatTypes();
-      case RegType::kRegTypeLongLo:   return src.IsLongTypes();
-      case RegType::kRegTypeDoubleLo: return src.IsDoubleTypes();
-      default:
-        if (!IsReferenceTypes()) {
-          LOG(FATAL) << "Unexpected register type in IsAssignableFrom: '" << src << "'";
-        }
-        if (src.IsZero()) {
-          return true;  // all reference types can be assigned null
-        } else if (!src.IsReferenceTypes()) {
-          return false;  // expect src to be a reference type
-        } else if (IsJavaLangObject()) {
-          return true;  // all reference types can be assigned to Object
-        } else if (!IsUnresolvedTypes() && GetClass()->IsInterface()) {
+    if (IsBoolean()) {
+      return src.IsBooleanTypes();
+    } else if (IsByte()) {
+      return src.IsByteTypes();
+    } else if (IsShort()) {
+      return src.IsShortTypes();
+    } else if (IsChar()) {
+      return src.IsCharTypes();
+    } else if (IsInteger()) {
+      return src.IsIntegralTypes();
+    } else if (IsFloat()) {
+      return src.IsFloatTypes();
+    } else if (IsLongLo()) {
+      return src.IsLongTypes();
+    } else if (IsDoubleLo()) {
+      return src.IsDoubleTypes();
+    } else {
+      if (!IsReferenceTypes()) {
+        LOG(FATAL) << "Unexpected register type in 4bleFrom: '" << src << "'";
+      }
+      if (src.IsZero()) {
+        return true;  // all reference types can be assigned null
+      } else if (!src.IsReferenceTypes()) {
+        return false;  // expect src to be a reference type
+      } else if (IsJavaLangObject()) {
+        return true;  // all reference types can be assigned to Object
+      } else if (!IsUnresolvedTypes() && GetClass()->IsInterface()) {
           return true;  // We allow assignment to any interface, see comment in ClassJoin
         } else if (IsJavaLangObjectArray()) {
           return src.IsObjectArrayTypes();  // All reference arrays may be assigned to Object[]
@@ -303,23 +732,39 @@
                    GetClass()->IsAssignableFrom(src.GetClass())) {
           // We're assignable from the Class point-of-view
           return true;
+        } else if (IsUnresolvedTypes()) {
+          // Unresolved types are only assignable for null, Object and equality.
+          return (src.IsZero() || src.IsJavaLangObject());
         } else {
-          // TODO: unresolved types are only assignable for null, Object and equality currently.
           return false;
         }
     }
   }
 }
 
+int32_t ConstantType::ConstantValue() const {
+  DCHECK(IsConstantTypes());
+  return constant_;
+}
+int32_t ConstantType::ConstantValueLo() const {
+  DCHECK(IsConstantLo());
+  return constant_;
+}
+int32_t ConstantType::ConstantValueHi() const {
+  if (IsConstantHi() || IsPreciseConstantHi() || IsImpreciseConstantHi()) {
+    return constant_;
+  } else {
+    DCHECK(false);
+    return 0;
+  }
+}
 static const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
   return a.IsConstant() ? b : a;
 }
 
 const RegType& RegType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const {
   DCHECK(!Equals(incoming_type));  // Trivial equality handled by caller
-  if (IsUndefined() && incoming_type.IsUndefined()) {
-    return *this;  // Undefined MERGE Undefined => Undefined
-  } else if (IsConflict()) {
+  if (IsConflict()) {
     return *this;  // Conflict MERGE * => Conflict
   } else if (incoming_type.IsConflict()) {
     return incoming_type;  // * MERGE Conflict => Conflict
@@ -497,40 +942,59 @@
 }
 
 void RegType::CheckInvariants() const {
-  bool checked = false;
   if (IsConstant() || IsConstantLo() || IsConstantHi()) {
-    // Constants: allocation_pc_or_constant_or_merged_types_ will hold the constant value, nothing
-    // else should be defined.
     CHECK(descriptor_.empty()) << *this;
     CHECK(klass_ == NULL) << *this;
-    checked = true;
   }
-  if (IsUnresolvedTypes()) {
-    if (IsUnresolvedMergedReference() || IsUnresolvedSuperClass()) {
-      // Unresolved super/merged types: allocation pc/merged types should be defined.
-      CHECK(descriptor_.empty()) << *this;
-      CHECK(klass_ == NULL) << *this;
-      CHECK_NE(allocation_pc_or_constant_or_merged_types_, 0U) << *this;
-    } else {
-      // Unresolved types: have a descriptor and no allocation pc/merged types.
-      CHECK(!descriptor_.empty()) << *this;
-      CHECK(klass_ == NULL) << *this;
-      if (!IsUnresolvedAndUninitializedReference()) {
-        CHECK_EQ(allocation_pc_or_constant_or_merged_types_, 0U) << *this;
-      }
-    }
-    checked = true;
-  }
-  if (IsReferenceTypes() && !checked) {
-    // A resolved reference type.
-    CHECK(descriptor_.empty()) << *this;
-    CHECK(klass_ != NULL) << *this;
-    CHECK(klass_->IsClass()) << *this;
-    if (!IsUninitializedReference()) {
-      CHECK_EQ(allocation_pc_or_constant_or_merged_types_, 0U) << *this;
-    }
-  }
-  CHECK(checked = true);
+}
+
+UninitializedType::UninitializedType(mirror::Class* klass, std::string& descriptor,
+                                     uint32_t allocation_pc, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id), allocation_pc_(allocation_pc) {
+}
+
+void UninitializedType::CheckInvariants() const {
+  CHECK_EQ(allocation_pc_, 0U) << *this;
+}
+
+void UninitialisedThisReferenceType::CheckInvariants() const {
+  UninitializedType::CheckInvariants();
+}
+
+UninitialisedThisReferenceType::UninitialisedThisReferenceType(mirror::Class* klass,
+  std::string& descriptor, uint16_t cache_id) : UninitializedType(klass, descriptor, 0, cache_id) {
+}
+
+void UnresolvedUninitialisedThisRefType::CheckInvariants() const {
+  UninitializedType::CheckInvariants();
+  CHECK(!descriptor_.empty()) << *this;
+  CHECK(klass_ == NULL) << *this;
+}
+
+void UnresolvedUninitializedRefType::CheckInvariants() const {
+  UninitializedType::CheckInvariants();
+  CHECK(!descriptor_.empty()) << *this;
+  CHECK(klass_ == NULL) << *this;
+}
+
+void UnresolvedMergedType::CheckInvariants() const {
+  // Unresolved merged types: merged types should be defined.
+  CHECK(descriptor_.empty()) << *this;
+  CHECK(klass_ == NULL) << *this;
+  CHECK_NE(merged_types_.first, 0U) << *this;
+  CHECK_NE(merged_types_.second, 0U) << *this;
+}
+
+void UnresolvedReferenceType::CheckInvariants() const {
+  CHECK(!descriptor_.empty()) << *this;
+  CHECK(klass_ == NULL) << *this;
+}
+
+void UnresolvedSuperClass::CheckInvariants() const {
+  // Unresolved merged types: merged types should be defined.
+  CHECK(descriptor_.empty()) << *this;
+  CHECK(klass_ == NULL) << *this;
+  CHECK_NE(unresolved_child_id_, 0U) << *this;
 }
 
 std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
diff --git a/src/verifier/reg_type.h b/src/verifier/reg_type.h
index dc9a33a..94adfe3 100644
--- a/src/verifier/reg_type.h
+++ b/src/verifier/reg_type.h
@@ -22,6 +22,7 @@
 
 #include "jni.h"
 
+#include <limits>
 #include <stdint.h>
 #include <set>
 #include <string>
@@ -33,385 +34,766 @@
 namespace verifier {
 
 class RegTypeCache;
-
 /*
  * RegType holds information about the "type" of data held in a register.
  */
 class RegType {
  public:
-  enum Type {
-    // A special state that identifies a register as undefined.
-    kRegTypeUndefined = 0,
-    // The bottom type, used to denote the type of operations such as returning a void, throwing
-    // an exception or merging incompatible types, such as an int and a long.
-    kRegTypeConflict,
-    kRegTypeBoolean,        // Z.
-    kRegType1nrSTART = kRegTypeBoolean,
-    kRegTypeIntegralSTART = kRegTypeBoolean,
-    kRegTypeByte,           // B.
-    kRegTypeShort,          // S.
-    kRegTypeChar,           // C.
-    kRegTypeInteger,        // I.
-    kRegTypeIntegralEND = kRegTypeInteger,
-    kRegTypeFloat,          // F.
-    kRegType1nrEND = kRegTypeFloat,
-    kRegTypeLongLo,         // J - lower-numbered register; endian-independent.
-    kRegTypeLongHi,
-    kRegTypeDoubleLo,       // D.
-    kRegTypeDoubleHi,
-    kRegTypeLastFixedLocation = kRegTypeDoubleHi,
-    kRegTypePreciseConst,   // 32-bit constant - could be float or int.
-    kRegTypeImpreciseConst, // 32-bit constant derived value - could be float or int.
-    kRegTypePreciseConstLo, // Const wide, lower half - could be long or double.
-    kRegTypePreciseConstHi, // Const wide, upper half - could be long or double.
-    kRegTypeImpreciseConstLo, // Const derived wide, lower half - could be long or double.
-    kRegTypeImpreciseConstHi, // Const derived wide, upper half - could be long or double.
-    kRegTypeUnresolvedReference,        // Reference type that couldn't be resolved.
-    kRegTypeUninitializedReference,     // Freshly allocated reference type.
-    kRegTypeUninitializedThisReference, // Freshly allocated reference passed as "this".
-    kRegTypeUnresolvedAndUninitializedReference, // Freshly allocated unresolved reference type.
-                                        // Freshly allocated unresolved reference passed as "this".
-    kRegTypeUnresolvedAndUninitializedThisReference,
-    kRegTypeUnresolvedMergedReference,  // Tree of merged references (at least 1 is unresolved).
-    kRegTypeUnresolvedSuperClass,       // Super class of an unresolved type.
-    kRegTypeReference,                  // Reference type.
-    kRegTypePreciseReference,           // Precisely the given type.
-  };
-
-  Type GetType() const {
-    return type_;
+  // The high half that corresponds to this low half
+  const RegType& HighHalf(RegTypeCache* cache) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsUndefined() const {
+    return false;
   }
-
-  bool IsUndefined() const { return type_ == kRegTypeUndefined; }
-  bool IsConflict() const { return type_ == kRegTypeConflict; }
-  bool IsBoolean() const { return type_ == kRegTypeBoolean; }
-  bool IsByte()    const { return type_ == kRegTypeByte; }
-  bool IsChar()    const { return type_ == kRegTypeChar; }
-  bool IsShort()   const { return type_ == kRegTypeShort; }
-  bool IsInteger() const { return type_ == kRegTypeInteger; }
-  bool IsLong()    const { return type_ == kRegTypeLongLo; }
-  bool IsFloat()   const { return type_ == kRegTypeFloat; }
-  bool IsDouble()  const { return type_ == kRegTypeDoubleLo; }
-  bool IsUnresolvedReference() const { return type_ == kRegTypeUnresolvedReference; }
-  bool IsUninitializedReference() const { return type_ == kRegTypeUninitializedReference; }
-  bool IsUninitializedThisReference() const { return type_ == kRegTypeUninitializedThisReference; }
-  bool IsUnresolvedAndUninitializedReference() const {
-    return type_ == kRegTypeUnresolvedAndUninitializedReference;
+  inline virtual bool IsConflict() const {
+    return false;
   }
-  bool IsUnresolvedAndUninitializedThisReference() const {
-    return type_ == kRegTypeUnresolvedAndUninitializedThisReference;
+  inline virtual bool IsBoolean() const {
+    return false;
   }
-  bool IsUnresolvedMergedReference() const {  return type_ == kRegTypeUnresolvedMergedReference; }
-  bool IsUnresolvedSuperClass() const {  return type_ == kRegTypeUnresolvedSuperClass; }
-  bool IsReference() const { return type_ == kRegTypeReference; }
-  bool IsPreciseReference() const { return type_ == kRegTypePreciseReference; }
-
-  bool IsUninitializedTypes() const {
-    return IsUninitializedReference() || IsUninitializedThisReference() ||
-        IsUnresolvedAndUninitializedReference() || IsUnresolvedAndUninitializedThisReference();
+  inline virtual bool IsByte() const {
+    return false;
   }
-  bool IsUnresolvedTypes() const {
-    return IsUnresolvedReference() || IsUnresolvedAndUninitializedReference() ||
-        IsUnresolvedAndUninitializedThisReference() || IsUnresolvedMergedReference() ||
-        IsUnresolvedSuperClass();
+  inline virtual bool IsChar() const {
+    return false;
   }
-  bool IsLowHalf() const {
-    return type_ == kRegTypeLongLo ||
-           type_ == kRegTypeDoubleLo ||
-           type_ == kRegTypePreciseConstLo ||
-           type_ == kRegTypeImpreciseConstLo;
+  inline virtual bool IsShort() const {
+    return false;
   }
-  bool IsHighHalf() const {
-    return type_ == kRegTypeLongHi ||
-           type_ == kRegTypeDoubleHi ||
-           type_ == kRegTypePreciseConstHi ||
-           type_ == kRegTypeImpreciseConstHi;
+  inline virtual bool IsInteger() const {
+    return false;
   }
-
-  bool IsLongOrDoubleTypes() const { return IsLowHalf(); }
-
-  // Check this is the low half, and that type_h is its matching high-half
-  bool CheckWidePair(const RegType& type_h) const {
-    if (IsLowHalf()) {
-      return (type_h.type_ == type_ + 1) ||
-          (IsPreciseConstantLo() && type_h.IsImpreciseConstantHi()) ||
-          (IsImpreciseConstantLo() && type_h.IsPreciseConstantHi());
-    }
+  inline virtual bool IsLongLo() const {
+    return false;
+  }
+  inline virtual bool IsLongHi() const {
+    return false;
+  }
+  inline virtual bool IsFloat() const {
+    return false;
+  }
+  inline virtual bool IsDouble() const {
+    return false;
+  }
+  inline virtual bool IsDoubleLo() const {
+    return false;
+  }
+  inline virtual bool IsDoubleHi() const {
+    return false;
+  }
+  inline virtual bool IsUnresolvedReference() const {
+    return false;
+  }
+  inline virtual bool IsUninitializedReference() const {
+    return false;
+  }
+  inline virtual bool IsUninitializedThisReference() const {
+    return false;
+  }
+  inline virtual bool IsUnresolvedAndUninitializedReference() const {
+    return false;
+  }
+  inline virtual bool IsUnresolvedAndUninitializedThisReference() const {
+    return false;
+  }
+  inline virtual bool IsUnresolvedMergedReference() const {
+    return false;
+  }
+  inline virtual bool IsUnresolvedSuperClass() const {
+    return false;
+  }
+  inline virtual bool IsReference() const {
+    return false;
+  }
+  inline virtual bool IsPreciseReference() const {
+    return false;
+  }
+  inline virtual bool IsPreciseConstant() const {
+    return false;
+  }
+  inline virtual bool IsPreciseConstantLo() const {
+    return false;
+  }
+  inline virtual bool IsPreciseConstantHi() const {
+    return false;
+  }
+  inline virtual bool IsImpreciseConstantLo() const {
+    return false;
+  }
+  inline virtual bool IsImpreciseConstantHi() const {
+    return false;
+  }
+  virtual bool IsImpreciseConstant() const {
     return false;
   }
 
-  // The high half that corresponds to this low half
-  const RegType& HighHalf(RegTypeCache* cache) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  bool IsPreciseConstant() const {
-    return type_ == kRegTypePreciseConst;
-  }
-  bool IsPreciseConstantLo() const {
-    return type_ == kRegTypePreciseConstLo;
-  }
-  bool IsPreciseConstantHi() const {
-    return type_ == kRegTypePreciseConstHi;
-  }
-  bool IsImpreciseConstantLo() const {
-    return type_ == kRegTypeImpreciseConstLo;
-  }
-  bool IsImpreciseConstantHi() const {
-    return type_ == kRegTypeImpreciseConstHi;
+  inline virtual bool IsConstantTypes() const {
+    return false;
   }
   bool IsConstant() const {
-    return type_ == kRegTypePreciseConst || type_ == kRegTypeImpreciseConst;
+    return (IsPreciseConstant() || IsImpreciseConstant());
   }
-
   bool IsConstantLo() const {
-    return type_ == kRegTypePreciseConstLo || type_ == kRegTypeImpreciseConstLo;
+    return (IsPreciseConstantLo() || IsImpreciseConstantLo());
+  }
+  bool IsPrecise() const {
+    return (IsPreciseConstantLo() || IsPreciseConstant() ||
+            IsPreciseConstantHi());
   }
   bool IsLongConstant() const {
     return IsConstantLo();
   }
   bool IsConstantHi() const {
-    return type_ == kRegTypePreciseConstHi || type_ == kRegTypeImpreciseConstHi;
+    return (IsPreciseConstantHi() || IsImpreciseConstantHi());
   }
   bool IsLongConstantHigh() const {
     return IsConstantHi();
   }
-
-  // If this is a 32-bit constant, what is the value? This value may be imprecise in which case
-  // the value represents part of the integer range of values that may be held in the register.
-  int32_t ConstantValue() const {
-    DCHECK(IsConstant());
-    return allocation_pc_or_constant_or_merged_types_;
+  bool IsUninitializedTypes() const {
+    return IsUninitializedReference() || IsUninitializedThisReference() ||
+           IsUnresolvedAndUninitializedReference() ||
+           IsUnresolvedAndUninitializedThisReference();
   }
-  int32_t ConstantValueLo() const {
-    DCHECK(IsConstantLo());
-    return allocation_pc_or_constant_or_merged_types_;
-  }
-  int32_t ConstantValueHi() const {
-    DCHECK(IsConstantHi());
-    return allocation_pc_or_constant_or_merged_types_;
+  bool IsUnresolvedTypes() const {
+    return IsUnresolvedReference() || IsUnresolvedAndUninitializedReference() ||
+           IsUnresolvedAndUninitializedThisReference() ||
+           IsUnresolvedMergedReference() || IsUnresolvedSuperClass();
   }
 
-  bool IsZero()         const { return IsPreciseConstant() && ConstantValue() == 0; }
-  bool IsOne()          const { return IsPreciseConstant() && ConstantValue() == 1; }
+  bool IsLowHalf() const {
+    return (IsLongLo() || IsDoubleLo() || IsPreciseConstantLo() ||
+            IsImpreciseConstantLo());
+  }
+  bool IsHighHalf() const {
+    return (IsLongHi() || IsDoubleHi() || IsPreciseConstantHi() ||
+            IsImpreciseConstantHi());
+  }
+  bool IsLongOrDoubleTypes() const {
+    return IsLowHalf();
+  }
+  // Check this is the low half, and that type_h is its matching high-half
+  inline bool CheckWidePair(const RegType& type_h) const {
+    return true;
+    if (IsLowHalf()) {
+      return ((IsPreciseConstantLo() && type_h.IsImpreciseConstantHi()) ||
+              (IsImpreciseConstantLo() && type_h.IsPreciseConstantHi()) ||
+              (IsDoubleLo() && type_h.IsDoubleHi()) ||
+              (IsLongLo() && type_h.IsLongHi()));
+    }
+    return false;
+  }
   bool IsConstantBoolean() const {
-    return IsConstant() && ConstantValue() >= 0 && ConstantValue() <= 1;
+    return IsConstant() && (ConstantValue() >= 0) && (ConstantValue() <= 1);
   }
-  bool IsConstantByte() const;
-  bool IsConstantShort() const;
-  bool IsConstantChar() const;
-
+  inline virtual bool IsConstantChar() const {
+    return false;
+  }
+  inline virtual bool IsConstantByte() const {
+    return false;
+  }
+  inline virtual bool IsConstantShort() const {
+    return false;
+  }
+  inline virtual bool IsOne() const {
+    return false;
+  }
+  inline virtual bool IsZero() const {
+    return false;
+  }
   bool IsReferenceTypes() const {
     return IsNonZeroReferenceTypes() || IsZero();
   }
-
   bool IsNonZeroReferenceTypes() const {
-    return IsReference() || IsPreciseReference() || IsUnresolvedReference() ||
-        IsUninitializedReference() || IsUninitializedThisReference() ||
-        IsUnresolvedAndUninitializedReference() || IsUnresolvedAndUninitializedThisReference() ||
-        IsUnresolvedMergedReference() || IsUnresolvedSuperClass();
+    return IsReference() || IsPreciseReference() ||
+           IsUninitializedReference() || IsUninitializedThisReference() ||
+           IsUnresolvedReference() || IsUnresolvedAndUninitializedReference() ||
+           IsUnresolvedAndUninitializedThisReference() ||
+           IsUnresolvedMergedReference() || IsUnresolvedSuperClass();
   }
-
   bool IsCategory1Types() const {
-    return (type_ >= kRegType1nrSTART && type_ <= kRegType1nrEND) || IsConstant();
+    return (IsBoolean() || IsByte() || IsShort() || IsChar() || IsInteger() ||
+            IsFloat() || IsConstant());
   }
-
   bool IsCategory2Types() const {
     return IsLowHalf();  // Don't expect explicit testing of high halves
   }
-
-  bool IsBooleanTypes() const { return IsBoolean() || IsConstantBoolean(); }
-  bool IsByteTypes() const { return IsByte() || IsBoolean() || IsConstantByte(); }
-  bool IsShortTypes() const { return IsShort() || IsByte() || IsBoolean() || IsConstantShort(); }
-  bool IsCharTypes() const { return IsChar() || IsBooleanTypes() || IsConstantChar(); }
-  bool IsIntegralTypes() const {
-    return (type_ >= kRegTypeIntegralSTART && type_ <= kRegTypeIntegralEND) || IsConstant();
+  bool IsBooleanTypes() const {
+    return IsBoolean() || IsConstantBoolean();
   }
-  bool IsArrayIndexTypes() const { return IsIntegralTypes(); }
-
+  bool IsByteTypes() const {
+    return IsByte() || IsBoolean() || IsConstantByte();
+  }
+  bool IsShortTypes() const {
+    return IsShort() || IsByte() || IsBoolean() || IsConstantShort();
+  }
+  bool IsCharTypes() const {
+    return IsChar() || IsBooleanTypes() || IsConstantChar();
+  }
+  bool IsIntegralTypes() const {
+    return (IsBoolean() || IsByte() || IsShort() || IsChar() || IsInteger() || IsConstant());
+  }
+  inline virtual int32_t ConstantValue() const {
+    CHECK(IsConstant());
+    return -1;
+  }
+  inline virtual int32_t ConstantValueLo() const {
+    CHECK(IsConstantLo());
+    return -1;
+  }
+  inline virtual int32_t ConstantValueHi() const {
+    CHECK(IsConstantHi());
+    return -1;
+  }
+  bool IsArrayIndexTypes() const {
+    return IsIntegralTypes();
+  }
   // Float type may be derived from any constant type
-  bool IsFloatTypes() const { return IsFloat() || IsConstant(); }
-
+  bool IsFloatTypes() const {
+    return IsFloat() || IsConstant();
+  }
   bool IsLongTypes() const {
-    return IsLong() || IsLongConstant();
+    return IsLongLo() || IsLongConstant();
   }
   bool IsLongHighTypes() const {
-    return type_ == kRegTypeLongHi ||
-           type_ == kRegTypePreciseConstHi ||
-           type_ == kRegTypeImpreciseConstHi;
+    return (IsLongConstantHigh() || IsPreciseConstantHi() ||
+            IsImpreciseConstantHi());
   }
   bool IsDoubleTypes() const {
-    return IsDouble() || IsLongConstant();
+    return IsDoubleLo() || IsLongConstant();
   }
   bool IsDoubleHighTypes() const {
-    return type_ == kRegTypeDoubleHi ||
-           type_ == kRegTypePreciseConstHi ||
-           type_ == kRegTypeImpreciseConstHi;
+    return (IsDoubleHi() || IsPreciseConstantHi() || IsImpreciseConstantHi());
   }
-
-  uint32_t GetAllocationPc() const {
-    DCHECK(IsUninitializedTypes());
-    return allocation_pc_or_constant_or_merged_types_;
+  inline virtual bool IsLong() const {
+    return false;
   }
-
   bool HasClass() const {
-    return IsReference() || IsPreciseReference();
+    return IsReference() || IsPreciseReference() || IsUninitializedReference() ||
+           IsUninitializedThisReference();
   }
-
-  mirror::Class* GetClass() const {
-    DCHECK(!IsUnresolvedReference());
-    DCHECK(klass_ != NULL);
-    return klass_;
-  }
-
   bool IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   bool IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   bool IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  Primitive::Type GetPrimitiveType() const {
-    if (IsNonZeroReferenceTypes()) {
-      return Primitive::kPrimNot;
-    } else if (IsBooleanTypes()) {
-      return Primitive::kPrimBoolean;
-    } else if (IsByteTypes()) {
-      return Primitive::kPrimByte;
-    } else if (IsShortTypes()) {
-      return Primitive::kPrimShort;
-    } else if (IsCharTypes()) {
-      return Primitive::kPrimChar;
-    } else if (IsFloat()) {
-      return Primitive::kPrimFloat;
-    } else if (IsIntegralTypes()) {
-      return Primitive::kPrimInt;
-    } else if (IsDouble()) {
-      return Primitive::kPrimDouble;
-    } else {
-      DCHECK(IsLongTypes());
-      return Primitive::kPrimLong;
-    }
-  }
-
+  Primitive::Type GetPrimitiveType() const ;
   bool IsJavaLangObjectArray() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   bool IsInstantiableTypes() const;
-
   std::string GetDescriptor() const {
     DCHECK(IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass());
     return descriptor_;
   }
-
   uint16_t GetId() const {
     return cache_id_;
   }
-
-  // The top of a tree of merged types.
-  std::pair<uint16_t, uint16_t> GetTopMergedTypes() const {
-    DCHECK(IsUnresolvedMergedReference());
-    uint16_t type1 = static_cast<uint16_t>(allocation_pc_or_constant_or_merged_types_ & 0xFFFF);
-    uint16_t type2 = static_cast<uint16_t>(allocation_pc_or_constant_or_merged_types_ >> 16);
-    return std::pair<uint16_t, uint16_t>(type1, type2);
-  }
-
-  // The complete set of merged types.
-  std::set<uint16_t> GetMergedTypes(const RegTypeCache* cache) const;
-
-  uint16_t GetUnresolvedSuperClassChildId() const {
-    DCHECK(IsUnresolvedSuperClass());
-    return static_cast<uint16_t>(allocation_pc_or_constant_or_merged_types_ & 0xFFFF);
-  }
-
   const RegType& GetSuperClass(RegTypeCache* cache) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  std::string Dump(const RegTypeCache* reg_types = NULL) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0;
   // Can this type access other?
-  bool CanAccess(const RegType& other) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  bool CanAccess(const RegType& other) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   // Can this type access a member with the given properties?
   bool CanAccessMember(mirror::Class* klass, uint32_t access_flags) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   // Can this type be assigned by src?
-  bool IsAssignableFrom(const RegType& src) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  bool Equals(const RegType& other) const { return GetId() == other.GetId(); }
-
+  bool IsAssignableFrom(const RegType& src) const  SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  bool Equals(const RegType& other) const {
+    return GetId() == other.GetId();
+  }
   // Compute the merge of this register from one edge (path) with incoming_type from another.
-  const RegType& Merge(const RegType& incoming_type, RegTypeCache* reg_types) const
+  virtual const RegType& Merge(const RegType& incoming_type, RegTypeCache* reg_types) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  mirror::Class* GetClass() const {
+    DCHECK(!IsUnresolvedReference());
+    DCHECK(klass_ != NULL);
+    DCHECK(HasClass());
+    return klass_;
+  }
+    /*
+     * A basic Join operation on classes. For a pair of types S and T the Join, written S v T = J, is
+     * S <: J, T <: J and for-all U such that S <: U, T <: U then J <: U. That is J is the parent of
+     * S and T such that there isn't a parent of both S and T that isn't also the parent of J (ie J
+     * is the deepest (lowest upper bound) parent of S and T).
+     *
+     * This operation applies for regular classes and arrays, however, for interface types there needn't
+     * be a partial ordering on the types. We could solve the problem of a lack of a partial order by
+     * introducing sets of types, however, the only operation permissible on an interface is
+     * invoke-interface. In the tradition of Java verifiers [1] we defer the verification of interface
+     * types until an invoke-interface call on the interface typed reference at runtime and allow
+     * the perversion of Object being assignable to an interface type (note, however, that we don't
+     * allow assignment of Object or Interface to any concrete class and are therefore type safe).
+     *
+     * [1] Java bytecode verification: algorithms and formalizations, Xavier Leroy
+     */
 
-  /*
-   * A basic Join operation on classes. For a pair of types S and T the Join, written S v T = J, is
-   * S <: J, T <: J and for-all U such that S <: U, T <: U then J <: U. That is J is the parent of
-   * S and T such that there isn't a parent of both S and T that isn't also the parent of J (ie J
-   * is the deepest (lowest upper bound) parent of S and T).
-   *
-   * This operation applies for regular classes and arrays, however, for interface types there needn't
-   * be a partial ordering on the types. We could solve the problem of a lack of a partial order by
-   * introducing sets of types, however, the only operation permissible on an interface is
-   * invoke-interface. In the tradition of Java verifiers [1] we defer the verification of interface
-   * types until an invoke-interface call on the interface typed reference at runtime and allow
-   * the perversion of Object being assignable to an interface type (note, however, that we don't
-   * allow assignment of Object or Interface to any concrete class and are therefore type safe).
-   *
-   * [1] Java bytecode verification: algorithms and formalizations, Xavier Leroy
-   */
   static mirror::Class* ClassJoin(mirror::Class* s, mirror::Class* t)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- private:
+  RegType(mirror::Class* klass, std::string descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : descriptor_(descriptor), klass_(klass), cache_id_(cache_id) {
+  }
+  inline virtual ~RegType() {
+  }
+  virtual void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   friend class RegTypeCache;
 
-  RegType(Type type, mirror::Class* klass,
-          uint32_t allocation_pc_or_constant_or_merged_types, uint16_t cache_id)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      : type_(type), klass_(klass),
-        allocation_pc_or_constant_or_merged_types_(allocation_pc_or_constant_or_merged_types),
-        cache_id_(cache_id) {
-#ifndef NDEBUG
-    CheckInvariants();
-#endif
-  }
-
-  RegType(Type type, const std::string& descriptor, uint32_t allocation_pc, uint16_t cache_id)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      : type_(type),
-        klass_(NULL),
-        descriptor_(descriptor),
-        allocation_pc_or_constant_or_merged_types_(allocation_pc),
-        cache_id_(cache_id) {
-#ifndef NDEBUG
-    CheckInvariants();
-#endif
-  }
-
-  void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  const Type type_;  // The current type of the register
-
-  // For reference types, if known the type of the register...
+ protected:
+  const std::string descriptor_;
   mirror::Class* klass_;
-  // ...else a String for the descriptor.
-  std::string descriptor_;
-
-  // Overloaded field that:
-  //   - if IsConstant() holds a 32bit constant value
-  //   - is IsUninitializedReference()/IsUnresolvedAndUninitializedReference() holds the pc the
-  //     instance in the register was being allocated.
-  const uint32_t allocation_pc_or_constant_or_merged_types_;
-
-  // A RegType cache densely encodes types, this is the location in the cache for this type
   const uint16_t cache_id_;
 
   DISALLOW_COPY_AND_ASSIGN(RegType);
 };
+
+class ConflictType : public RegType {
+ public:
+  inline virtual bool IsConflict() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ConflictType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                      uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ConflictType* GetInstance();
+  static void Destroy();
+ private:
+  ConflictType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ConflictType* instance_;
+};
+
+class UndefinedType : public RegType {
+ public:
+  inline virtual bool IsUndefined() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static UndefinedType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                       uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static UndefinedType* GetInstance();
+  static void Destroy();
+ private:
+  UndefinedType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : RegType(klass, descriptor, cache_id) {
+  }
+  virtual const RegType& Merge(const RegType& incoming_type, RegTypeCache* reg_types) const
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static UndefinedType* instance_;
+};
+
+class IntegerType : public RegType {
+ public:
+  inline virtual bool IsInteger() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static IntegerType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                     uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static IntegerType* GetInstance();
+  static void Destroy();
+ private:
+  IntegerType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static IntegerType* instance_;
+};
+
+class BooleanType : public RegType {
+ public:
+  inline virtual bool IsBoolean() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static BooleanType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                     uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static BooleanType* GetInstance();
+  static void Destroy();
+ private:
+  BooleanType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static BooleanType* instance;
+};
+
+class ByteType : public RegType {
+ public:
+  inline virtual bool IsByte() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ByteType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                  uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ByteType* GetInstance();
+  static void Destroy();
+ private:
+  ByteType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ByteType* instance_;
+};
+
+class ShortType : public RegType {
+ public:
+  inline virtual bool IsShort() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ShortType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                   uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ShortType* GetInstance();
+  static void Destroy();
+ private:
+  ShortType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static ShortType* instance_;
+};
+
+class CharType : public RegType {
+ public:
+  inline virtual bool IsChar() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static CharType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                  uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static CharType* GetInstance();
+  static void Destroy();
+ private:
+  CharType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static CharType* instance_;
+};
+
+class FloatType : public RegType {
+ public:
+  inline virtual bool IsFloat() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static FloatType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                   uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static FloatType* GetInstance();
+  static void Destroy();
+ private:
+  FloatType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static FloatType* instance_;
+};
+
+class LongLoType : public RegType {
+ public:
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsLongLo() const {
+    return true;
+  }
+  inline virtual bool IsLong() const {
+    return true;
+  }
+  static LongLoType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                    uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+   static LongLoType* GetInstance();
+  static void Destroy();
+ private:
+  LongLoType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static LongLoType* instance_;
+};
+
+class LongHiType : public RegType {
+ public:
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsLongHi() const {
+    return true;
+  }
+  static LongHiType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                    uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static LongHiType* GetInstance();
+  static void Destroy();
+ private:
+  LongHiType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static LongHiType* instance_;
+};
+
+class DoubleLoType : public RegType {
+ public:
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsDoubleLo() const {
+    return true;
+  }
+  inline virtual bool IsDouble() const {
+    return true;
+  }
+  static DoubleLoType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                      uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static DoubleLoType* GetInstance();
+  static void Destroy();
+ private:
+  DoubleLoType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static DoubleLoType* instance_;
+};
+
+class DoubleHiType : public RegType {
+ public:
+  virtual std::string Dump() const;
+  inline virtual bool IsDoubleHi() const {
+    return true;
+  }
+  static DoubleHiType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+                                      uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static DoubleHiType* GetInstance();
+  static void Destroy();
+ private:
+  DoubleHiType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  static DoubleHiType* instance_;
+};
+
+class ConstantType : public RegType {
+ public:
+  ConstantType(uint32_t constat, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  inline virtual ~ConstantType() {
+  }
+  const uint32_t constant_;
+  // If this is a 32-bit constant, what is the value? This value may be imprecise in which case
+  // the value represents part of the integer range of values that may be held in the register.
+  virtual int32_t ConstantValue() const;
+  virtual int32_t ConstantValueLo() const;
+  virtual int32_t ConstantValueHi() const;
+
+  bool IsZero() const {
+    return IsPreciseConstant() && ConstantValue() == 0;
+  }
+  bool IsOne() const {
+    return IsPreciseConstant() && ConstantValue() == 1;
+  }
+
+  bool IsConstantChar() const {
+    return IsConstant() && ConstantValue() >= 0 &&
+           ConstantValue() <= std::numeric_limits<jchar>::max();
+  }
+  bool IsConstantByte() const {
+    return IsConstant() &&
+           ConstantValue() >= std::numeric_limits<jbyte>::min() &&
+           ConstantValue() <= std::numeric_limits<jbyte>::max();
+  }
+  bool IsConstantShort() const {
+    return IsConstant() &&
+           ConstantValue() >= std::numeric_limits<jshort>::min() &&
+           ConstantValue() <= std::numeric_limits<jshort>::max();
+  }
+  inline virtual bool IsConstantTypes() const { return true; }
+};
+class PreciseConstType : public ConstantType {
+ public:
+  PreciseConstType(uint32_t constat, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : ConstantType(constat, cache_id) {
+  }
+
+  inline virtual bool IsPreciseConstant() const {
+    return true;
+  }
+
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+class PreciseConstLoType : public ConstantType {
+ public:
+  PreciseConstLoType(uint32_t constat, uint16_t cache_id)
+     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : ConstantType(constat, cache_id) {
+  }
+  inline virtual bool IsPreciseConstantLo() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+class PreciseConstHiType : public ConstantType {
+ public:
+  PreciseConstHiType(uint32_t constat, uint16_t cache_id)
+     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : ConstantType(constat, cache_id) {
+  }
+  inline virtual bool IsPreciseConstantHi() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+
+class ImpreciseConstType : public ConstantType {
+ public:
+  ImpreciseConstType(uint32_t constat, uint16_t cache_id)
+     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual  bool IsImpreciseConstant() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+class ImpreciseConstLoType : public ConstantType {
+ public:
+  ImpreciseConstLoType(uint32_t constat, uint16_t cache_id)
+     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : ConstantType(constat, cache_id) {
+  }
+  inline virtual bool IsImpreciseConstantLo() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+class ImpreciseConstHiType : public ConstantType {
+ public:
+  ImpreciseConstHiType(uint32_t constat, uint16_t cache_id)
+     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : ConstantType(constat, cache_id) {
+  }
+  inline virtual bool IsImpreciseConstantHi() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+class UninitializedType : public RegType {
+ public:
+  UninitializedType(mirror::Class* klass, std::string& descriptor, uint32_t allocation_pc,
+                    uint16_t cache_id);
+  inline virtual ~UninitializedType() {
+  }
+
+  uint32_t GetAllocationPc() const {
+    DCHECK(IsUninitializedTypes());
+    return allocation_pc_;
+  }
+  virtual void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+  const uint32_t allocation_pc_;
+};
+
+class UninitialisedReferenceType : public UninitializedType {
+ public:
+  UninitialisedReferenceType(mirror::Class* klass, std::string& descriptor, uint32_t allocation_pc,
+                             uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  inline virtual bool IsUninitializedReference() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+
+class UnresolvedUninitializedRefType : public UninitializedType {
+ public:
+  UnresolvedUninitializedRefType(std::string& descriptor, uint32_t allocation_pc,
+                                 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsUnresolvedAndUninitializedReference() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+
+class UninitialisedThisReferenceType : public UninitializedType {
+ public:
+  UninitialisedThisReferenceType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsUninitializedThisReference() const {
+    return true;
+  }
+};
+class UnresolvedUninitialisedThisRefType : public UninitializedType {
+ public:
+  UnresolvedUninitialisedThisRefType(std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsUnresolvedAndUninitializedThisReference() const {
+    return true;
+  }
+};
+
+class ReferenceType : public RegType {
+ public:
+  ReferenceType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsReference() const {
+    return true;
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+};
+
+class PreciseReferenceType : public RegType {
+ public:
+  PreciseReferenceType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsPreciseReference() const {
+    return true;
+  }
+};
+
+class UnresolvedReferenceType : public RegType {
+ public:
+  UnresolvedReferenceType(std::string& descriptor, uint16_t cache_id)
+     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : RegType(NULL, descriptor, cache_id) {
+  }
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  inline virtual bool IsUnresolvedReference() const {
+    return true;
+  }
+};
+
+class UnresolvedSuperClass : public RegType {
+ public:
+  UnresolvedSuperClass(uint16_t child_id, RegTypeCache* reg_type_cache, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : RegType(NULL, "", cache_id), unresolved_child_id_(child_id),
+        reg_type_cache_(reg_type_cache) {
+  }
+  inline virtual bool IsUnresolvedSuperClass() const {
+    return true;
+  }
+  uint16_t GetUnresolvedSuperClassChildId() const {
+    DCHECK(IsUnresolvedSuperClass());
+    return static_cast<uint16_t>(unresolved_child_id_ & 0xFFFF);
+  }
+  virtual void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+ const uint16_t unresolved_child_id_;
+ const RegTypeCache* const reg_type_cache_;
+};
+
+class UnresolvedMergedType : public RegType {
+ public:
+  UnresolvedMergedType(uint16_t left_id, uint16_t right_id, const RegTypeCache* reg_type_cache, uint16_t cache_id)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+      : RegType(NULL, "", cache_id), reg_type_cache_(reg_type_cache) ,merged_types_(left_id, right_id) {
+  }
+  // The top of a tree of merged types.
+  std::pair<uint16_t, uint16_t> GetTopMergedTypes() const {
+    DCHECK(IsUnresolvedMergedReference());
+    return merged_types_;
+  }
+  // The complete set of merged types.
+  std::set<uint16_t> GetMergedTypes() const;
+  inline virtual bool IsUnresolvedMergedReference() const {
+    return true;
+  }
+  virtual void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  virtual std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+  const RegTypeCache* const reg_type_cache_;
+  const std::pair<uint16_t, uint16_t> merged_types_;
+};
+
 std::ostream& operator<<(std::ostream& os, const RegType& rhs)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
 }  // namespace verifier
 }  // namespace art
 
diff --git a/src/verifier/reg_type_cache-inl.h b/src/verifier/reg_type_cache-inl.h
new file mode 100644
index 0000000..0c6e8d0
--- /dev/null
+++ b/src/verifier/reg_type_cache-inl.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_VERIFIER_REG_TYPE_CACHE_INL_H_
+#define ART_SRC_VERIFIER_REG_TYPE_CACHE_INL_H_
+
+#include "reg_type.h"
+#include "reg_type_cache.h"
+#include "class_linker.h"
+
+namespace art {
+namespace verifier {
+template <class Type>
+Type* RegTypeCache::CreatePrimitiveTypeInstance(mirror::ClassLoader* loader, std::string descriptor) {
+  mirror::Class* klass = NULL;
+  // Try loading the class from linker.
+  if (!descriptor.empty()) {
+    klass = art::Runtime::Current()->GetClassLinker()->FindSystemClass(descriptor.c_str());
+  }
+  Type* entry = Type::CreateInstance(klass, descriptor, RegTypeCache::primitive_count_);
+  RegTypeCache::primitive_count_++;
+  return entry;
+}
+
+}  // namespace verifier
+}  // namespace art
+#endif  // ART_SRC_VERIFIER_REG_TYPE_CACHE_INL_H_
diff --git a/src/verifier/reg_type_cache.cc b/src/verifier/reg_type_cache.cc
index 96a6c24..c7a1b4f 100644
--- a/src/verifier/reg_type_cache.cc
+++ b/src/verifier/reg_type_cache.cc
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-#include "reg_type_cache.h"
+#include "reg_type_cache-inl.h"
 
+#include "base/casts.h"
 #include "dex_file-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/object-inl.h"
@@ -23,356 +24,466 @@
 
 namespace art {
 namespace verifier {
-
-static RegType::Type RegTypeFromPrimitiveType(Primitive::Type prim_type) {
-  switch (prim_type) {
-    case Primitive::kPrimBoolean: return RegType::kRegTypeBoolean;
-    case Primitive::kPrimByte:    return RegType::kRegTypeByte;
-    case Primitive::kPrimShort:   return RegType::kRegTypeShort;
-    case Primitive::kPrimChar:    return RegType::kRegTypeChar;
-    case Primitive::kPrimInt:     return RegType::kRegTypeInteger;
-    case Primitive::kPrimLong:    return RegType::kRegTypeLongLo;
-    case Primitive::kPrimFloat:   return RegType::kRegTypeFloat;
-    case Primitive::kPrimDouble:  return RegType::kRegTypeDoubleLo;
-    case Primitive::kPrimVoid:
-    default:                      return RegType::kRegTypeConflict;
-  }
-}
-
-static RegType::Type RegTypeFromDescriptor(const std::string& descriptor) {
-  if (descriptor.length() == 1) {
-    switch (descriptor[0]) {
-      case 'Z': return RegType::kRegTypeBoolean;
-      case 'B': return RegType::kRegTypeByte;
-      case 'S': return RegType::kRegTypeShort;
-      case 'C': return RegType::kRegTypeChar;
-      case 'I': return RegType::kRegTypeInteger;
-      case 'J': return RegType::kRegTypeLongLo;
-      case 'F': return RegType::kRegTypeFloat;
-      case 'D': return RegType::kRegTypeDoubleLo;
-      case 'V':
-      default:  return RegType::kRegTypeConflict;
-    }
-  } else if (descriptor[0] == 'L' || descriptor[0] == '[') {
-    return RegType::kRegTypeReference;
-  } else {
-    return RegType::kRegTypeConflict;
-  }
-}
-
-const RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor,
-                                            bool precise) {
-  return From(RegTypeFromDescriptor(descriptor), loader, descriptor, precise);
-}
+bool RegTypeCache::primitive_initialized_ = false;
+uint16_t RegTypeCache::primitive_start_ = 0;
+uint16_t RegTypeCache::primitive_count_ = 0;
 
 static bool MatchingPrecisionForClass(RegType* entry, bool precise)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   return (entry->IsPreciseReference() == precise) || (entry->GetClass()->IsFinal() && !precise);
 }
 
-const RegType& RegTypeCache::From(RegType::Type type, mirror::ClassLoader* loader,
-                                  const char* descriptor, bool precise) {
-  if (type <= RegType::kRegTypeLastFixedLocation) {
-    // entries should be sized greater than primitive types
-    DCHECK_GT(entries_.size(), static_cast<size_t>(type));
-    RegType* entry = entries_[type];
-    if (entry == NULL) {
-      mirror::Class* c = NULL;
-      if (strlen(descriptor) != 0) {
-        c = Runtime::Current()->GetClassLinker()->FindSystemClass(descriptor);
-      }
-      entry = new RegType(type, c, 0, type);
-      entries_[type] = entry;
-    }
-    return *entry;
-  } else {
-    DCHECK(type == RegType::kRegTypeReference || type == RegType::kRegTypePreciseReference);
-    ClassHelper kh;
-    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
-      RegType* cur_entry = entries_[i];
-      // check resolved and unresolved references, ignore uninitialized references
-      if (cur_entry->HasClass()) {
-        kh.ChangeClass(cur_entry->GetClass());
-        if (MatchingPrecisionForClass(cur_entry, precise) &&
-            (strcmp(descriptor, kh.GetDescriptor()) == 0)) {
-          return *cur_entry;
-        }
-      } else if (cur_entry->IsUnresolvedReference() &&
-                 cur_entry->GetDescriptor() == descriptor) {
-        return *cur_entry;
-      }
-    }
-    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-    mirror::Class* c;
-    if (can_load_classes_) {
-      c = class_linker->FindClass(descriptor, loader);
-    } else {
-      c = class_linker->LookupClass(descriptor, loader);
-    }
-    if (c != NULL) {
-      // Able to resolve so create resolved register type that is precise if we
-      // know the type is final.
-      RegType* entry = new RegType(c->IsFinal() ? RegType::kRegTypePreciseReference
-                                                : RegType::kRegTypeReference,
-                                   c, 0, entries_.size());
-      entries_.push_back(entry);
-      return *entry;
-    } else {
-      // TODO: we assume unresolved, but we may be able to do better by validating whether the
-      // descriptor string is valid
-      // Unable to resolve so create unresolved register type
-      if (can_load_classes_) {
-        DCHECK(Thread::Current()->IsExceptionPending());
-        Thread::Current()->ClearException();
-      } else {
-        DCHECK(!Thread::Current()->IsExceptionPending());
-      }
-      if (IsValidDescriptor(descriptor)) {
-        RegType* entry =
-            new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size());
-        entries_.push_back(entry);
-        return *entry;
-      } else {
-        // The descriptor is broken return the unknown type as there's nothing sensible that
-        // could be done at runtime
+void RegTypeCache::FillPrimitiveTypes() {
+  entries_.push_back(UndefinedType::GetInstance());
+  entries_.push_back(ConflictType::GetInstance());
+  entries_.push_back(BooleanType::GetInstance());
+  entries_.push_back(ByteType::GetInstance());
+  entries_.push_back(ShortType::GetInstance());
+  entries_.push_back(CharType::GetInstance());
+  entries_.push_back(IntegerType::GetInstance());
+  entries_.push_back(LongLoType::GetInstance());
+  entries_.push_back(LongHiType::GetInstance());
+  entries_.push_back(FloatType::GetInstance());
+  entries_.push_back(DoubleLoType::GetInstance());
+  entries_.push_back(DoubleHiType::GetInstance());
+  DCHECK_EQ(entries_.size(), primitive_count_);
+}
+
+const RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise) {
+  CHECK(RegTypeCache::primitive_initialized_);
+  if (std::string(descriptor).length() == 1) {
+    switch (descriptor[0]) {
+      case 'Z':
+        return Boolean();
+      case 'B':
+        return Byte();
+      case 'S':
+        return Short();
+      case 'C':
+        return Char();
+      case 'I':
+        return Integer();
+      case 'J':
+        return LongLo();
+      case 'F':
+        return Float();
+      case 'D':
+        return DoubleLo();
+      case 'V':  // For void types, conflict types.
+      default:
         return Conflict();
-      }
     }
+  } else if (descriptor[0] == 'L' || descriptor[0] == '[') {
+    return From(loader, descriptor, precise);
+  } else {
+    return Conflict();
+  }
+};
+
+const art::verifier::RegType& RegTypeCache::GetFromId(uint16_t id) const {
+  DCHECK_LT(id, entries_.size());
+  RegType* result = entries_[id];
+  DCHECK(result != NULL);
+  return *result;
+}
+
+const RegType& RegTypeCache::RegTypeFromPrimitiveType(
+    Primitive::Type prim_type) const {
+  CHECK(RegTypeCache::primitive_initialized_);
+  switch (prim_type) {
+    case Primitive::kPrimBoolean:
+      return *BooleanType::GetInstance();
+    case Primitive::kPrimByte:
+      return *ByteType::GetInstance();
+    case Primitive::kPrimShort:
+      return *ShortType::GetInstance();
+    case Primitive::kPrimChar:
+      return *CharType::GetInstance();
+    case Primitive::kPrimInt:
+      return *IntegerType::GetInstance();
+    case Primitive::kPrimLong:
+      return *LongLoType::GetInstance();
+    case Primitive::kPrimFloat:
+      return *FloatType::GetInstance();
+    case Primitive::kPrimDouble:
+      return *DoubleLoType::GetInstance();
+    case Primitive::kPrimVoid:
+    default:
+      return *ConflictType::GetInstance();
   }
 }
 
+bool RegTypeCache::MatchDescriptor(size_t idx, std::string& descriptor, bool precise) {
+  ClassHelper kh;
+  RegType* cur_entry = entries_[idx];
+  // Check if we have matching descriptors and precision
+  // in cases where the descriptor available
+  if (cur_entry->descriptor_ != "" &&
+      MatchingPrecisionForClass(cur_entry, precise) &&
+      descriptor == cur_entry->descriptor_) {
+    return true;
+  }
+  // check resolved and unresolved references, ignore uninitialized references
+  if (cur_entry->HasClass()) {
+    kh.ChangeClass(cur_entry->GetClass());
+    // So we might have cases where we have the class but not the descriptor
+    // for that class we need the class helper to get the descriptor
+    // and match it with the one we are given.
+    if (MatchingPrecisionForClass(cur_entry, precise) &&
+        (strcmp(descriptor.c_str(), kh.GetDescriptor()) == 0)) {
+      return true;
+    }
+  } else if (cur_entry->IsUnresolvedReference() && cur_entry->GetDescriptor() == descriptor) {
+    return true;
+  }
+  return false;
+}
+
+mirror::Class* RegTypeCache::ResolveClass(std::string descriptor, mirror::ClassLoader* loader) {
+  // Class was not found, must create new type.
+  // Try resolving class
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  mirror::Class* klass = NULL;
+  if (can_load_classes_) {
+    klass = class_linker->FindClass(descriptor.c_str(), loader);
+  } else {
+    klass = class_linker->LookupClass(descriptor.c_str(), loader);
+  }
+  return klass;
+}
+void RegTypeCache::ClearException() {
+  if (can_load_classes_) {
+    DCHECK(Thread::Current()->IsExceptionPending());
+    Thread::Current()->ClearException();
+  } else {
+    DCHECK(!Thread::Current()->IsExceptionPending());
+  }
+}
+const RegType& RegTypeCache::From(mirror::ClassLoader* loader, std::string descriptor, bool precise) {
+  // Try resolving class.
+  mirror::Class* klass = ResolveClass(descriptor, loader);
+  if (klass != NULL) {
+    // Class resolved, first look for the class in the list of entries
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
+      if (entries_[i]->HasClass()) {
+        if (MatchDescriptor(i, descriptor, precise)) {
+          return *(entries_[i]);
+        }
+      }
+    }
+    // Class was not found, must create new type.
+
+    // Create a type if:
+    // 1-The class is instantiable ( not Abstract or Interface ), we should
+    //   abort failing the verification if we get that.
+    // 2- And, the class should be instantiable (Not interface, Abstract or a
+    //    primitive type) OR it is imprecise.
+
+    // Create a precise type if :
+    // 1-The class is final.
+    // 2-OR the precise was passed as true .
+    CHECK(!precise || klass->IsInstantiable());
+    RegType* entry;
+    // Create an imprecise type if we can'tt tell for a fact that it is precise.
+    if (klass->IsFinal() || precise) {
+      entry = new PreciseReferenceType(klass, descriptor, entries_.size());
+    } else {
+      entry = new ReferenceType(klass, descriptor, entries_.size());
+    }
+    entries_.push_back(entry);
+    return *entry;
+  } else {  // Class not resolved.
+    // We tried loading the class and failed, this might get an exception raised
+    // so we want to clear it before we go on.
+    ClearException();
+    // Unable to resolve class. Look through unresolved types in the catch and see
+    // if we have it created before.
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
+      if (entries_[i]->IsUnresolvedReference() &&
+          entries_[i]->descriptor_ == descriptor) {
+        return *(entries_[i]);
+      }
+    }
+    if (IsValidDescriptor(descriptor.c_str())) {
+      RegType* entry = new UnresolvedReferenceType(descriptor, entries_.size());
+      entries_.push_back(entry);
+      return *entry;
+    } else {
+      // The descriptor is broken return the unknown type as there's nothing sensible that
+      // could be done at runtime
+      return Conflict();
+    }
+  }
+}
 const RegType& RegTypeCache::FromClass(mirror::Class* klass, bool precise) {
   if (klass->IsPrimitive()) {
-    RegType::Type type = RegTypeFromPrimitiveType(klass->GetPrimitiveType());
-    // entries should be sized greater than primitive types
-    DCHECK_GT(entries_.size(), static_cast<size_t>(type));
-    RegType* entry = entries_[type];
-    if (entry == NULL) {
-      entry = new RegType(type, klass, 0, type);
-      entries_[type] = entry;
-    }
-    return *entry;
+    return RegTypeFromPrimitiveType(klass->GetPrimitiveType());
+
   } else {
-    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+    // Look for the reference in the list of entries to have.
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
       RegType* cur_entry = entries_[i];
       if ((cur_entry->HasClass()) &&
           MatchingPrecisionForClass(cur_entry, precise) && cur_entry->GetClass() == klass) {
         return *cur_entry;
       }
     }
-    RegType* entry = new RegType(precise ? RegType::kRegTypePreciseReference
-                                         : RegType::kRegTypeReference,
-                                 klass, 0, entries_.size());
+    // No reference to the class was found, create new reference.
+    RegType* entry;
+    std::string empty = "";
+    if (precise) {
+      entry = new PreciseReferenceType(klass, empty, entries_.size());
+    } else {
+      entry = new ReferenceType(klass, empty, entries_.size());
+    }
     entries_.push_back(entry);
     return *entry;
   }
 }
 
+RegTypeCache::~RegTypeCache() {
+  CHECK_LE(primitive_count_, entries_.size());
+  // Delete only the non primitive types.
+  if (primitive_count_  == static_cast<uint16_t>(entries_.size())) {
+    // All entries are primitive, nothing to delete.
+    return;
+  }
+  std::vector<RegType*>::iterator non_primitive_begin = entries_.begin();
+  std::advance(non_primitive_begin, primitive_count_);
+  STLDeleteContainerPointers(non_primitive_begin, entries_.end());
+}
+
+void RegTypeCache::ShutDown() {
+  if (RegTypeCache::primitive_initialized_) {
+    UndefinedType::Destroy();
+    ConflictType::Destroy();
+    BooleanType::Destroy();
+    ByteType::Destroy();
+    ShortType::Destroy();
+    CharType::Destroy();
+    IntegerType::Destroy();
+    LongLoType::Destroy();
+    LongHiType::Destroy();
+    FloatType::GetInstance();
+    DoubleLoType::Destroy();
+    DoubleHiType::Destroy();
+   RegTypeCache::primitive_initialized_ = false;
+   RegTypeCache::primitive_count_ = 0;
+  }
+}
+
+void RegTypeCache::CreatePrimitiveTypes() {
+  CreatePrimitiveTypeInstance<UndefinedType>(NULL, "");
+  CreatePrimitiveTypeInstance<ConflictType>(NULL, "");
+  CreatePrimitiveTypeInstance<BooleanType>(NULL, "Z");
+  CreatePrimitiveTypeInstance<ByteType>(NULL, "B");
+  CreatePrimitiveTypeInstance<ShortType>(NULL, "S");
+  CreatePrimitiveTypeInstance<CharType>(NULL, "C");
+  CreatePrimitiveTypeInstance<IntegerType>(NULL, "I");
+  CreatePrimitiveTypeInstance<LongLoType>(NULL, "J");
+  CreatePrimitiveTypeInstance<LongHiType>(NULL, "J");
+  CreatePrimitiveTypeInstance<FloatType>(NULL, "F");
+  CreatePrimitiveTypeInstance<DoubleLoType>(NULL, "D");
+  CreatePrimitiveTypeInstance<DoubleHiType>(NULL, "D");
+}
+
 const RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) {
   std::set<uint16_t> types;
   if (left.IsUnresolvedMergedReference()) {
-    types = left.GetMergedTypes(this);
+    RegType& non_const(const_cast<RegType&>(left));
+    types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes();
   } else {
     types.insert(left.GetId());
   }
   if (right.IsUnresolvedMergedReference()) {
-    std::set<uint16_t> right_types = right.GetMergedTypes(this);
+    RegType& non_const(const_cast<RegType&>(right));
+    std::set<uint16_t> right_types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes();
     types.insert(right_types.begin(), right_types.end());
   } else {
     types.insert(right.GetId());
   }
   // Check if entry already exists.
-  for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+  for (size_t i = primitive_count_; i < entries_.size(); i++) {
     RegType* cur_entry = entries_[i];
     if (cur_entry->IsUnresolvedMergedReference()) {
-      std::set<uint16_t> cur_entry_types = cur_entry->GetMergedTypes(this);
+      std::set<uint16_t> cur_entry_types =
+          (down_cast<UnresolvedMergedType*>(cur_entry))->GetMergedTypes();
       if (cur_entry_types == types) {
         return *cur_entry;
       }
     }
   }
   // Create entry.
-  uint32_t merged_ids = static_cast<uint32_t>(left.GetId()) << 16 |
-                        static_cast<uint32_t>(right.GetId());
-  RegType* entry = new RegType(RegType::kRegTypeUnresolvedMergedReference, NULL, merged_ids,
-                               entries_.size());
+  RegType* entry = new UnresolvedMergedType(left.GetId(), right.GetId(), this, entries_.size());
   entries_.push_back(entry);
-#ifndef DEBUG
-  std::set<uint16_t> check_types = entry->GetMergedTypes(this);
+#ifndef NDEBUG
+  UnresolvedMergedType* tmp_entry = down_cast<UnresolvedMergedType*>(entry);
+  std::set<uint16_t> check_types = tmp_entry->GetMergedTypes();
   CHECK(check_types == types);
 #endif
   return *entry;
 }
-
 const RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) {
   // Check if entry already exists.
-   for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
-     RegType* cur_entry = entries_[i];
-     if (cur_entry->IsUnresolvedSuperClass()) {
-       uint16_t unresolved_super_child_id = cur_entry->GetUnresolvedSuperClassChildId();
-       if (unresolved_super_child_id == child.GetId()) {
-         return *cur_entry;
-       }
-     }
-   }
-   // Create entry.
-   RegType* entry = new RegType(RegType::kRegTypeUnresolvedSuperClass, NULL, child.GetId(),
-                                entries_.size());
-   entries_.push_back(entry);
-   return *entry;
-}
-
-const RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
-  RegType* entry;
-  if (type.IsUnresolvedTypes()) {
-    std::string descriptor(type.GetDescriptor());
-    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
-      RegType* cur_entry = entries_[i];
-      if (cur_entry->IsUnresolvedAndUninitializedReference() &&
-          cur_entry->GetAllocationPc() == allocation_pc &&
-          cur_entry->GetDescriptor() == descriptor) {
+  for (size_t i = primitive_count_; i < entries_.size(); i++) {
+    RegType* cur_entry = entries_[i];
+    if (cur_entry->IsUnresolvedSuperClass()) {
+      UnresolvedSuperClass* tmp_entry =
+          down_cast<UnresolvedSuperClass*>(cur_entry);
+      uint16_t unresolved_super_child_id =
+          tmp_entry->GetUnresolvedSuperClassChildId();
+      if (unresolved_super_child_id == child.GetId()) {
         return *cur_entry;
       }
     }
-    entry = new RegType(RegType::kRegTypeUnresolvedAndUninitializedReference,
-                        descriptor, allocation_pc, entries_.size());
+  }
+  RegType* entry = new UnresolvedSuperClass(child.GetId(), this, entries_.size());
+  entries_.push_back(entry);
+  return *entry;
+}
+const RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
+  RegType* entry = NULL;
+  RegType* cur_entry = NULL;
+  if (type.IsUnresolvedTypes()) {
+    std::string descriptor(type.GetDescriptor());
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
+      cur_entry = entries_[i];
+      if (cur_entry->IsUnresolvedAndUninitializedReference() &&
+          down_cast<UnresolvedUninitializedRefType*>(cur_entry)->GetAllocationPc() == allocation_pc &&
+          (cur_entry->GetDescriptor() == descriptor)) {
+        return *cur_entry;
+      }
+    }
+    entry = new UnresolvedUninitializedRefType(descriptor, allocation_pc, entries_.size());
   } else {
     mirror::Class* klass = type.GetClass();
-    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
-      RegType* cur_entry = entries_[i];
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
+      cur_entry = entries_[i];
       if (cur_entry->IsUninitializedReference() &&
-          cur_entry->GetAllocationPc() == allocation_pc &&
+          down_cast<UninitialisedReferenceType*>(cur_entry)
+              ->GetAllocationPc() == allocation_pc &&
           cur_entry->GetClass() == klass) {
         return *cur_entry;
       }
     }
-    entry = new RegType(RegType::kRegTypeUninitializedReference,
-                        klass, allocation_pc, entries_.size());
+    std::string descriptor = "";
+    entry = new UninitialisedReferenceType(klass, descriptor, allocation_pc, entries_.size());
   }
   entries_.push_back(entry);
   return *entry;
 }
-
 const RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) {
   RegType* entry;
   if (uninit_type.IsUnresolvedTypes()) {
     std::string descriptor(uninit_type.GetDescriptor());
-    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
       RegType* cur_entry = entries_[i];
-      if (cur_entry->IsUnresolvedReference() && cur_entry->GetDescriptor() == descriptor) {
+      if (cur_entry->IsUnresolvedReference() &&
+          cur_entry->GetDescriptor() == descriptor) {
         return *cur_entry;
       }
     }
-    entry = new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size());
+    entry = new UnresolvedReferenceType(descriptor, entries_.size());
   } else {
     mirror::Class* klass = uninit_type.GetClass();
-    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
       RegType* cur_entry = entries_[i];
       if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) {
         return *cur_entry;
       }
     }
-    entry = new RegType(RegType::kRegTypePreciseReference, klass, 0, entries_.size());
+    std::string descriptor = "";
+    entry = new PreciseReferenceType(klass, descriptor, entries_.size());
   }
   entries_.push_back(entry);
   return *entry;
 }
-
 const RegType& RegTypeCache::ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   return FromCat1Const(std::numeric_limits<jbyte>::min(), false);
 }
-
 const RegType& RegTypeCache::ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   return FromCat1Const(std::numeric_limits<jshort>::min(), false);
 }
-
 const RegType& RegTypeCache::IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   return FromCat1Const(std::numeric_limits<jint>::max(), false);
 }
-
 const RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
-  // TODO: implement descriptor version.
   RegType* entry;
   if (type.IsUnresolvedTypes()) {
     std::string descriptor(type.GetDescriptor());
-    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
       RegType* cur_entry = entries_[i];
       if (cur_entry->IsUnresolvedAndUninitializedThisReference() &&
           cur_entry->GetDescriptor() == descriptor) {
         return *cur_entry;
       }
     }
-    entry = new RegType(RegType::kRegTypeUnresolvedAndUninitializedThisReference, descriptor, 0,
-                        entries_.size());
+    entry = new UnresolvedUninitialisedThisRefType(descriptor, entries_.size());
   } else {
     mirror::Class* klass = type.GetClass();
-    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+    for (size_t i = primitive_count_; i < entries_.size(); i++) {
       RegType* cur_entry = entries_[i];
-      if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) {
+      if (cur_entry->IsUninitializedThisReference() &&
+          cur_entry->GetClass() == klass) {
         return *cur_entry;
       }
     }
-    entry = new RegType(RegType::kRegTypeUninitializedThisReference, klass, 0, entries_.size());
+    std::string descriptor = "";
+    entry = new UninitialisedThisReferenceType(klass, descriptor, entries_.size());
   }
   entries_.push_back(entry);
   return *entry;
 }
-
-const RegType& RegTypeCache::FromType(RegType::Type type) {
-  CHECK(type < RegType::kRegTypeReference);
-  switch (type) {
-    case RegType::kRegTypeBoolean:  return From(type, NULL, "Z", true);
-    case RegType::kRegTypeByte:     return From(type, NULL, "B", true);
-    case RegType::kRegTypeShort:    return From(type, NULL, "S", true);
-    case RegType::kRegTypeChar:     return From(type, NULL, "C", true);
-    case RegType::kRegTypeInteger:  return From(type, NULL, "I", true);
-    case RegType::kRegTypeFloat:    return From(type, NULL, "F", true);
-    case RegType::kRegTypeLongLo:
-    case RegType::kRegTypeLongHi:   return From(type, NULL, "J", true);
-    case RegType::kRegTypeDoubleLo:
-    case RegType::kRegTypeDoubleHi: return From(type, NULL, "D", true);
-    default:                        return From(type, NULL, "", true);
-  }
-}
-
 const RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
-  RegType::Type wanted_type =
-      precise ? RegType::kRegTypePreciseConst : RegType::kRegTypeImpreciseConst;
-  for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+  for (size_t i = primitive_count_; i < entries_.size(); i++) {
     RegType* cur_entry = entries_[i];
-    if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValue() == value) {
+    if (cur_entry->IsConstant() && cur_entry->IsPreciseConstant() == precise &&
+        (down_cast<ConstantType*>(cur_entry))->ConstantValue() == value) {
       return *cur_entry;
     }
   }
-  RegType* entry = new RegType(wanted_type, NULL, value, entries_.size());
+  RegType* entry;
+  if (precise) {
+    entry = new PreciseConstType(value, entries_.size());
+  } else {
+    entry = new ImpreciseConstType(value, entries_.size());
+  }
   entries_.push_back(entry);
   return *entry;
 }
 
 const RegType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) {
-  RegType::Type wanted_type =
-      precise ? RegType::kRegTypePreciseConstLo : RegType::kRegTypeImpreciseConstLo;
-  for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+  for (size_t i = primitive_count_; i < entries_.size(); i++) {
     RegType* cur_entry = entries_[i];
-    if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValueLo() == value) {
+    if (cur_entry->IsConstantLo() && (cur_entry->IsPrecise() == precise) &&
+        (down_cast<ConstantType*>(cur_entry))->ConstantValueLo() == value) {
       return *cur_entry;
     }
   }
-  RegType* entry = new RegType(wanted_type, NULL, value, entries_.size());
+  RegType* entry;
+  if (precise) {
+    entry = new PreciseConstLoType(value, entries_.size());
+  } else {
+    entry = new ImpreciseConstLoType(value, entries_.size());
+  }
   entries_.push_back(entry);
   return *entry;
 }
 
 const RegType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) {
-  RegType::Type wanted_type =
-      precise ? RegType::kRegTypePreciseConstHi : RegType::kRegTypeImpreciseConstHi;
-  for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
+  for (size_t i = primitive_count_; i < entries_.size(); i++) {
     RegType* cur_entry = entries_[i];
-    if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValueHi() == value) {
+    if (cur_entry->IsConstantHi() && (cur_entry->IsPrecise() == precise) &&
+        (down_cast<ConstantType*>(cur_entry))->ConstantValueHi() == value) {
       return *cur_entry;
     }
   }
-  RegType* entry = new RegType(wanted_type, NULL, value, entries_.size());
+  RegType* entry;
+  if (precise) {
+    entry = new PreciseConstHiType(value, entries_.size());
+  } else {
+    entry = new ImpreciseConstHiType(value, entries_.size());
+  }
   entries_.push_back(entry);
   return *entry;
 }
diff --git a/src/verifier/reg_type_cache.h b/src/verifier/reg_type_cache.h
index adab18c..cacd517 100644
--- a/src/verifier/reg_type_cache.h
+++ b/src/verifier/reg_type_cache.h
@@ -17,10 +17,13 @@
 #ifndef ART_SRC_VERIFIER_REG_TYPE_CACHE_H_
 #define ART_SRC_VERIFIER_REG_TYPE_CACHE_H_
 
+#include "base/casts.h"
 #include "base/macros.h"
 #include "base/stl_util.h"
 #include "reg_type.h"
+#include "runtime.h"
 
+#include <stdint.h>
 #include <vector>
 
 namespace art {
@@ -30,26 +33,30 @@
 }  // namespace mirror
 namespace verifier {
 
+class RegType;
+
 class RegTypeCache {
  public:
-  explicit RegTypeCache(bool can_load_classes)
-      : entries_(RegType::kRegTypeLastFixedLocation + 1), can_load_classes_(can_load_classes) {
-    Undefined();  // ensure Undefined is initialized
+  explicit RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) {
+    FillPrimitiveTypes();
   }
-  ~RegTypeCache() {
-    STLDeleteElements(&entries_);
+  ~RegTypeCache();
+  static void Init() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    if(!RegTypeCache::primitive_initialized_) {
+      CHECK_EQ(RegTypeCache::primitive_count_, 0);
+      CreatePrimitiveTypes();
+      CHECK_EQ(RegTypeCache::primitive_count_, 12);
+      RegTypeCache::primitive_initialized_ = true;
+    }
   }
-
-  const RegType& GetFromId(uint16_t id) const {
-    DCHECK_LT(id, entries_.size());
-    RegType* result = entries_[id];
-    DCHECK(result != NULL);
-    return *result;
-  }
-
-  const RegType& From(RegType::Type type, mirror::ClassLoader* loader, const char* descriptor,
-                      bool precise)
+  static void ShutDown();
+  const art::verifier::RegType& GetFromId(uint16_t id) const;
+  const RegType& From(mirror::ClassLoader* loader, std::string descriptor, bool precise)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  template <class Type>
+  static Type* CreatePrimitiveTypeInstance(mirror::ClassLoader*, std::string)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void FillPrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& FromClass(mirror::Class* klass, bool precise)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& FromCat1Const(int32_t value, bool precise)
@@ -60,74 +67,66 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  const RegType& FromType(RegType::Type)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& FromUnresolvedMerge(const RegType& left, const RegType& right)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& FromUnresolvedSuperClass(const RegType& child)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  const RegType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeBoolean);
-  }
-  const RegType& Byte() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeByte);
-  }
-  const RegType& Char() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeChar);
-  }
-  const RegType& Short() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeShort);
-  }
-  const RegType& Integer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeInteger);
-  }
-  const RegType& Float() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeFloat);
-  }
-  const RegType& LongLo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeLongLo);
-  }
-  const RegType& LongHi() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeLongHi);
-  }
-  const RegType& DoubleLo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeDoubleLo);
-  }
-  const RegType& DoubleHi() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeDoubleHi);
-  }
-
-  const RegType& JavaLangClass(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return From(precise ? RegType::kRegTypeReference
-                        : RegType::kRegTypePreciseReference,
-                NULL, "Ljava/lang/Class;", precise);
-  }
-  const RegType& JavaLangObject(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return From(precise ? RegType::kRegTypeReference
-                        : RegType::kRegTypePreciseReference,
-                NULL, "Ljava/lang/Object;", precise);
-  }
   const RegType& JavaLangString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     // String is final and therefore always precise.
-    return From(RegType::kRegTypePreciseReference, NULL, "Ljava/lang/String;", true);
+    return From(NULL, "Ljava/lang/String;", true);
   }
-  const RegType& JavaLangThrowable(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return From(precise ? RegType::kRegTypeReference
-                        : RegType::kRegTypePreciseReference,
-                NULL, "Ljava/lang/Throwable;", precise);
-  }
-
-  const RegType& Undefined() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeUndefined);
-  }
-  const RegType& Conflict() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return FromType(RegType::kRegTypeConflict);
+  const RegType& JavaLangThrowable(bool precise)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return From(NULL, "Ljava/lang/Throwable;", precise);
   }
   const RegType& Zero() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return FromCat1Const(0, true);
   }
-
+  size_t GetCacheSize() {
+    return entries_.size();
+  }
+  const RegType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return *BooleanType::GetInstance();
+  }
+  const RegType& Byte() {
+    return *ByteType::GetInstance();
+  }
+  const RegType& Char()  {
+    return *CharType::GetInstance();
+  }
+  const RegType& Short()  {
+    return *ShortType::GetInstance();
+  }
+  const RegType& Integer() {
+    return *IntegerType::GetInstance();
+  }
+  const RegType& Float() {
+    return *FloatType::GetInstance();
+  }
+  const RegType& LongLo() {
+    return *LongLoType::GetInstance();
+  }
+  const RegType& LongHi() {
+    return *LongHiType::GetInstance();
+  }
+  const RegType& DoubleLo() {
+    return *DoubleLoType::GetInstance();
+  }
+  const RegType& DoubleHi() {
+    return *DoubleHiType::GetInstance();
+  }
+  const RegType& Undefined() {
+    return *UndefinedType::GetInstance();
+  }
+  const RegType& Conflict() {
+    return *ConflictType::GetInstance();
+  }
+  const RegType& JavaLangClass(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return From(NULL, "Ljava/lang/Class;", precise);
+  }
+  const RegType& JavaLangObject(bool precise) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return From(NULL, "Ljava/lang/Object;", precise);
+  }
   const RegType& Uninitialized(const RegType& type, uint32_t allocation_pc)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   // Create an uninitialized 'this' argument for the given type.
@@ -135,26 +134,28 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& FromUninitialized(const RegType& uninit_type)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  // Representatives of various constant types. When merging constants we can't infer a type,
-  // (an int may later be used as a float) so we select these representative values meaning future
-  // merges won't know the exact constant value but have some notion of its size.
   const RegType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  const RegType& RegTypeFromPrimitiveType(Primitive::Type) const;
 
  private:
-  // The allocated entries
   std::vector<RegType*> entries_;
+  static bool primitive_initialized_;
+  static uint16_t primitive_start_;
+  static uint16_t primitive_count_;
+  static void CreatePrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   // Whether or not we're allowed to load classes.
   const bool can_load_classes_;
-
   DISALLOW_COPY_AND_ASSIGN(RegTypeCache);
+  mirror::Class* ResolveClass(std::string descriptor, mirror::ClassLoader* loader)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void ClearException();
+  bool MatchDescriptor(size_t idx, std::string& descriptor, bool precise)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 };
 
 }  // namespace verifier
diff --git a/src/verifier/reg_type_test.cc b/src/verifier/reg_type_test.cc
index c66477c..333f9b0 100644
--- a/src/verifier/reg_type_test.cc
+++ b/src/verifier/reg_type_test.cc
@@ -15,17 +15,18 @@
  */
 
 #include "reg_type.h"
+#include "reg_type_cache-inl.h"
 
-#include "reg_type_cache.h"
-
+#include "base/casts.h"
 #include "common_test.h"
+#include <set>
 
 namespace art {
 namespace verifier {
 
 class RegTypeTest : public CommonTest {};
-
 TEST_F(RegTypeTest, Primitives) {
+
   ScopedObjectAccess soa(Thread::Current());
   RegTypeCache cache(true);
 
@@ -278,12 +279,185 @@
   EXPECT_FALSE(double_reg_type.IsArrayIndexTypes());
 }
 
-// TODO: test reference RegType
-// TODO: test constant RegType
-// TODO: test VerifyAgainst
-// TODO: test Merge
-// TODO: test Equals
-// TODO: test ClassJoin
+
+class RegTypeReferenceTest : public CommonTest {};
+
+TEST_F(RegTypeReferenceTest, JavalangObjectImprecise) {
+  ScopedObjectAccess soa(Thread::Current());
+  // Tests matching precisions. A reference type that was created precise doesn't
+  // match the one that is imprecise.
+  RegTypeCache cache(true);
+  const RegType& imprecise_obj = cache.JavaLangObject(false);
+  const RegType& precise_obj = cache.JavaLangObject(true);
+  const RegType& precise_obj_2 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true);
+
+  EXPECT_TRUE(precise_obj.Equals(precise_obj_2));
+  EXPECT_FALSE(imprecise_obj.Equals(precise_obj));
+  EXPECT_FALSE(imprecise_obj.Equals(precise_obj));
+  EXPECT_FALSE(imprecise_obj.Equals(precise_obj_2));
+}
+
+TEST_F(RegTypeReferenceTest, UnresolvedType) {
+  ScopedObjectAccess soa(Thread::Current());
+  // Tests creating unresolved types. Miss for the first time asking the cache and
+  // a hit second time.
+  RegTypeCache cache(true);
+  const RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
+  EXPECT_TRUE(ref_type_0.IsUnresolvedReference());
+
+  const RegType& ref_type_1 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
+  EXPECT_TRUE(ref_type_0.Equals(ref_type_1));
+
+  const RegType& unresolved_super_class =  cache.FromUnresolvedSuperClass(ref_type_0);
+  EXPECT_TRUE(unresolved_super_class.IsUnresolvedSuperClass());
+}
+
+TEST_F(RegTypeReferenceTest, UnresolvedUnintializedType) {
+  ScopedObjectAccess soa(Thread::Current());
+  // Tests creating types uninitialized types from unresolved types.
+  RegTypeCache cache(true);
+  const RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
+  EXPECT_TRUE(ref_type_0.IsUnresolvedReference());
+  const RegType& ref_type = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
+  EXPECT_TRUE(ref_type_0.Equals(ref_type));
+
+  // Create an uninitialized type of this unresolved type
+  const RegType& unresolved_unintialised = cache.Uninitialized(ref_type, 1101ull);
+  EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference());
+  EXPECT_TRUE(unresolved_unintialised.IsUninitializedTypes());
+
+  // Create an uninitialized type of this unresolved type with different  PC
+  const RegType& ref_type_unresolved_unintialised_1 =  cache.Uninitialized(ref_type, 1102ull);
+  EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference());
+  EXPECT_FALSE(unresolved_unintialised.Equals(ref_type_unresolved_unintialised_1));
+
+  // Create an uninitialized type of this unresolved type with the same PC
+  const RegType& unresolved_unintialised_2 =
+      cache.Uninitialized(ref_type, 1101ull);
+  EXPECT_TRUE(unresolved_unintialised.Equals(unresolved_unintialised_2));
+}
+
+TEST_F(RegTypeReferenceTest, Dump) {
+  ScopedObjectAccess soa(Thread::Current());
+  // Tests creating types uninitialized types from unresolved types.
+  RegTypeCache cache(true);
+
+  const RegType& unresolved_ref = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
+  const RegType& unresolved_ref_another = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExistEither;", true);
+  const RegType& resolved_ref = cache.JavaLangString();
+
+  const RegType& resolved_unintialiesd = cache.Uninitialized(resolved_ref, 10);
+  const RegType& unresolved_unintialized = cache.Uninitialized(unresolved_ref, 12);
+  const RegType& unresolved_merged = cache.FromUnresolvedMerge(unresolved_ref, unresolved_ref_another);
+
+  std::string expected = "Unresolved Reference: java.lang.DoesNotExist";
+  EXPECT_EQ(expected, unresolved_ref.Dump());
+  expected = "Precise Reference: java.lang.String";
+  EXPECT_EQ( expected, resolved_ref.Dump());
+  expected ="Uninitialized Reference: java.lang.String Allocation PC: 10";
+  EXPECT_EQ(expected, resolved_unintialiesd.Dump());
+  expected = "Unresolved And Uninitialized Reference: java.lang.DoesNotExist Allocation PC: 12";
+  EXPECT_EQ(expected, unresolved_unintialized.Dump());
+  expected = "UnresolvedMergedReferences(Unresolved Reference: java.lang.DoesNotExist, Unresolved Reference: java.lang.DoesNotExistEither)";
+  EXPECT_EQ(expected, unresolved_merged.Dump());
+}
+
+
+TEST_F(RegTypeReferenceTest, JavalangString) {
+  // Add a class to the cache then look for the same class and make sure it is  a
+  // Hit the second time. Then check for the same effect when using
+  // The JavaLangObject method instead of FromDescriptor. String class is final.
+  ScopedObjectAccess soa(Thread::Current());
+  RegTypeCache cache(true);
+  const RegType& ref_type = cache.JavaLangString();
+  const RegType& ref_type_2 = cache.JavaLangString();
+  const RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/String;", true);
+
+  EXPECT_TRUE(ref_type.Equals(ref_type_2));
+  EXPECT_TRUE(ref_type_2.Equals(ref_type_3));
+  EXPECT_TRUE(ref_type.IsPreciseReference());
+
+  // Create an uninitialized type out of this:
+  const RegType& ref_type_unintialized = cache.Uninitialized(ref_type, 0110ull);
+  EXPECT_TRUE(ref_type_unintialized.IsUninitializedReference());
+  EXPECT_FALSE(ref_type_unintialized.IsUnresolvedAndUninitializedReference());
+
+}
+TEST_F(RegTypeReferenceTest, JavalangObject) {
+  // Add a class to the cache then look for the same class and make sure it is  a
+  // Hit the second time. Then I am checking for the same effect when using
+  // The JavaLangObject method instead of FromDescriptor. Object Class in not final.
+  ScopedObjectAccess soa(Thread::Current());
+  RegTypeCache cache(true);
+  const RegType& ref_type = cache.JavaLangObject(true);
+  const RegType& ref_type_2 = cache.JavaLangObject(true);
+  const RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true);
+
+  EXPECT_TRUE(ref_type.Equals(ref_type_2));
+  EXPECT_TRUE(ref_type_3.Equals(ref_type_2));
+  EXPECT_EQ(ref_type.GetId(), ref_type_3.GetId());
+}
+TEST_F(RegTypeReferenceTest, Merging) {
+  // Tests merging logic
+  //String and object , LUB is object.
+  ScopedObjectAccess soa(Thread::Current());
+  RegTypeCache cache_new(true);
+  const RegType& string = cache_new.JavaLangString();
+  const RegType& Object = cache_new.JavaLangObject(true);
+  EXPECT_TRUE(string.Merge(Object, &cache_new).IsJavaLangObject());
+  // Merge two unresolved types.
+  const RegType& ref_type_0 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true);
+  EXPECT_TRUE(ref_type_0.IsUnresolvedReference());
+  const RegType& ref_type_1 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExistToo;", true);
+  EXPECT_FALSE(ref_type_0.Equals(ref_type_1));
+
+  const RegType& merged = ref_type_1.Merge(ref_type_0, &cache_new);
+  EXPECT_TRUE(merged.IsUnresolvedMergedReference());
+  RegType& merged_nonconst = const_cast<RegType&>(merged);
+
+  std::set<uint16_t> merged_ids = (down_cast<UnresolvedMergedType*>(&merged_nonconst))->GetMergedTypes();
+  EXPECT_EQ(ref_type_0.GetId(), *(merged_ids.begin()));
+  EXPECT_EQ(ref_type_1.GetId(), *((++merged_ids.begin())));
+}
+
+TEST_F(RegTypeTest, ConstLoHi) {
+  // Tests creating primitive types types.
+  ScopedObjectAccess soa(Thread::Current());
+  RegTypeCache cache(true);
+  const RegType& ref_type_const_0 = cache.FromCat1Const(10, true);
+  const RegType& ref_type_const_1 = cache.FromCat1Const(10, true);
+  const RegType& ref_type_const_2 = cache.FromCat1Const(30, true);
+  const RegType& ref_type_const_3 = cache.FromCat1Const(30, false);
+
+  EXPECT_TRUE(ref_type_const_0.Equals(ref_type_const_1));
+  EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_2));
+  EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_3));
+
+  const RegType& ref_type_const_wide_0 = cache.FromCat2ConstHi(50, true);
+  const RegType& ref_type_const_wide_1 = cache.FromCat2ConstHi(50, true);
+  EXPECT_TRUE(ref_type_const_wide_0.Equals(ref_type_const_wide_1));
+
+  const RegType& ref_type_const_wide_2 = cache.FromCat2ConstLo(50, true);
+  const RegType& ref_type_const_wide_3 = cache.FromCat2ConstLo(50, true);
+  const RegType& ref_type_const_wide_4 = cache.FromCat2ConstLo(55, true);
+
+  EXPECT_TRUE(ref_type_const_wide_2.Equals(ref_type_const_wide_3));
+  EXPECT_FALSE(ref_type_const_wide_2.Equals(ref_type_const_wide_4));
+}
+
+
+TEST_F(RegTypeTest, ConstPrecision) {
+
+  // Tests creating primitive types types.
+  ScopedObjectAccess soa(Thread::Current());
+  RegTypeCache cache_new(true);
+  const RegType& imprecise_const = cache_new.FromCat1Const(10, false);
+  const RegType& precise_const = cache_new.FromCat1Const(10, true);
+
+  EXPECT_TRUE(imprecise_const.IsImpreciseConstant());
+  EXPECT_TRUE(precise_const.IsPreciseConstant());
+  EXPECT_FALSE(imprecise_const.Equals(precise_const));
+}
 
 }  // namespace verifier
 }  // namespace art
diff --git a/src/verifier/register_line.cc b/src/verifier/register_line.cc
index 74f83da..544a9ee 100644
--- a/src/verifier/register_line.cc
+++ b/src/verifier/register_line.cc
@@ -74,24 +74,19 @@
 }
 
 void RegisterLine::SetResultTypeToUnknown() {
-  result_[0] = RegType::kRegTypeUndefined;
-  result_[1] = RegType::kRegTypeUndefined;
+  result_[0] = verifier_->GetRegTypeCache()->Undefined().GetId();
+  result_[1] = result_[0];
 }
 
 void RegisterLine::SetResultRegisterType(const RegType& new_type) {
   DCHECK(!new_type.IsLowHalf());
   DCHECK(!new_type.IsHighHalf());
   result_[0] = new_type.GetId();
-  result_[1] = RegType::kRegTypeUndefined;
-  if (new_type.IsLowHalf()) {
-    DCHECK_EQ(new_type.HighHalf(verifier_->GetRegTypeCache()).GetId(), new_type.GetId() + 1);
-    result_[1] = new_type.GetId() + 1;
-  } else {
-    result_[1] = RegType::kRegTypeUndefined;
-  }
+  result_[1] = verifier_->GetRegTypeCache()->Undefined().GetId();
 }
 
-void RegisterLine::SetResultRegisterTypeWide(const RegType& new_type1, const RegType& new_type2) {
+void RegisterLine::SetResultRegisterTypeWide(const RegType& new_type1,
+                                             const RegType& new_type2) {
   DCHECK(new_type1.CheckWidePair(new_type2));
   result_[0] = new_type1.GetId();
   result_[1] = new_type2.GetId();
@@ -118,16 +113,18 @@
   return this_type;
 }
 
-bool RegisterLine::VerifyRegisterType(uint32_t vsrc, const RegType& check_type) {
+bool RegisterLine::VerifyRegisterType(uint32_t vsrc,
+                                      const RegType& check_type) {
   // Verify the src register type against the check type refining the type of the register
   const RegType& src_type = GetRegisterType(vsrc);
-  if (!check_type.IsAssignableFrom(src_type)) {
+  if (!(check_type.IsAssignableFrom(src_type))) {
     // Hard fail if one of the types is primitive, since they are concretely known.
     enum VerifyError fail_type = (!check_type.IsNonZeroReferenceTypes() ||
-                                  !src_type.IsNonZeroReferenceTypes()) ?
-                                  VERIFY_ERROR_BAD_CLASS_HARD : VERIFY_ERROR_BAD_CLASS_SOFT;
-    verifier_->Fail(fail_type) << "register v" << vsrc << " has type " << src_type
-                               << " but expected " << check_type;
+                                  !src_type.IsNonZeroReferenceTypes())
+                                 ? VERIFY_ERROR_BAD_CLASS_HARD
+                                 : VERIFY_ERROR_BAD_CLASS_SOFT;
+    verifier_->Fail(fail_type) << "register v" << vsrc << " has type "
+                               << src_type << " but expected " << check_type;
     return false;
   }
   if (check_type.IsLowHalf()) {
@@ -185,11 +182,11 @@
   std::string result;
   for (size_t i = 0; i < num_regs_; i++) {
     result += StringPrintf("%zd:[", i);
-    result += GetRegisterType(i).Dump(verifier_->GetRegTypeCache());
+    result += GetRegisterType(i).Dump();
     result += "],";
   }
-  typedef std::deque<uint32_t>::const_iterator It; // TODO: C++0x auto
-  for (It it = monitors_.begin(), end = monitors_.end(); it != end ; ++it) {
+  typedef std::deque<uint32_t>::const_iterator It;  // TODO: C++0x auto
+  for (It it = monitors_.begin(), end = monitors_.end(); it != end; ++it) {
     result += StringPrintf("{%d},", *it);
   }
   return result;
@@ -240,7 +237,7 @@
   } else {
     DCHECK(verifier_->GetRegTypeCache()->GetFromId(result_[1]).IsUndefined());
     SetRegisterType(vdst, type);
-    result_[0] = RegType::kRegTypeUndefined;
+    result_[0] = verifier_->GetRegTypeCache()->Undefined().GetId();
   }
 }
 
@@ -257,13 +254,15 @@
   } else {
     DCHECK(type_l.CheckWidePair(type_h));  // Set should never allow this case
     SetRegisterTypeWide(vdst, type_l, type_h);  // also sets the high
-    result_[0] = RegType::kRegTypeUndefined;
-    result_[1] = RegType::kRegTypeUndefined;
+    result_[0] = verifier_->GetRegTypeCache()->Undefined().GetId();
+    result_[1] = verifier_->GetRegTypeCache()->Undefined().GetId();
+
   }
 }
 
 void RegisterLine::CheckUnaryOp(const DecodedInstruction& dec_insn,
-                                const RegType& dst_type, const RegType& src_type) {
+                                const RegType& dst_type,
+                                const RegType& src_type) {
   if (VerifyRegisterType(dec_insn.vB, src_type)) {
     SetRegisterType(dec_insn.vA, dst_type);
   }
diff --git a/src/verifier/register_line.h b/src/verifier/register_line.h
index 8253f51..5719082 100644
--- a/src/verifier/register_line.h
+++ b/src/verifier/register_line.h
@@ -52,10 +52,11 @@
 class RegisterLine {
  public:
   RegisterLine(size_t num_regs, MethodVerifier* verifier)
-      : line_(new uint16_t[num_regs]), verifier_(verifier), num_regs_(num_regs) {
+      : line_(new uint16_t[num_regs]),
+        verifier_(verifier),
+        num_regs_(num_regs) {
     memset(line_.get(), 0, num_regs_ * sizeof(uint16_t));
-    result_[0] = RegType::kRegTypeUndefined;
-    result_[1] = RegType::kRegTypeUndefined;
+    SetResultTypeToUnknown();
   }
 
   // Implement category-1 "move" instructions. Copy a 32-bit value from "vsrc" to "vdst".
@@ -78,7 +79,7 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Set the invisible result register to unknown
-  void SetResultTypeToUnknown();
+  void SetResultTypeToUnknown() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Set the type of register N, verifying that the register is valid.  If "newType" is the "Lo"
   // part of a 64-bit value, register N+1 will be set to "newType+1".
