[JSC] Inline `NumericStrings` int cache lookup in DFG and FTL `ToString(Int32)`
186e2a9
NumericStrings는 VM 단위로 유지되는 캐시로, 정수를 미리 계산된 JSString 표현과 대응시킵니다. 두 계층으로 구성됩니다. 하나는 0..1023 범위의 small-int를 직접 인덱싱하는 배열이고, 다른 하나는 WTF::IntHash<int> (rapidHashMix64 mum mixer)를 키로 사용하는 hash 기반의 m_intCache입니다. DFG/FTL이 cache lookup을 인라인화할 때는, hash 연산·memory load·조건 분기를 native instruction으로 직접 내보냅니다. C++ call frame은 없으며, 명시적으로 내보낸 것 이외의 runtime guard도 존재하지 않습니다.
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
- slowCases.append(branch32(AboveOrEqual, valueGPR, TrustedImm32(NumericStrings::cacheSize)));
- move(valueGPR, resultGPR);
- lshiftPtr(TrustedImm32(WTF::fastLog2(static_cast<unsigned>(sizeof(NumericStrings::StringWithJSString)))), resultGPR);
- addPtr(TrustedImmPtr(vm().numericStrings.smallIntCache()), resultGPR);
- loadPtr(Address(resultGPR, NumericStrings::StringWithJSString::offsetOfJSString()), resultGPR);
- doneCases.append(branchTestPtr(NonZero, resultGPR));
- callOperation(operationInt32ToStringWithValidRadix, resultGPR, LinkableConstant::globalObject(*this, node), valueGPR, TrustedImm32(10));
Source/JavaScriptCore/b3/B3AbstractHeapRepository.h
+ macro(IntCache, 0, sizeof(NumericStrings::CacheEntryWithJSString<int>)) \
이 commit은 64-bit DFG와 FTL backend에서 NumericStrings int-cache hash lookup을 인라인화했습니다. 대상은 기존 0..1023 small-int 범위 밖의 값에 대한 radix-10 ToString(Int32) 처리입니다. rapidHashMix64를 JIT machine code로 직접 내보내 m_intCache를 인덱싱하고, key가 일치하면 캐시된 JSString을 반환합니다. miss인 경우에만 vmCall이 실행됩니다. 새롭게 추가된 IntCache B3 abstract heap은 optimizer의 load 재배치 방식을 제어합니다. 32-bit DFG backend는 기존 small-int 전용 경로를 유지합니다. rapidHashMix64에 필요한 128-bit 곱셈이 32-bit 환경에서는 실용적이지 않기 때문입니다.
Significance
이로써 hot JIT code에서 large integer를 string으로 변환하는 속도가 약 2.38배 향상됩니다. 단, 새롭게 내보내진 JIT code는 runtime hash table에서 GC가 관리하는 JSString 포인터를 직접 역참조합니다.
Audit directions
Aaa Aa Aaa Aaaaaaaaaaa Aaaaaaaa Aaa Aaaaa Aaaaaa Aa Aaaaa Aaaa a Aa Aaaaaaaa Aa Aaaaaaaaaa Aaa Aaaa Aaaa Aaaaaa Aa Aaa a a Aaaa Aaa Aaaaa Aaa Aaa Aaaaa Aaaaaaaaaaa Aa Aaa Aaa Aaa Aaa a Aaaaa
Aaaaaaaaaaaaaaaaa Aaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaa Aa Aaa Aaa Aaaa Aaaa Aa Aaa Aaaa Aaaaaaaaaa Aa Aa a Aa Aaaa Aaa Aaaa Aaaaaaaa Aa Aaaaa Aaaaa Aaaa Aaaaa Aaa Aaa Aaaa Aaaaaaaaaaa Aaa a Aaaaa
Aaa Aaa Aa Aaaaaaaaaa Aaaaaaaa Aaaaa Aa Aaaaaa Aa Aaaa Aaaa Aaaaa Aaa Aaa Aaaaaa Aaa Aaaaa Aaaaaaa Aaaa Aaaa Aaaaaaaaaa Aaaaa Aaaa Aaaa Aaaaa Aaaa Aaaaaa Aaaa Aa Aaaa a a Aaaaa
Aaaaaa Aaaaaaa Aaaaaa Aa Aa Aaa Aaaa Aaaa Aaaa Aaaaaaa Aa Aaaaa Aaa Aaaaa Aaa Aaaaaa Aaaaaaaaa Aaa Aa Aa Aaaaaa Aa Aa Aa Aaaaaaa Aa Aaa Aaa a Aaaaa
🔒New JIT-emitted GC-pointer loads from a hash table — edge cases in the inline fast path and B3 alias analysis are worth security investigation.
더 확인하려면 구독해 주세요