Profiler directed clean-up of dex2oat.

Fix bad usage of std::string in: the verifier and compiler driver method
arguments, causing unnecessary boxing and allocations; in creating a symbol for
the dex compilation unit, that is only used in portable builds; in pattern
matching for intrinsics by name.

Make class linker dex and classes locks reader/writer to allow concurrent
dex cache or class querying. Refactor ComputeCompilingMethodsClass to pass in a
dex cache hint, to avoid taking any locks when the dex file of the compiling
method matches that of the field or method being resolved.

Make the RegType's HasClass method virtual to avoid frequent virtual method
dispatch. Make RegTypeCache GetFromId inlinable.

Various other bits of whitespace and formatting clean-up.

Change-Id: Id152e1e5a6fed2961dad0b612b7aa0c48001ef94
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 85dcdf6..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();
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/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 1b2d9f3..a7d26bb 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;
 }
@@ -3160,7 +3160,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.
@@ -3168,7 +3168,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);
@@ -3338,7 +3338,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);
@@ -3371,7 +3371,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_);
 };