[optimizing] Don't rely on the verifier for String.<init>.

Continue work on cutting the dependency on the verifier.

Change-Id: I0f95b1eb2e10fd8f6bf54817f1202bdf6dfdb0fe
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index fe52c44..31d6412 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -756,6 +756,35 @@
   current_block_ = nullptr;
 }
 
+void HGraphBuilder::PotentiallySimplifyFakeString(uint16_t original_dex_register,
+                                                  uint32_t dex_pc,
+                                                  HInvoke* actual_string) {
+  if (!graph_->IsDebuggable()) {
+    // Notify that we cannot compile with baseline. The dex registers aliasing
+    // with `original_dex_register` will be handled when we optimize
+    // (see HInstructionSimplifer::VisitFakeString).
+    can_use_baseline_for_string_init_ = false;
+    return;
+  }
+  const VerifiedMethod* verified_method =
+      compiler_driver_->GetVerifiedMethod(dex_file_, dex_compilation_unit_->GetDexMethodIndex());
+  if (verified_method != nullptr) {
+    UpdateLocal(original_dex_register, actual_string);
+    const SafeMap<uint32_t, std::set<uint32_t>>& string_init_map =
+        verified_method->GetStringInitPcRegMap();
+    auto map_it = string_init_map.find(dex_pc);
+    if (map_it != string_init_map.end()) {
+      std::set<uint32_t> reg_set = map_it->second;
+      for (auto set_it = reg_set.begin(); set_it != reg_set.end(); ++set_it) {
+        HInstruction* load_local = LoadLocal(original_dex_register, Primitive::kPrimNot);
+        UpdateLocal(*set_it, load_local);
+      }
+    }
+  } else {
+    can_use_baseline_for_string_init_ = false;
+  }
+}
+
 bool HGraphBuilder::BuildInvoke(const Instruction& instruction,
                                 uint32_t dex_pc,
                                 uint32_t method_idx,
@@ -997,34 +1026,23 @@
   if (clinit_check_requirement == HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit) {
     // Add the class initialization check as last input of `invoke`.
     DCHECK(clinit_check != nullptr);
+    DCHECK(!is_string_init);
     invoke->SetArgumentAt(argument_index, clinit_check);
+    argument_index++;
   }
 
-  current_block_->AddInstruction(invoke);
-  latest_result_ = invoke;
-
   // Add move-result for StringFactory method.
   if (is_string_init) {
     uint32_t orig_this_reg = is_range ? register_index : args[0];
-    UpdateLocal(orig_this_reg, invoke);
-    const VerifiedMethod* verified_method =
-        compiler_driver_->GetVerifiedMethod(dex_file_, dex_compilation_unit_->GetDexMethodIndex());
-    if (verified_method == nullptr) {
-      LOG(WARNING) << "No verified method for method calling String.<init>: "
-                   << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_);
-      return false;
-    }
-    const SafeMap<uint32_t, std::set<uint32_t>>& string_init_map =
-        verified_method->GetStringInitPcRegMap();
-    auto map_it = string_init_map.find(dex_pc);
-    if (map_it != string_init_map.end()) {
-      std::set<uint32_t> reg_set = map_it->second;
-      for (auto set_it = reg_set.begin(); set_it != reg_set.end(); ++set_it) {
-        HInstruction* load_local = LoadLocal(orig_this_reg, Primitive::kPrimNot);
-        UpdateLocal(*set_it, load_local);
-      }
-    }
+    HInstruction* fake_string = LoadLocal(orig_this_reg, Primitive::kPrimNot);
+    invoke->SetArgumentAt(argument_index, fake_string);
+    current_block_->AddInstruction(invoke);
+    PotentiallySimplifyFakeString(orig_this_reg, dex_pc, invoke);
+  } else {
+    current_block_->AddInstruction(invoke);
   }
+  latest_result_ = invoke;
+
   return true;
 }
 
@@ -2239,10 +2257,10 @@
     case Instruction::NEW_INSTANCE: {
       uint16_t type_index = instruction.VRegB_21c();
       if (compiler_driver_->IsStringTypeIndex(type_index, dex_file_)) {
-        // Turn new-instance of string into a const 0.
         int32_t register_index = instruction.VRegA();
-        HNullConstant* constant = graph_->GetNullConstant();
-        UpdateLocal(register_index, constant);
+        HFakeString* fake_string = new (arena_) HFakeString();
+        current_block_->AddInstruction(fake_string);
+        UpdateLocal(register_index, fake_string);
       } else {
         QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
             ? kQuickAllocObjectWithAccessCheck