mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
Buffer.from of strings, arrays and Uint8Arrays, Buffer.allocUnsafe and Buffer.concat now return views into a per-thread pool slab of Buffer.poolSize bytes (64 KiB by default) when the size is below Buffer.poolSize >>> 1, following Node's allocate, fromStringFast and fromArrayLike: 8-byte aligned offsets, a new slab when a request does not fit, and the four-bytes-per-unit reservation for strings. Buffer.poolSize can be read and set, and Buffer.allocUnsafeSlow returns an unpooled Buffer. A slab lives while any of its views does. Its ArrayBuffer cannot be transferred, and structuredClone of a typed array view copies the whole ArrayBuffer and keeps the view's offset. Buffer.alloc, allocUnsafe and allocUnsafeSlow validate sizes with Node's ERR_OUT_OF_RANGE error. The first pooled allocation finds the startup slab, which has the default 64 KiB size. A request it cannot hold gets a slab of the current Buffer.poolSize, as in Node, and the room is checked after every new slab, so a Buffer.poolSize raised before the first pooled allocation cannot place a reservation past the end of a 64 KiB slab. A reservation larger than a fresh slab traps instead of writing past it. Corpus 5531 (typed) and 5532 (untyped) raise Buffer.poolSize before the first pooled allocation and allocate just under the new threshold through each pooled path, each case in a fresh child process, and also shrink Buffer.poolSize and change it between allocations. The node-types fenced fixture no longer lists Buffer.poolSize, which now compiles.
17 lines
983 B
TypeScript
17 lines
983 B
TypeScript
// Small Buffers from Buffer.from, Buffer.concat and Buffer.allocUnsafe are
|
|
// views into a shared pool slab. Reading a Buffer's window of its
|
|
// ArrayBuffer through byteOffset and length gives its own bytes, and
|
|
// Buffer.alloc is never pooled.
|
|
const small = Buffer.from("hello");
|
|
const copy = small.buffer.slice(small.byteOffset, small.byteOffset + small.length);
|
|
console.log(copy.byteLength, new TextDecoder().decode(new Uint8Array(copy)));
|
|
const view = new Uint8Array(small.buffer, small.byteOffset, small.length);
|
|
console.log(Array.from(view).join(","));
|
|
const joined = Buffer.concat([Buffer.from("ab"), Buffer.from("cd")]);
|
|
const data = new DataView(joined.buffer, joined.byteOffset, joined.length);
|
|
console.log(data.getUint16(0), data.byteLength);
|
|
const unsafe = Buffer.allocUnsafe(4).fill(7);
|
|
console.log(Array.from(new Uint8Array(unsafe.buffer, unsafe.byteOffset, 4)).join(","));
|
|
const zeroed = Buffer.alloc(16, 1);
|
|
console.log(zeroed.buffer.byteLength, zeroed.byteOffset);
|