Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
roytam1 2024-01-09 12:01:14 +08:00
commit d4a80aa2c4
42 changed files with 538 additions and 364 deletions

View file

@ -1007,6 +1007,10 @@ public:
: mWorkerPrivate(aWorkerPrivate)
{
MOZ_ASSERT(aWorkerPrivate);
// Magical number 2. Workers have the base recursion depth 1, and normal
// runnables run at level 2, and we don't want to process microtasks
// at any other level.
SetTargetedMicroTaskRecursionDepth(2);
}
~WorkerJSContext()
@ -1092,26 +1096,14 @@ public:
}
}
virtual void AfterProcessTask(uint32_t aRecursionDepth) override
virtual void DispatchToMicroTask(already_AddRefed<MicroTaskRunnable> aRunnable) override
{
// Only perform the Promise microtask checkpoint on the outermost event
// loop. Don't run it, for example, during sync XHR or importScripts.
if (aRecursionDepth == 2) {
CycleCollectedJSContext::AfterProcessTask(aRecursionDepth);
} else if (aRecursionDepth > 2) {
AutoDisableMicroTaskCheckpoint disableMicroTaskCheckpoint;
CycleCollectedJSContext::AfterProcessTask(aRecursionDepth);
}
}
virtual void DispatchToMicroTask(already_AddRefed<nsIRunnable> aRunnable) override
{
RefPtr<nsIRunnable> runnable(aRunnable);
RefPtr<MicroTaskRunnable> runnable(aRunnable);
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(runnable);
std::queue<nsCOMPtr<nsIRunnable>>* microTaskQueue = nullptr;
std::queue<RefPtr<MicroTaskRunnable>>* microTaskQueue = nullptr;
JSContext* cx = GetCurrentThreadJSContext();
NS_ASSERTION(cx, "This should never be null!");
@ -1120,15 +1112,15 @@ public:
NS_ASSERTION(global, "This should never be null!");
// On worker threads, if the current global is the worker global, we use the
// main promise micro task queue. Otherwise, the current global must be
// main micro task queue. Otherwise, the current global must be
// either the debugger global or a debugger sandbox, and we use the debugger
// promise micro task queue instead.
// micro task queue instead.
if (IsWorkerGlobal(global)) {
microTaskQueue = &mPromiseMicroTaskQueue;
microTaskQueue = &GetMicroTaskQueue();
} else {
MOZ_ASSERT(IsDebuggerGlobal(global) || IsDebuggerSandbox(global));
microTaskQueue = &mDebuggerPromiseMicroTaskQueue;
microTaskQueue = &GetDebuggerMicroTaskQueue();
}
microTaskQueue->push(runnable.forget());

View file

@ -40,6 +40,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/Likely.h"
#include "mozilla/LoadContext.h"
@ -4815,8 +4816,10 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
static_cast<nsIRunnable*>(runnable)->Run();
runnable->Release();
// Flush the promise queue.
Promise::PerformWorkerDebuggerMicroTaskCheckpoint();
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (ccjs) {
ccjs->PerformDebuggerMicroTaskCheckpoint();
}
if (debuggerRunnablesPending) {
WorkerDebuggerGlobalScope* globalScope = DebuggerGlobalScope();
@ -5802,8 +5805,12 @@ WorkerPrivate::EnterDebuggerEventLoop()
{
MutexAutoLock lock(mMutex);
CycleCollectedJSContext* context = CycleCollectedJSContext::Get();
std::queue<RefPtr<MicroTaskRunnable>>& debuggerMtQueue =
context->GetDebuggerMicroTaskQueue();
while (mControlQueue.IsEmpty() &&
!(debuggerRunnablesPending = !mDebuggerQueue.IsEmpty())) {
!(debuggerRunnablesPending = !mDebuggerQueue.IsEmpty()) &&
debuggerMtQueue.empty()) {
WaitForWorkerEvents();
}
@ -5812,6 +5819,11 @@ WorkerPrivate::EnterDebuggerEventLoop()
// XXXkhuey should we abort JS on the stack here if we got Abort above?
}
CycleCollectedJSContext* context = CycleCollectedJSContext::Get();
if (context) {
context->PerformDebuggerMicroTaskCheckpoint();
}
if (debuggerRunnablesPending) {
// Start the periodic GC timer if it is not already running.
SetGCTimerMode(PeriodicTimer);
@ -5828,8 +5840,10 @@ WorkerPrivate::EnterDebuggerEventLoop()
static_cast<nsIRunnable*>(runnable)->Run();
runnable->Release();
// Flush the promise queue.
Promise::PerformWorkerDebuggerMicroTaskCheckpoint();
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (ccjs) {
ccjs->PerformDebuggerMicroTaskCheckpoint();
}
// Now *might* be a good time to GC. Let the JS engine make the decision.
if (JS::CurrentGlobalOrNull(cx)) {
@ -6256,8 +6270,8 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
RefPtr<Function> callback = info->mHandler->GetCallback();
if (!callback) {
// scope for the AutoEntryScript, so it comes off the stack before we do
// Promise::PerformMicroTaskCheckpoint.
nsAutoMicroTask mt;
AutoEntryScript aes(global, reason, false);
// Evaluate the timeout expression.
@ -6292,10 +6306,6 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
rv.SuppressException();
}
// Since we might be processing more timeouts, go ahead and flush
// the promise queue now before we do that.
Promise::PerformWorkerMicroTaskCheckpoint();
NS_ASSERTION(mRunningExpiredTimeouts, "Someone changed this!");
}

View file

@ -151,6 +151,8 @@ public:
IMPL_EVENT_HANDLER(online)
IMPL_EVENT_HANDLER(offline)
IMPL_EVENT_HANDLER(rejectionhandled)
IMPL_EVENT_HANDLER(unhandledrejection)
void
Dump(const Optional<nsAString>& aString) const;