Avoid use of std::string where we have const char*.

Removing the ClassHelper caused std::string creation for all calls to
Class::GetDescriptor and a significant performance regression. Make the
std::string an out argument so the caller can maintain it and its life time
while allowing GetDescriptor to return the common const char* case.

Don't generate GC maps when compilation is disabled.

Remove other uses of std::string that are occuring on critical paths.
Use the cheaper SkipClass in CompileMethod in CompilerDriver.
Specialize the utf8 as utf16 comparison code for the common shorter byte
encoding.
Force a bit of inlining, remove some UNLIKELYs (they are prone to pessimizing
code), add some LIKELYs.

x86-64 host 1-thread interpret-only of 57 apks:
Before: 29.539s
After: 23.467s

Regular compile:
Before: 1m35.347s
After: 1m20.056s

Bug: 16853450
Change-Id: Ic705ea24784bee24ab80084d06174cbf87d557ad
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index bc13379..fa1a1a8 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -451,6 +451,13 @@
   return static_cast<JDWP::JdwpTag>(descriptor[0]);
 }
 
+static JDWP::JdwpTag BasicTagFromClass(mirror::Class* klass)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  std::string temp;
+  const char* descriptor = klass->GetDescriptor(&temp);
+  return BasicTagFromDescriptor(descriptor);
+}
+
 static JDWP::JdwpTag TagFromClass(const ScopedObjectAccessUnchecked& soa, mirror::Class* c)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   CHECK(c != NULL);
@@ -824,7 +831,8 @@
   if (!o->IsClass()) {
     return StringPrintf("non-class %p", o);  // This is only used for debugging output anyway.
   }
-  return DescriptorToName(o->AsClass()->GetDescriptor().c_str());
+  std::string temp;
+  return DescriptorToName(o->AsClass()->GetDescriptor(&temp));
 }
 
 JDWP::JdwpError Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& class_object_id) {
@@ -1140,7 +1148,8 @@
   Runtime::Current()->GetClassLinker()->VisitClasses(ClassListCreator::Visit, &clc);
 }
 
-JDWP::JdwpError Dbg::GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor) {
+JDWP::JdwpError Dbg::GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag,
+                                  uint32_t* pStatus, std::string* pDescriptor) {
   JDWP::JdwpError status;
   mirror::Class* c = DecodeClass(class_id, status);
   if (c == NULL) {
@@ -1160,7 +1169,8 @@
   }
 
   if (pDescriptor != NULL) {
-    *pDescriptor = c->GetDescriptor();
+    std::string temp;
+    *pDescriptor = c->GetDescriptor(&temp);
   }
   return JDWP::ERR_NONE;
 }
@@ -1196,7 +1206,8 @@
   if (c == NULL) {
     return status;
   }
-  *signature = c->GetDescriptor();
+  std::string temp;
+  *signature = c->GetDescriptor(&temp);
   return JDWP::ERR_NONE;
 }
 
@@ -1275,14 +1286,12 @@
     LOG(WARNING) << __FUNCTION__ << " access out of bounds: offset=" << offset << "; count=" << count;
     return JDWP::ERR_INVALID_LENGTH;
   }
-  std::string descriptor(a->GetClass()->GetDescriptor());
-  JDWP::JdwpTag tag = BasicTagFromDescriptor(descriptor.c_str() + 1);
-
-  expandBufAdd1(pReply, tag);
+  JDWP::JdwpTag element_tag = BasicTagFromClass(a->GetClass()->GetComponentType());
+  expandBufAdd1(pReply, element_tag);
   expandBufAdd4BE(pReply, count);
 
-  if (IsPrimitiveTag(tag)) {
-    size_t width = GetTagWidth(tag);
+  if (IsPrimitiveTag(element_tag)) {
+    size_t width = GetTagWidth(element_tag);
     uint8_t* dst = expandBufAddSpace(pReply, count * width);
     if (width == 8) {
       const uint64_t* src8 = reinterpret_cast<uint64_t*>(a->GetRawData(sizeof(uint64_t), 0));
@@ -1303,7 +1312,7 @@
     for (int i = 0; i < count; ++i) {
       mirror::Object* element = oa->Get(offset + i);
       JDWP::JdwpTag specific_tag = (element != nullptr) ? TagFromObject(soa, element)
-                                                        : tag;
+                                                        : element_tag;
       expandBufAdd1(pReply, specific_tag);
       expandBufAddObjectId(pReply, gRegistry->Add(element));
     }
@@ -1337,11 +1346,10 @@
     LOG(WARNING) << __FUNCTION__ << " access out of bounds: offset=" << offset << "; count=" << count;
     return JDWP::ERR_INVALID_LENGTH;
   }
-  std::string descriptor = dst->GetClass()->GetDescriptor();
-  JDWP::JdwpTag tag = BasicTagFromDescriptor(descriptor.c_str() + 1);
+  JDWP::JdwpTag element_tag = BasicTagFromClass(dst->GetClass()->GetComponentType());
 
-  if (IsPrimitiveTag(tag)) {
-    size_t width = GetTagWidth(tag);
+  if (IsPrimitiveTag(element_tag)) {
+    size_t width = GetTagWidth(element_tag);
     if (width == 8) {
       CopyArrayData<uint64_t>(dst, request, offset, count);
     } else if (width == 4) {
@@ -2729,7 +2737,8 @@
   // since the class may not yet be verified.
   int state = JDWP::CS_VERIFIED | JDWP::CS_PREPARED;
   JDWP::JdwpTypeTag tag = GetTypeTag(c);
-  gJdwpState->PostClassPrepare(tag, gRegistry->Add(c), c->GetDescriptor(), state);
+  std::string temp;
+  gJdwpState->PostClassPrepare(tag, gRegistry->Add(c), c->GetDescriptor(&temp), state);
 }
 
 void Dbg::UpdateDebugger(Thread* thread, mirror::Object* this_object,
@@ -4518,7 +4527,8 @@
     int idx = HeadIndex();
     while (count--) {
       AllocRecord* record = &recent_allocation_records_[idx];
-      class_names.Add(record->Type()->GetDescriptor());
+      std::string temp;
+      class_names.Add(record->Type()->GetDescriptor(&temp));
       for (size_t i = 0; i < kMaxAllocRecordStackDepth; i++) {
         mirror::ArtMethod* m = record->StackElement(i)->Method();
         if (m != NULL) {
@@ -4559,9 +4569,9 @@
     JDWP::Append2BE(bytes, method_names.Size());
     JDWP::Append2BE(bytes, filenames.Size());
 
-    count = alloc_record_count_;
     idx = HeadIndex();
-    while (count--) {
+    std::string temp;
+    for (count = alloc_record_count_; count != 0; --count) {
       // For each entry:
       // (4b) total allocation size
       // (2b) thread id
@@ -4570,7 +4580,7 @@
       AllocRecord* record = &recent_allocation_records_[idx];
       size_t stack_depth = record->GetDepth();
       size_t allocated_object_class_name_index =
-          class_names.IndexOf(record->Type()->GetDescriptor().c_str());
+          class_names.IndexOf(record->Type()->GetDescriptor(&temp));
       JDWP::Append4BE(bytes, record->ByteCount());
       JDWP::Append2BE(bytes, record->ThinLockId());
       JDWP::Append2BE(bytes, allocated_object_class_name_index);
@@ -4591,7 +4601,6 @@
         JDWP::Append2BE(bytes, file_name_index);
         JDWP::Append2BE(bytes, record->StackElement(stack_frame)->LineNumber());
       }
-
       idx = (idx + 1) & (alloc_record_max_ - 1);
     }