[JSC] Add Array#concat DFG nodes
94e35cf
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+ case ArrayConcatIntrinsic: {
+ if (argumentCountIncludingThis != 2)
+ return CallOptimizationResult::DidNothing;
+
+ if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantCache)
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, ExoticObjectMode))
+ return CallOptimizationResult::DidNothing;
+
+ ArrayMode arrayMode = getArrayMode(Array::Read);
+ if (!arrayMode.isJSArray())
+ return CallOptimizationResult::DidNothing;
+
+ if (!arrayMode.isJSArrayWithOriginalStructure())
+ return CallOptimizationResult::DidNothing;
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
+ case ArrayConcatArray:
+ case ArrayConcatAppendOne:
+ setTypeForNode(node, SpecArray);
+ break;
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
a Aaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aaa Aaaaaaaaaa Aaaa Aaaaaa Aa Aaa Aaaaa Aaaaaaa Aaaa Aaaaaaa Aaaaaaaa Aaaaaaaa Aaaaa Aa Aaaaaaaaaaaaaaaaaaaaa Aaa Aaa Aaaaaa Aaaaaa Aaaaaaa Aaa Aaaaa Aaaaa Aaaaaaaa Aaa Aa Aaa Aaaaa Aaaa a Aaaaaaaa Aaaaaaaaaaa Aaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaa Aa Aaaaa Aaaaaaaaaaaaaa
a Aaaaa Aaaaaaaaa Aaaaa Aaaaaaaaaaaa Aaaa Aaaaaaaa Aa Aa Aaaaa Aaaaa Aaaa a Aaa Aaaaaa Aaaaaaa Aa Aaaaa Aaaaaa Aa Aaa Aaaa Aaaaaaaaaa Aaaaaaaaaaa Aaaaaaa Aa Aaa Aaaaaaaa Aaaaaaaaa Aaaaa Aaaaaa Aaa Aaaaaaaa Aaaaaaaaaaaa Aaaaaa Aaa Aaaaaaa Aaaaaaa Aaa Aaa Aaaa Aaaaa Aaa Aaaa Aa Aaa Aaaaaaaa Aaaaaa Aaaaaaaaa Aaa Aaaaa Aaaaaaaaaaa Aaaaaaaaa Aaaaaaaaaa Aaaaaaaaaaa Aa Aaaaaaaa
a Aaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaa Aaaaaaa Aaaaaaaaaa Aaaaaaaaaaaa Aaa Aaa Aaaaaaaaaaaa Aaaaa Aaa Aaaaa Aa Aaaaaaaaaaaa Aaa Aaaaaaaaa Aaaaaaaaa Aaaaaaaa Aaaaaa Aaa Aaaaaaaaaa Aaaaa Aaaaaaaaaaaaa Aaaaaa Aa Aaaaa Aaa Aaaa Aaaaaaa
a Aaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaa Aaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaa Aaaa Aaaaa a Aaaaaaa Aaaaa Aa Aaaaaaa Aaaaa Aaaaaaa Aaaa Aaaaa Aaaaaaaa Aaa Aaaaaaaaa Aaaaaaaaaa Aaaaaaa Aaaaaaaaa Aaaaa Aaaaaaa Aaaaa Aaaaaaaa
🔒New JIT fast paths for a complex builtin — edge cases in type specialization and COW handling are worth close inspection.
Subscribe to read more