Closed Bug 1901166 Opened 6 months ago Closed 5 months ago

Assertion failure: cx_->hadResourceExhaustion(), at jit/WarpOracle.cpp:206

Categories

(Core :: JavaScript Engine: JIT, defect, P2)

x86_64
Linux
defect

Tracking

()

RESOLVED FIXED
129 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox126 --- wontfix
firefox127 --- wontfix
firefox128 --- wontfix
firefox129 --- fixed

People

(Reporter: gkw, Assigned: iain)

References

(Blocks 2 open bugs, Regression)

Details

(Keywords: regression, reporter-external, testcase)

Attachments

(2 files)

Attached file testcase

Testcase is attached.

205         MOZ_ASSERT_IF(hash == oldHash && !js::SupportDifferentialTesting(),
(gdb) bt
#0  js::jit::WarpOracle::createSnapshot (this=0x7fffffffc790) at /home/yksubu/trees/mozilla-central/js/src/jit/WarpOracle.cpp:205
#1  0x00005555583e748d in js::jit::CreateWarpSnapshot (cx=cx@entry=0x7ffff6635100, mirGen=mirGen@entry=0x7ffff5a50180, script=...) at /home/yksubu/trees/mozilla-central/js/src/jit/Ion.cpp:1653
#2  0x00005555583b842e in js::jit::IonCompile (cx=0x7ffff6635100, script=..., osrPc=0x0) at /home/yksubu/trees/mozilla-central/js/src/jit/Ion.cpp:1723
#3  js::jit::Compile (cx=cx@entry=0x7ffff6635100, script=script@entry=..., osrFrame=osrFrame@entry=0x7fffffffca58, osrPc=osrPc@entry=0x0) at /home/yksubu/trees/mozilla-central/js/src/jit/Ion.cpp:1916
#4  0x00005555583b9209 in BaselineCanEnterAtEntry (cx=0x7ffff6635100, script=..., frame=0x7fffffffca58) at /home/yksubu/trees/mozilla-central/js/src/jit/Ion.cpp:2048
#5  IonCompileScriptForBaseline (cx=0x7ffff6635100, frame=0x7fffffffca58, pc=<optimized out>) at /home/yksubu/trees/mozilla-central/js/src/jit/Ion.cpp:2173
#6  0x0000177be6713536 in ?? ()
#7  0x0000000000000000 in ?? ()
(gdb)

Run with --fuzzing-safe --no-threads --baseline-eager, compile with AR=ar sh ../configure --enable-debug --enable-debug-symbols --with-ccache --enable-nspr-build --enable-ctypes --enable-gczeal --enable-rust-simd --disable-tests, tested on m-c rev 2044dc55cd3a.

Still bisecting - it seems to go further back than m-c rev 1db2ef126a6a8555dbf50345e16492c977b42e92 for now.

The first bad revision is:
changeset:   https://hg.mozilla.org/mozilla-central/rev/9882c0d924b8
user:        Jon Coppeard
date:        Fri Jul 07 17:05:44 2023 +0000
summary:     Bug 1837620 - Part 6: Make edges for multiple shape guard weak too r=sfink

Oh wait, this points to a GC issue. In that case, I'm not sure if the actual bug is a GC issue, or is merely a performance-related assertion failure. Jon, is bug 1837620 a likely regressor?

Group: core-security
Flags: sec-bounty?
Flags: needinfo?(jcoppeard)
Keywords: regression
Regressed by: 1837620

I'm guessing my bugs going forward should be marked reporter-external as well.

Set release status flags based on info from the regressing bug 1837620

Group: core-security → javascript-core-security

This is a possible performance issue and not security sensitive, as per the comment in WarpOracle::createSnapshot.

I can reproduce and confirmed the bisection is correct.

I don't know what's going on here but probably the GC is affecting the JIT behaviour when it sweeps the ShapeListObject and removes shapes from it (which is happening with this testcase). I couldn't find exactly what that was going wrong though.

Jan do you have any ideas?

Group: javascript-core-security
Flags: needinfo?(jcoppeard) → needinfo?(jdemooij)

Iain, can you take a look at this one?

Flags: needinfo?(jdemooij) → needinfo?(iireland)

There are a lot of moving pieces in this bug, but most of them (including the shape list sweeping) are distractions. This is a corner case in stub folding bailout loop detection. Here's a reduced testcase:

// |jit-test| --fast-warmup; --ion-inlining=off; --no-threads

var classes = [];
for (var i = 0; i < 16; i++) {
  class C extends Uint8Array {
    constructor(n) { super(n); }
    0 = 1;
  }
  classes.push(C);
}

function foo(classIdx, size) {
  return new classes[classIdx](size);
}

// Compile with 7-shape list.
for (var i = 0; i < 100; i++) {
  foo(i % 7, 5);
}

// Bail out with invalid index
for (var i = 0; i < 10; i++) {
  try {
    foo(7, 0);
  } catch {}
}

// Recompile with full list
for (var i = 0; i < 20; i++) {
  foo(i % 16, 5);
}

We create a subclass of TypedArray with an initializer. In the constructor, we call super, and then call into the initializer for 0 = 1, which is equivalent to this[0] = 1. The initializer is implemented using an InitProp, which attaches an IC that guards the shape of the receiver and then uses StoreTypedArrayElement. Because there are many different classes with different shapes, stub folding collapses the shape guards into a single GuardMultipleShapes.

(In the original fuzz bug, there were lots of shapes, but the combination of gczeal and frequent random unrelated allocations means that we always run a GC and clear out the shape list before it hits the limit. My reduced testcase triggers the same bug without jumping through those hoops.)

We start by compiling with a partially filled shape list. We transpile the GuardMultipleShapes and the StoreTypedArrayElement. After we've compiled, we invoke the initializer on a 0-length typed array with an unknown shape. The shapeguard fails, we bail out, and we hit the fallback, but we don't attach a new stub. Instead, we see that our write would be out-of-bounds, and return AttachResult::NoAction. The call to InitElemOperation returns early before incrementing the failure count. So we don't hit the failure count, and we also don't add a new entry to the shape list yet.

We invalidate and save a failure hash.

After we invalidate, we add new shapes to the shape list, which resets the entry count for the fallback stub. Eventually we recompile. The failure count is still 0 and the only active stub is the folded stub, so we transpile the same CacheIR and assert.

I think the fix is probably to change DoSetElemFallback so that we call trackNotAttached even if we throw.

Flags: needinfo?(iireland)

Iain, do you want to take on this bug or can you suggest an assignee? Also, can you help set a severity/priority? Thanks!

Flags: needinfo?(iireland)
Blocks: sm-js-perf
Severity: -- → S3
Priority: -- → P2
Assignee: nobody → iireland
Severity: S3 → S4
Flags: needinfo?(iireland)

These are the only cases that use AttachDecision::Deferred.

Pushed by iireland@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/7640908c76aa Call trackNotAttached even when throwing r=jandem
Status: NEW → RESOLVED
Closed: 5 months ago
Resolution: --- → FIXED
Target Milestone: --- → 129 Branch

The patch landed in nightly and beta is affected.
:iain, is this bug important enough to require an uplift?

  • If yes, please nominate the patch for beta approval.
  • If no, please set status-firefox128 to wontfix.

For more information, please visit BugBot documentation.

Flags: needinfo?(iireland)

This is at worst a small performance hit in a pathological case. No need to uplift it.

Flags: needinfo?(iireland)
Flags: sec-bounty? → sec-bounty-
QA Whiteboard: [qa-129b-p2]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: