Closed Bug 1985591 Opened 19 days ago Closed 3 days ago

Assertion failure: cx_->hadResourceExhaustion(), at /builds/worker/checkouts/gecko/js/src/jit/WarpOracle.cpp:212

Categories

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

defect

Tracking

()

RESOLVED FIXED
144 Branch
Tracking Status
firefox-esr128 --- unaffected
firefox-esr140 --- unaffected
firefox142 --- unaffected
firefox143 --- unaffected
firefox144 --- fixed

People

(Reporter: tsmith, Assigned: alexical)

References

(Blocks 1 open bug, Regression, )

Details

(Keywords: assertion, pernosco, regression)

Attachments

(2 files)

Found with m-c 20250826-b7573b229c2d (--enable-debug)

This was found by visiting a live website with a debug build.

STR:

  • Launch browser and visit site

This issue was triggered by visiting https://www.soccer24.com/.

A Pernosco session is available here: https://pernos.co/debug/1_Xf91PKfDGYRLVs0Sy9ww/index.html

Assertion failure: cx_->hadResourceExhaustion(), at /builds/worker/checkouts/gecko/js/src/jit/WarpOracle.cpp:212

0|0|libxul.so|js::jit::WarpOracle::createSnapshot()|hg:hg.mozilla.org/mozilla-central:js/src/jit/WarpOracle.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|211|0x8f2
0|1|libxul.so|js::jit::Compile(JSContext*, JS::Handle<JSScript*>, js::jit::BaselineFrame*, unsigned char*)|hg:hg.mozilla.org/mozilla-central:js/src/jit/Ion.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|2016|0x805
0|2|libxul.so|IonCompileScriptForBaseline(JSContext*, js::jit::BaselineFrame*, unsigned char*)|hg:hg.mozilla.org/mozilla-central:js/src/jit/Ion.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|2273|0x49b
0|3|||||
0|4|||||
0|5|||||
0|6|||||
0|7|||||
0|8|||||
0|9|||||
0|10|||||
0|11|||||
0|12|||||
0|13|||||
0|14|||||
0|15|||||
0|16|||||
0|17|||||
0|18|||||
0|19|||||
0|20|||||
0|21|||||
0|22|||||
0|23|||||
0|24|||||
0|25|||||
0|26|||||
0|27|||||
0|28|libxul.so|js::jit::MaybeEnterJit(JSContext*, js::RunState&)|hg:hg.mozilla.org/mozilla-central:js/src/jit/Jit.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|260|0x526
0|29|libxul.so|js::RunScript(JSContext*, js::RunState&)|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|461|0x3ba
0|30|libxul.so|js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|629|0x2e5
0|31|libxul.so|js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason)|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|696|0x12c
0|32|libxul.so|JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>)|hg:hg.mozilla.org/mozilla-central:js/src/vm/CallAndConstruct.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|119|0x20b
0|33|libxul.so|mozilla::dom::EventHandlerNonNull::Call(mozilla::dom::BindingCallContext&, JS::Handle<JS::Value>, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&)|s3:gecko-generated-sources:6bb50a9febd07b2ad041cb59a1fa6678b97d5dfa7934c45cdfb310e02ee1d5fd2d0aff84c3cbda807717ae7247884aa5f52594385c678b698b0d951ba796aa45/dom/bindings/EventHandlerBinding.cpp:|65|0x305
0|34|libxul.so|mozilla::dom::EventHandlerNonNull::Call<nsCOMPtr<mozilla::dom::EventTarget> >(nsCOMPtr<mozilla::dom::EventTarget> const&, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObjectBase::ExceptionHandling, JS::Realm*)|s3:gecko-generated-sources:2c0600fb668133ec78b4dbdd71621eeefcafca4a527e24f8dcefe291fb1ae7c5c4647bce637883fe669db31805b6a9d1251a807433b4f2db5c3b207f28308026/dist/include/mozilla/dom/EventHandlerBinding.h:|82|0x12b
0|35|libxul.so|mozilla::JSEventHandler::HandleEvent(mozilla::dom::Event*)|hg:hg.mozilla.org/mozilla-central:dom/events/JSEventHandler.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|201|0x52b
0|36|libxul.so|mozilla::EventListenerManager::HandleEventSingleListener(mozilla::EventListenerManager::Listener*, nsAtom*, mozilla::WidgetEvent*, mozilla::dom::Event*, mozilla::dom::EventTarget*, bool)|hg:hg.mozilla.org/mozilla-central:dom/events/EventListenerManager.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|1392|0x301
0|37|libxul.so|mozilla::EventListenerManager::HandleEventWithListenerArray(mozilla::EventListenerManager::ListenerArray*, nsAtom*, mozilla::EventMessage, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, bool)|hg:hg.mozilla.org/mozilla-central:dom/events/EventListenerManager.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|1698|0x389
0|38|libxul.so|mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool)|hg:hg.mozilla.org/mozilla-central:dom/events/EventListenerManager.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|1603|0x1df
0|39|libxul.so|mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&)|hg:hg.mozilla.org/mozilla-central:dom/events/EventDispatcher.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|367|0x1de
0|40|libxul.so|mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&)|hg:hg.mozilla.org/mozilla-central:dom/events/EventDispatcher.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|608|0x65c
0|41|libxul.so|mozilla::EventDispatcher::Dispatch(mozilla::dom::EventTarget*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*)|hg:hg.mozilla.org/mozilla-central:dom/events/EventDispatcher.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|1263|0x154b
0|42|libxul.so|mozilla::EventDispatcher::DispatchDOMEvent(mozilla::dom::EventTarget*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsPresContext*, nsEventStatus*)|hg:hg.mozilla.org/mozilla-central:dom/events/EventDispatcher.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1||0x11a
0|43|libxul.so|nsWindowRoot::DispatchEvent(mozilla::dom::Event&, mozilla::dom::CallerType, mozilla::ErrorResult&)|hg:hg.mozilla.org/mozilla-central:dom/base/nsWindowRoot.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|83|0x3b
0|44|libxul.so|mozilla::dom::EventTarget::DispatchEvent(mozilla::dom::Event&)|hg:hg.mozilla.org/mozilla-central:dom/events/EventTarget.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|215|0x57
0|45|libxul.so|mozilla::dom::PostMessageRunnable::DispatchMessage() const|hg:hg.mozilla.org/mozilla-central:dom/messagechannel/MessagePort.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|135|0x2c0
0|46|libxul.so|mozilla::dom::PostMessageRunnable::Run()|hg:hg.mozilla.org/mozilla-central:dom/messagechannel/MessagePort.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|71|0x32
0|47|libxul.so|mozilla::RunnableTask::Run()|hg:hg.mozilla.org/mozilla-central:xpcom/threads/TaskController.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|703|0x17
0|48|libxul.so|mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/TaskController.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|1310|0x50e
0|49|libxul.so|mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/TaskController.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|1133|0x57
0|50|libxul.so|mozilla::TaskController::ProcessPendingMTTask(bool)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/TaskController.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|639|0x65
0|51|libxul.so|mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run()|hg:hg.mozilla.org/mozilla-central:xpcom/threads/nsThreadUtils.h:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|548|0x16
0|52|libxul.so|nsThread::ProcessNextEvent(bool, bool*)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/nsThread.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|1159|0x5aa
0|53|libxul.so|NS_ProcessNextEvent(nsIThread*, bool)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/nsThreadUtils.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|480|0x4f
0|54|libxul.so|mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*)|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessagePump.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|85|0xc0
0|55|libxul.so|MessageLoop::Run()|hg:hg.mozilla.org/mozilla-central:ipc/chromium/src/base/message_loop.cc:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|349|0x61
0|56|libxul.so|nsBaseAppShell::Run()|hg:hg.mozilla.org/mozilla-central:widget/nsBaseAppShell.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|148|0x28
0|57|libxul.so|nsAppShell::Run()|hg:hg.mozilla.org/mozilla-central:widget/gtk/nsAppShell.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|471|0x114
0|58|libxul.so|XRE_RunAppShell()|hg:hg.mozilla.org/mozilla-central:toolkit/xre/nsEmbedFunctions.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|657|0x6b
0|59|libxul.so|mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*)|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessagePump.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|235|0x3c
0|60|libxul.so|MessageLoop::Run()|hg:hg.mozilla.org/mozilla-central:ipc/chromium/src/base/message_loop.cc:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|349|0x61
0|61|libxul.so|XRE_InitChildProcess(int, char**, XREChildData const*)|hg:hg.mozilla.org/mozilla-central:toolkit/xre/nsEmbedFunctions.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|595|0xa25
0|62|firefox-bin|main|hg:hg.mozilla.org/mozilla-central:browser/app/nsBrowserApp.cpp:b7573b229c2d2e6a660decc4e3ed7183c761f8e1|397|0x1df

Looks like this is a subtle issue in the patches for bug 1974519.

In this code in MacroAssembler::preserveWrapper, we increment the number of preserved wrappers and return that value (which is guaranteed to be non-zero) to indicate success. However, in the caller, we're consuming that value using bailoutIfFalseBool. Because we expect a bool result, this checks whether (result&0xff) is zero. If the new number of preserved wrappers is divisible by 256, this will spuriously bail out.

We bail out and try again. However, we've already added the wrapper to the preserved buffer once, so when we do so again, the result is no longer divisible by 256. Nothing fails, we continue, we eventually recompile with the same CacheIR, and we assert.

It looks like we should be able to fix this by returning a fixed value (eg 1) from the non-ABI-call path in preserveWrapper, or by changing the calls to masm.bailout/branchIfFalseBool to instead do a 32-bit comparison.

Looking at the code, though, I wonder if there's another latent bailout loop issue. In preserveWrapper, we return false if the buffer has reached capacity. If we are preserving wrappers quickly enough to consistently fill the buffer before triggering a GC, it seems like we could get stuck bailing out of Ion and then recompiling with the same CacheIR.

Alex, can you take a look?

Flags: needinfo?(dothayer)
Severity: -- → S3
Priority: -- → P2
Assignee: nobody → dothayer
Flags: needinfo?(dothayer)

Added a patch for the primary issue. For the more subtle bailout loop, do you have a recommended course of action? It should be exceedingly rare to hit that case, but if you wrote code specifically targeting it I think you could. I don't think we want to dynamically increase the max capacity or globally turn off this optimization in the event that we run out of space here, so is there a good way to set state specific to the call site so that we emit CacheIR that just does the full VM call?

Discussed elsewhere, summarizing here: it seems like we can probably get away with just draining the buffer when it's full instead of returning false, which avoids the problem.

Duplicate of this bug: 1987401

Is this a regression that needs to be tracked? Does it impact functionality for users?

Keywords: regression
Regressed by: 1974519

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

This could cause a small performance hit in pathological cases (if a single AddProp preserves 256 wrappers between GCs at least 10 times, we will bailout + recompile). Other than performance, it shouldn't have any user-visible effects.

This is the final week of Nightly for Fx144 before going to Beta next week.
:alexical, mentioning if you plan on landing this in time for Fx144?

Flags: needinfo?(dothayer)

Shoot, all right - I need to take a closer look at the second patch and what's doing a GC call when committing, but the first patch in the stack should address the core problem mentioned in the bug and should be very safe to land, so I'm going to push just that.

Flags: needinfo?(dothayer)

(In reply to Alex Thayer [:alexical] (she/her) from comment #14)

Shoot, all right - I need to take a closer look at the second patch and what's doing a GC call when committing

The preserveWrapperCallback call is an indirect call because it uses a function pointer, and the hazard analysis can't see through those to determine if the call can GC. Adding a JS::AutoSuppressGCAnalysis suppress; before the call should help.

(In reply to Jan de Mooij [:jandem] from comment #15)

(In reply to Alex Thayer [:alexical] (she/her) from comment #14)

Shoot, all right - I need to take a closer look at the second patch and what's doing a GC call when committing

The preserveWrapperCallback call is an indirect call because it uses a function pointer, and the hazard analysis can't see through those to determine if the call can GC. Adding a JS::AutoSuppressGCAnalysis suppress; before the call should help.

Ah okay - thank you for the tip. I think I'll update and land the second patch after the code freeze though still? I would expect the case it's helping is exceedingly uncommon.

Status: NEW → RESOLVED
Closed: 3 days ago
Resolution: --- → FIXED
Target Milestone: --- → 144 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: