Replace String CharArray with internal uint16_t array.

Summary of high level changes:
  - Adds compiler inliner support to identify string init methods
  - Adds compiler support (quick & optimizing) with new invoke code path
    that calls method off the thread pointer
  - Adds thread entrypoints for all string init methods
  - Adds map to verifier to log when receiver of string init has been
    copied to other registers. used by compiler and interpreter

Change-Id: I797b992a8feb566f9ad73060011ab6f51eb7ce01
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 4765ebc..ef3c6e2 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -21,6 +21,7 @@
 #include "debugger.h"
 #include "mirror/array-inl.h"
 #include "unstarted_runtime.h"
+#include "verifier/method_verifier.h"
 
 namespace art {
 namespace interpreter {
@@ -485,16 +486,28 @@
 template<bool is_range, bool do_assignability_check>
 bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
             const Instruction* inst, uint16_t inst_data, JValue* result) {
+  bool string_init = false;
+  // Replace calls to String.<init> with equivalent StringFactory call.
+  if (called_method->GetDeclaringClass()->IsStringClass() && called_method->IsConstructor()) {
+    ScopedObjectAccessUnchecked soa(self);
+    jmethodID mid = soa.EncodeMethod(called_method);
+    called_method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
+    string_init = true;
+  }
+
   // Compute method information.
   const DexFile::CodeItem* code_item = called_method->GetCodeItem();
   const uint16_t num_ins = (is_range) ? inst->VRegA_3rc(inst_data) : inst->VRegA_35c(inst_data);
   uint16_t num_regs;
   if (LIKELY(code_item != nullptr)) {
     num_regs = code_item->registers_size_;
-    DCHECK_EQ(num_ins, code_item->ins_size_);
   } else {
     DCHECK(called_method->IsNative() || called_method->IsProxyMethod());
     num_regs = num_ins;
+    if (string_init) {
+      // The new StringFactory call is static and has one fewer argument.
+      num_regs--;
+    }
   }
 
   // Allocate shadow frame on the stack.
@@ -504,7 +517,7 @@
                                                     memory));
 
   // Initialize new shadow frame.
-  const size_t first_dest_reg = num_regs - num_ins;
+  size_t first_dest_reg = num_regs - num_ins;
   if (do_assignability_check) {
     // Slow path.
     // We might need to do class loading, which incurs a thread state change to kNative. So
@@ -536,6 +549,10 @@
       new_shadow_frame->SetVRegReference(dest_reg, shadow_frame.GetVRegReference(receiver_reg));
       ++dest_reg;
       ++arg_offset;
+    } else if (string_init) {
+      // Skip the referrer for the new static StringFactory call.
+      ++dest_reg;
+      ++arg_offset;
     }
     for (uint32_t shorty_pos = 0; dest_reg < num_regs; ++shorty_pos, ++dest_reg, ++arg_offset) {
       DCHECK_LT(shorty_pos + 1, shorty_len);
@@ -583,7 +600,12 @@
   } else {
     // Fast path: no extra checks.
     if (is_range) {
-      const uint16_t first_src_reg = inst->VRegC_3rc();
+      uint16_t first_src_reg = inst->VRegC_3rc();
+      if (string_init) {
+        // Skip the referrer for the new static StringFactory call.
+        ++first_src_reg;
+        ++first_dest_reg;
+      }
       for (size_t src_reg = first_src_reg, dest_reg = first_dest_reg; dest_reg < num_regs;
           ++dest_reg, ++src_reg) {
         AssignRegister(new_shadow_frame, shadow_frame, dest_reg, src_reg);
@@ -592,12 +614,18 @@
       DCHECK_LE(num_ins, 5U);
       uint16_t regList = inst->Fetch16(2);
       uint16_t count = num_ins;
+      size_t arg_index = 0;
+      if (string_init) {
+        // Skip the referrer for the new static StringFactory call.
+        regList >>= 4;
+        ++arg_index;
+      }
       if (count == 5) {
         AssignRegister(new_shadow_frame, shadow_frame, first_dest_reg + 4U,
                        (inst_data >> 8) & 0x0f);
         --count;
        }
-      for (size_t arg_index = 0; arg_index < count; ++arg_index, regList >>= 4) {
+      for (; arg_index < count; ++arg_index, regList >>= 4) {
         AssignRegister(new_shadow_frame, shadow_frame, first_dest_reg + arg_index, regList & 0x0f);
       }
     }
@@ -631,6 +659,38 @@
   } else {
     UnstartedRuntimeInvoke(self, code_item, new_shadow_frame, result, first_dest_reg);
   }
+
+  if (string_init && !self->IsExceptionPending()) {
+    // Set the new string result of the StringFactory.
+    uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
+    shadow_frame.SetVRegReference(vregC, result->GetL());
+    // Overwrite all potential copies of the original result of the new-instance of string with the
+    // new result of the StringFactory. Use the verifier to find this set of registers.
+    mirror::ArtMethod* method = shadow_frame.GetMethod();
+    MethodReference method_ref = method->ToMethodReference();
+    SafeMap<uint32_t, std::set<uint32_t>> string_init_map;
+    SafeMap<uint32_t, std::set<uint32_t>>* string_init_map_ptr;
+    MethodRefToStringInitRegMap& method_to_string_init_map = Runtime::Current()->GetStringInitMap();
+    auto it = method_to_string_init_map.find(method_ref);
+    if (it == method_to_string_init_map.end()) {
+      string_init_map = std::move(verifier::MethodVerifier::FindStringInitMap(method));
+      method_to_string_init_map.Overwrite(method_ref, string_init_map);
+      string_init_map_ptr = &string_init_map;
+    } else {
+      string_init_map_ptr = &it->second;
+    }
+    if (string_init_map_ptr->size() != 0) {
+      uint32_t dex_pc = shadow_frame.GetDexPC();
+      auto map_it = string_init_map_ptr->find(dex_pc);
+      if (map_it != string_init_map_ptr->end()) {
+        const std::set<uint32_t>& reg_set = map_it->second;
+        for (auto set_it = reg_set.begin(); set_it != reg_set.end(); ++set_it) {
+          shadow_frame.SetVRegReference(*set_it, result->GetL());
+        }
+      }
+    }
+  }
+
   return !self->IsExceptionPending();
 }