21:50
<James M Snell>

Hello all. I've got a proposal that I'd like to surface for consideration. I put this together after speaking a bit with Matteo Collina and @ljharb... The fundamental idea is to introduce a mechanism for zero-copy concatenation of ArrayBuffer in a way that allows the result to still be an ArrayBuffer that can be wrapped with a TypedArray. The explainer is here: https://github.com/jasnell/proposal-zero-copy-arraybuffer-list/blob/main/README.md

For a quick example:

const ab1 = new ArrayBuffer(10);
const ab2 = new ArrayBuffer(20);
const combined = ArrayBuffer.of(ab1, ab2);
const u8 = new Uint8Array(combined);

Here, combined is effectively a list of the component ArrayBuffer instances that is itself an ArrayBuffer.

The idea here is adapted from the very popular npm module bl which implements a similar idea around Node.js Buffer interface but in a way that still has a number of warts.

There is a more detailed example in the explainer. @littledan and ljharb have already graciously provided some extremely helpful feedback.

21:54
<bakkot>
cc shu ^ as the arraybuffer guy
21:57
<bakkot>
I know very little about engine internals, but from my own limited perspective, I can say that this seems useful but the cost of making ArrayBuffer fundamentals more complex is usually quite high, so it may not be worth it. It would mean a branch in every access of every TA, or a fair bit of optimization work to avoid that branch.
22:00
<James M Snell>
Indeed, I do not imagine and won't pretend that the implementation would be trivial. Just the fact, for instance, that v8's internal implementation of v8::ArrayBuffer is backed by a single v8::BackingStore that is expected to be a single contiguous block of memory presents a challenge. However, I think there's enough potential benefit here that it should warrant at least some consideration and if the ultimate answer is it's not worth it, then so be it :-)
22:00
<bakkot>
Also, nit, I am not totally clear on what the utility of subarray is supposed to be
22:01
<bakkot>
you can't work with ArrayBuffers directly anyway; you have to use a TA. and TAs are already potentially partial views of an underlying buffer
22:07
<James M Snell>
Suppose I have two Uint8Arrays and I want to concat those with zero-copy, taking the byteOffset and byteLength properly into account. subarray would allow for... new Uint8Array(ArrayBuffer.of(u8a.buffer.subarray(u8a.byteOffset, u8a.byteLength), u8b.buffer.subarray(u8b.byteOffset, u8a.byteLength)))
22:07
<James M Snell>
Using the existing ArrayBuffer.prototype.slice(...) here instead would copy
22:08
<bakkot>
Ah, makes sense
22:09
<bakkot>
Does mean the underlying implementation would need to get even more complicated, but I guess the additional delta isn't that large