summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2020-01-22 19:28:33 -0500
committerGaming4JC <g4jc@hyperbola.info>2020-01-26 15:50:49 -0500
commit43a8113072b96affb2b7a3a7a4e965547d3d0c41 (patch)
treedd685edd37f2bffec27c55060e50ba8289e05760
parent14d115cfe32ab72b7193a4fb74e13c06c6d4cc8f (diff)
downloaduxp-43a8113072b96affb2b7a3a7a4e965547d3d0c41.tar.gz
Bug 1405821 - Move microtask handling to CycleCollectedJSContext
Tag UXP Issue #1344
-rw-r--r--dom/base/CustomElementRegistry.cpp1
-rw-r--r--dom/base/nsContentUtils.cpp46
-rw-r--r--dom/base/nsContentUtils.h25
-rw-r--r--dom/base/nsDocument.cpp13
-rw-r--r--dom/base/nsJSUtils.cpp11
-rw-r--r--dom/bindings/CallbackObject.cpp11
-rw-r--r--dom/events/EventListenerManager.cpp10
-rw-r--r--dom/jsurl/nsJSProtocolHandler.cpp3
-rw-r--r--xpcom/base/CycleCollectedJSContext.cpp12
-rw-r--r--xpcom/base/CycleCollectedJSContext.h51
-rw-r--r--xpcom/base/moz.build1
11 files changed, 100 insertions, 84 deletions
diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp
index 2d7907bd73..ab1e603660 100644
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -6,6 +6,7 @@
#include "mozilla/dom/CustomElementRegistry.h"
+#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/dom/CustomElementRegistryBinding.h"
#include "mozilla/dom/HTMLElementBinding.h"
#include "mozilla/dom/WebComponentsBinding.h"
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 87c879746a..402dfd1c5b 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -259,7 +259,6 @@ nsIWordBreaker *nsContentUtils::sWordBreaker;
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nullptr;
uint32_t nsContentUtils::sScriptBlockerCount = 0;
uint32_t nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
-uint32_t nsContentUtils::sMicroTaskLevel = 0;
AutoTArray<nsCOMPtr<nsIRunnable>, 8>* nsContentUtils::sBlockedScriptRunners = nullptr;
uint32_t nsContentUtils::sRunnersCountAtFirstBlocker = 0;
nsIInterfaceRequestor* nsContentUtils::sSameOriginChecker = nullptr;
@@ -5302,51 +5301,6 @@ nsContentUtils::RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable)
CycleCollectedJSContext::Get()->RunInMetastableState(Move(aRunnable));
}
-void
-nsContentUtils::EnterMicroTask()
-{
- MOZ_ASSERT(NS_IsMainThread());
- ++sMicroTaskLevel;
-}
-
-void
-nsContentUtils::LeaveMicroTask()
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (--sMicroTaskLevel == 0) {
- PerformMainThreadMicroTaskCheckpoint();
- }
-}
-
-bool
-nsContentUtils::IsInMicroTask()
-{
- MOZ_ASSERT(NS_IsMainThread());
- return sMicroTaskLevel != 0;
-}
-
-uint32_t
-nsContentUtils::MicroTaskLevel()
-{
- MOZ_ASSERT(NS_IsMainThread());
- return sMicroTaskLevel;
-}
-
-void
-nsContentUtils::SetMicroTaskLevel(uint32_t aLevel)
-{
- MOZ_ASSERT(NS_IsMainThread());
- sMicroTaskLevel = aLevel;
-}
-
-void
-nsContentUtils::PerformMainThreadMicroTaskCheckpoint()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- nsDOMMutationObserver::HandleMutations();
-}
-
/*
* Helper function for nsContentUtils::ProcessViewportInfo.
*
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 19b0075915..4200a06213 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1740,17 +1740,6 @@ public:
*/
static void RunInMetastableState(already_AddRefed<nsIRunnable> aRunnable);
- // Call EnterMicroTask when you're entering JS execution.
- // Usually the best way to do this is to use nsAutoMicroTask.
- static void EnterMicroTask();
- static void LeaveMicroTask();
-
- static bool IsInMicroTask();
- static uint32_t MicroTaskLevel();
- static void SetMicroTaskLevel(uint32_t aLevel);
-
- static void PerformMainThreadMicroTaskCheckpoint();
-
/* Process viewport META data. This gives us information for the scale
* and zoom of a page on mobile devices. We stick the information in
* the document header and use it later on after rendering.
@@ -2850,7 +2839,6 @@ private:
static bool sInitialized;
static uint32_t sScriptBlockerCount;
static uint32_t sDOMNodeRemovedSuppressCount;
- static uint32_t sMicroTaskLevel;
// Not an nsCOMArray because removing elements from those is slower
static AutoTArray<nsCOMPtr<nsIRunnable>, 8>* sBlockedScriptRunners;
static uint32_t sRunnersCountAtFirstBlocker;
@@ -2928,19 +2916,6 @@ public:
}
};
-class MOZ_STACK_CLASS nsAutoMicroTask
-{
-public:
- nsAutoMicroTask()
- {
- nsContentUtils::EnterMicroTask();
- }
- ~nsAutoMicroTask()
- {
- nsContentUtils::LeaveMicroTask();
- }
-};
-
namespace mozilla {
namespace dom {
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index f3e4925893..293e48eb0d 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12610,8 +12610,12 @@ MarkDocumentTreeToBeInSyncOperation(nsIDocument* aDoc, void* aData)
nsAutoSyncOperation::nsAutoSyncOperation(nsIDocument* aDoc)
{
- mMicroTaskLevel = nsContentUtils::MicroTaskLevel();
- nsContentUtils::SetMicroTaskLevel(0);
+ mMicroTaskLevel = 0;
+ CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
+ if (ccjs) {
+ mMicroTaskLevel = ccjs->MicroTaskLevel();
+ ccjs->SetMicroTaskLevel(0);
+ }
if (aDoc) {
if (nsPIDOMWindowOuter* win = aDoc->GetWindow()) {
if (nsCOMPtr<nsPIDOMWindowOuter> top = win->GetTop()) {
@@ -12627,7 +12631,10 @@ nsAutoSyncOperation::~nsAutoSyncOperation()
for (int32_t i = 0; i < mDocuments.Count(); ++i) {
mDocuments[i]->SetIsInSyncOperation(false);
}
- nsContentUtils::SetMicroTaskLevel(mMicroTaskLevel);
+ CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
+ if (ccjs) {
+ ccjs->SetMicroTaskLevel(mMicroTaskLevel);
+ }
}
gfxUserFontSet*
diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp
index 98b367b663..b6c8430657 100644
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -25,7 +25,7 @@
#include "xpcpublic.h"
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
-
+#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Date.h"
#include "mozilla/dom/Element.h"
@@ -159,7 +159,8 @@ nsJSUtils::EvaluateString(JSContext* aCx,
aEvaluationGlobal);
MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(nsContentUtils::IsInMicroTask());
+ MOZ_ASSERT(CycleCollectedJSContext::Get() &&
+ CycleCollectedJSContext::Get()->MicroTaskLevel());
// Unfortunately, the JS engine actually compiles scripts with a return value
// in a different, less efficient way. Furthermore, it can't JIT them in many
@@ -293,7 +294,8 @@ nsJSUtils::CompileModule(JSContext* aCx,
aEvaluationGlobal);
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(nsContentUtils::IsInMicroTask());
+ MOZ_ASSERT(CycleCollectedJSContext::Get() &&
+ CycleCollectedJSContext::Get()->MicroTaskLevel());
NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK);
@@ -330,7 +332,8 @@ nsJSUtils::ModuleEvaluation(JSContext* aCx, JS::Handle<JSObject*> aModule)
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(nsContentUtils::IsInMicroTask());
+ MOZ_ASSERT(CycleCollectedJSContext::Get() &&
+ CycleCollectedJSContext::Get()->MicroTaskLevel());
NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp
index bb01c804c4..398acf9da3 100644
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/CallbackObject.h"
+#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "jsfriendapi.h"
#include "nsIScriptGlobalObject.h"
@@ -79,7 +80,10 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
, mIsMainThread(NS_IsMainThread())
{
if (mIsMainThread) {
- nsContentUtils::EnterMicroTask();
+ CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
+ if (ccjs) {
+ ccjs->EnterMicroTask();
+ }
}
// Compute the caller's subject principal (if necessary) early, before we
@@ -288,7 +292,10 @@ CallbackObject::CallSetup::~CallSetup()
// It is important that this is the last thing we do, after leaving the
// compartment and undoing all our entry/incumbent script changes
if (mIsMainThread) {
- nsContentUtils::LeaveMicroTask();
+ CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
+ if (ccjs) {
+ ccjs->LeaveMicroTask();
+ }
}
}
diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp
index 0774c32966..2add7d0090 100644
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -1087,7 +1087,10 @@ EventListenerManager::HandleEventSubType(Listener* aListener,
if (NS_SUCCEEDED(result)) {
if (mIsMainThreadELM) {
- nsContentUtils::EnterMicroTask();
+ CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
+ if (ccjs) {
+ ccjs->EnterMicroTask();
+ }
}
// nsIDOMEvent::currentTarget is set in EventDispatcher.
if (listenerHolder.HasWebIDLCallback()) {
@@ -1099,7 +1102,10 @@ EventListenerManager::HandleEventSubType(Listener* aListener,
result = listenerHolder.GetXPCOMCallback()->HandleEvent(aDOMEvent);
}
if (mIsMainThreadELM) {
- nsContentUtils::LeaveMicroTask();
+ CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
+ if (ccjs) {
+ ccjs->LeaveMicroTask();
+ }
}
}
diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp
index 90171db102..df1e6cbf5c 100644
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -46,6 +46,7 @@
#include "nsIWritablePropertyBag2.h"
#include "nsIContentSecurityPolicy.h"
#include "nsSandboxFlags.h"
+#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsILoadInfo.h"
#include "nsContentSecurityManager.h"
@@ -241,7 +242,7 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
// New script entry point required, due to the "Create a script" step of
// http://www.whatwg.org/specs/web-apps/current-work/#javascript-protocol
- nsAutoMicroTask mt;
+ mozilla::nsAutoMicroTask mt;
AutoEntryScript aes(innerGlobal, "javascript: URI", true);
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> globalJSObject(cx, innerGlobal->GetGlobalJSObject());
diff --git a/xpcom/base/CycleCollectedJSContext.cpp b/xpcom/base/CycleCollectedJSContext.cpp
index e16c154554..0a85ae6ac6 100644
--- a/xpcom/base/CycleCollectedJSContext.cpp
+++ b/xpcom/base/CycleCollectedJSContext.cpp
@@ -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();
@@ -1660,6 +1662,14 @@ CycleCollectedJSContext::DispatchToMicroTask(already_AddRefed<nsIRunnable> aRunn
}
void
+CycleCollectedJSContext::PerformMainThreadMicroTaskCheckpoint()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsDOMMutationObserver::HandleMutations();
+}
+
+void
CycleCollectedJSContext::EnvironmentPreparer::invoke(JS::HandleObject scope,
js::ScriptEnvironmentPreparer::Closure& closure)
{
diff --git a/xpcom/base/CycleCollectedJSContext.h b/xpcom/base/CycleCollectedJSContext.h
index ac4cf43617..2197eae920 100644
--- a/xpcom/base/CycleCollectedJSContext.h
+++ b/xpcom/base/CycleCollectedJSContext.h
@@ -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.
diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build
index d6a336b409..0fdf47d7d5 100644
--- a/xpcom/base/moz.build
+++ b/xpcom/base/moz.build
@@ -152,6 +152,7 @@ FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'../build',
+ '/dom/base',
'/xpcom/ds',
]