Merge "Elision of checks optimization." into dalvik-dev
diff --git a/build/Android.common.mk b/build/Android.common.mk
index f6a1300..5c642be 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -114,6 +114,9 @@
 # We build with GCC 4.6 on the host.
 ART_HOST_CFLAGS += -Wthread-safety
 
+# Make host builds easier to debug and profile by not omitting the frame pointer.
+ART_HOST_CFLAGS += -fno-omit-frame-pointer
+
 # To use oprofile_android --callgraph, uncomment this and recompile with "mmm art -B -j16"
 # ART_TARGET_CFLAGS += -fno-omit-frame-pointer -marm -mapcs
 
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 46c2ade..cbdcbe0 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -196,7 +196,7 @@
 
 ClassLinker::ClassLinker(InternTable* intern_table)
     // dex_lock_ is recursive as it may be used in stack dumping.
-    : dex_lock_("ClassLinker dex lock", kDefaultMutexLevel, true),
+    : dex_lock_("ClassLinker dex lock", kDefaultMutexLevel),
       class_roots_(NULL),
       array_iftable_(NULL),
       init_done_(false),
@@ -663,22 +663,22 @@
 }
 
 void ClassLinker::RegisterOatFile(const OatFile& oat_file) {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  WriterMutexLock mu(Thread::Current(), dex_lock_);
   RegisterOatFileLocked(oat_file);
 }
 
 void ClassLinker::RegisterOatFileLocked(const OatFile& oat_file) {
-  dex_lock_.AssertHeld(Thread::Current());
-#ifndef NDEBUG
-  for (size_t i = 0; i < oat_files_.size(); ++i) {
-    CHECK_NE(&oat_file, oat_files_[i]) << oat_file.GetLocation();
+  dex_lock_.AssertExclusiveHeld(Thread::Current());
+  if (kIsDebugBuild) {
+    for (size_t i = 0; i < oat_files_.size(); ++i) {
+      CHECK_NE(&oat_file, oat_files_[i]) << oat_file.GetLocation();
+    }
   }
-#endif
   oat_files_.push_back(&oat_file);
 }
 
 OatFile* ClassLinker::OpenOat(const ImageSpace* space) {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  WriterMutexLock mu(Thread::Current(), dex_lock_);
   const Runtime* runtime = Runtime::Current();
   const ImageHeader& image_header = space->GetImageHeader();
   // Grab location but don't use Object::AsString as we haven't yet initialized the roots to
@@ -709,7 +709,7 @@
 }
 
 const OatFile* ClassLinker::FindOpenedOatFileForDexFile(const DexFile& dex_file) {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  ReaderMutexLock mu(Thread::Current(), dex_lock_);
   return FindOpenedOatFileFromDexLocation(dex_file.GetLocation());
 }
 
@@ -755,7 +755,7 @@
 
 const DexFile* ClassLinker::FindOrCreateOatFileForDexLocation(const std::string& dex_location,
                                                               const std::string& oat_location) {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  WriterMutexLock mu(Thread::Current(), dex_lock_);
   return FindOrCreateOatFileForDexLocationLocked(dex_location, oat_location);
 }
 
@@ -857,7 +857,7 @@
 }
 
 const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::string& dex_location) {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  WriterMutexLock mu(Thread::Current(), dex_lock_);
 
   const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location);
   if (open_oat_file != NULL) {
@@ -924,7 +924,7 @@
 }
 
 const OatFile* ClassLinker::FindOatFileFromOatLocation(const std::string& oat_location) {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  ReaderMutexLock mu(Thread::Current(), dex_lock_);
   return FindOatFileFromOatLocationLocked(oat_location);
 }
 
@@ -1062,14 +1062,14 @@
   visitor(class_roots_, arg);
   Thread* self = Thread::Current();
   {
-    MutexLock mu(self, dex_lock_);
+    ReaderMutexLock mu(self, dex_lock_);
     for (size_t i = 0; i < dex_caches_.size(); i++) {
       visitor(dex_caches_[i], arg);
     }
   }
 
   {
-    MutexLock mu(self, *Locks::classlinker_classes_lock_);
+    ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_);
     typedef Table::const_iterator It;  // TODO: C++0x auto
     for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) {
       visitor(it->second, arg);
@@ -1084,7 +1084,7 @@
 }
 
 void ClassLinker::VisitClasses(ClassVisitor* visitor, void* arg) const {
-  MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+  ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
   typedef Table::const_iterator It;  // TODO: C++0x auto
   for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) {
     if (!visitor(it->second, arg)) {
@@ -1813,7 +1813,7 @@
 }
 
 bool ClassLinker::IsDexFileRegisteredLocked(const DexFile& dex_file) const {
-  dex_lock_.AssertHeld(Thread::Current());
+  dex_lock_.AssertSharedHeld(Thread::Current());
   for (size_t i = 0; i != dex_caches_.size(); ++i) {
     if (dex_caches_[i]->GetDexFile() == &dex_file) {
       return true;
@@ -1823,12 +1823,12 @@
 }
 
 bool ClassLinker::IsDexFileRegistered(const DexFile& dex_file) const {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  ReaderMutexLock mu(Thread::Current(), dex_lock_);
   return IsDexFileRegisteredLocked(dex_file);
 }
 
 void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache) {
-  dex_lock_.AssertHeld(Thread::Current());
+  dex_lock_.AssertExclusiveHeld(Thread::Current());
   CHECK(dex_cache.get() != NULL) << dex_file.GetLocation();
   CHECK(dex_cache->GetLocation()->Equals(dex_file.GetLocation()));
   dex_caches_.push_back(dex_cache.get());
@@ -1839,7 +1839,7 @@
 void ClassLinker::RegisterDexFile(const DexFile& dex_file) {
   Thread* self = Thread::Current();
   {
-    MutexLock mu(self, dex_lock_);
+    ReaderMutexLock mu(self, dex_lock_);
     if (IsDexFileRegisteredLocked(dex_file)) {
       return;
     }
@@ -1849,7 +1849,7 @@
   // get to a suspend point.
   SirtRef<mirror::DexCache> dex_cache(self, AllocDexCache(self, dex_file));
   {
-    MutexLock mu(self, dex_lock_);
+    WriterMutexLock mu(self, dex_lock_);
     if (IsDexFileRegisteredLocked(dex_file)) {
       return;
     }
@@ -1858,12 +1858,12 @@
 }
 
 void ClassLinker::RegisterDexFile(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache) {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  WriterMutexLock mu(Thread::Current(), dex_lock_);
   RegisterDexFileLocked(dex_file, dex_cache);
 }
 
 mirror::DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  ReaderMutexLock mu(Thread::Current(), dex_lock_);
   // Search assuming unique-ness of dex file.
   for (size_t i = 0; i != dex_caches_.size(); ++i) {
     mirror::DexCache* dex_cache = dex_caches_[i];
@@ -1889,7 +1889,7 @@
 }
 
 void ClassLinker::FixupDexCaches(mirror::AbstractMethod* resolution_method) const {
-  MutexLock mu(Thread::Current(), dex_lock_);
+  ReaderMutexLock mu(Thread::Current(), dex_lock_);
   for (size_t i = 0; i != dex_caches_.size(); ++i) {
     dex_caches_[i]->Fixup(resolution_method);
   }
@@ -2085,7 +2085,7 @@
     LOG(INFO) << "Loaded class " << descriptor << source;
   }
   size_t hash = StringPieceHash()(descriptor);
-  MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+  WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
   Table& classes = image_class ? image_classes_ : classes_;
   mirror::Class* existing = LookupClassLocked(descriptor.data(), klass->GetClassLoader(), hash, classes);
 #ifndef NDEBUG
@@ -2103,7 +2103,7 @@
 
 bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* class_loader) {
   size_t hash = Hash(descriptor);
-  MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+  WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
   typedef Table::iterator It;  // TODO: C++0x auto
   // TODO: determine if its better to search classes_ or image_classes_ first
   ClassHelper kh;
@@ -2131,7 +2131,7 @@
 mirror::Class* ClassLinker::LookupClass(const char* descriptor,
                                         const mirror::ClassLoader* class_loader) {
   size_t hash = Hash(descriptor);
-  MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+  ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
   // TODO: determine if its better to search classes_ or image_classes_ first
   mirror::Class* klass = NULL;
   // Use image class only if the class_loader is null.
@@ -2171,7 +2171,7 @@
 void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Class*>& classes) {
   classes.clear();
   size_t hash = Hash(descriptor);
-  MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+  ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
   typedef Table::const_iterator It;  // TODO: C++0x auto
   // TODO: determine if its better to search classes_ or image_classes_ first
   ClassHelper kh(NULL, this);
@@ -2505,7 +2505,7 @@
   mirror::DexCache* dex_cache = NULL;
   {
     mirror::ObjectArray<mirror::Class>* resolved_types = proxy_method->GetDexCacheResolvedTypes();
-    MutexLock mu(Thread::Current(), dex_lock_);
+    ReaderMutexLock mu(Thread::Current(), dex_lock_);
     for (size_t i = 0; i != dex_caches_.size(); ++i) {
       if (dex_caches_[i]->GetResolvedTypes() == resolved_types) {
         dex_cache = dex_caches_[i];
@@ -3885,7 +3885,7 @@
   // lock held, because it might need to resolve a field's type, which would try to take the lock.
   std::vector<mirror::Class*> all_classes;
   {
-    MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+    ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
     typedef Table::const_iterator It;  // TODO: C++0x auto
     for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) {
       all_classes.push_back(it->second);
@@ -3901,13 +3901,13 @@
 }
 
 void ClassLinker::DumpForSigQuit(std::ostream& os) const {
-  MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+  ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
   os << "Loaded classes: " << image_classes_.size() << " image classes; "
      << classes_.size() << " allocated classes\n";
 }
 
 size_t ClassLinker::NumLoadedClasses() const {
-  MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+  ReaderMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
   return classes_.size() + image_classes_.size();
 }
 
diff --git a/src/class_linker.h b/src/class_linker.h
index d41373c..79fa8ba 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -240,7 +240,7 @@
       LOCKS_EXCLUDED(dex_lock_);
 
   const OatFile* FindOatFileFromOatLocationLocked(const std::string& location)
-      EXCLUSIVE_LOCKS_REQUIRED(dex_lock_);
+      SHARED_LOCKS_REQUIRED(dex_lock_);
 
   // Finds the oat file for a dex location, generating the oat file if
   // it is missing or out of date. Returns the DexFile from within the
@@ -420,7 +420,7 @@
   void RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache)
       EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  bool IsDexFileRegisteredLocked(const DexFile& dex_file) const EXCLUSIVE_LOCKS_REQUIRED(dex_lock_);
+  bool IsDexFileRegisteredLocked(const DexFile& dex_file) const SHARED_LOCKS_REQUIRED(dex_lock_);
   void RegisterOatFileLocked(const OatFile& oat_file) EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
       EXCLUSIVE_LOCKS_REQUIRED(dex_lock_);
 
@@ -489,10 +489,9 @@
       LOCKS_EXCLUDED(dex_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const OatFile* FindOpenedOatFileFromDexLocation(const std::string& dex_location)
-      EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, dex_lock_);
   const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location)
-      EXCLUSIVE_LOCKS_REQUIRED(dex_lock_);
+      SHARED_LOCKS_REQUIRED(dex_lock_);
   const DexFile* VerifyAndOpenDexFileFromOatFile(const OatFile* oat_file,
                                                  const std::string& dex_location,
                                                  uint32_t dex_location_checksum)
@@ -508,7 +507,7 @@
 
   std::vector<const DexFile*> boot_class_path_;
 
-  mutable Mutex dex_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+  mutable ReaderWriterMutex dex_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
   std::vector<mirror::DexCache*> dex_caches_ GUARDED_BY(dex_lock_);
   std::vector<const OatFile*> oat_files_ GUARDED_BY(dex_lock_);
 
@@ -522,8 +521,7 @@
 
   mirror::Class* LookupClassLocked(const char* descriptor, const mirror::ClassLoader* class_loader,
                                    size_t hash, const Table& classes)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-      EXCLUSIVE_LOCKS_REQUIRED(Locks::classlinker_classes_lock_);
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::classlinker_classes_lock_);
 
   // indexes into class_roots_.
   // needs to be kept in sync with class_roots_descriptors_.
diff --git a/src/compiler/dex/quick/gen_invoke.cc b/src/compiler/dex/quick/gen_invoke.cc
index f44272a..733fdc9 100644
--- a/src/compiler/dex/quick/gen_invoke.cc
+++ b/src/compiler/dex/quick/gen_invoke.cc
@@ -15,6 +15,7 @@
  */
 
 #include "compiler/dex/compiler_ir.h"
+#include "dex_file-inl.h"
 #include "invoke_type.h"
 #include "mirror/array.h"
 #include "mirror/string.h"
@@ -1177,6 +1178,10 @@
     // TODO - add Mips implementation
     return false;
   }
+  if (cu_->instruction_set == kX86 && is_object) {
+    // TODO: fix X86, it exhausts registers for card marking.
+    return false;
+  }
   // Unused - RegLocation rl_src_unsafe = info->args[0];
   RegLocation rl_src_obj = info->args[1];  // Object
   RegLocation rl_src_offset = info->args[2];  // long low
@@ -1220,8 +1225,10 @@
    * method.  By doing this during basic block construction, we can also
    * take advantage of/generate new useful dataflow info.
    */
-  std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
-  if (tgt_method.find(" java.lang") != std::string::npos) {
+  const char* tgt_methods_declaring_class =
+      cu_->dex_file->GetMethodDeclaringClassDescriptor(cu_->dex_file->GetMethodId(info->index));
+  if (strstr(tgt_methods_declaring_class, "Ljava/lang") != NULL) {
+    std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
     if (tgt_method == "long java.lang.Double.doubleToRawLongBits(double)") {
       return GenInlinedDoubleCvt(info);
     }
@@ -1275,7 +1282,8 @@
     if (tgt_method == "java.lang.Thread java.lang.Thread.currentThread()") {
       return GenInlinedCurrentThread(info);
     }
-  } else if (tgt_method.find(" sun.misc.Unsafe") != std::string::npos) {
+  } else if (strstr(tgt_methods_declaring_class, "Lsun/misc/Unsafe;") != NULL) {
+    std::string tgt_method(PrettyMethod(info->index, *cu_->dex_file));
     if (tgt_method == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") {
       return GenInlinedCas32(info, false);
     }
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index bf8bb8a..cc65cbe 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -500,7 +500,7 @@
   InitializeClasses(class_loader, dex_files, thread_pool, timings);
 }
 
-bool CompilerDriver::IsImageClass(const std::string& descriptor) const {
+bool CompilerDriver::IsImageClass(const char* descriptor) const {
   if (image_classes_ == NULL) {
     return false;
   }
@@ -610,9 +610,14 @@
 }
 
 static mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa,
+                                                   mirror::DexCache* dex_cache,
                                                    const DexCompilationUnit* mUnit)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  mirror::DexCache* dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile());
+  // The passed dex_cache is a hint, sanity check before asking the class linker that will take a
+  // lock.
+  if (dex_cache->GetDexFile() != mUnit->GetDexFile()) {
+    dex_cache = mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile());
+  }
   mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader());
   const DexFile::MethodId& referrer_method_id = mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex());
   return mUnit->GetClassLinker()->ResolveType(*mUnit->GetDexFile(), referrer_method_id.class_idx_,
@@ -649,7 +654,9 @@
   // Try to resolve field and ignore if an Incompatible Class Change Error (ie is static).
   mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
   if (resolved_field != NULL && !resolved_field->IsStatic()) {
-    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+    mirror::Class* referrer_class =
+        ComputeCompilingMethodsClass(soa, resolved_field->GetDeclaringClass()->GetDexCache(),
+                                     mUnit);
     if (referrer_class != NULL) {
       mirror::Class* fields_class = resolved_field->GetDeclaringClass();
       bool access_ok = referrer_class->CanAccess(fields_class) &&
@@ -698,7 +705,9 @@
   // Try to resolve field and ignore if an Incompatible Class Change Error (ie isn't static).
   mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
   if (resolved_field != NULL && resolved_field->IsStatic()) {
-    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+    mirror::Class* referrer_class =
+        ComputeCompilingMethodsClass(soa, resolved_field->GetDeclaringClass()->GetDexCache(),
+                                     mUnit);
     if (referrer_class != NULL) {
       mirror::Class* fields_class = resolved_field->GetDeclaringClass();
       if (fields_class == referrer_class) {
@@ -842,7 +851,9 @@
   if (resolved_method != NULL) {
     // Don't try to fast-path if we don't understand the caller's class or this appears to be an
     // Incompatible Class Change Error.
-    mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+    mirror::Class* referrer_class =
+        ComputeCompilingMethodsClass(soa, resolved_method->GetDeclaringClass()->GetDexCache(),
+                                     mUnit);
     bool icce = resolved_method->CheckIncompatibleClassChange(invoke_type);
     if (referrer_class != NULL && !icce) {
       mirror::Class* methods_class = resolved_method->GetDeclaringClass();
@@ -910,6 +921,7 @@
             GetCodeAndMethodForDirectCall(invoke_type, kDirect, referrer_class, called_method,
                                           direct_code, direct_method, update_stats);
             bool compiler_needs_dex_cache =
+                (GetCompilerBackend() == kPortable) ||
                 (GetCompilerBackend() == kQuick && instruction_set_ != kThumb2) ||
                 (direct_code == 0) || (direct_code == static_cast<unsigned int>(-1)) ||
                 (direct_method == 0) || (direct_method == static_cast<unsigned int>(-1));
diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h
index 250532b..c1e449e 100644
--- a/src/compiler/driver/compiler_driver.h
+++ b/src/compiler/driver/compiler_driver.h
@@ -267,7 +267,7 @@
   }
 
   // Checks if class specified by type_idx is one of the image_classes_
-  bool IsImageClass(const std::string& descriptor) const;
+  bool IsImageClass(const char* descriptor) const;
 
   void RecordClassStatus(ClassReference ref, CompiledClass* compiled_class);
 
diff --git a/src/compiler/driver/dex_compilation_unit.cc b/src/compiler/driver/dex_compilation_unit.cc
index 962df42..c7a4df6 100644
--- a/src/compiler/driver/dex_compilation_unit.cc
+++ b/src/compiler/driver/dex_compilation_unit.cc
@@ -31,18 +31,17 @@
       code_item_(cu->code_item),
       class_def_idx_(cu->class_def_idx),
       dex_method_idx_(cu->method_idx),
-      access_flags_(cu->access_flags),
-      symbol_(StringPrintf("dex_%s", MangleForJni(PrettyMethod(dex_method_idx_, *dex_file_)).c_str())) {
+      access_flags_(cu->access_flags) {
 }
 
-DexCompilationUnit:: DexCompilationUnit(CompilationUnit* cu,
-                                        jobject class_loader,
-                                        ClassLinker* class_linker,
-                                        const DexFile& dex_file,
-                                        const DexFile::CodeItem* code_item,
-                                        uint32_t class_def_idx,
-                                        uint32_t method_idx,
-                                        uint32_t access_flags)
+DexCompilationUnit::DexCompilationUnit(CompilationUnit* cu,
+                                       jobject class_loader,
+                                       ClassLinker* class_linker,
+                                       const DexFile& dex_file,
+                                       const DexFile::CodeItem* code_item,
+                                       uint32_t class_def_idx,
+                                       uint32_t method_idx,
+                                       uint32_t access_flags)
     : cu_(cu),
       class_loader_(class_loader),
       class_linker_(class_linker),
@@ -50,8 +49,15 @@
       code_item_(code_item),
       class_def_idx_(class_def_idx),
       dex_method_idx_(method_idx),
-      access_flags_(access_flags),
-      symbol_(StringPrintf("dex_%s", MangleForJni(PrettyMethod(dex_method_idx_, *dex_file_)).c_str())) {
+      access_flags_(access_flags) {
+}
+
+const std::string& DexCompilationUnit::GetSymbol() {
+  if (symbol_.empty()) {
+    symbol_ = "dex_";
+    symbol_ += MangleForJni(PrettyMethod(dex_method_idx_, *dex_file_));
+  }
+  return symbol_;
 }
 
 } // namespace art
diff --git a/src/compiler/driver/dex_compilation_unit.h b/src/compiler/driver/dex_compilation_unit.h
index 0b90aaa..3c6129d 100644
--- a/src/compiler/driver/dex_compilation_unit.h
+++ b/src/compiler/driver/dex_compilation_unit.h
@@ -92,9 +92,7 @@
     return ((access_flags_ & kAccSynchronized) != 0);
   }
 
-  const std::string& GetSymbol() const {
-    return symbol_;
-  }
+  const std::string& GetSymbol();
 
  private:
   CompilationUnit* const cu_;
@@ -110,7 +108,7 @@
   const uint32_t dex_method_idx_;
   const uint32_t access_flags_;
 
-  const std::string symbol_;
+  std::string symbol_;
 };
 
 } // namespace art
diff --git a/src/compiler/llvm/llvm_compilation_unit.h b/src/compiler/llvm/llvm_compilation_unit.h
index d96e778..857d924 100644
--- a/src/compiler/llvm/llvm_compilation_unit.h
+++ b/src/compiler/llvm/llvm_compilation_unit.h
@@ -81,10 +81,10 @@
   void SetCompilerDriver(CompilerDriver* driver) {
     driver_ = driver;
   }
-  const DexCompilationUnit* GetDexCompilationUnit() {
+  DexCompilationUnit* GetDexCompilationUnit() {
     return dex_compilation_unit_;
   }
-  void SetDexCompilationUnit(const DexCompilationUnit* dex_compilation_unit) {
+  void SetDexCompilationUnit(DexCompilationUnit* dex_compilation_unit) {
     dex_compilation_unit_ = dex_compilation_unit;
   }
 
@@ -113,7 +113,7 @@
   UniquePtr<IntrinsicHelper> intrinsic_helper_;
   UniquePtr<LLVMInfo> llvm_info_;
   CompilerDriver* driver_;
-  const DexCompilationUnit* dex_compilation_unit_;
+  DexCompilationUnit* dex_compilation_unit_;
 
   std::string bitcode_filename_;
 
diff --git a/src/dex_file.cc b/src/dex_file.cc
index 0f0bed4..a8fb0e0 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -373,10 +373,10 @@
   const uint16_t class_idx = GetIndexForTypeId(declaring_klass);
   const uint32_t name_idx = GetIndexForStringId(name);
   const uint16_t type_idx = GetIndexForTypeId(type);
-  uint32_t lo = 0;
-  uint32_t hi = NumFieldIds() - 1;
+  int32_t lo = 0;
+  int32_t hi = NumFieldIds() - 1;
   while (hi >= lo) {
-    uint32_t mid = (hi + lo) / 2;
+    int32_t mid = (hi + lo) / 2;
     const DexFile::FieldId& field = GetFieldId(mid);
     if (class_idx > field.class_idx_) {
       lo = mid + 1;
@@ -408,10 +408,10 @@
   const uint16_t class_idx = GetIndexForTypeId(declaring_klass);
   const uint32_t name_idx = GetIndexForStringId(name);
   const uint16_t proto_idx = GetIndexForProtoId(signature);
-  uint32_t lo = 0;
-  uint32_t hi = NumMethodIds() - 1;
+  int32_t lo = 0;
+  int32_t hi = NumMethodIds() - 1;
   while (hi >= lo) {
-    uint32_t mid = (hi + lo) / 2;
+    int32_t mid = (hi + lo) / 2;
     const DexFile::MethodId& method = GetMethodId(mid);
     if (class_idx > method.class_idx_) {
       lo = mid + 1;
@@ -437,10 +437,10 @@
 }
 
 const DexFile::StringId* DexFile::FindStringId(const std::string& string) const {
-  uint32_t lo = 0;
-  uint32_t hi = NumStringIds() - 1;
+  int32_t lo = 0;
+  int32_t hi = NumStringIds() - 1;
   while (hi >= lo) {
-    uint32_t mid = (hi + lo) / 2;
+    int32_t mid = (hi + lo) / 2;
     uint32_t length;
     const DexFile::StringId& str_id = GetStringId(mid);
     const char* str = GetStringDataAndLength(str_id, &length);
@@ -457,10 +457,10 @@
 }
 
 const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const {
-  uint32_t lo = 0;
-  uint32_t hi = NumTypeIds() - 1;
+  int32_t lo = 0;
+  int32_t hi = NumTypeIds() - 1;
   while (hi >= lo) {
-    uint32_t mid = (hi + lo) / 2;
+    int32_t mid = (hi + lo) / 2;
     const TypeId& type_id = GetTypeId(mid);
     if (string_idx > type_id.descriptor_idx_) {
       lo = mid + 1;
@@ -475,10 +475,10 @@
 
 const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx,
                                          const std::vector<uint16_t>& signature_type_idxs) const {
-  uint32_t lo = 0;
-  uint32_t hi = NumProtoIds() - 1;
+  int32_t lo = 0;
+  int32_t hi = NumProtoIds() - 1;
   while (hi >= lo) {
-    uint32_t mid = (hi + lo) / 2;
+    int32_t mid = (hi + lo) / 2;
     const DexFile::ProtoId& proto = GetProtoId(mid);
     int compare = return_type_idx - proto.return_type_idx_;
     if (compare == 0) {
diff --git a/src/locks.cc b/src/locks.cc
index eb0620c..51a40c3 100644
--- a/src/locks.cc
+++ b/src/locks.cc
@@ -22,7 +22,7 @@
 
 Mutex* Locks::abort_lock_ = NULL;
 Mutex* Locks::breakpoint_lock_ = NULL;
-Mutex* Locks::classlinker_classes_lock_ = NULL;
+ReaderWriterMutex* Locks::classlinker_classes_lock_ = NULL;
 ReaderWriterMutex* Locks::heap_bitmap_lock_ = NULL;
 Mutex* Locks::logging_lock_ = NULL;
 ReaderWriterMutex* Locks::mutator_lock_ = NULL;
@@ -52,7 +52,8 @@
     DCHECK(breakpoint_lock_ == NULL);
     breakpoint_lock_ = new Mutex("breakpoint lock", kBreakpointLock);
     DCHECK(classlinker_classes_lock_ == NULL);
-    classlinker_classes_lock_ = new Mutex("ClassLinker classes lock", kClassLinkerClassesLock);
+    classlinker_classes_lock_ = new ReaderWriterMutex("ClassLinker classes lock",
+                                                      kClassLinkerClassesLock);
     DCHECK(heap_bitmap_lock_ == NULL);
     heap_bitmap_lock_ = new ReaderWriterMutex("heap bitmap lock", kHeapBitmapLock);
     DCHECK(mutator_lock_ == NULL);
diff --git a/src/locks.h b/src/locks.h
index 431a148..ceb04b9 100644
--- a/src/locks.h
+++ b/src/locks.h
@@ -143,7 +143,7 @@
   static Mutex* trace_lock_ ACQUIRED_AFTER(breakpoint_lock_);
 
   // Guards lists of classes within the class linker.
-  static Mutex* classlinker_classes_lock_ ACQUIRED_AFTER(trace_lock_);
+  static ReaderWriterMutex* classlinker_classes_lock_ ACQUIRED_AFTER(trace_lock_);
 
   // When declaring any Mutex add DEFAULT_MUTEX_ACQUIRED_AFTER to use annotalysis to check the code
   // doesn't try to hold a higher level Mutex.
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 4a86112..e225d2c 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -955,9 +955,9 @@
   const std::vector<uint8_t>* dex_gc_map = CreateLengthPrefixedDexGcMap(*(map.get()));
   verifier::MethodVerifier::SetDexGcMap(ref, *dex_gc_map);
 
-  MethodVerifier::PcToConreteMethod* pc_to_conrete_method = GenerateDevirtMap();
-  if(pc_to_conrete_method != NULL ) {
-    SetDevirtMap(ref, pc_to_conrete_method);
+  MethodVerifier::PcToConcreteMethod* pc_to_concrete_method = GenerateDevirtMap();
+  if(pc_to_concrete_method != NULL ) {
+    SetDevirtMap(ref, pc_to_concrete_method);
   }
   return true;
 }
@@ -3229,7 +3229,7 @@
   *log2_max_gc_pc = i;
 }
 
-MethodVerifier::PcToConreteMethod* MethodVerifier::GenerateDevirtMap() {
+MethodVerifier::PcToConcreteMethod* MethodVerifier::GenerateDevirtMap() {
 
   // It is risky to rely on reg_types for sharpening in cases of soft
   // verification, we might end up sharpening to a wrong implementation. Just abort.
@@ -3237,7 +3237,7 @@
     return NULL;
   }
 
-  UniquePtr<PcToConreteMethod> pc_to_concrete_method(new PcToConreteMethod());
+  UniquePtr<PcToConcreteMethod> pc_to_concrete_method(new PcToConcreteMethod());
   uint32_t dex_pc = 0;
   const uint16_t* insns = code_item_->insns_ ;
   const Instruction* inst = Instruction::At(insns);
@@ -3407,7 +3407,7 @@
   CHECK(GetDexGcMap(ref) != NULL);
 }
 
-void  MethodVerifier::SetDevirtMap(CompilerDriver::MethodReference ref, const PcToConreteMethod* devirt_map) {
+void  MethodVerifier::SetDevirtMap(CompilerDriver::MethodReference ref, const PcToConcreteMethod* devirt_map) {
 
   MutexLock mu(Thread::Current(), *devirt_maps_lock_);
   DevirtualizationMapTable::iterator it = devirt_maps_->find(ref);
@@ -3440,7 +3440,7 @@
   }
 
   // Look up the PC in the map, get the concrete method to execute and return its reference.
-  MethodVerifier::PcToConreteMethod::const_iterator pc_to_concrete_method = it->second->find(dex_pc);
+  MethodVerifier::PcToConcreteMethod::const_iterator pc_to_concrete_method = it->second->find(dex_pc);
   if(pc_to_concrete_method != it->second->end()) {
     return &(pc_to_concrete_method->second);
   } else {
diff --git a/src/verifier/method_verifier.h b/src/verifier/method_verifier.h
index 755d089..9b4b8e5 100644
--- a/src/verifier/method_verifier.h
+++ b/src/verifier/method_verifier.h
@@ -584,15 +584,16 @@
 
 
   // Devirtualization map.
-  typedef SafeMap<const uint32_t, CompilerDriver::MethodReference> PcToConreteMethod;
-  typedef SafeMap<const CompilerDriver::MethodReference, const PcToConreteMethod*,
+  typedef SafeMap<const uint32_t, CompilerDriver::MethodReference> PcToConcreteMethod;
+  typedef SafeMap<const CompilerDriver::MethodReference, const PcToConcreteMethod*,
       CompilerDriver::MethodReferenceComparator> DevirtualizationMapTable;
-  MethodVerifier::PcToConreteMethod* GenerateDevirtMap()
+  MethodVerifier::PcToConcreteMethod* GenerateDevirtMap()
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   static Mutex* devirt_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
   static DevirtualizationMapTable* devirt_maps_ GUARDED_BY(devirt_maps_lock_);
-  static void SetDevirtMap(CompilerDriver::MethodReference ref, const PcToConreteMethod* pc_method_map);
+  static void SetDevirtMap(CompilerDriver::MethodReference ref,
+                           const PcToConcreteMethod* pc_method_map)
         LOCKS_EXCLUDED(devirt_maps_lock_);
   typedef std::set<CompilerDriver::ClassReference> RejectedClassesTable;
   static Mutex* rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
diff --git a/src/verifier/reg_type.cc b/src/verifier/reg_type.cc
index 32679f6..5db6aff 100644
--- a/src/verifier/reg_type.cc
+++ b/src/verifier/reg_type.cc
@@ -32,7 +32,6 @@
 namespace art {
 namespace verifier {
 
-static const bool kIsDebugBuild = false;
 UndefinedType* UndefinedType::instance_ = NULL;
 ConflictType* ConflictType::instance_ = NULL;
 BooleanType* BooleanType::instance = NULL;
@@ -70,36 +69,44 @@
 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,
+DoubleHiType* DoubleHiType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
                                            uint16_t cache_id) {
   if (instance_ == NULL) {
     instance_ = new DoubleHiType(klass, descriptor, cache_id);
@@ -119,7 +126,7 @@
   }
 }
 
-DoubleLoType* DoubleLoType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+DoubleLoType* DoubleLoType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
                                            uint16_t cache_id) {
   if (instance_ == NULL) {
     instance_ = new DoubleLoType(klass, descriptor, cache_id);
@@ -139,7 +146,7 @@
   }
 }
 
-LongLoType* LongLoType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+LongLoType* LongLoType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
                                        uint16_t cache_id) {
   if (instance_ == NULL) {
     instance_ = new LongLoType(klass, descriptor, cache_id);
@@ -147,7 +154,7 @@
   return instance_;
 }
 
-LongHiType* LongHiType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+LongHiType* LongHiType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
                                        uint16_t cache_id) {
   if (instance_ == NULL) {
     instance_ = new LongHiType(klass, descriptor, cache_id);
@@ -179,9 +186,8 @@
   }
 }
 
-FloatType* FloatType::CreateInstance(mirror::Class* klass, std::string& descriptor,
-                                     uint16_t cache_id)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+FloatType* FloatType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
+                                     uint16_t cache_id) {
   if (instance_ == NULL) {
     instance_ = new FloatType(klass, descriptor, cache_id);
   }
@@ -199,17 +205,19 @@
   }
 }
 
-CharType* CharType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+CharType* CharType::CreateInstance(mirror::Class* klass, const 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_;
@@ -217,81 +225,94 @@
   }
 }
 
-ShortType* ShortType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+ShortType* ShortType::CreateInstance(mirror::Class* klass, const 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_) {
+
+ByteType* ByteType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
+                                   uint16_t cache_id) {
   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,
+
+IntegerType* IntegerType::CreateInstance(mirror::Class* klass, const 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,
+
+ConflictType* ConflictType::CreateInstance(mirror::Class* klass, const 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,
+
+BooleanType* BooleanType::CreateInstance(mirror::Class* klass, const 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;
@@ -307,23 +328,27 @@
 std::string UndefinedType::Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   return "Undefined";
 }
-UndefinedType* UndefinedType::CreateInstance(mirror::Class* klass, std::string& descriptor,
+
+UndefinedType* UndefinedType::CreateInstance(mirror::Class* klass, const 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();
@@ -338,6 +363,7 @@
   result << ")";
   return result.str();
 }
+
 std::string UnresolvedSuperClass::Dump() const {
   std::stringstream result;
   uint16_t super_type_id = GetUnresolvedSuperClassChildId();
@@ -358,7 +384,7 @@
   return result.str();
 }
 
-std::string UnresolvedUninitialisedThisRefType::Dump() const {
+std::string UnresolvedUninitializedThisRefType::Dump() const {
   std::stringstream result;
   result << "Unresolved And Uninitialized This Reference" << PrettyDescriptor(GetDescriptor());
   return result.str();
@@ -376,13 +402,14 @@
   return result.str();
 }
 
-std::string UninitialisedReferenceType::Dump() const {
+std::string UninitializedReferenceType::Dump() const {
   std::stringstream result;
   result << "Uninitialized Reference" << ": " << PrettyDescriptor(GetClass());
   result << " Allocation PC: " << GetAllocationPc();
   return result.str();
 }
-std::string UninitialisedThisReferenceType::Dump() const {
+
+std::string UninitializedThisReferenceType::Dump() const {
   std::stringstream result;
   result << "Uninitialized This Reference" << ": " << PrettyDescriptor(GetClass());
   result << "Allocation PC: " << GetAllocationPc();
@@ -459,76 +486,77 @@
   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)
+BooleanType::BooleanType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-ByteType::ByteType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+ConflictType::ConflictType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-ShortType::ShortType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+ByteType::ByteType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-CharType::CharType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+ShortType::ShortType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-IntegerType::IntegerType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+CharType::CharType(mirror::Class* klass, const 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)
+IntegerType::IntegerType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, std::string& descriptor,
+ConstantType::ConstantType(uint32_t constant, uint16_t cache_id)
+    : RegType(NULL, "", cache_id), constant_(constant) {
+}
+
+ReferenceType::ReferenceType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
+    : RegType(klass, descriptor, cache_id) {
+}
+
+PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, const std::string& descriptor,
                                            uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
   DCHECK(klass->IsInstantiable());
 }
 
-UnresolvedUninitialisedThisRefType::UnresolvedUninitialisedThisRefType(std::string& descriptor,
+UnresolvedUninitializedThisRefType::UnresolvedUninitializedThisRefType(const std::string& descriptor,
                                                                        uint16_t cache_id)
     : UninitializedType(NULL, descriptor, 0, cache_id) {
 }
 
-UnresolvedUninitializedRefType::UnresolvedUninitializedRefType( std::string& descriptor,
+UnresolvedUninitializedRefType::UnresolvedUninitializedRefType(const 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)
+UninitializedReferenceType::UninitializedReferenceType(mirror::Class* klass,
+                                                       const 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)
+LongHiType::LongHiType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-FloatType::FloatType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+FloatType::FloatType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-DoubleLoType::DoubleLoType(mirror::Class* klass,  std::string& descriptor, uint16_t cache_id)
+DoubleLoType::DoubleLoType(mirror::Class* klass,  const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-DoubleHiType::DoubleHiType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+DoubleHiType::DoubleHiType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
-LongLoType::LongLoType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+LongLoType::LongLoType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id) {
 }
 
@@ -749,10 +777,12 @@
   DCHECK(IsConstantTypes());
   return constant_;
 }
+
 int32_t ConstantType::ConstantValueLo() const {
   DCHECK(IsConstantLo());
   return constant_;
 }
+
 int32_t ConstantType::ConstantValueHi() const {
   if (IsConstantHi() || IsPreciseConstantHi() || IsImpreciseConstantHi()) {
     return constant_;
@@ -761,6 +791,7 @@
     return 0;
   }
 }
+
 static const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
   return a.IsConstant() ? b : a;
 }
@@ -951,7 +982,7 @@
   }
 }
 
-UninitializedType::UninitializedType(mirror::Class* klass, std::string& descriptor,
+UninitializedType::UninitializedType(mirror::Class* klass, const std::string& descriptor,
                                      uint32_t allocation_pc, uint16_t cache_id)
     : RegType(klass, descriptor, cache_id), allocation_pc_(allocation_pc) {
 }
@@ -960,15 +991,15 @@
   CHECK_EQ(allocation_pc_, 0U) << *this;
 }
 
-void UninitialisedThisReferenceType::CheckInvariants() const {
+void UninitializedThisReferenceType::CheckInvariants() const {
   UninitializedType::CheckInvariants();
 }
 
-UninitialisedThisReferenceType::UninitialisedThisReferenceType(mirror::Class* klass,
-  std::string& descriptor, uint16_t cache_id) : UninitializedType(klass, descriptor, 0, cache_id) {
+UninitializedThisReferenceType::UninitializedThisReferenceType(mirror::Class* klass,
+  const std::string& descriptor, uint16_t cache_id) : UninitializedType(klass, descriptor, 0, cache_id) {
 }
 
-void UnresolvedUninitialisedThisRefType::CheckInvariants() const {
+void UnresolvedUninitializedThisRefType::CheckInvariants() const {
   UninitializedType::CheckInvariants();
   CHECK(!descriptor_.empty()) << *this;
   CHECK(klass_ == NULL) << *this;
diff --git a/src/verifier/reg_type.h b/src/verifier/reg_type.h
index 7c42536..39c33c6 100644
--- a/src/verifier/reg_type.h
+++ b/src/verifier/reg_type.h
@@ -268,9 +268,8 @@
   inline virtual bool IsLong() const {
     return false;
   }
-  bool HasClass() const {
-    return IsReference() || IsPreciseReference() || IsUninitializedReference() ||
-           IsUninitializedThisReference();
+  virtual bool HasClass() const {
+    return false;
   }
   bool IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   bool IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -326,7 +325,7 @@
 
   static mirror::Class* ClassJoin(mirror::Class* s, mirror::Class* t)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  RegType(mirror::Class* klass, std::string descriptor, uint16_t cache_id)
+  RegType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
       : descriptor_(descriptor), klass_(klass), cache_id_(cache_id) {
   }
@@ -349,12 +348,13 @@
     return true;
   }
   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* CreateInstance(mirror::Class* klass, const 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)
+  ConflictType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static ConflictType* instance_;
 };
@@ -365,13 +365,13 @@
     return true;
   }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static UndefinedType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static UndefinedType* CreateInstance(mirror::Class* klass, const 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)
+  UndefinedType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
       : RegType(klass, descriptor, cache_id) {
   }
@@ -386,13 +386,13 @@
     return true;
   }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static IntegerType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static IntegerType* CreateInstance(mirror::Class* klass, const 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)
+  IntegerType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static IntegerType* instance_;
 };
@@ -403,13 +403,13 @@
     return true;
   }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static BooleanType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static BooleanType* CreateInstance(mirror::Class* klass, const 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)
+  BooleanType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static BooleanType* instance;
 };
@@ -420,13 +420,13 @@
     return true;
   }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static ByteType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static ByteType* CreateInstance(mirror::Class* klass, const 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)
+  ByteType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static ByteType* instance_;
 };
@@ -437,13 +437,13 @@
     return true;
   }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static ShortType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static ShortType* CreateInstance(mirror::Class* klass, const 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)
+  ShortType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static ShortType* instance_;
 };
@@ -454,13 +454,13 @@
     return true;
   }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static CharType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static CharType* CreateInstance(mirror::Class* klass, const 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)
+  CharType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static CharType* instance_;
 };
@@ -471,13 +471,13 @@
     return true;
   }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  static FloatType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static FloatType* CreateInstance(mirror::Class* klass, const 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)
+  FloatType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static FloatType* instance_;
 };
@@ -491,13 +491,13 @@
   bool IsLong() const {
     return true;
   }
-  static LongLoType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static LongLoType* CreateInstance(mirror::Class* klass, const 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)
+  LongLoType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static LongLoType* instance_;
 };
@@ -508,13 +508,13 @@
   bool IsLongHi() const {
     return true;
   }
-  static LongHiType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static LongHiType* CreateInstance(mirror::Class* klass, const 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)
+  LongHiType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static LongHiType* instance_;
 };
@@ -528,13 +528,13 @@
   bool IsDouble() const {
     return true;
   }
-  static DoubleLoType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static DoubleLoType* CreateInstance(mirror::Class* klass, const 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)
+  DoubleLoType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static DoubleLoType* instance_;
 };
@@ -545,13 +545,13 @@
   virtual bool IsDoubleHi() const {
     return true;
   }
-  static DoubleHiType* CreateInstance(mirror::Class* klass, std::string& descriptor,
+  static DoubleHiType* CreateInstance(mirror::Class* klass, const 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)
+  DoubleHiType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   static DoubleHiType* instance_;
 };
@@ -664,7 +664,7 @@
 
 class UninitializedType : public RegType {
  public:
-  UninitializedType(mirror::Class* klass, std::string& descriptor, uint32_t allocation_pc,
+  UninitializedType(mirror::Class* klass, const std::string& descriptor, uint32_t allocation_pc,
                     uint16_t cache_id);
   inline virtual ~UninitializedType() {
   }
@@ -679,20 +679,23 @@
   const uint32_t allocation_pc_;
 };
 
-class UninitialisedReferenceType : public UninitializedType {
+class UninitializedReferenceType : public UninitializedType {
  public:
-  UninitialisedReferenceType(mirror::Class* klass, std::string& descriptor, uint32_t allocation_pc,
+  UninitializedReferenceType(mirror::Class* klass, const std::string& descriptor, uint32_t allocation_pc,
                              uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   bool IsUninitializedReference() const {
     return true;
   }
+  bool HasClass() const {
+    return true;
+  }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 };
 
 class UnresolvedUninitializedRefType : public UninitializedType {
  public:
-  UnresolvedUninitializedRefType(std::string& descriptor, uint32_t allocation_pc,
+  UnresolvedUninitializedRefType(const std::string& descriptor, uint32_t allocation_pc,
                                  uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   bool IsUnresolvedAndUninitializedReference() const {
@@ -701,20 +704,23 @@
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 };
 
-class UninitialisedThisReferenceType : public UninitializedType {
+class UninitializedThisReferenceType : public UninitializedType {
  public:
-  UninitialisedThisReferenceType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+  UninitializedThisReferenceType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  inline virtual bool IsUninitializedThisReference() const {
+  virtual bool IsUninitializedThisReference() const {
+    return true;
+  }
+  bool HasClass() const {
     return true;
   }
 };
 
-class UnresolvedUninitialisedThisRefType : public UninitializedType {
+class UnresolvedUninitializedThisRefType : public UninitializedType {
  public:
-  UnresolvedUninitialisedThisRefType(std::string& descriptor, uint16_t cache_id)
+  UnresolvedUninitializedThisRefType(const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -725,27 +731,33 @@
 
 class ReferenceType : public RegType {
  public:
-  ReferenceType(mirror::Class* klass, std::string& descriptor, uint16_t cache_id)
+  ReferenceType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   bool IsReference() const {
     return true;
   }
+  bool HasClass() const {
+    return true;
+  }
   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)
+  PreciseReferenceType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   bool IsPreciseReference() const {
     return true;
   }
+  bool HasClass() const {
+    return true;
+  }
 };
 
 class UnresolvedReferenceType : public RegType {
  public:
-  UnresolvedReferenceType(std::string& descriptor, uint16_t cache_id)
+  UnresolvedReferenceType(const std::string& descriptor, uint16_t cache_id)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : RegType(NULL, descriptor, cache_id) {
   }
   std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/src/verifier/reg_type_cache-inl.h b/src/verifier/reg_type_cache-inl.h
index f6b0056..42474d1 100644
--- a/src/verifier/reg_type_cache-inl.h
+++ b/src/verifier/reg_type_cache-inl.h
@@ -24,7 +24,7 @@
 namespace art {
 namespace verifier {
 template <class Type>
-Type* RegTypeCache::CreatePrimitiveTypeInstance(std::string descriptor) {
+Type* RegTypeCache::CreatePrimitiveTypeInstance(const std::string& descriptor) {
   mirror::Class* klass = NULL;
   // Try loading the class from linker.
   if (!descriptor.empty()) {
@@ -35,6 +35,12 @@
   return entry;
 }
 
+inline const art::verifier::RegType& RegTypeCache::GetFromId(uint16_t id) const {
+  DCHECK_LT(id, entries_.size());
+  RegType* result = entries_[id];
+  DCHECK(result != NULL);
+  return *result;
+}
 }  // 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 e914d1e..57a825b 100644
--- a/src/verifier/reg_type_cache.cc
+++ b/src/verifier/reg_type_cache.cc
@@ -24,6 +24,7 @@
 
 namespace art {
 namespace verifier {
+
 bool RegTypeCache::primitive_initialized_ = false;
 uint16_t RegTypeCache::primitive_start_ = 0;
 uint16_t RegTypeCache::primitive_count_ = 0;
@@ -49,9 +50,10 @@
   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) {
+const RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor,
+                                            bool precise) {
+  DCHECK(RegTypeCache::primitive_initialized_);
+  if (descriptor[1] == '\0') {
     switch (descriptor[0]) {
       case 'Z':
         return Boolean();
@@ -80,15 +82,7 @@
   }
 };
 
-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 {
+const RegType& RegTypeCache::RegTypeFromPrimitiveType(Primitive::Type prim_type) const {
   CHECK(RegTypeCache::primitive_initialized_);
   switch (prim_type) {
     case Primitive::kPrimBoolean:
@@ -113,21 +107,22 @@
   }
 }
 
-bool RegTypeCache::MatchDescriptor(size_t idx, std::string& descriptor, bool precise) {
+bool RegTypeCache::MatchDescriptor(size_t idx, const char* descriptor, bool precise) {
   RegType* cur_entry = entries_[idx];
   if (cur_entry->HasClass()) {
     // Check the descriptor in the reg_type if available.
     if(!cur_entry->descriptor_.empty()) {
-      if (descriptor == cur_entry->descriptor_ && MatchingPrecisionForClass(cur_entry, precise)) {
+      if (cur_entry->descriptor_ == descriptor && MatchingPrecisionForClass(cur_entry, precise)) {
         return true;
       }
     } else {
-      // Descriptor not found in reg_type , maybe available in Class object.
+      // TODO: maintain an invariant that when we have a Class the descriptor is computed from that.
+      // Descriptor not found in reg_type, maybe available in Class object.
       // 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.
       ClassHelper kh(cur_entry->GetClass());
-      if ((strcmp(descriptor.c_str(), kh.GetDescriptor()) == 0) &&
+      if ((strcmp(descriptor, kh.GetDescriptor()) == 0) &&
           MatchingPrecisionForClass(cur_entry, precise)) {
         return true;
       }
@@ -138,16 +133,15 @@
   return false;
 }
 
-
-mirror::Class* RegTypeCache::ResolveClass(std::string descriptor, mirror::ClassLoader* loader) {
+mirror::Class* RegTypeCache::ResolveClass(const char* 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);
+    klass = class_linker->FindClass(descriptor, loader);
   } else {
-    klass = class_linker->LookupClass(descriptor.c_str(), loader);
+    klass = class_linker->LookupClass(descriptor, loader);
     if (klass != NULL && !klass->IsLoaded()) {
       // We found the class but without it being loaded its not safe for use.
       klass = NULL;
@@ -155,6 +149,7 @@
   }
   return klass;
 }
+
 void RegTypeCache::ClearException() {
   if (can_load_classes_) {
     DCHECK(Thread::Current()->IsExceptionPending());
@@ -163,8 +158,9 @@
     DCHECK(!Thread::Current()->IsExceptionPending());
   }
 }
-const RegType& RegTypeCache::From(mirror::ClassLoader* loader, std::string descriptor, bool precise) {
 
+const RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor,
+                                  bool precise) {
   // Try looking up the class in the cache first.
   for (size_t i = primitive_count_; i < entries_.size(); i++) {
     if (MatchDescriptor(i, descriptor, precise)) {
@@ -198,7 +194,7 @@
     // We tried loading the class and failed, this might get an exception raised
     // so we want to clear it before we go on.
     ClearException();
-    if (IsValidDescriptor(descriptor.c_str())) {
+    if (IsValidDescriptor(descriptor)) {
       RegType* entry = new UnresolvedReferenceType(descriptor, entries_.size());
       entries_.push_back(entry);
       return *entry;
@@ -209,6 +205,7 @@
     }
   }
 }
+
 const RegType& RegTypeCache::FromClass(mirror::Class* klass, bool precise) {
   if (klass->IsPrimitive()) {
     return RegTypeFromPrimitiveType(klass->GetPrimitiveType());
@@ -223,11 +220,10 @@
     }
     // No reference to the class was found, create new reference.
     RegType* entry;
-    std::string empty = "";
     if (precise) {
-      entry = new PreciseReferenceType(klass, empty, entries_.size());
+      entry = new PreciseReferenceType(klass, "", entries_.size());
     } else {
-      entry = new ReferenceType(klass, empty, entries_.size());
+      entry = new ReferenceType(klass, "", entries_.size());
     }
     entries_.push_back(entry);
     return *entry;
@@ -309,13 +305,14 @@
   // Create entry.
   RegType* entry = new UnresolvedMergedType(left.GetId(), right.GetId(), this, entries_.size());
   entries_.push_back(entry);
-#ifndef NDEBUG
-  UnresolvedMergedType* tmp_entry = down_cast<UnresolvedMergedType*>(entry);
-  std::set<uint16_t> check_types = tmp_entry->GetMergedTypes();
-  CHECK(check_types == types);
-#endif
+  if (kIsDebugBuild) {
+    UnresolvedMergedType* tmp_entry = down_cast<UnresolvedMergedType*>(entry);
+    std::set<uint16_t> check_types = tmp_entry->GetMergedTypes();
+    CHECK(check_types == types);
+  }
   return *entry;
 }
+
 const RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) {
   // Check if entry already exists.
   for (size_t i = primitive_count_; i < entries_.size(); i++) {
@@ -334,11 +331,12 @@
   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());
+    const std::string& descriptor(type.GetDescriptor());
     for (size_t i = primitive_count_; i < entries_.size(); i++) {
       cur_entry = entries_[i];
       if (cur_entry->IsUnresolvedAndUninitializedReference() &&
@@ -347,29 +345,29 @@
         return *cur_entry;
       }
     }
-    entry = new UnresolvedUninitializedRefType(descriptor, allocation_pc, entries_.size());
+    entry = new UnresolvedUninitializedRefType(descriptor.c_str(), allocation_pc, entries_.size());
   } else {
     mirror::Class* klass = type.GetClass();
     for (size_t i = primitive_count_; i < entries_.size(); i++) {
       cur_entry = entries_[i];
       if (cur_entry->IsUninitializedReference() &&
-          down_cast<UninitialisedReferenceType*>(cur_entry)
+          down_cast<UninitializedReferenceType*>(cur_entry)
               ->GetAllocationPc() == allocation_pc &&
           cur_entry->GetClass() == klass) {
         return *cur_entry;
       }
     }
-    std::string descriptor("");
-    entry = new UninitialisedReferenceType(klass, descriptor, allocation_pc, entries_.size());
+    entry = new UninitializedReferenceType(klass, "", 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());
+    const std::string& descriptor(uninit_type.GetDescriptor());
     for (size_t i = primitive_count_; i < entries_.size(); i++) {
       RegType* cur_entry = entries_[i];
       if (cur_entry->IsUnresolvedReference() &&
@@ -377,7 +375,7 @@
         return *cur_entry;
       }
     }
-    entry = new UnresolvedReferenceType(descriptor, entries_.size());
+    entry = new UnresolvedReferenceType(descriptor.c_str(), entries_.size());
   } else {
     mirror::Class* klass = uninit_type.GetClass();
     if(uninit_type.IsUninitializedThisReference() && !klass->IsFinal()) {
@@ -388,10 +386,8 @@
           return *cur_entry;
         }
       }
-      std::string descriptor("");
-      entry = new ReferenceType(klass, descriptor, entries_.size());
+      entry = new ReferenceType(klass, "", entries_.size());
     } else {
-        std::string descriptor;
         if (klass->IsFinal()) {
           if (klass->IsInstantiable()) {
             for (size_t i = primitive_count_; i < entries_.size(); i++) {
@@ -401,7 +397,7 @@
               }
             }
             // Precise type was not found , create one !
-            entry = new PreciseReferenceType(klass, descriptor, entries_.size());
+            entry = new PreciseReferenceType(klass, "", entries_.size());
           } else {
             return Conflict();
           }
@@ -414,26 +410,30 @@
             return *cur_entry;
           }
         }
-        entry = new ReferenceType(klass, descriptor, entries_.size());
+        entry = new ReferenceType(klass, "", entries_.size());
       }
     }
  }
   entries_.push_back(entry);
   return *entry;
 }
-const RegType& RegTypeCache::ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+
+const RegType& RegTypeCache::ByteConstant() {
   return FromCat1Const(std::numeric_limits<jbyte>::min(), false);
 }
-const RegType& RegTypeCache::ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+
+const RegType& RegTypeCache::ShortConstant() {
   return FromCat1Const(std::numeric_limits<jshort>::min(), false);
 }
-const RegType& RegTypeCache::IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+
+const RegType& RegTypeCache::IntConstant() {
   return FromCat1Const(std::numeric_limits<jint>::max(), false);
 }
+
 const RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
   RegType* entry;
   if (type.IsUnresolvedTypes()) {
-    std::string descriptor(type.GetDescriptor());
+    const std::string& descriptor(type.GetDescriptor());
     for (size_t i = primitive_count_; i < entries_.size(); i++) {
       RegType* cur_entry = entries_[i];
       if (cur_entry->IsUnresolvedAndUninitializedThisReference() &&
@@ -441,7 +441,7 @@
         return *cur_entry;
       }
     }
-    entry = new UnresolvedUninitialisedThisRefType(descriptor, entries_.size());
+    entry = new UnresolvedUninitializedThisRefType(descriptor, entries_.size());
   } else {
     mirror::Class* klass = type.GetClass();
     for (size_t i = primitive_count_; i < entries_.size(); i++) {
@@ -451,12 +451,12 @@
         return *cur_entry;
       }
     }
-    std::string descriptor("");
-    entry = new UninitialisedThisReferenceType(klass, descriptor, entries_.size());
+    entry = new UninitializedThisReferenceType(klass, "", entries_.size());
   }
   entries_.push_back(entry);
   return *entry;
 }
+
 const RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
   for (size_t i = primitive_count_; i < entries_.size(); i++) {
     RegType* cur_entry = entries_[i];
@@ -514,8 +514,8 @@
 const RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) {
   CHECK(array.IsArrayTypes());
   if (array.IsUnresolvedTypes()) {
-    std::string descriptor(array.GetDescriptor());
-    std::string component(descriptor.substr(1, descriptor.size() - 1));
+    const std::string& descriptor(array.GetDescriptor());
+    const std::string component(descriptor.substr(1, descriptor.size() - 1));
     return FromDescriptor(loader, component.c_str(), false);
   } else {
     mirror::Class* klass = array.GetClass()->GetComponentType();
diff --git a/src/verifier/reg_type_cache.h b/src/verifier/reg_type_cache.h
index 602c950..a5304db 100644
--- a/src/verifier/reg_type_cache.h
+++ b/src/verifier/reg_type_cache.h
@@ -52,10 +52,10 @@
   }
   static void ShutDown();
   const art::verifier::RegType& GetFromId(uint16_t id) const;
-  const RegType& From(mirror::ClassLoader* loader, std::string descriptor, bool precise)
+  const RegType& From(mirror::ClassLoader* loader, const char* descriptor, bool precise)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   template <class Type>
-  static Type* CreatePrimitiveTypeInstance(std::string descriptor)
+  static Type* CreatePrimitiveTypeInstance(const std::string& descriptor)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void FillPrimitiveTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const RegType& FromClass(mirror::Class* klass, bool precise)
@@ -152,10 +152,10 @@
   // 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)
+  mirror::Class* ResolveClass(const char* descriptor, mirror::ClassLoader* loader)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void ClearException();
-  bool MatchDescriptor(size_t idx, std::string& descriptor, bool precise)
+  bool MatchDescriptor(size_t idx, const char* descriptor, bool precise)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 };