[JSC] Add Array#concat DFG nodes
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
JSC's DFG (Data Flow Graph) JIT is a speculative mid-tier compiler that lowers bytecode to an IR of typed nodes, applies type-prediction-driven optimizations in phases, and emits speculative machine code that can OSR-exit when assumptions fail. COW (Copy-on-Write) butterfly arrays are a storage optimization for array literals: the backing store is shared and marked read-only until a write triggers a copy. Array.prototype.concat is particularly complex because the spec allows arbitrary objects to opt in or out of spreading via [Symbol.isConcatSpreadable], making any fast path contingent on ruling out that hook.
This commit adds two new DFG/FTL intrinsic IR nodes, ArrayConcatArray and ArrayConcatAppendOne, enabling JIT compilation of Array.prototype.concat. The fixup phase uses type predictions to specialize the generic append node into the array-specific variant. Fast paths are guarded by watchpoints on arrayIsConcatSpreadableWatchpointSet and original-structure checks (isJSArrayWithOriginalStructure); when complicated side effects are detected at runtime, the operation returns nullptr and the JIT OSR-exits via ExoticObjectMode. The runtime test that motivated the patch documents an existing crash in tryConcatOneArgFast where a non-array object reached an uncheckedDowncast to JSArray and dereferenced a bogus butterfly pointer.
Significance
The fixup phase converts ArrayConcatAppendOne to ArrayConcatArray based on type prediction; crafting inputs whose type changes after the fixup decision is the canonical JIT type-confusion lever. Combined with COW butterfly reuse and a fresh OSR-exit boundary, this is one of the most fertile correctness surfaces JSC has added this year.
Audit directions
- Lingering
uncheckedDowncast<JSArray>assumptions. The regression test points to the exact pattern that crashed pre-fix. Adjacent logic intryConcatOneArgFastand the shared concat helpers may still carry implicit "if we got here, it's a JSArray" assumptions reachable from prototype-poisoning or proxy reach-arounds. - COW butterfly reuse soundness. When
concatof an empty array plus a COW source returns an array backed by the same butterfly, correctness depends on COW tracking remaining sound across the abstract interpreter, fixup, and codegen phases. The COW test calls out that if the abstract result structure set omits CopyOnWrite variants, downstream speculation is unsound. - Watchpoint-vs-execution ordering. If
[Symbol.isConcatSpreadable]is installed between watchpoint registration and the JIT-compiled call, the order of invalidation vs. in-flight execution matters; verify the watchpoint fires synchronously enough to cover the full window. - OSR-exit
ExoticObjectModeinvariant preservation. Thenullptr-return path takes a two-way split at codegen time. Confirm both paths preserve all necessary invariants (object identity, array length, index bounds).