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/utils.cc b/runtime/utils.cc
index 48d6cdf..b845f50 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -222,19 +222,20 @@
   if (java_descriptor == NULL) {
     return "null";
   }
-  return PrettyDescriptor(java_descriptor->ToModifiedUtf8());
+  return PrettyDescriptor(java_descriptor->ToModifiedUtf8().c_str());
 }
 
 std::string PrettyDescriptor(mirror::Class* klass) {
   if (klass == NULL) {
     return "null";
   }
-  return PrettyDescriptor(klass->GetDescriptor());
+  std::string temp;
+  return PrettyDescriptor(klass->GetDescriptor(&temp));
 }
 
-std::string PrettyDescriptor(const std::string& descriptor) {
+std::string PrettyDescriptor(const char* descriptor) {
   // Count the number of '['s to get the dimensionality.
-  const char* c = descriptor.c_str();
+  const char* c = descriptor;
   size_t dim = 0;
   while (*c == '[') {
     dim++;
@@ -275,15 +276,14 @@
     result.push_back(ch);
   }
   // ...and replace the semicolon with 'dim' "[]" pairs:
-  while (dim--) {
+  for (size_t i = 0; i < dim; ++i) {
     result += "[]";
   }
   return result;
 }
 
 std::string PrettyDescriptor(Primitive::Type type) {
-  std::string descriptor_string(Primitive::Descriptor(type));
-  return PrettyDescriptor(descriptor_string);
+  return PrettyDescriptor(Primitive::Descriptor(type));
 }
 
 std::string PrettyField(mirror::ArtField* f, bool with_type) {
@@ -341,8 +341,10 @@
     } else {
       ++argument_length;
     }
-    std::string argument_descriptor(signature, argument_length);
-    result += PrettyDescriptor(argument_descriptor);
+    {
+      std::string argument_descriptor(signature, argument_length);
+      result += PrettyDescriptor(argument_descriptor.c_str());
+    }
     if (signature[argument_length] != ')') {
       result += ", ";
     }
@@ -410,9 +412,10 @@
   if (obj->GetClass() == NULL) {
     return "(raw)";
   }
-  std::string result(PrettyDescriptor(obj->GetClass()->GetDescriptor()));
+  std::string temp;
+  std::string result(PrettyDescriptor(obj->GetClass()->GetDescriptor(&temp)));
   if (obj->IsClass()) {
-    result += "<" + PrettyDescriptor(obj->AsClass()->GetDescriptor()) + ">";
+    result += "<" + PrettyDescriptor(obj->AsClass()->GetDescriptor(&temp)) + ">";
   }
   return result;
 }
@@ -622,11 +625,20 @@
 
 std::string DescriptorToDot(const char* descriptor) {
   size_t length = strlen(descriptor);
-  if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
-    std::string result(descriptor + 1, length - 2);
-    std::replace(result.begin(), result.end(), '/', '.');
-    return result;
+  if (length > 1) {
+    if (descriptor[0] == 'L' && descriptor[length - 1] == ';') {
+      // Descriptors have the leading 'L' and trailing ';' stripped.
+      std::string result(descriptor + 1, length - 2);
+      std::replace(result.begin(), result.end(), '/', '.');
+      return result;
+    } else {
+      // For arrays the 'L' and ';' remain intact.
+      std::string result(descriptor);
+      std::replace(result.begin(), result.end(), '/', '.');
+      return result;
+    }
   }
+  // Do nothing for non-class/array descriptors.
   return descriptor;
 }