Skip to content

Commit

Permalink
Bug 1591923 - Remove some dead code for cooperative contexts from XPC…
Browse files Browse the repository at this point in the history
…onnect, XPCOM and JSAPI. r=mccr8

Differential Revision: https://phabricator.services.mozilla.com/D50802
  • Loading branch information
jandem committed Oct 28, 2019
1 parent a1f3d0e commit 13ebe00
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 194 deletions.
12 changes: 0 additions & 12 deletions js/src/jsapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
24 changes: 2 additions & 22 deletions js/src/jsapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 6 additions & 13 deletions js/xpconnect/src/XPCJSContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -1251,9 +1246,7 @@ nsresult XPCJSContext::Initialize(XPCJSContext* aPrimaryContext) {

JS_AddInterruptCallback(cx, InterruptCallback);

if (!aPrimaryContext) {
Runtime()->Initialize(cx);
}
Runtime()->Initialize(cx);

LoadStartupJSPrefs(this);

Expand Down Expand Up @@ -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.");
}
Expand Down
30 changes: 6 additions & 24 deletions js/xpconnect/src/nsXPConnect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();

Expand Down Expand Up @@ -109,7 +109,7 @@ nsXPConnect::~nsXPConnect() {
// shutdown the logging system
XPC_LOG_FINISH();

delete gPrimaryContext;
delete gContext;

MOZ_ASSERT(gSelf == this);
gSelf = nullptr;
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions js/xpconnect/src/xpcprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ class XPCJSContext final : public mozilla::CycleCollectedJSContext,
public mozilla::LinkedListElement<XPCJSContext> {
public:
static void InitTLS();
static XPCJSContext* NewXPCJSContext(XPCJSContext* aPrimaryContext);
static XPCJSContext* NewXPCJSContext();
static XPCJSContext* Get();

XPCJSRuntime* Runtime() const;
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 0 additions & 10 deletions js/xpconnect/src/xpcpublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
72 changes: 18 additions & 54 deletions xpcom/base/CycleCollectedJSContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ using namespace mozilla::dom;
namespace mozilla {

CycleCollectedJSContext::CycleCollectedJSContext()
: mIsPrimaryContext(true),
mRuntime(nullptr),
: mRuntime(nullptr),
mJSContext(nullptr),
mDoingStableStates(false),
mTargetedMicroTaskRecursionDepth(0),
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -147,51 +150,12 @@ void CycleCollectedJSContext::InitializeCommon() {

// Cast to PerThreadAtomCache for dom::GetAtomCache(JSContext*).
JS_SetContextPrivate(mJSContext, static_cast<PerThreadAtomCache*>(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.
Expand Down
13 changes: 0 additions & 13 deletions xpcom/base/CycleCollectedJSContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -273,12 +266,6 @@ class CycleCollectedJSContext
js::UniquePtr<SavedJobQueue> 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;
Expand Down
39 changes: 0 additions & 39 deletions xpcom/base/nsCycleCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3815,8 +3815,6 @@ bool nsCycleCollector_init() {
return sCollectorData.init();
}

static nsCycleCollector* gMainThreadCollector;

void nsCycleCollector_startup() {
if (sCollectorData.get()) {
MOZ_CRASH();
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit 13ebe00

Please sign in to comment.