diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2020-01-22 19:28:33 -0500 |
---|---|---|
committer | Gaming4JC <g4jc@hyperbola.info> | 2020-01-26 15:50:49 -0500 |
commit | 43a8113072b96affb2b7a3a7a4e965547d3d0c41 (patch) | |
tree | dd685edd37f2bffec27c55060e50ba8289e05760 | |
parent | 14d115cfe32ab72b7193a4fb74e13c06c6d4cc8f (diff) | |
download | uxp-43a8113072b96affb2b7a3a7a4e965547d3d0c41.tar.gz |
Bug 1405821 - Move microtask handling to CycleCollectedJSContext
Tag UXP Issue #1344
-rw-r--r-- | dom/base/CustomElementRegistry.cpp | 1 | ||||
-rw-r--r-- | dom/base/nsContentUtils.cpp | 46 | ||||
-rw-r--r-- | dom/base/nsContentUtils.h | 25 | ||||
-rw-r--r-- | dom/base/nsDocument.cpp | 13 | ||||
-rw-r--r-- | dom/base/nsJSUtils.cpp | 11 | ||||
-rw-r--r-- | dom/bindings/CallbackObject.cpp | 11 | ||||
-rw-r--r-- | dom/events/EventListenerManager.cpp | 10 | ||||
-rw-r--r-- | dom/jsurl/nsJSProtocolHandler.cpp | 3 | ||||
-rw-r--r-- | xpcom/base/CycleCollectedJSContext.cpp | 12 | ||||
-rw-r--r-- | xpcom/base/CycleCollectedJSContext.h | 51 | ||||
-rw-r--r-- | xpcom/base/moz.build | 1 |
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', ] |