Skip to content

Commit 5e8bd02

Browse files
mkustermannCommit Queue
authored and
Commit Queue
committed
[dart2wasm] Make json parser use cache of boxed integers <=255
Many json files may have small integer numbers in them. Both dart2js and VM don't need to actually box those small numbers as they have small tagged integer support. Though dart2wasm boxes all integers when they flow into top types. => We can use a cache of boxed integer numbers <= 255. It does seem to overall improve json decoding benchmarks and will reduce memory usage / pressure on the GC. Change-Id: I026831e0f0841ae84a66652c0cc0e4689a4ab75e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/410000 Commit-Queue: Martin Kustermann <[email protected]> Reviewed-by: Ömer Ağacan <[email protected]>
1 parent 6273c19 commit 5e8bd02

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

pkg/dart2wasm/lib/translator.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ class Translator with KernelNodes {
301301
w.NumType.f64: boxedDoubleClass,
302302
};
303303

304+
late final Set<Class> boxClasses = {
305+
boxedBoolClass,
306+
boxedIntClass,
307+
boxedDoubleClass,
308+
};
309+
304310
/// Classes whose identity hash code is their hash code rather than the
305311
/// identity hash code field in the struct. Each implementation class maps to
306312
/// the class containing the implementation of its `hashCode` getter.
@@ -689,7 +695,7 @@ class Translator with KernelNodes {
689695
bool isWasmType(Class cls) =>
690696
cls == wasmTypesBaseClass || _hasSuperclass(cls, wasmTypesBaseClass);
691697

692-
w.StorageType translateStorageType(DartType type) {
698+
w.StorageType translateStorageType(DartType type, {bool unbox = true}) {
693699
bool nullable = type.isPotentiallyNullable;
694700
if (type is InterfaceType) {
695701
Class cls = type.classNode;
@@ -741,7 +747,8 @@ class Translator with KernelNodes {
741747
}
742748

743749
// Other built-in type?
744-
w.StorageType? builtin = builtinTypes[cls];
750+
w.StorageType? builtin =
751+
(unbox || !boxClasses.contains(cls)) ? builtinTypes[cls] : null;
745752
if (builtin != null) {
746753
if (!nullable) {
747754
return builtin;
@@ -816,8 +823,10 @@ class Translator with KernelNodes {
816823
while (type is TypeParameterType) {
817824
type = type.bound;
818825
}
819-
return wasmArrayType(
820-
translateStorageType(type), type.toText(defaultAstTextStrategy),
826+
// If we write `WasmArray<BoxedInt>` we actually want an array of boxed
827+
// integers and not a `WasmArray<WasmI64>`.
828+
return wasmArrayType(translateStorageType(type, unbox: false),
829+
type.toText(defaultAstTextStrategy),
821830
mutable: mutable);
822831
}
823832

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

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import "dart:_boxed_int";
56
import "dart:_compact_hash" show createMapFromStringKeyValueListUnsafe;
67
import "dart:_error_utils";
78
import "dart:_internal"
@@ -176,6 +177,15 @@ class _JsonListener {
176177
this.value = value;
177178
}
178179

180+
@pragma('wasm:prefer-inline')
181+
void handleIntegerNumber(int value) {
182+
if (value.toWasmI64().leU(0xff.toWasmI64())) {
183+
handleNumber(_intBoxes256[value]);
184+
return;
185+
}
186+
handleNumber(value);
187+
}
188+
179189
void handleNumber(num value) {
180190
this.value = value;
181191
}
@@ -1433,7 +1443,7 @@ mixin _ChunkedJsonParser<T> on _ChunkedJsonParserState {
14331443

14341444
void finishChunkNumber(int state, int start, int end) {
14351445
if (state == NUM_ZERO) {
1436-
listener.handleNumber(0);
1446+
listener.handleIntegerNumber(0);
14371447
numberBuffer.clear();
14381448
return;
14391449
}
@@ -1578,7 +1588,7 @@ mixin _ChunkedJsonParser<T> on _ChunkedJsonParserState {
15781588
if (!isDouble) {
15791589
int bitFlag = -(sign + 1) >> 1; // 0 if sign == -1, -1 if sign == 1
15801590
// Negate if bitFlag is -1 by doing ~intValue + 1
1581-
listener.handleNumber((intValue ^ bitFlag) - bitFlag);
1591+
listener.handleIntegerNumber((intValue ^ bitFlag) - bitFlag);
15821592
return position;
15831593
}
15841594
// Double values at or above this value (2 ** 53) may have lost precision.
@@ -2795,3 +2805,38 @@ double _jsParseFloat(String string) => JS<double>(
27952805
'(s) => parseFloat(s)',
27962806
jsStringFromDartString(string).toExternRef,
27972807
);
2808+
2809+
const ImmutableWasmArray<BoxedInt> _intBoxes256 = ImmutableWasmArray.literal([
2810+
0, 1, 2, 3, 4, 5, 6, 7, //
2811+
8, 9, 10, 11, 12, 13, 14, 15, //
2812+
16, 17, 18, 19, 20, 21, 22, 23, //
2813+
24, 25, 26, 27, 28, 29, 30, 31, //
2814+
32, 33, 34, 35, 36, 37, 38, 39, //
2815+
40, 41, 42, 43, 44, 45, 46, 47, //
2816+
48, 49, 50, 51, 52, 53, 54, 55, //
2817+
56, 57, 58, 59, 60, 61, 62, 63, //
2818+
64, 65, 66, 67, 68, 69, 70, 71, //
2819+
72, 73, 74, 75, 76, 77, 78, 79, //
2820+
80, 81, 82, 83, 84, 85, 86, 87, //
2821+
88, 89, 90, 91, 92, 93, 94, 95, //
2822+
96, 97, 98, 99, 100, 101, 102, 103, //
2823+
104, 105, 106, 107, 108, 109, 110, 111, //
2824+
112, 113, 114, 115, 116, 117, 118, 119, //
2825+
120, 121, 122, 123, 124, 125, 126, 127, //
2826+
128, 129, 130, 131, 132, 133, 134, 135, //
2827+
136, 137, 138, 139, 140, 141, 142, 143, //
2828+
144, 145, 146, 147, 148, 149, 150, 151, //
2829+
152, 153, 154, 155, 156, 157, 158, 159, //
2830+
160, 161, 162, 163, 164, 165, 166, 167, //
2831+
168, 169, 170, 171, 172, 173, 174, 175, //
2832+
176, 177, 178, 179, 180, 181, 182, 183, //
2833+
184, 185, 186, 187, 188, 189, 190, 191, //
2834+
192, 193, 194, 195, 196, 197, 198, 199, //
2835+
200, 201, 202, 203, 204, 205, 206, 207, //
2836+
208, 209, 210, 211, 212, 213, 214, 215, //
2837+
216, 217, 218, 219, 220, 221, 222, 223, //
2838+
224, 225, 226, 227, 228, 229, 230, 231, //
2839+
232, 233, 234, 235, 236, 237, 238, 239, //
2840+
240, 241, 242, 243, 244, 245, 246, 247, //
2841+
248, 249, 250, 251, 252, 253, 254, 255, //
2842+
]);

0 commit comments

Comments
 (0)