← All issues

[JSC] Add DFG MultiGetByVal and MultiPutByVal

8f6bc9a

Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

+void SpeculativeJIT::compileMultiGetByVal(Node* node)
+{
+ ArrayMode arrayMode = node->arrayMode();
+ ...
+ auto cases = node->multiGetByValData().cases();
+ for (unsigned i = 0; i < cases.size(); ++i) {
+ auto& c = cases[i];
+ m_jit.load8(MacroAssembler::Address(baseGPR, JSCell::indexingTypeAndMiscOffset()), ...
+ switch (c.arrayType()) {
+ case ArrayWithInt32:
+ case ArrayWithDouble:
+ case ArrayWithContiguous:
+ ...
+ case TypedArrayType::Float32:
+ ...
+ }
+ }
+ // OOB sane chain: index가 음수가 아님을 추정하고, slow path 없이 undefined 반환
+ ...
+}

Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

+case MultiGetByVal: {
+ ...
+ for (auto& c : node->multiGetByValData().cases()) {
+ if (c.result() == Int32Result || c.result() == Int52Result) {
+ // ValueRep은 FTL에서만 사용 가능 — GetByVal로 fallback
+ node->convertToGetByVal();
+ break;
+ }
+ }
+ break;
+}

JSC의 JIT pipeline은 Baseline → DFG → FTL의 세 단계로 구성됩니다. DFG(Data Flow Graph)는 node 기반 IR을 사용해 비교적 빠르게 컴파일하는 speculative JIT입니다. FTL은 그 위에 위치하며, LLVM 기반 IR과 ValueRep phase를 포함한 추가 최적화 pass를 수행합니다. ValueRep phase는 각 값의 표현 방식(tagged JSValue, unboxed int32, int52, double)을 주석 형태로 추적합니다.

MultiGetByValMultiPutByVal은 "polymorphic merge" node입니다. GetByVal 호출 지점에서 여러 array 형태(예: Int32 JSArray, Float64Array, Contiguous JSArray)가 관찰된 경우, JIT는 각 타입별로 specialized fast path로 dispatch하는 branch tree를 생성합니다. 이를 통해 호출마다 generic IC slow path를 거치지 않아도 됩니다.

이 commit은 MultiGetByValMultiPutByVal을 FTL에서 DFG 단계로 이식하였습니다. 다만 Int32ResultInt52Result 표현 방식은 의도적으로 제외되었습니다. DFG에는 unboxed 정수 표현을 추적하는 FTL의 ValueRep annotation phase가 없기 때문입니다. 결과적으로 지원되는 result 타입은 JSResultDoubleResult로 한정됩니다. fixup phase에서는 case가 Int32/Int52 result를 요구할 경우 해당 node를 일반 GetByVal로 변환합니다.

Before:                          After:
  DFG tier                         DFG tier
  GetByVal (polymorphic site)      MultiGetByVal (NEW)
    └─► IC miss → slow path          ├─► Int32 array fast path
                                     ├─► Double array fast path
                                     ├─► Contiguous fast path
                                     ├─► TypedArray fast paths
                                     └─► OOB → undefined (sane chain)
                                   (JSResult / DoubleResult only)

다양한 타입이 관찰된 array 접근이 FTL 승격을 기다리지 않고 DFG 단계에서 inlined multi-shape dispatch로 최적화될 수 있게 되었습니다. 역사적으로 버그가 많았던 type-specialized JIT code path의 attack surface가 그만큼 넓어진 셈입니다. 이 로직은 이제 SpeculativeJIT라는 별도의 코드 생성기를 통해 생성됩니다. 해당 코드 생성기는 자체적인 OOB 및 speculation 메커니즘을 갖추고 있으며, FTL 대비 테스트가 충분히 수행되지 않은 상태입니다.

Audit directions Significance

🔒

New DFG JIT multi-shape array dispatch with its own OOB speculation path — type and bounds edge cases are worth security investigation.

더 확인하려면 구독해 주세요

🔒

New DFG JIT multi-shape array dispatch with its own OOB speculation path — type and bounds edge cases are worth security investigation.

더 확인하려면 구독해 주세요