[dart2wasm] More JSON decoding improvements

- Use unchecked reads when reading from `U8List` chunks.

- Use unchecked reads when reading from "transition table" in UTF16 decoder.

- Fix a typo in a comment.

Tested: performance refactoring, covered by existing tests.
Change-Id: I1b90781f2b419188d6a560994159b48faad16075
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371301
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Ömer Sinan Ağacan 2024-06-13 18:49:18 +00:00 committed by Commit Queue
parent 9974252ac6
commit 1ec4677870
2 changed files with 12 additions and 11 deletions

View file

@ -531,7 +531,7 @@ mixin _ChunkedJsonParser<T> on _JsonParserWithListener {
* Get character/code unit of current chunk.
*
* The [index] must be non-negative and less than `chunkEnd`.
* In practive, [index] will be no smaller than the `start` argument passed
* In practice, [index] will be no smaller than the `start` argument passed
* to [parse].
*/
int getChar(int index);

View file

@ -519,7 +519,7 @@ mixin _ChunkedJsonParser<T> on _JsonParserWithListener {
* Get character/code unit of current chunk.
*
* The [index] must be non-negative and less than `chunkEnd`.
* In practive, [index] will be no smaller than the `start` argument passed
* In practice, [index] will be no smaller than the `start` argument passed
* to [parse].
*/
int getChar(int index);
@ -2072,7 +2072,10 @@ class _Utf8Decoder {
String decode16(Uint8List bytes, int start, int end, int size) {
assert(start < end);
final String transitionTable = _Utf8Decoder.transitionTable;
final OneByteString transitionTable =
unsafeCast<OneByteString>(_Utf8Decoder.transitionTable);
final OneByteString typeTable =
unsafeCast<OneByteString>(_Utf8Decoder.typeTable);
TwoByteString result = TwoByteString.withLength(size);
int i = start;
int j = 0;
@ -2083,21 +2086,19 @@ class _Utf8Decoder {
assert(!isErrorState(state));
final int byte = bytes[i++];
final int type =
_Utf8Decoder.typeTable.oneByteStringCodeUnitAtUnchecked(byte) &
typeMask;
oneByteStringCodeUnitAtUnchecked(typeTable, byte) & typeMask;
if (state == accept) {
char = byte & (shiftedByteMask >> type);
state = transitionTable.codeUnitAt(type);
state = oneByteStringCodeUnitAtUnchecked(transitionTable, type);
} else {
char = (byte & 0x3F) | (_charOrIndex << 6);
state = transitionTable.codeUnitAt(state + type);
state = oneByteStringCodeUnitAtUnchecked(transitionTable, state + type);
}
while (i < end) {
final int byte = bytes[i++];
final int type =
_Utf8Decoder.typeTable.oneByteStringCodeUnitAtUnchecked(byte) &
typeMask;
oneByteStringCodeUnitAtUnchecked(typeTable, byte) & typeMask;
if (state == accept) {
if (char >= 0x10000) {
assert(char < 0x110000);
@ -2107,14 +2108,14 @@ class _Utf8Decoder {
writeIntoTwoByteString(result, j++, char);
}
char = byte & (shiftedByteMask >> type);
state = transitionTable.codeUnitAt(type);
state = oneByteStringCodeUnitAtUnchecked(transitionTable, type);
} else if (isErrorState(state)) {
_state = state;
_charOrIndex = i - 2;
return "";
} else {
char = (byte & 0x3F) | (char << 6);
state = transitionTable.codeUnitAt(state + type);
state = oneByteStringCodeUnitAtUnchecked(transitionTable, state + type);
}
}