From 13ebe0048049ef64e051c8544c1f92ab10c6c41f Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Mon, 28 Oct 2019 14:38:03 +0000 Subject: [PATCH] Bug 1591923 - Remove some dead code for cooperative contexts from XPConnect, XPCOM and JSAPI. r=mccr8 Differential Revision: https://phabricator.services.mozilla.com/D50802 --- js/src/jsapi.cpp | 12 ----- js/src/jsapi.h | 24 +-------- js/xpconnect/src/XPCJSContext.cpp | 19 +++---- js/xpconnect/src/nsXPConnect.cpp | 30 +++-------- js/xpconnect/src/xpcprivate.h | 4 +- js/xpconnect/src/xpcpublic.h | 10 ---- xpcom/base/CycleCollectedJSContext.cpp | 72 +++++++------------------- xpcom/base/CycleCollectedJSContext.h | 13 ----- xpcom/base/nsCycleCollector.cpp | 39 -------------- xpcom/base/nsCycleCollector.h | 5 -- 10 files changed, 34 insertions(+), 194 deletions(-) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index baf2583c68efb..f1310ad49b6ed 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -369,18 +369,6 @@ JS_PUBLIC_API JSContext* JS_NewContext(uint32_t maxbytes, return NewContext(maxbytes, parentRuntime); } -JS_PUBLIC_API JSContext* JS_NewCooperativeContext(JSContext* siblingContext) { - MOZ_CRASH("Cooperative scheduling is unsupported"); -} - -JS_PUBLIC_API void JS_YieldCooperativeContext(JSContext* cx) { - MOZ_CRASH("Cooperative scheduling is unsupported"); -} - -JS_PUBLIC_API void JS_ResumeCooperativeContext(JSContext* cx) { - MOZ_CRASH("Cooperative scheduling is unsupported"); -} - JS_PUBLIC_API void JS_DestroyContext(JSContext* cx) { DestroyContext(cx); } JS_PUBLIC_API void* JS_GetContextPrivate(JSContext* cx) { return cx->data; } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 57bfecd606eee..c013b5f5d9d2e 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -329,28 +329,8 @@ extern JS_PUBLIC_API bool JS_IsBuiltinFunctionConstructor(JSFunction* fun); extern JS_PUBLIC_API JSContext* JS_NewContext( uint32_t maxbytes, JSRuntime* parentRuntime = nullptr); -// The methods below for controlling the active context in a cooperatively -// multithreaded runtime are not threadsafe, and the caller must ensure they -// are called serially if there is a chance for contention between threads. - -// Called from the active context for a runtime, yield execution so that -// this context is no longer active and can no longer use the API. -extern JS_PUBLIC_API void JS_YieldCooperativeContext(JSContext* cx); - -// Called from a context whose runtime has no active context, this thread -// becomes the active context for that runtime and may use the API. -extern JS_PUBLIC_API void JS_ResumeCooperativeContext(JSContext* cx); - -// Create a new context on this thread for cooperative multithreading in the -// same runtime as siblingContext. Called on a runtime (as indicated by -// siblingContet) which has no active context, on success the new context will -// become the runtime's active context. -extern JS_PUBLIC_API JSContext* JS_NewCooperativeContext( - JSContext* siblingContext); - -// Destroy a context allocated with JS_NewContext or JS_NewCooperativeContext. -// The context must be the current active context in the runtime, and after -// this call the runtime will have no active context. +// Destroy a context allocated with JS_NewContext. Must be called on the thread +// that called JS_NewContext. extern JS_PUBLIC_API void JS_DestroyContext(JSContext* cx); JS_PUBLIC_API void* JS_GetContextPrivate(JSContext* cx); diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index 2751797be6b19..2f9c9b5d42ef7 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -1097,14 +1097,9 @@ CycleCollectedJSRuntime* XPCJSContext::CreateRuntime(JSContext* aCx) { return new XPCJSRuntime(aCx); } -nsresult XPCJSContext::Initialize(XPCJSContext* aPrimaryContext) { - nsresult rv; - if (aPrimaryContext) { - rv = CycleCollectedJSContext::InitializeNonPrimary(aPrimaryContext); - } else { - rv = CycleCollectedJSContext::Initialize(nullptr, JS::DefaultHeapMaxBytes, - JS::DefaultNurseryMaxBytes); - } +nsresult XPCJSContext::Initialize() { + nsresult rv = CycleCollectedJSContext::Initialize( + nullptr, JS::DefaultHeapMaxBytes, JS::DefaultNurseryMaxBytes); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -1251,9 +1246,7 @@ nsresult XPCJSContext::Initialize(XPCJSContext* aPrimaryContext) { JS_AddInterruptCallback(cx, InterruptCallback); - if (!aPrimaryContext) { - Runtime()->Initialize(cx); - } + Runtime()->Initialize(cx); LoadStartupJSPrefs(this); @@ -1290,9 +1283,9 @@ WatchdogManager* XPCJSContext::GetWatchdogManager() { void XPCJSContext::InitTLS() { MOZ_RELEASE_ASSERT(gTlsContext.init()); } // static -XPCJSContext* XPCJSContext::NewXPCJSContext(XPCJSContext* aPrimaryContext) { +XPCJSContext* XPCJSContext::NewXPCJSContext() { XPCJSContext* self = new XPCJSContext(); - nsresult rv = self->Initialize(aPrimaryContext); + nsresult rv = self->Initialize(); if (NS_FAILED(rv)) { MOZ_CRASH("new XPCJSContext failed to initialize."); } diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index d63b0c97ea02e..a86435118f184 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -61,8 +61,8 @@ const char XPC_SCRIPT_ERROR_CONTRACTID[] = "@mozilla.org/scripterror;1"; /***************************************************************************/ // This global should be used very sparingly: only to create and destroy -// nsXPConnect and when creating a new cooperative (non-primary) XPCJSContext. -static XPCJSContext* gPrimaryContext; +// nsXPConnect. +static XPCJSContext* gContext; nsXPConnect::nsXPConnect() : mShuttingDown(false) { XPCJSContext::InitTLS(); @@ -72,16 +72,16 @@ nsXPConnect::nsXPConnect() : mShuttingDown(false) { profiler_unregister_thread); #endif - XPCJSContext* xpccx = XPCJSContext::NewXPCJSContext(nullptr); + XPCJSContext* xpccx = XPCJSContext::NewXPCJSContext(); if (!xpccx) { MOZ_CRASH("Couldn't create XPCJSContext."); } - gPrimaryContext = xpccx; + gContext = xpccx; mRuntime = xpccx->Runtime(); } nsXPConnect::~nsXPConnect() { - MOZ_ASSERT(XPCJSContext::Get() == gPrimaryContext); + MOZ_ASSERT(XPCJSContext::Get() == gContext); mRuntime->DeleteSingletonScopes(); @@ -109,7 +109,7 @@ nsXPConnect::~nsXPConnect() { // shutdown the logging system XPC_LOG_FINISH(); - delete gPrimaryContext; + delete gContext; MOZ_ASSERT(gSelf == this); gSelf = nullptr; @@ -1196,24 +1196,6 @@ bool ThreadSafeIsChromeOrXBLOrUAWidget(JSContext* cx, JSObject* obj) { } // namespace dom } // namespace mozilla -void xpc::CreateCooperativeContext() { - MOZ_ASSERT(gPrimaryContext); - XPCJSContext::NewXPCJSContext(gPrimaryContext); -} - -void xpc::DestroyCooperativeContext() { - MOZ_ASSERT(XPCJSContext::Get() != gPrimaryContext); - delete XPCJSContext::Get(); -} - -void xpc::YieldCooperativeContext() { - JS_YieldCooperativeContext(XPCJSContext::Get()->Context()); -} - -void xpc::ResumeCooperativeContext() { - JS_ResumeCooperativeContext(XPCJSContext::Get()->Context()); -} - void xpc::CacheAutomationPref(bool* aMirror) { // The obvious thing is to make this pref a static pref. But then it would // always be defined and always show up in about:config, and users could flip diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 691e80e56af00..52d06e73c7f40 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -313,7 +313,7 @@ class XPCJSContext final : public mozilla::CycleCollectedJSContext, public mozilla::LinkedListElement { public: static void InitTLS(); - static XPCJSContext* NewXPCJSContext(XPCJSContext* aPrimaryContext); + static XPCJSContext* NewXPCJSContext(); static XPCJSContext* Get(); XPCJSRuntime* Runtime() const; @@ -425,7 +425,7 @@ class XPCJSContext final : public mozilla::CycleCollectedJSContext, XPCJSContext(); MOZ_IS_CLASS_INIT - nsresult Initialize(XPCJSContext* aPrimaryContext); + nsresult Initialize(); XPCCallContext* mCallContext; AutoMarkingPtr* mAutoRoots; diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index bbfb8c75c763f..fa83f7a947eae 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -700,16 +700,6 @@ inline bool IsInAutomation() { return sAutomationPrefIsSet && AreNonLocalConnectionsDisabled(); } -void CreateCooperativeContext(); - -void DestroyCooperativeContext(); - -// Please see JS_YieldCooperativeContext in jsapi.h. -void YieldCooperativeContext(); - -// Please see JS_ResumeCooperativeContext in jsapi.h. -void ResumeCooperativeContext(); - /** * Extract the native nsID object from a JS ID, IfaceID, ClassID, or ContractID * value. diff --git a/xpcom/base/CycleCollectedJSContext.cpp b/xpcom/base/CycleCollectedJSContext.cpp index 9a8e6d33cd184..aeed31dd6ee40 100644 --- a/xpcom/base/CycleCollectedJSContext.cpp +++ b/xpcom/base/CycleCollectedJSContext.cpp @@ -53,8 +53,7 @@ using namespace mozilla::dom; namespace mozilla { CycleCollectedJSContext::CycleCollectedJSContext() - : mIsPrimaryContext(true), - mRuntime(nullptr), + : mRuntime(nullptr), mJSContext(nullptr), mDoingStableStates(false), mTargetedMicroTaskRecursionDepth(0), @@ -82,10 +81,7 @@ CycleCollectedJSContext::~CycleCollectedJSContext() { JS_SetContextPrivate(mJSContext, nullptr); mRuntime->RemoveContext(this); - - if (mIsPrimaryContext) { - mRuntime->Shutdown(mJSContext); - } + mRuntime->Shutdown(mJSContext); // Last chance to process any events. CleanupIDBTransactions(mBaseRecursionDepth); @@ -109,24 +105,31 @@ CycleCollectedJSContext::~CycleCollectedJSContext() { JS_DestroyContext(mJSContext); mJSContext = nullptr; - if (mIsPrimaryContext) { - nsCycleCollector_forgetJSContext(); - } else { - nsCycleCollector_forgetNonPrimaryContext(); - } + nsCycleCollector_forgetJSContext(); mozilla::dom::DestroyScriptSettings(); mOwningThread->SetScriptObserver(nullptr); NS_RELEASE(mOwningThread); - if (mIsPrimaryContext) { - delete mRuntime; - } + delete mRuntime; mRuntime = nullptr; } -void CycleCollectedJSContext::InitializeCommon() { +nsresult CycleCollectedJSContext::Initialize(JSRuntime* aParentRuntime, + uint32_t aMaxBytes, + uint32_t aMaxNurseryBytes) { + MOZ_ASSERT(!mJSContext); + + mozilla::dom::InitScriptSettings(); + mJSContext = JS_NewContext(aMaxBytes, aParentRuntime); + if (!mJSContext) { + return NS_ERROR_OUT_OF_MEMORY; + } + + JS_SetGCParameter(mJSContext, JSGC_MAX_NURSERY_BYTES, aMaxNurseryBytes); + + mRuntime = CreateRuntime(mJSContext); mRuntime->AddContext(this); mOwningThread->SetScriptObserver(this); @@ -147,51 +150,12 @@ void CycleCollectedJSContext::InitializeCommon() { // Cast to PerThreadAtomCache for dom::GetAtomCache(JSContext*). JS_SetContextPrivate(mJSContext, static_cast(this)); -} - -nsresult CycleCollectedJSContext::Initialize(JSRuntime* aParentRuntime, - uint32_t aMaxBytes, - uint32_t aMaxNurseryBytes) { - MOZ_ASSERT(!mJSContext); - - mozilla::dom::InitScriptSettings(); - mJSContext = JS_NewContext(aMaxBytes, aParentRuntime); - if (!mJSContext) { - return NS_ERROR_OUT_OF_MEMORY; - } - - JS_SetGCParameter(mJSContext, JSGC_MAX_NURSERY_BYTES, aMaxNurseryBytes); - - mRuntime = CreateRuntime(mJSContext); - - InitializeCommon(); nsCycleCollector_registerJSContext(this); return NS_OK; } -nsresult CycleCollectedJSContext::InitializeNonPrimary( - CycleCollectedJSContext* aPrimaryContext) { - MOZ_ASSERT(!mJSContext); - - mIsPrimaryContext = false; - - mozilla::dom::InitScriptSettings(); - mJSContext = JS_NewCooperativeContext(aPrimaryContext->mJSContext); - if (!mJSContext) { - return NS_ERROR_OUT_OF_MEMORY; - } - - mRuntime = aPrimaryContext->mRuntime; - - InitializeCommon(); - - nsCycleCollector_registerNonPrimaryContext(this); - - return NS_OK; -} - /* static */ CycleCollectedJSContext* CycleCollectedJSContext::GetFor(JSContext* aCx) { // Cast from void* matching JS_SetContextPrivate. diff --git a/xpcom/base/CycleCollectedJSContext.h b/xpcom/base/CycleCollectedJSContext.h index 6615a938d8dab..15670e9e2eebf 100644 --- a/xpcom/base/CycleCollectedJSContext.h +++ b/xpcom/base/CycleCollectedJSContext.h @@ -98,18 +98,11 @@ class CycleCollectedJSContext nsresult Initialize(JSRuntime* aParentRuntime, uint32_t aMaxBytes, uint32_t aMaxNurseryBytes); - // See explanation in mIsPrimaryContext. - MOZ_IS_CLASS_INIT - nsresult InitializeNonPrimary(CycleCollectedJSContext* aPrimaryContext); - virtual CycleCollectedJSRuntime* CreateRuntime(JSContext* aCx) = 0; size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; private: - MOZ_IS_CLASS_INIT - void InitializeCommon(); - static JSObject* GetIncumbentGlobalCallback(JSContext* aCx); static bool EnqueuePromiseJobCallback(JSContext* aCx, JS::HandleObject aPromise, @@ -273,12 +266,6 @@ class CycleCollectedJSContext js::UniquePtr saveJobQueue(JSContext*) override; private: - // A primary context owns the mRuntime. Non-main-thread contexts should always - // be primary. On the main thread, the primary context should be the first one - // created and the last one destroyed. Non-primary contexts are used for - // cooperatively scheduled threads. - bool mIsPrimaryContext; - CycleCollectedJSRuntime* mRuntime; JSContext* mJSContext; diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 2dbad35f3f662..a058ed262cbad 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -3815,8 +3815,6 @@ bool nsCycleCollector_init() { return sCollectorData.init(); } -static nsCycleCollector* gMainThreadCollector; - void nsCycleCollector_startup() { if (sCollectorData.get()) { MOZ_CRASH(); @@ -3827,40 +3825,6 @@ void nsCycleCollector_startup() { data->mContext = nullptr; sCollectorData.set(data); - - if (NS_IsMainThread()) { - MOZ_ASSERT(!gMainThreadCollector); - gMainThreadCollector = data->mCollector; - } -} - -void nsCycleCollector_registerNonPrimaryContext(CycleCollectedJSContext* aCx) { - if (sCollectorData.get()) { - MOZ_CRASH(); - } - - MOZ_ASSERT(gMainThreadCollector); - - CollectorData* data = new CollectorData; - - data->mCollector = gMainThreadCollector; - data->mContext = aCx; - - sCollectorData.set(data); -} - -void nsCycleCollector_forgetNonPrimaryContext() { - CollectorData* data = sCollectorData.get(); - - // We should have started the cycle collector by now. - MOZ_ASSERT(data); - // And we shouldn't have already forgotten our context. - MOZ_ASSERT(data->mContext); - // We should not have shut down the cycle collector yet. - MOZ_ASSERT(data->mCollector); - - delete data; - sCollectorData.set(nullptr); } void nsCycleCollector_setBeforeUnlinkCallback(CC_BeforeUnlinkCallback aCB) { @@ -3993,9 +3957,6 @@ void nsCycleCollector_shutdown(bool aDoCollect) { MOZ_ASSERT(data->mCollector); AUTO_PROFILER_LABEL("nsCycleCollector_shutdown", OTHER); - if (gMainThreadCollector == data->mCollector) { - gMainThreadCollector = nullptr; - } data->mCollector->Shutdown(aDoCollect); data->mCollector = nullptr; if (data->mContext) { diff --git a/xpcom/base/nsCycleCollector.h b/xpcom/base/nsCycleCollector.h index 15b7a6dd6f942..f4d39747e5268 100644 --- a/xpcom/base/nsCycleCollector.h +++ b/xpcom/base/nsCycleCollector.h @@ -67,9 +67,4 @@ void nsCycleCollector_shutdown(bool aDoCollect = true); void nsCycleCollector_registerJSContext(mozilla::CycleCollectedJSContext* aCx); void nsCycleCollector_forgetJSContext(); -// Helpers for cooperative threads. -void nsCycleCollector_registerNonPrimaryContext( - mozilla::CycleCollectedJSContext* aCx); -void nsCycleCollector_forgetNonPrimaryContext(); - #endif // nsCycleCollector_h__