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/utf-inl.h b/runtime/utf-inl.h
index d8c258b..1373d17 100644
--- a/runtime/utf-inl.h
+++ b/runtime/utf-inl.h
@@ -40,20 +40,60 @@
 
 inline int CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(const char* utf8_1,
                                                                    const char* utf8_2) {
-  for (;;) {
-    if (*utf8_1 == '\0') {
-      return (*utf8_2 == '\0') ? 0 : -1;
-    } else if (*utf8_2 == '\0') {
+  uint16_t c1, c2;
+  do {
+    c1 = *utf8_1;
+    c2 = *utf8_2;
+    // Did we reach a terminating character?
+    if (c1 == 0) {
+      return (c2 == 0) ? 0 : -1;
+    } else if (c2 == 0) {
       return 1;
     }
-
-    int c1 = GetUtf16FromUtf8(&utf8_1);
-    int c2 = GetUtf16FromUtf8(&utf8_2);
-
-    if (c1 != c2) {
-      return c1 > c2 ? 1 : -1;
+    // Assume 1-byte value and handle all cases first.
+    utf8_1++;
+    utf8_2++;
+    if ((c1 & 0x80) == 0) {
+      if (c1 == c2) {
+        // Matching 1-byte values.
+        continue;
+      } else {
+        // Non-matching values.
+        if ((c2 & 0x80) == 0) {
+          // 1-byte value, do nothing.
+        } else if ((c2 & 0x20) == 0) {
+          // 2-byte value.
+          c2 = ((c2 & 0x1f) << 6) | (*utf8_2 & 0x3f);
+        } else {
+          // 3-byte value.
+          c2 = ((c2 & 0x0f) << 12) | ((utf8_2[0] & 0x3f) << 6) | (utf8_2[1] & 0x3f);
+        }
+        return static_cast<int>(c1) - static_cast<int>(c2);
+      }
     }
-  }
+    // Non-matching or multi-byte values.
+    if ((c1 & 0x20) == 0) {
+      // 2-byte value.
+      c1 = ((c1 & 0x1f) << 6) | (*utf8_1 & 0x3f);
+      utf8_1++;
+    } else {
+      // 3-byte value.
+      c1 = ((c1 & 0x0f) << 12) | ((utf8_1[0] & 0x3f) << 6) | (utf8_1[1] & 0x3f);
+      utf8_1 += 2;
+    }
+    if ((c2 & 0x80) == 0) {
+      // 1-byte value, do nothing.
+    } else if ((c2 & 0x20) == 0) {
+      // 2-byte value.
+      c2 = ((c2 & 0x1f) << 6) | (*utf8_2 & 0x3f);
+      utf8_2++;
+    } else {
+      // 3-byte value.
+      c2 = ((c2 & 0x0f) << 12) | ((utf8_2[0] & 0x3f) << 6) | (utf8_2[1] & 0x3f);
+      utf8_2 += 2;
+    }
+  } while (c1 == c2);
+  return static_cast<int>(c1) - static_cast<int>(c2);
 }
 
 }  // namespace art