Bug 1405821 - Move microtask handling to CycleCollectedJSContext

Tag UXP Issue #1344
This commit is contained in:
Gaming4JC 2020-01-22 19:28:33 -05:00 committed by Roy Tam
commit fb6f6ec903
11 changed files with 100 additions and 84 deletions

View file

@ -79,6 +79,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsCycleCollector.h"
#include "nsDOMJSUtils.h"
#include "nsDOMMutationObserver.h"
#include "nsJSUtils.h"
#include "nsWrapperCache.h"
@ -438,6 +439,7 @@ CycleCollectedJSContext::CycleCollectedJSContext()
, mJSHolders(256)
, mDoingStableStates(false)
, mDisableMicroTaskCheckpoint(false)
, mMicroTaskLevel(0)
, mOutOfMemoryState(OOMState::OK)
, mLargeAllocationFailureState(OOMState::OK)
{
@ -1379,7 +1381,7 @@ CycleCollectedJSContext::AfterProcessTask(uint32_t aRecursionDepth)
// Step 4.1: Execute microtasks.
if (!mDisableMicroTaskCheckpoint) {
if (NS_IsMainThread()) {
nsContentUtils::PerformMainThreadMicroTaskCheckpoint();
PerformMainThreadMicroTaskCheckpoint();
Promise::PerformMicroTaskCheckpoint();
} else {
Promise::PerformWorkerMicroTaskCheckpoint();
@ -1659,6 +1661,14 @@ CycleCollectedJSContext::DispatchToMicroTask(already_AddRefed<nsIRunnable> aRunn
mPromiseMicroTaskQueue.push(runnable.forget());
}
void
CycleCollectedJSContext::PerformMainThreadMicroTaskCheckpoint()
{
MOZ_ASSERT(NS_IsMainThread());
nsDOMMutationObserver::HandleMutations();
}
void
CycleCollectedJSContext::EnvironmentPreparer::invoke(JS::HandleObject scope,
js::ScriptEnvironmentPreparer::Closure& closure)

View file

@ -402,6 +402,37 @@ public:
// Queue an async microtask to the current main or worker thread.
virtual void DispatchToMicroTask(already_AddRefed<nsIRunnable> aRunnable);
// Call EnterMicroTask when you're entering JS execution.
// Usually the best way to do this is to use nsAutoMicroTask.
void EnterMicroTask()
{
++mMicroTaskLevel;
}
void LeaveMicroTask()
{
if (--mMicroTaskLevel == 0) {
PerformMainThreadMicroTaskCheckpoint();
}
}
bool IsInMicroTask()
{
return mMicroTaskLevel != 0;
}
uint32_t MicroTaskLevel()
{
return mMicroTaskLevel;
}
void SetMicroTaskLevel(uint32_t aLevel)
{
mMicroTaskLevel = aLevel;
}
void PerformMainThreadMicroTaskCheckpoint();
// Storage for watching rejected promises waiting for some client to
// consume their rejection.
@ -452,6 +483,7 @@ private:
bool mDisableMicroTaskCheckpoint;
uint32_t mMicroTaskLevel;
OOMState mOutOfMemoryState;
OOMState mLargeAllocationFailureState;
@ -470,6 +502,25 @@ private:
EnvironmentPreparer mEnvironmentPreparer;
};
class MOZ_STACK_CLASS nsAutoMicroTask
{
public:
nsAutoMicroTask()
{
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (ccjs) {
ccjs->EnterMicroTask();
}
}
~nsAutoMicroTask()
{
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (ccjs) {
ccjs->LeaveMicroTask();
}
}
};
void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer);
// Returns true if the JS::TraceKind is one the cycle collector cares about.

View file

@ -152,6 +152,7 @@ FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'../build',
'/dom/base',
'/xpcom/ds',
]