← All issues

DFG/FTL ArrayUnshift intrinsic

5965900

JSTests/stress/array-unshift-intrinsic-ftl.js

+(function () {
+ function unshiftDouble(a, v) { return a.unshift(v); }
+ noInline(unshiftDouble);
+ for (var i = 0; i < testLoopCount; ++i) {
+ var array = [1.5];
+ shouldBe(unshiftDouble(array, 2.5), 2);
+ }
+ var array = [1.5];
+ var r = unshiftDouble(array, NaN);
+ shouldBe(r, 2);
+ shouldBe(array.length, 2);
+ shouldBe(Number.isNaN(array[0]), true);
+ shouldBe(array[1], 1.5);
+})();

JSC는 Baseline → DFG → FTL로 이어지는 계층형 JIT 구조를 사용합니다. 자주 호출되는 내장 함수에 대해 DFG bytecode parser는 "intrinsic"을 인식하고 전용 DFG 노드를 생성합니다. Array.prototype.unshiftpush보다 구조적으로 복잡합니다. 기존 원소 전체를 더 높은 인덱스 방향으로 한 칸 이상 이동시켜야 하므로, butterfly storage에 대한 memmove가 수반됩니다. Contiguous 배열(GC가 관리하는 JSValue를 저장하는 배열)의 경우, 이동하는 원소 하나하나에 write barrier가 필요합니다.

이 commit은 Array.prototype.unshift를 DFG 및 FTL의 first-class intrinsic으로 구현했습니다. Int32, Double, Contiguous 세 가지 storage 타입에 대해 0개 및 1개 인수 처리를 위한 inline fast path를 지원하며, ArrayStorage는 slow path로 처리됩니다. 이 intrinsic은 bytecode parser, fixup, clobberize, abstract interpreter, speculative JIT (64-bit), FTL B3 lowering에 이르는 전 단계에 걸쳐 연결되었습니다.

메모리 내 기존 원소 전체를 오른쪽으로 이동시키는, 대규모 변형을 수반하는 배열 연산에 대해 JIT 컴파일된 코드 경로가 새로 추가되었습니다. 이 영역은 JIT 컴파일러에서 type confusion과 bounds 오류가 역사적으로 자주 발생해 온 곳입니다.

🔒

New JIT-compiled memory-mutation fast paths with inline butterfly writes and GC barriers — several edge cases are worth security investigation.

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