Matcher: Avoid excessive String copies.

We avoid calls to GetStringChars on every JNI call to find or findNext.
Given that we now have a moving collector, we always copy on GetStringChars.
Moreover, on Android O, we incur the cost of these copies even if the
String in question is in a non-moveable space because the String might
be compressed. The cost of these calls can quickly add up, especially
for the case where the pattern in question occurs several times in the
string.

Relevant benchmark results are included below. This shows that for a
String size of 64kb with near worst case repetition of patterns, the new
implementation takes ~1/100th the time (8ms vs 737ms)

BEFORE:
Experiment {instrument=runtime, benchmarkMethod=timeReplaceAllTrivialPatternSingleOccurence, vm=default, parameters={s=NON_MOVEABLE}}
  runtime(ns): min=1832194.71, 1st qu.=1865190.38, median=1918799.21, mean=1951987.04, 3rd qu.=2032988.61, max=2171749.44
Experiment {instrument=runtime, benchmarkMethod=timeReplaceTrivialPatternAllRepeated, vm=default, parameters={s=MOVEABLE_256}}
  runtime(ns): min=91264.94, 1st qu.=91999.01, median=92500.85, mean=92864.29, 3rd qu.=94001.42, max=94304.77
Experiment {instrument=runtime, benchmarkMethod=timeReplaceTrivialPatternAllRepeated, vm=default, parameters={s=MOVEABLE_1024}}
  runtime(ns): min=460049.96, 1st qu.=464198.96, median=473150.38, mean=477171.31, 3rd qu.=489764.60, max=508391.29
Experiment {instrument=runtime, benchmarkMethod=timeReplaceTrivialPatternAllRepeated, vm=default, parameters={s=NON_MOVEABLE}}
  runtime(ns): min=736209191.00, 1st qu.=736360924.50, median=737412847.00, mean=737419384.78, 3rd qu.=738278240.00, max=738760545.00

AFTER:
Experiment {instrument=runtime, benchmarkMethod=timeReplaceAllTrivialPatternSingleOccurence, vm=default, parameters={s=NON_MOVEABLE}}
  runtime(ns): min=1518890.99, 1st qu.=1528913.92, median=1637897.87, mean=1626845.46, 3rd qu.=1712046.38, max=1750239.83
Experiment {instrument=runtime, benchmarkMethod=timeReplaceTrivialPatternAllRepeated, vm=default, parameters={s=MOVEABLE_256}}
  runtime(ns): min=61491.55, 1st qu.=62453.80, median=63083.26, mean=63023.21, 3rd qu.=63730.98, max=64245.10
Experiment {instrument=runtime, benchmarkMethod=timeReplaceTrivialPatternAllRepeated, vm=default, parameters={s=MOVEABLE_1024}}
  runtime(ns): min=175484.27, 1st qu.=176039.91, median=177751.78, mean=179295.87, 3rd qu.=183334.40, max=187095.50
Experiment {instrument=runtime, benchmarkMethod=timeReplaceTrivialPatternAllRepeated, vm=default, parameters={s=NON_MOVEABLE}}
  runtime(ns): min=8268762.61, 1st qu.=8396197.28, median=8662951.07, mean=8596467.31, 3rd qu.=8731159.36, max=8973943.49

bug: 36366255
bug: 36818684
Test: cts -m CtsLibcoreTestCases
Test: benchmark

Change-Id: Iff07cf2c2ebe89f04289bfa92bcd2469fec349e7
3 files changed