mirror of
https://github.com/dart-lang/sdk
synced 2024-09-06 00:59:09 +00:00
[js_runtime] Utf8 - reuse buffer to avoid creating many small buffers
Allocating typed data on Chrome is surprisingly expensive (e.g. https://bugs.chromium.org/p/v8/issues/detail?id=9199). This makes it worthwhile to keep a buffer around for reuse rather than allocating a new one for each conversion that requires copying. Change-Id: I8b2823f487cd8b869fc8b22f309490475c7c010d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/337462 Reviewed-by: Nicholas Shahan <nshahan@google.com> Commit-Queue: Stephen Adams <sra@google.com>
This commit is contained in:
parent
69666dc283
commit
3f2432f36c
|
@ -55,10 +55,8 @@ class _Utf8Decoder {
|
|||
bytes = casted;
|
||||
errorOffset = 0;
|
||||
} else {
|
||||
// TODO(sra): Use a persistent buffer to avoid allocations for shorter
|
||||
// inputs, perhaps up to several kB.
|
||||
bytes = JS<NativeUint8List>(
|
||||
'NativeUint8List', '#', _makeUint8List(codeUnits, start, end));
|
||||
'NativeUint8List', '#', _makeNativeUint8List(codeUnits, start, end));
|
||||
errorOffset = start;
|
||||
end -= start;
|
||||
start = 0;
|
||||
|
@ -113,6 +111,29 @@ class _Utf8Decoder {
|
|||
return decodeGeneral(bytes, start, end, single);
|
||||
}
|
||||
|
||||
static Uint8List _makeNativeUint8List(
|
||||
List<int> codeUnits, int start, int end) {
|
||||
final int length = end - start;
|
||||
// Re-use a dedicated buffer to avoid allocating small buffers as this is
|
||||
// unreasonably expensive on some JavaScript engines.
|
||||
final Uint8List bytes =
|
||||
length <= _reusableBufferSize ? _reusableBuffer : Uint8List(length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int b = codeUnits[start + i];
|
||||
if ((b & 0xFF) != b) {
|
||||
// Replace invalid byte values by 0xFF, which is a valid byte value that
|
||||
// is an invalid UTF8 sequence.
|
||||
b = 0xFF;
|
||||
}
|
||||
JS('', '#[#] = #', bytes, i, b); // bytes[i] = b;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static const _reusableBufferSize = 4096;
|
||||
static final Uint8List _reusableBuffer = Uint8List(_reusableBufferSize);
|
||||
|
||||
static String? _convertInterceptedUint8List(
|
||||
bool allowMalformed, NativeUint8List codeUnits, int start, int end) {
|
||||
final decoder = allowMalformed ? _decoderNonfatal : _decoder;
|
||||
|
|
Loading…
Reference in a new issue