Optimize JNI:GetStringRegion() for compressed strings.

Looking at the disassembly, it seems clang++ was unable to
optimize this properly, probably due to possible aliasing,
despite inlining the String::CharAt() and seeing all the
String::IsCompressed() expressions.

Explicitly use the fact that the string is compressed to
optimize the function and similar patterns in JNI.

Test: m test-art-host-gtest
Bug: 169674485
Change-Id: I35dd2540a1e79611a65d2d84f2a557c826120409
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index 9e4cc7d..9aad198 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -1838,8 +1838,9 @@
     } else {
       CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
       if (s->IsCompressed()) {
+        const uint8_t* src = s->GetValueCompressed() + start;
         for (int i = 0; i < length; ++i) {
-          buf[i] = static_cast<jchar>(s->CharAt(start+i));
+          buf[i] = static_cast<jchar>(src[i]);
         }
       } else {
         const jchar* chars = static_cast<jchar*>(s->GetValue());
@@ -1862,8 +1863,9 @@
         return;
       }
       if (s->IsCompressed()) {
+        const uint8_t* src = s->GetValueCompressed() + start;
         for (int i = 0; i < length; ++i) {
-          buf[i] = s->CharAt(start+i);
+          buf[i] = static_cast<jchar>(src[i]);
         }
         buf[length] = '\0';
       } else {
@@ -1884,8 +1886,9 @@
       jchar* chars = new jchar[s->GetLength()];
       if (s->IsCompressed()) {
         int32_t length = s->GetLength();
+        const uint8_t* src = s->GetValueCompressed();
         for (int i = 0; i < length; ++i) {
-          chars[i] = s->CharAt(i);
+          chars[i] = static_cast<jchar>(src[i]);
         }
       } else {
         memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
@@ -1920,9 +1923,10 @@
         *is_copy = JNI_TRUE;
       }
       int32_t length = s->GetLength();
+      const uint8_t* src = s->GetValueCompressed();
       jchar* chars = new jchar[length];
       for (int i = 0; i < length; ++i) {
-        chars[i] = s->CharAt(i);
+        chars[i] = static_cast<jchar>(src[i]);
       }
       return chars;
     } else {
@@ -1978,8 +1982,9 @@
     char* bytes = new char[byte_count + 1];
     CHECK(bytes != nullptr);  // bionic aborts anyway.
     if (s->IsCompressed()) {
+      const uint8_t* src = s->GetValueCompressed();
       for (size_t i = 0; i < byte_count; ++i) {
-        bytes[i] = s->CharAt(i);
+        bytes[i] = src[i];
       }
     } else {
       const uint16_t* chars = s->GetValue();