tor-browser

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

commit 69ce3c1b9fafe4f0e77f498436e944e076d62e1c
parent 6e1dbd670bcf13e7884e74e897e33596474a1c32
Author: Atila Butkovits <abutkovits@mozilla.com>
Date:   Fri, 28 Nov 2025 20:39:55 +0200

Revert "Bug 1997192, Bug 2002876, Bug 2002035, Bug 2002849 - Enable JS MicroTaskQueue by default r=smaug" for causing xpc failures at test_promise_job_across_sandbox.js.

This reverts commit 4c000c7022cf307cc781a54f14f71b8f1cb83ab9.

Revert "Bug 2002876 - Remove un-necessary copy & move root out of loop r=smaug"

This reverts commit ff03e52ebf738ece9bbe7d0bf9ed94a892b28f97.

Revert "Bug 2002035 - Remove unnecessary barriers in MustConsumeMicroTaskRunnable r=jonco"

This reverts commit 120f48b684865bbc169066d3236d4469026779e9.

Revert "Bug 2002849 - Revert "Bug 1997702 - Remove use of PersistentRooted on JSContext for MicroTaskQueues" r=jonco"

This reverts commit e78b98f730ecd5918e4ee804a70a21abbe478d04.

Diffstat:
Mjs/src/vm/JSContext.cpp | 19+++++++++++++------
Mjs/src/vm/JSContext.h | 4++--
Mmodules/libpref/init/StaticPrefList.yaml | 4+++-
Mxpcom/base/CycleCollectedJSContext.cpp | 4++--
Mxpcom/base/CycleCollectedJSContext.h | 8+++-----
5 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp @@ -1067,9 +1067,11 @@ void js::MicroTaskQueueElement::trace(JSTracer* trc) { auto* queue = cx->jobQueue.ref(); if (!queue || value.isGCThing()) { - TraceRoot(trc, &value, "microtask-queue-entry"); + TraceEdge(trc, &value, "microtask-queue-entry"); } else { - queue->traceNonGCThingMicroTask(trc, &value); + // It's OK to use unbarriered address here because this is not a GC thing + // and so there are no worthwhile barriers to consider here. + queue->traceNonGCThingMicroTask(trc, value.unbarrieredAddress()); } } @@ -1161,7 +1163,7 @@ JS_PUBLIC_API bool JS::HasDebuggerMicroTasks(JSContext* cx) { struct SavedMicroTaskQueueImpl : public JS::SavedMicroTaskQueue { explicit SavedMicroTaskQueueImpl(JSContext* cx) : savedQueues(cx) { savedQueues = js::MakeUnique<js::MicroTaskQueueSet>(cx); - std::swap(cx->microTaskQueues.get(), savedQueues.get()); + std::swap(cx->microTaskQueues, savedQueues.get()); } ~SavedMicroTaskQueueImpl() override = default; JS::PersistentRooted<js::UniquePtr<js::MicroTaskQueueSet>> savedQueues; @@ -1184,7 +1186,7 @@ JS_PUBLIC_API void JS::RestoreMicroTaskQueue( // There's only one impl, so we know this is safe. SavedMicroTaskQueueImpl* savedQueueImpl = static_cast<SavedMicroTaskQueueImpl*>(savedQueue.get()); - std::swap(savedQueueImpl->savedQueues.get(), cx->microTaskQueues.get()); + std::swap(savedQueueImpl->savedQueues.get(), cx->microTaskQueues); } JS_PUBLIC_API size_t JS::GetRegularMicroTaskCount(JSContext* cx) { @@ -1290,8 +1292,7 @@ JSContext::JSContext(JSRuntime* runtime, const JS::ContextOptions& options) canSkipEnqueuingJobs(this, false), promiseRejectionTrackerCallback(this, nullptr), promiseRejectionTrackerCallbackData(this, nullptr), - insideExclusiveDebuggerOnEval(this, nullptr), - microTaskQueues(this) { + insideExclusiveDebuggerOnEval(this, nullptr) { MOZ_ASSERT(static_cast<JS::RootingContext*>(this) == JS::RootingContext::get(this)); } @@ -1537,6 +1538,12 @@ void JSContext::trace(JSTracer* trc) { #ifdef ENABLE_WASM_JSPI wasm().promiseIntegration.trace(trc); #endif + + // Skip tracing the microtask queues on minor GC as we will be updating + // nursery pointers through the store buffer instead. + if (!trc->isTenuringTracer() && microTaskQueues) { + microTaskQueues->trace(trc); + } } JS::NativeStackLimit JSContext::stackLimitForJitCode(JS::StackKind kind) { diff --git a/js/src/vm/JSContext.h b/js/src/vm/JSContext.h @@ -166,7 +166,7 @@ struct MicroTaskQueueElement { void trace(JSTracer* trc); private: - JS::Value value; + js::HeapPtr<JS::Value> value; }; // Use TempAllocPolicy to report OOM @@ -1070,7 +1070,7 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext, bool hasExecutionTracer() { return false; } #endif - JS::PersistentRooted<js::UniquePtr<js::MicroTaskQueueSet>> microTaskQueues; + js::UniquePtr<js::MicroTaskQueueSet> microTaskQueues; }; /* struct JSContext */ inline JSContext* JSRuntime::mainContextFromOwnThread() { diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml @@ -9424,9 +9424,11 @@ do_not_use_directly: true # Use the JS microtask queue for Promise jobs and other microtasks. +# DO NOT TURN THIS ON BY DEFAULT WITHOUT THE BUGS BLOCKING +# BUG 1990841 being fixed (especially Bug 1990842). - name: javascript.options.use_js_microtask_queue type: RelaxedAtomicBool - value: true + value: false # Changing this mid process will break invariants and crash, however # making this mirror: once, and set_spidermonkey_pref: startup is # broken: See Bug 1989094 diff --git a/xpcom/base/CycleCollectedJSContext.cpp b/xpcom/base/CycleCollectedJSContext.cpp @@ -1197,7 +1197,7 @@ bool CycleCollectedJSContext::PerformMicroTaskCheckPoint(bool aForce) { while (JS::HasAnyMicroTasks(cx)) { MOZ_ASSERT(mDebuggerMicroTaskQueue.empty()); MOZ_ASSERT(mPendingMicroTaskRunnables.empty()); - job.set(DequeueNextMicroTask(cx)); + job = DequeueNextMicroTask(cx); // To avoid us accidentally re-enqueing a SuppressionMicroTaskList in // itself, we determine here if the job is actually the suppression task @@ -1327,11 +1327,11 @@ void CycleCollectedJSContext::PerformDebuggerMicroTaskCheckpoint() { JSContext* cx = Context(); if (StaticPrefs::javascript_options_use_js_microtask_queue()) { - JS::Rooted<MustConsumeMicroTask> job(cx); while (JS::HasDebuggerMicroTasks(cx)) { MOZ_ASSERT(mDebuggerMicroTaskQueue.empty()); MOZ_ASSERT(mPendingMicroTaskRunnables.empty()); + JS::Rooted<MustConsumeMicroTask> job(cx); job.set(DequeueNextDebuggerMicroTask(cx)); RunMicroTask(cx, &job); diff --git a/xpcom/base/CycleCollectedJSContext.h b/xpcom/base/CycleCollectedJSContext.h @@ -109,9 +109,7 @@ class SuppressedMicroTasks : public MicroTaskRunnable { // A gecko wrapper for the JS::MicroTask type. Used to enforce both // that this is handled move only, but also that we have succesfully // consumed this microtask before destruction. -// -// This type must be rooted, it holds onto a JS reference. -class MOZ_STACK_CLASS MustConsumeMicroTask { +class MustConsumeMicroTask { public: // We need a public constructor to allow forward declared Rooted MustConsumeMicroTask() = default; @@ -255,14 +253,14 @@ class MOZ_STACK_CLASS MustConsumeMicroTask { } void trace(JSTracer* aTrc) { - TraceRoot(aTrc, &mMicroTask, "MustConsumeMicroTask value"); + TraceEdge(aTrc, &mMicroTask, "MustConsumeMicroTask value"); } private: explicit MustConsumeMicroTask(JS::GenericMicroTask&& aMicroTask) : mMicroTask(aMicroTask) {} - JS::GenericMicroTask mMicroTask; + JS::Heap<JS::GenericMicroTask> mMicroTask; }; class SuppressedMicroTaskList final : public MicroTaskRunnable {