tor-browser

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

commit b31de09df6f4f2cdfbd8a5113f7a0c97e80d1c5a
parent 4a128f5d807df9ec662e00b98d5554410703b0cd
Author: Jan de Mooij <jdemooij@mozilla.com>
Date:   Fri, 28 Nov 2025 07:46:54 +0000

Bug 2002447 - Fix overzealous assertion for GuardMultipleShapes. r=iain

This includes the Major-GC number in the `ICScript` hash to handle the case where
a new shape is added later but then removed again by the GC (the list has weak pointers).

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

Diffstat:
Ajs/src/jit-test/tests/warp/bug2002447.js | 16++++++++++++++++
Mjs/src/jit/JitScript.cpp | 7++++++-
Mjs/src/jit/JitScript.h | 2+-
Mjs/src/jit/WarpOracle.cpp | 5+++--
4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/js/src/jit-test/tests/warp/bug2002447.js b/js/src/jit-test/tests/warp/bug2002447.js @@ -0,0 +1,16 @@ +// |jit-test| --fast-warmup +gczeal(2, 54); +var bin = new Uint8Array(2); +function f(i) { + bin[1] = i; + Object.defineProperty(bin, [], {get: function() {}, [bin]: f}); + WebAssembly(x); +} +function test() { + for (let i = 1; i < 120; i++) { + try { + f(i); + } catch {} + } +} +test(); diff --git a/js/src/jit/JitScript.cpp b/js/src/jit/JitScript.cpp @@ -982,7 +982,7 @@ JitScript* ICScript::outerJitScript() { // 5. The hash will change if the set of shapes stored in ShapeListSnapshot // is changed by stub folding or GC (the shapes in ShapeListObject are weak // pointers). -HashNumber ICScript::hash() { +HashNumber ICScript::hash(JSContext* cx) { HashNumber h = 0; for (size_t i = 0; i < numICEntries(); i++) { ICStub* stub = icEntry(i).firstStub(); @@ -1010,6 +1010,11 @@ HashNumber ICScript::hash() { Shape* shape = shapesObject->getUnbarriered(i); h = mozilla::AddToHash(h, shape); } + // Also include the GC number to handle the case where we bail + // out, add an additional shape, remove this new shape during GC, + // and then recompile with the current set of shapes. + // See bug 2002447. + h = mozilla::AddToHash(h, cx->runtime()->gc.majorGCCount()); } break; } diff --git a/js/src/jit/JitScript.h b/js/src/jit/JitScript.h @@ -214,7 +214,7 @@ class alignas(uintptr_t) ICScript final : public TrailingArray<ICScript> { bool traceWeak(JSTracer* trc); #ifdef DEBUG - mozilla::HashNumber hash(); + mozilla::HashNumber hash(JSContext* cx); #endif private: diff --git a/js/src/jit/WarpOracle.cpp b/js/src/jit/WarpOracle.cpp @@ -134,7 +134,8 @@ void WarpOracle::addScriptSnapshot(WarpScriptSnapshot* scriptSnapshot, scriptSnapshots_.insertBack(scriptSnapshot); accumulatedBytecodeSize_ += bytecodeLength; #ifdef DEBUG - runningScriptHash_ = mozilla::AddToHash(runningScriptHash_, icScript->hash()); + runningScriptHash_ = + mozilla::AddToHash(runningScriptHash_, icScript->hash(cx_)); #endif } @@ -207,7 +208,7 @@ AbortReasonOr<WarpSnapshot*> WarpOracle::createSnapshot() { // Failing this assertion is not a correctness/security problem. // We therefore ignore cases involving resource exhaustion (OOM, // stack overflow, etc), or stubs purged by GC. - HashNumber hash = mozilla::AddToHash(icScript->hash(), runningScriptHash_); + HashNumber hash = mozilla::AddToHash(icScript->hash(cx_), runningScriptHash_); if (outerScript_->jitScript()->hasFailedICHash()) { HashNumber oldHash = outerScript_->jitScript()->getFailedICHash(); MOZ_ASSERT_IF(hash == oldHash && !js::SupportDifferentialTesting(),