I looked into this a lot last year. It would make sense to have either all on-heap or all off-heap backing stores for array buffers. This would simplify generated code a lot as well (currently we do this trick where we have to add two pointers together to get the pointer to the backing store).
The other big advantage of on-heap array (apart from inline allocation in CSA) is that they don't need to use the ArrayBufferTracker to finalize the backing store. When the backing store is off-heap, we need to explicitly delete it, rather than it being implicitly collected like regular GC'd objects. For every off-heap buffer, we add time to the GC proportional to the buffers that die, rather than the ones that live, which is bad™ for GC.
There are three reasons we can't use all on-heap buffers (or increase the threshold much).
1. People expect detaching array-buffers to be 0-copy. The spec doesn't require it, but that's how people expect it to work on the web today: when you postMessage an ArrayBuffer, the underlying buffer should just be transferred and not copied. With on-heap backing stores, we always have to copy (for security, but also because the isolate that the Heap came from could go away). For larger arrays, the time to copy will be noticeable.
2. Embedders (Chrome) can provide an externally allocated backing store when constructing an ArrayBuffer through the API. Unless we remove this API then we can't get rid of off-heap backing stores. This doesn't prevent us from increasing the limit, though.
3. Embedders can get access to created ArrayBuffers (created by the embedder or via JS) and get a pointer to their backing store. The current contract of the API is that when we give out these backing store pointers, the backing stores can't move (it might, due to GC if it is on-heap). The way we enforce this is that we have mostly off-heap backing stores, and when giving out pointers to on-heap backing stores, we first 'externalize' the ArrayBuffer, reallocating the backing store externally and copying the data (this gets more expensive for bigger backing stores).
For the non-moving and 0-copy detaching constraints, you'd think it might be possible to say 'OK, let's keep external buffers (regardless of size) for these use cases and allocate everything else on-heap'. The problem there is that we don't know upfront which buffers will be detached or externalized in the future :(.
My opinion re. an on/off flag vs. a size limit flag - other embedders might use it differently so I think it's safer to leave it as-is.
Cheers,
Peter
P.S Here's a handy table of the constraints vs. different options.
