[JSC] Add DFG / FTL intrinsic for `%TypedArray%.prototype.set`
Component: JSC JIT | a1e5cdc
%TypedArray%.prototype.set normally runs as a C++ host function that validates the receiver, coerces the offset, checks the source fits, handles overlapping or differently-typed sources, and copies. DFG and FTL can replace such builtins with intrinsics that speculate on the common case and OSR-exit when a guess fails — correctness then depends on clobberize (reads/writes), doesGC, and which runtime conditions generated code re-checks. Typed array length is mutable state: buffers can be detached via transfer or resized.
The patch adds a TypedArraySet node that speculates same typed-array type, neither array resizable or detached, and the copy fitting the target, then calls a memmove-only operation; a failed speculation OSR-exits and disables the intrinsic at that site. It touches the bytecode parser, abstract interpreter, clobberize, doesGC, fixup, safeToExecute, SpeculativeJIT and FTL lowering.
call site ─► TypedArraySet node
├─ check same TypedArrayType
├─ check !resizable, !detached
├─ check offset+len <= target len
├─ ok ─► operation: memmove only
└─ fail ─► OSR exit (intrinsic disabled at site)
Significance
Small copies were dominated by host-call and argument-validation overhead; typed-array-set-small improves 3.3x and typed-array-set-concat 4.1x. Bounds, detach and resize checks for a raw memmove into typed array storage now live in compiler-generated code.
Audit directions
- Bounds arithmetic. Review offset coercion, offset+length overflow and operand fixup in
compileTypedArraySetand the FTL lowering. - Checks after arbitrary JS. Confirm detach/resize checks follow every point that can run JS (offset
valueOf, other side effects) and that length and base pointer are re-read rather than taken from stale state, including resizes from inside offset coercion while compiled code runs. - Effect modeling. Check that
clobberizeanddoesGCdeclare reads of length and vector and writes to the array's heap precisely enough that CSE and LICM cannot reorder the node across a detach or resize. - Type and alias edges. Check Uint8 vs Uint8Clamped distinction, shared-ArrayBuffer aliasing (memmove must handle overlap), DFG/FTL gaps (
safeToExecute, abstract interpreter filtering,FTLCapabilities), and OSR-exit recovery after operand conversion. Existing-exit/-largestress tests cover SharedArrayBuffer, growable buffers, subclasses and.callwith non-typed-array receivers; cross-type sources after tier-up remain the likelier gap.