← All issues

JSC: cache Symbol.prototype.toString result

5e57a58

+function test(sym) { return sym.toString(); }
+noInline(test);
+const sym = Symbol("cocoa");
+for (let i = 0; i < testLoopCount; ++i)
+ shouldBe(test(sym), "Symbol(cocoa)");

JSC's optimization pipeline has three relevant tiers here: DFG (typed IR with speculation), FTL (B3 backend), and a GC that must trace every live heap pointer. An intrinsic is a built-in function the JIT recognizes by identity and replaces with a hand-coded IR node. This commit adds a per-Symbol cached JSString field and a SymbolToString DFG/FTL intrinsic node. DFGByteCodeParser emits the specialized node, DFGFixupPhase constrains its input to SymbolUse, and SpeculativeJIT/FTL lower it to a raw memory load of the new cached-string field.

A new JIT intrinsic touching a GC-traced field creates a multi-layered attack surface — type speculation, GC liveness, and slow-path write-back all have to be correct simultaneously.

🔒

New JIT intrinsic with GC-traced cache field — type speculation edges and the slow-path write-back boundary carry audit-worthy risk.

Subscribe to read more