Fix updating of JNI references for String.<init>.

Was missing updates to globals and weak globals.

Bug: 21288130
Bug: 21440428

(cherry picked from commit 1a302fb4f84525289c1cf7a437f5be1999a75251)

Change-Id: I41b64e8aae906f5986de483db096d8191e45f260
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index d321d27..f8c7081 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -464,7 +464,7 @@
   InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
   if (is_string_init) {
     // For string init, remap original receiver to StringFactory result.
-    soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+    UpdateReference(soa.Self(), obj, result.GetL());
   }
   return result;
 }
@@ -494,7 +494,7 @@
   InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
   if (is_string_init) {
     // For string init, remap original receiver to StringFactory result.
-    soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+    UpdateReference(soa.Self(), obj, result.GetL());
   }
   return result;
 }
@@ -525,7 +525,7 @@
   InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
   if (is_string_init) {
     // For string init, remap original receiver to StringFactory result.
-    soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+    UpdateReference(soa.Self(), obj, result.GetL());
   }
   return result;
 }
@@ -556,7 +556,7 @@
   InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
   if (is_string_init) {
     // For string init, remap original receiver to StringFactory result.
-    soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+    UpdateReference(soa.Self(), obj, result.GetL());
   }
   return result;
 }
@@ -882,4 +882,21 @@
                                              actual_class_name.c_str()).c_str());
 }
 
+// This only works if there's one reference which points to the object in obj.
+// Will need to be fixed if there's cases where it's not.
+void UpdateReference(Thread* self, jobject obj, mirror::Object* result) {
+  IndirectRef ref = reinterpret_cast<IndirectRef>(obj);
+  IndirectRefKind kind = GetIndirectRefKind(ref);
+  if (kind == kLocal) {
+    self->GetJniEnv()->locals.Update(obj, result);
+  } else if (kind == kHandleScopeOrInvalid) {
+    LOG(FATAL) << "Unsupported UpdateReference for kind kHandleScopeOrInvalid";
+  } else if (kind == kGlobal) {
+    self->GetJniEnv()->vm->UpdateGlobal(self, ref, result);
+  } else {
+    DCHECK_EQ(kind, kWeakGlobal);
+    self->GetJniEnv()->vm->UpdateWeakGlobal(self, ref, result);
+  }
+}
+
 }  // namespace art