Remove String.setCharAt().

The internal API String.setCharAt() breaks the assumption
that strings are really immutable. That in turn breaks
string compression invariants - compressible strings must
be compressed. This CL removes the String.setCharAt() API.

The method was used only in String.replace(char, char)
when we found a match, copying the string on first match.
Instead, introduce a new native method that does the whole
replacement with a single call when we find the first match.

StringReplaceBenchmark results on Nexus 6P, lower is better:
  timeReplaceCharNonExistent/EMPTY   41.93 ->   38.25 (-9%)
  timeReplaceCharNonExistent/L_16   114.90 ->   95.09 (-17%)
  timeReplaceCharNonExistent/L_64   419.97 ->  320.65 (-24%)
  timeReplaceCharNonExistent/L_256 1667.01 -> 1091.25 (-35%)
  timeReplaceCharNonExistent/L_512 3253.50 -> 2075.62 (-36%)
  timeReplaceCharRepeated/EMPTY      41.93 ->   39.58 (-6%)
  timeReplaceCharRepeated/L_16      114.87 ->   95.40 (-17%)
  timeReplaceCharRepeated/L_64     1267.29 ->  704.32 (-44%)
  timeReplaceCharRepeated/L_256    5139.14 -> 1361.80 (-74%)
  timeReplaceCharRepeated/L_512   10787.81 -> 2338.41 (-78%)
  timeReplaceSingleChar/EMPTY        41.78 ->   37.16 (-11%)
  timeReplaceSingleChar/L_16        449.54 ->  497.51 (+11%)
  timeReplaceSingleChar/L_64        942.08 ->  891.35 (-5%)
  timeReplaceSingleChar/L_256      2756.18 -> 2174.64 (-21%)
  timeReplaceSingleChar/L_512      5489.91 -> 3983.32 (-27%)

Test: testrunner.py --host
Test: run-libcore-tests.sh --mode=host
Test: testrunner.py --host with string compression enabled.
Test: run-libcore-tests.sh --mode=host with string compression enabled.
Bug: 31040547
Change-Id: I9cf0d5457182f0a33ca8251c29931d3eb624ae07
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index af0478c..80554c2 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -1330,17 +1330,18 @@
   result->SetC(string->CharAt(index));
 }
 
-// This allows setting chars from the new style of String objects during compilation.
-void UnstartedRuntime::UnstartedStringSetCharAt(
-    Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
-  jint index = shadow_frame->GetVReg(arg_offset + 1);
-  jchar c = shadow_frame->GetVReg(arg_offset + 2);
-  mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
+// This allows creating String objects with replaced characters during compilation.
+// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
+void UnstartedRuntime::UnstartedStringDoReplace(
+    Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
+  jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
+  jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
+  ObjPtr<mirror::String> string = shadow_frame->GetVRegReference(arg_offset)->AsString();
   if (string == nullptr) {
-    AbortTransactionOrFail(self, "String.setCharAt with null object");
+    AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
     return;
   }
-  string->SetCharAt(index, c);
+  result->SetL(string->DoReplace(self, old_c, new_c));
 }
 
 // This allows creating the new style of String objects during compilation.
diff --git a/runtime/interpreter/unstarted_runtime_list.h b/runtime/interpreter/unstarted_runtime_list.h
index 6fc7989..e9435e4 100644
--- a/runtime/interpreter/unstarted_runtime_list.h
+++ b/runtime/interpreter/unstarted_runtime_list.h
@@ -63,7 +63,7 @@
   V(RuntimeAvailableProcessors, "int java.lang.Runtime.availableProcessors()") \
   V(StringGetCharsNoCheck, "void java.lang.String.getCharsNoCheck(int, int, char[], int)") \
   V(StringCharAt, "char java.lang.String.charAt(int)") \
-  V(StringSetCharAt, "void java.lang.String.setCharAt(int, char)") \
+  V(StringDoReplace, "java.lang.String java.lang.String.doReplace(char, char)") \
   V(StringFactoryNewStringFromChars, "java.lang.String java.lang.StringFactory.newStringFromChars(int, int, char[])") \
   V(StringFactoryNewStringFromString, "java.lang.String java.lang.StringFactory.newStringFromString(java.lang.String)") \
   V(StringFastSubstring, "java.lang.String java.lang.String.fastSubstring(int, int)") \