tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit fd5559fa78b153f3d701ea2300b0d4ae0fc4aa0d
parent 7ec42fbf0649536481a72206cf5e4c4312d9b558
Author: Jan de Mooij <jdemooij@mozilla.com>
Date:   Thu, 27 Nov 2025 08:23:58 +0000

Bug 2001665 part 2 - Try folding stubs in WarpOracle. r=iain

We perform stub folding during trial inlining or when going megamorphic, but we
didn't fold when a second stub was added between trial inlining and Warp compilation.

This fixes the micro-benchmark in the bug and makes the Babylon test in JetStream 3
20-25% faster.

Drive-by change: `TryFoldingStubs` can't GC (it suppresses it) so remove some rooting overhead.

Differential Revision: https://phabricator.services.mozilla.com/D274118

Diffstat:
Mjs/src/jit/StubFolding.cpp | 2+-
Mjs/src/jit/WarpOracle.cpp | 11++++++++---
2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/js/src/jit/StubFolding.cpp b/js/src/jit/StubFolding.cpp @@ -54,7 +54,7 @@ bool js::jit::TryFoldingStubs(JSContext* cx, ICFallbackStub* fallback, uint32_t numActive = 0; mozilla::Maybe<uint32_t> foldableFieldOffset; - RootedValueVector shapeList(cx); + GCVector<Value, 8> shapeList(cx); // Try to add a shape to the list. Can fail on OOM or for cross-realm shapes. // Returns true if the shape was successfully added to the list, and false diff --git a/js/src/jit/WarpOracle.cpp b/js/src/jit/WarpOracle.cpp @@ -23,6 +23,7 @@ #include "jit/JitZone.h" #include "jit/MIRGenerator.h" #include "jit/ShapeList.h" +#include "jit/StubFolding.h" #include "jit/TrialInlining.h" #include "jit/TypeData.h" #include "jit/WarpBuilder.h" @@ -1007,7 +1008,6 @@ AbortReasonOr<Ok> WarpScriptOracle::maybeInlineIC(WarpOpSnapshotList& snapshots, ICFallbackStub* fallbackStub; const ICEntry& entry = getICEntryAndFallback(loc, &fallbackStub); - ICStub* firstStub = entry.firstStub(); uint32_t offset = loc.bytecodeToOffset(script_); @@ -1020,7 +1020,7 @@ AbortReasonOr<Ok> WarpScriptOracle::maybeInlineIC(WarpOpSnapshotList& snapshots, // invalidating. fallbackStub->clearUsedByTranspiler(); - if (firstStub == fallbackStub) { + if (entry.firstStub() == fallbackStub) { [[maybe_unused]] unsigned line; [[maybe_unused]] JS::LimitedColumnNumberOneOrigin column; LineNumberAndColumn(script_, loc, &line, &column); @@ -1044,7 +1044,10 @@ AbortReasonOr<Ok> WarpScriptOracle::maybeInlineIC(WarpOpSnapshotList& snapshots, return Ok(); } - ICCacheIRStub* stub = firstStub->toCacheIRStub(); + // Try to fold stubs, in case new stubs were added after trial inlining. + if (!TryFoldingStubs(cx_, fallbackStub, script_, icScript_)) { + return abort(AbortReason::Error); + } // Don't transpile if this IC ever encountered a case where it had // no stub to attach. @@ -1059,6 +1062,8 @@ AbortReasonOr<Ok> WarpScriptOracle::maybeInlineIC(WarpOpSnapshotList& snapshots, return Ok(); } + ICCacheIRStub* stub = entry.firstStub()->toCacheIRStub(); + // Don't transpile if there are other stubs with entered-count > 0. Counters // are reset when a new stub is attached so this means the stub that was added // most recently didn't handle all cases.