Use UTF-8 strings to avoid duplicate caching, part 1

StringBlock instances containing UTF-8 strings use a cache to convert
into UTF-16, but using that cache and then using a JNI call to NewString
causes the UTF-8 string as well as two copies of the UTF-16 string to
be held in memory. Getting the UTF-8 string directly from the StringPool
eliminates one copy of the UTF-16 string being held in memory.

This is part 1. Part 2 will include ResXMLParser optimizations.

Change-Id: Ibd4509a485db746d59cd4b9501f544877139276c
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index a82a21e..5afa0342 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1466,19 +1466,25 @@
     for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
         value = bag->map.value;
         jstring str = NULL;
-        
+
         // Take care of resolving the found resource to its final value.
         ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
         if (value.dataType == Res_value::TYPE_STRING) {
-            const char16_t* str16 = res.getTableStringBlock(block)->stringAt(value.data, &strLen);
-            str = env->NewString(str16, strLen);
-            if (str == NULL) {
-                doThrow(env, "java/lang/OutOfMemoryError");
-                res.unlockBag(startOfBag);
-                return NULL;
+            const ResStringPool* pool = res.getTableStringBlock(block);
+            const char* str8 = pool->string8At(value.data, &strLen);
+            if (str8 != NULL) {
+                str = env->NewStringUTF(str8);
+            } else {
+                const char16_t* str16 = pool->stringAt(value.data, &strLen);
+                str = env->NewString(str16, strLen);
+                if (str == NULL) {
+                    doThrow(env, "java/lang/OutOfMemoryError");
+                    res.unlockBag(startOfBag);
+                    return NULL;
+                }
             }
         }
-        
+
         env->SetObjectArrayElement(array, i, str);
     }
     res.unlockBag(startOfBag);