[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 <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
diff --git a/sdk/lib/_internal/wasm/lib/string.dart b/sdk/lib/_internal/wasm/lib/string.dart
index f83307c..ec6b650 100644
--- a/sdk/lib/_internal/wasm/lib/string.dart
+++ b/sdk/lib/_internal/wasm/lib/string.dart
@@ -58,12 +58,39 @@
U8List bytes, int start, int end) =>
createOneByteStringFromCharactersArray(bytes.data, start, end);
+/// Create a [OneByteString] with the [array] contents in the range from
+/// [start] to [end] (exclusive).
@pragma("wasm:prefer-inline")
OneByteString createOneByteStringFromCharactersArray(
- WasmArray<WasmI8> bytes, int start, int end) {
+ WasmArray<WasmI8> array, int start, int end) {
final len = end - start;
final s = OneByteString.withLength(len);
- s._array.copy(0, bytes, start, len);
+ s._array.copy(0, array, start, len);
+ return s;
+}
+
+/// Same as [createOneByteStringFromCharactersArray], but the one-byte
+/// character array is an `i16 array` instead of `i8 array`.
+@pragma("wasm:prefer-inline")
+OneByteString createOneByteStringFromTwoByteCharactersArray(
+ WasmArray<WasmI16> array, int start, int end) {
+ final len = end - start;
+ final s = OneByteString.withLength(len);
+ for (int i = 0; i < len; i += 1) {
+ final i16 = array.readUnsigned(start + i);
+ s._array.write(i, i16);
+ }
+ return s;
+}
+
+/// Create a [TwoByteString] with the [array] contents in the range from
+/// [start] to [end] (exclusive).
+@pragma("wasm:prefer-inline")
+TwoByteString createTwoByteStringFromCharactersArray(
+ WasmArray<WasmI16> array, int start, int end) {
+ final len = end - start;
+ final s = TwoByteString.withLength(len);
+ s._array.copy(0, array, start, len);
return s;
}
diff --git a/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart b/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart
index d5d74d8..96c8779 100644
--- a/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart
@@ -3,11 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
import "dart:_internal" show patch;
-import "dart:_string" show StringBase, TwoByteString;
+import "dart:_string";
+import "dart:_typed_data";
import "dart:_wasm";
-import "dart:typed_data" show Uint16List;
-
@patch
class StringBuffer {
static const int _BUFFER_SIZE = 64;
@@ -42,7 +41,7 @@
* used when writing short strings or individual char codes to the
* buffer. The buffer is allocated on demand.
*/
- Uint16List? _buffer;
+ WasmArray<WasmI16>? _buffer;
int _bufferPosition = 0;
/**
@@ -80,7 +79,7 @@
}
_ensureCapacity(1);
final localBuffer = _buffer!;
- localBuffer[_bufferPosition++] = charCode;
+ localBuffer.write(_bufferPosition++, charCode);
_bufferCodeUnitMagnitude |= charCode;
} else {
if (charCode > 0x10FFFF) {
@@ -89,8 +88,8 @@
_ensureCapacity(2);
int bits = charCode - 0x10000;
final localBuffer = _buffer!;
- localBuffer[_bufferPosition++] = 0xD800 | (bits >> 10);
- localBuffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF);
+ localBuffer.write(_bufferPosition++, 0xD800 | (bits >> 10));
+ localBuffer.write(_bufferPosition++, 0xDC00 | (bits & 0x3FF));
_bufferCodeUnitMagnitude |= 0xFFFF;
}
}
@@ -140,7 +139,7 @@
void _ensureCapacity(int n) {
final localBuffer = _buffer;
if (localBuffer == null) {
- _buffer = Uint16List(_BUFFER_SIZE);
+ _buffer = WasmArray<WasmI16>(_BUFFER_SIZE);
} else if (_bufferPosition + n > localBuffer.length) {
_consumeBuffer();
}
@@ -212,11 +211,11 @@
/**
* Create a [String] from the UFT-16 code units in buffer.
*/
- static String _create(Uint16List buffer, int length, bool isLatin1) {
+ static String _create(WasmArray<WasmI16> buffer, int length, bool isLatin1) {
if (isLatin1) {
- return StringBase.createOneByteString(buffer, 0, length);
+ return createOneByteStringFromTwoByteCharactersArray(buffer, 0, length);
} else {
- return TwoByteString.allocateFromTwoByteList(buffer, 0, length);
+ return createTwoByteStringFromCharactersArray(buffer, 0, length);
}
}
}