Do not use String.setCharAt() in CaseMapper.

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 is a first step of removing this API.

We now do an extra allocation for those paths where we
previously used a modifiable String but on the other hand
we avoid repeated JNI calls when mapping longer strings.
Relevant cases from StringCaseMappingBenchmark:
  (Lower is better.)
  timeToLowerCase_US/UPPER2:     443.46 ->   376.47 (-15%)
  timeToLowerCase_US/MIXED2:     441.58 ->   358.37 (-19%)
  timeToLowerCase_US/UPPER8:    1062.30 ->   548.56 (-48%)
  timeToLowerCase_US/MIXED8:     896.00 ->   550.03 (-39%)
  timeToLowerCase_US/UPPER32:   5175.08 ->  1502.36 (-71%)
  timeToLowerCase_US/MIXED32:   2743.20 ->  1387.55 (-49%)
  timeToLowerCase_US/UPPER512: 68071.45 -> 18709.82 (-73%)
  timeToLowerCase_US/MIXED512: 46786.96 -> 18748.79 (-59%)
  timeToUpperCase_US/LOWER2:     602.21 ->   706.88 (+17%)
  timeToUpperCase_US/MIXED2:     511.35 ->   773.32 (+51%)
  timeToUpperCase_US/LOWER8:    1194.41 ->   989.79 (-20%)
  timeToUpperCase_US/MIXED8:    1113.68 ->  1033.80 (-13%)
  timeToUpperCase_US/LOWER32:   4899.31 ->  2246.14 (-54%)
  timeToUpperCase_US/MIXED32:   3469.12 ->  2455.02 (-30%)
  timeToUpperCase_US/LOWER512: 76607.06 -> 25412.57 (-67%)
  timeToUpperCase_US/MIXED512: 55735.11 -> 26115.87 (-56%)
There was a lot of noise, especially in the short string
benchmarks, for example the timeToLowerCase_US/LOWER2 which
should have been unaffected (not listed above) had +35%.
The timeToUpperCase_US/LOWER2 from this report seems to be
on the low end of the range while timeToUpperCase_US/MIXED2
hit the high end of the range. The timings for long strings
are much more consistent.

Test: testrunner.sh --host
Test: run-libcore-tests.sh --mode=host
Bug: 31040547
Change-Id: Id107428c000de1ff3db94b4824f70bf3ae5001dc
1 file changed