Skip to content

Commit 76f6a32

Browse files
osa1Commit Queue
authored andcommitted
[dart2wasm] StringBuffer improvements
Use `U16List` instead of `Uint16List` as the character buffer type. Access the Wasm array directly when writing characters and converting the final buffer to a String. This avoids bounds checks and uses `array.copy` when allocating the final string. Change-Id: I570494e8349adc7a268544544516c9947abc8604 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371681 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Ömer Ağacan <[email protected]>
1 parent 7078310 commit 76f6a32

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

sdk/lib/_internal/wasm/lib/string.dart

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,39 @@ OneByteString createOneByteStringFromCharacters(
5858
U8List bytes, int start, int end) =>
5959
createOneByteStringFromCharactersArray(bytes.data, start, end);
6060

61+
/// Create a [OneByteString] with the [array] contents in the range from
62+
/// [start] to [end] (exclusive).
6163
@pragma("wasm:prefer-inline")
6264
OneByteString createOneByteStringFromCharactersArray(
63-
WasmArray<WasmI8> bytes, int start, int end) {
65+
WasmArray<WasmI8> array, int start, int end) {
6466
final len = end - start;
6567
final s = OneByteString.withLength(len);
66-
s._array.copy(0, bytes, start, len);
68+
s._array.copy(0, array, start, len);
69+
return s;
70+
}
71+
72+
/// Same as [createOneByteStringFromCharactersArray], but the one-byte
73+
/// character array is an `i16 array` instead of `i8 array`.
74+
@pragma("wasm:prefer-inline")
75+
OneByteString createOneByteStringFromTwoByteCharactersArray(
76+
WasmArray<WasmI16> array, int start, int end) {
77+
final len = end - start;
78+
final s = OneByteString.withLength(len);
79+
for (int i = 0; i < len; i += 1) {
80+
final i16 = array.readUnsigned(start + i);
81+
s._array.write(i, i16);
82+
}
83+
return s;
84+
}
85+
86+
/// Create a [TwoByteString] with the [array] contents in the range from
87+
/// [start] to [end] (exclusive).
88+
@pragma("wasm:prefer-inline")
89+
TwoByteString createTwoByteStringFromCharactersArray(
90+
WasmArray<WasmI16> array, int start, int end) {
91+
final len = end - start;
92+
final s = TwoByteString.withLength(len);
93+
s._array.copy(0, array, start, len);
6794
return s;
6895
}
6996

sdk/lib/_internal/wasm/lib/string_buffer_patch.dart

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import "dart:_internal" show patch;
6-
import "dart:_string" show StringBase, TwoByteString;
6+
import "dart:_string";
7+
import "dart:_typed_data";
78
import "dart:_wasm";
89

9-
import "dart:typed_data" show Uint16List;
10-
1110
@patch
1211
class StringBuffer {
1312
static const int _BUFFER_SIZE = 64;
@@ -42,7 +41,7 @@ class StringBuffer {
4241
* used when writing short strings or individual char codes to the
4342
* buffer. The buffer is allocated on demand.
4443
*/
45-
Uint16List? _buffer;
44+
WasmArray<WasmI16>? _buffer;
4645
int _bufferPosition = 0;
4746

4847
/**
@@ -80,7 +79,7 @@ class StringBuffer {
8079
}
8180
_ensureCapacity(1);
8281
final localBuffer = _buffer!;
83-
localBuffer[_bufferPosition++] = charCode;
82+
localBuffer.write(_bufferPosition++, charCode);
8483
_bufferCodeUnitMagnitude |= charCode;
8584
} else {
8685
if (charCode > 0x10FFFF) {
@@ -89,8 +88,8 @@ class StringBuffer {
8988
_ensureCapacity(2);
9089
int bits = charCode - 0x10000;
9190
final localBuffer = _buffer!;
92-
localBuffer[_bufferPosition++] = 0xD800 | (bits >> 10);
93-
localBuffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF);
91+
localBuffer.write(_bufferPosition++, 0xD800 | (bits >> 10));
92+
localBuffer.write(_bufferPosition++, 0xDC00 | (bits & 0x3FF));
9493
_bufferCodeUnitMagnitude |= 0xFFFF;
9594
}
9695
}
@@ -140,7 +139,7 @@ class StringBuffer {
140139
void _ensureCapacity(int n) {
141140
final localBuffer = _buffer;
142141
if (localBuffer == null) {
143-
_buffer = Uint16List(_BUFFER_SIZE);
142+
_buffer = WasmArray<WasmI16>(_BUFFER_SIZE);
144143
} else if (_bufferPosition + n > localBuffer.length) {
145144
_consumeBuffer();
146145
}
@@ -212,11 +211,11 @@ class StringBuffer {
212211
/**
213212
* Create a [String] from the UFT-16 code units in buffer.
214213
*/
215-
static String _create(Uint16List buffer, int length, bool isLatin1) {
214+
static String _create(WasmArray<WasmI16> buffer, int length, bool isLatin1) {
216215
if (isLatin1) {
217-
return StringBase.createOneByteString(buffer, 0, length);
216+
return createOneByteStringFromTwoByteCharactersArray(buffer, 0, length);
218217
} else {
219-
return TwoByteString.allocateFromTwoByteList(buffer, 0, length);
218+
return createTwoByteStringFromCharactersArray(buffer, 0, length);
220219
}
221220
}
222221
}

0 commit comments

Comments
 (0)