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/mirror/string-inl.h b/runtime/mirror/string-inl.h
index c2407d7..57b20a1 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -36,7 +36,7 @@
namespace mirror {
inline uint32_t String::ClassSize(PointerSize pointer_size) {
- uint32_t vtable_entries = Object::kVTableLength + 57;
+ uint32_t vtable_entries = Object::kVTableLength + 56;
return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 1, 2, pointer_size);
}
@@ -311,9 +311,7 @@
inline bool String::AllASCII(const MemoryType* chars, const int length) {
static_assert(std::is_unsigned<MemoryType>::value, "Expecting unsigned MemoryType");
for (int i = 0; i < length; ++i) {
- // Valid ASCII characters are in range 1..0x7f. Zero is not considered ASCII
- // because it would complicate the detection of ASCII strings in Modified-UTF8.
- if ((chars[i] - 1u) >= 0x7fu) {
+ if (!IsASCII(chars[i])) {
return false;
}
}