
ALT circa 2024: Interpreter-in-a-box (SpiderMonkey, QJS, …) Performance ~30x slower than native (10-100x range) weval (partial eval) + Portable Baseline Interpreter in SpiderMonkey (PLDI’25) 1.5-3x speedups; still ~20x slower than native

ALT Instead, seed a points-to with concrete heap + analyze from entry-point What do we “ignore”? (incomplete list) assume globals are static-type after init snapshot assume builtins, functions, methods are not dynamically rebound/monkeypatched We like Andersen for its inclusion semantics: “aware of dataflow direction” We like Steensgaard for its “size cap”: one cell cannot hold arbitrary set We don’t do much with a multi-entry points-to set: e.g. no polymorphic dispatch. Why not coarsen? Together, these form the “likely-types analysis” Decorate the JS bytecode with types Then compile using these types, as if they were IC-derived type observations

ALT Optimistic highest tier with fully type-specialized code Generic lower (but still compiled) “baseline” tier Possibility of de-opt at any guard Possibility of “tier up” at designated points (usually func + loop headers) Barriers on every store check the type, and clear a header bit on failure Now we can guard once per object-ref that we see; all reads are free Objects have two “likely” prediction dimensions: field types, and field slots Invalidated slots can stay in fastpath but with mini IC sites for slot lookup We need multiloop (Wasm proposal: fully general CFG in a region) Prototype: up to 27% smaller code, up to 18% perf improvement

ALT Ion / NightMonkey: 2.45x (best: 1.3x) NightMonkey / wasm-interp: 13.4x (best: 46x) NightMonkey / weval: 7.89x (best: 30x) Config Performance vs. NightMonkey No likely-types facts 0.44x No heap abstractions/types 0.76x No direct call targets 0.82x No MIR-level inlining 0.87x No field-slot predictions 0.88x No interprocedural arg/return types 0.88x No int32 specialization for numerics 0.89x No MIR opts 0.95x



















