Skip to content

Commit c554548

Browse files
mkustermannCommit Queue
authored andcommitted
[dart2wasm] Make json decoder construct [OneByteStrings] if possible
If the input to `utf8.decode()` has only a single non-ascii character we currently make all strings [TwoByteString]s. Not only is this very memory intensive, it's also going to make comparisons later on slower (e.g. a json['foo'] will use [OneByteString] for `foo` but the actual map will have a [TwoByteString] as `foo`). In general it would be better to have an invariant that strings that can be [OneByteString]s should be [OneByteString]s. Change-Id: I740b3eeb0f3660f2bf8fdd094e12f78f318f9a5f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/409320 Reviewed-by: Ömer Ağacan <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
1 parent 66fa0e2 commit c554548

File tree

1 file changed

+40
-6
lines changed

1 file changed

+40
-6
lines changed

sdk/lib/_internal/wasm/lib/convert_patch.dart

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,11 @@ mixin _ChunkedJsonParser<T> on _ChunkedJsonParserState {
669669
*/
670670
void addSliceToString(int start, int end);
671671

672+
/**
673+
* Adds a string slice to the string being built.
674+
*/
675+
void addStringSliceToString(String string);
676+
672677
/** Finalizes the string being built and returns it as a String. */
673678
String endString();
674679

@@ -1181,7 +1186,9 @@ mixin _ChunkedJsonParser<T> on _ChunkedJsonParserState {
11811186
if (char == BACKSLASH) {
11821187
int sliceEnd = position - 1;
11831188
beginString();
1184-
if (start < sliceEnd) addSliceToString(start, sliceEnd);
1189+
if (start < sliceEnd) {
1190+
addStringSliceToString(getString(start, sliceEnd, bits));
1191+
}
11851192
return parseStringToBuffer(sliceEnd);
11861193
}
11871194
if (char < SPACE) {
@@ -1589,7 +1596,11 @@ class _JsonOneByteStringParser extends _ChunkedJsonParserState
15891596
}
15901597

15911598
void addSliceToString(int start, int end) {
1592-
stringBuffer.write(chunk.substringUnchecked(start, end));
1599+
addStringSliceToString(chunk.substringUnchecked(start, end));
1600+
}
1601+
1602+
void addStringSliceToString(String string) {
1603+
stringBuffer.write(string);
15931604
}
15941605

15951606
void addCharToString(int charCode) {
@@ -1635,15 +1646,34 @@ class _JsonTwoByteStringParser extends _ChunkedJsonParserState
16351646

16361647
int getChar(int position) => chunk.codeUnitAtUnchecked(position);
16371648

1638-
String getString(int start, int end, int bits) =>
1639-
chunk.substringUnchecked(start, end);
1649+
String getString(int start, int end, int bits) {
1650+
int length = end - start;
1651+
if (length == 0) return '';
1652+
1653+
final WasmArray<WasmI16> sourceArray = chunk.array;
1654+
const int asciiBits = 0x7f;
1655+
if (bits <= asciiBits) {
1656+
final result = OneByteString.withLength(length);
1657+
for (int i = 0; i < length; ++i) {
1658+
result.array.write(i, sourceArray.readUnsigned(start++));
1659+
}
1660+
return result;
1661+
}
1662+
final result = TwoByteString.withLength(length);
1663+
result.array.copy(0, sourceArray, start, length);
1664+
return result;
1665+
}
16401666

16411667
void beginString() {
16421668
assert(stringBuffer.isEmpty);
16431669
}
16441670

16451671
void addSliceToString(int start, int end) {
1646-
stringBuffer.write(chunk.substringUnchecked(start, end));
1672+
addStringSliceToString(chunk.substringUnchecked(start, end));
1673+
}
1674+
1675+
void addStringSliceToString(String string) {
1676+
stringBuffer.write(string);
16471677
}
16481678

16491679
void addCharToString(int charCode) {
@@ -1835,7 +1865,11 @@ class _JsonUtf8Parser extends _ChunkedJsonParserState
18351865
}
18361866

18371867
void addSliceToString(int start, int end) {
1838-
stringBuffer.write(decoder.convertChunked(chunk, start, end));
1868+
addStringSliceToString(decoder.convertChunked(chunk, start, end));
1869+
}
1870+
1871+
void addStringSliceToString(String string) {
1872+
stringBuffer.write(string);
18391873
}
18401874

18411875
void addCharToString(int charCode) {

0 commit comments

Comments
 (0)