Revert "Revert "Move rewritten StringFactory call results into dex registers for deopt""

Potential gc points can make the result value stale. We now set the result value
to null proactively once it's moved to shadow frame registers. IsStringInit()
is written in a way that does string comparison instead of requiring method
resolution so that it doesn't have a gc point. Also we don't cache the callee
method during frame unwinding since the method may be rewritten already.

Bug: 28555675

Change-Id: Ic51511a4a0fc84a852d8d907f91e7835f49ac478
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 12d70c5..53d5e43 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -540,6 +540,30 @@
                  result, method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty());
 }
 
+void SetStringInitValueToAllAliases(ShadowFrame* shadow_frame,
+                                    uint16_t this_obj_vreg,
+                                    JValue result)
+    SHARED_REQUIRES(Locks::mutator_lock_) {
+  Object* existing = shadow_frame->GetVRegReference(this_obj_vreg);
+  if (existing == nullptr) {
+    // If it's null, we come from compiled code that was deoptimized. Nothing to do,
+    // as the compiler verified there was no alias.
+    // Set the new string result of the StringFactory.
+    shadow_frame->SetVRegReference(this_obj_vreg, result.GetL());
+    return;
+  }
+  // Set the string init result into all aliases.
+  for (uint32_t i = 0, e = shadow_frame->NumberOfVRegs(); i < e; ++i) {
+    if (shadow_frame->GetVRegReference(i) == existing) {
+      DCHECK_EQ(shadow_frame->GetVRegReference(i),
+                reinterpret_cast<mirror::Object*>(shadow_frame->GetVReg(i)));
+      shadow_frame->SetVRegReference(i, result.GetL());
+      DCHECK_EQ(shadow_frame->GetVRegReference(i),
+                reinterpret_cast<mirror::Object*>(shadow_frame->GetVReg(i)));
+    }
+  }
+}
+
 template <bool is_range,
           bool do_assignability_check,
           size_t kVarArgMax>
@@ -739,24 +763,7 @@
   }
 
   if (string_init && !self->IsExceptionPending()) {
-    mirror::Object* existing = shadow_frame.GetVRegReference(string_init_vreg_this);
-    if (existing == nullptr) {
-      // If it's null, we come from compiled code that was deoptimized. Nothing to do,
-      // as the compiler verified there was no alias.
-      // Set the new string result of the StringFactory.
-      shadow_frame.SetVRegReference(string_init_vreg_this, result->GetL());
-    } else {
-      // Replace the fake string that was allocated with the StringFactory result.
-      for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
-        if (shadow_frame.GetVRegReference(i) == existing) {
-          DCHECK_EQ(shadow_frame.GetVRegReference(i),
-                    reinterpret_cast<mirror::Object*>(shadow_frame.GetVReg(i)));
-          shadow_frame.SetVRegReference(i, result->GetL());
-          DCHECK_EQ(shadow_frame.GetVRegReference(i),
-                    reinterpret_cast<mirror::Object*>(shadow_frame.GetVReg(i)));
-        }
-      }
-    }
+    SetStringInitValueToAllAliases(&shadow_frame, string_init_vreg_this, *result);
   }
 
   return !self->IsExceptionPending();