From 507ab50e0f33f0b4264c68179055ad8a7dc60320 Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Thu, 28 Oct 2021 13:32:58 -0700 Subject: [PATCH] perf(encoding): avoid copying the input data in `TextDecoder` (#12573) The implementation of `TextDecoder` had a bug where it was copying the input data in every case. This change removes that copy in non-`SharedArrayBuffer` cases. Since passing a shared buffer source to Rust would fail, this copy of the input data was making `TextDecoder` work in cases where the input is shared. In order to avoid a breaking change, the copy is retained in those cases. --- ext/web/08_text_encoding.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ext/web/08_text_encoding.js b/ext/web/08_text_encoding.js index 28f2848b86..d3f6d45fbc 100644 --- a/ext/web/08_text_encoding.js +++ b/ext/web/08_text_encoding.js @@ -114,7 +114,14 @@ } else { input = new Uint8Array(input); } - return core.opSync("op_encoding_decode", new Uint8Array(input), { + if (input.buffer instanceof SharedArrayBuffer) { + // We clone the data into a non-shared ArrayBuffer so we can pass it + // to Rust. + // `input` is now a Uint8Array, and calling the TypedArray constructor + // with a TypedArray argument copies the data. + input = new Uint8Array(input); + } + return core.opSync("op_encoding_decode", input, { rid: this.#rid, stream: options.stream, });