mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
Bug 675068 - change off-main-thread cycle collection not to use a (thread-local) safe JS context (r=mrbkap)
--HG-- extra : rebase_source : b5a8a4ffa590bc9d0f2491d6a14bb95a37ff55e9
This commit is contained in:
parent
6fa760edaf
commit
b79f27d2f5
@ -468,10 +468,22 @@ nsresult
|
||||
nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb,
|
||||
bool explainLiveExpectedGarbage)
|
||||
{
|
||||
// It is important not to call GetSafeJSContext while on the
|
||||
// cycle-collector thread since this context will be destroyed
|
||||
// asynchronously and race with the main thread. In particular, we must
|
||||
// ensure that a context is passed to the XPCCallContext constructor.
|
||||
JSContext *cx = mRuntime->GetJSCycleCollectionContext();
|
||||
if (!cx)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Clear after mCycleCollectionContext is destroyed
|
||||
JS_SetContextThread(cx);
|
||||
|
||||
NS_ASSERTION(!mCycleCollectionContext, "Didn't call FinishTraverse?");
|
||||
mCycleCollectionContext = new XPCCallContext(NATIVE_CALLER);
|
||||
mCycleCollectionContext = new XPCCallContext(NATIVE_CALLER, cx);
|
||||
if (!mCycleCollectionContext->IsValid()) {
|
||||
mCycleCollectionContext = nsnull;
|
||||
JS_ClearContextThread(cx);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -521,8 +533,11 @@ nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb,
|
||||
nsresult
|
||||
nsXPConnect::FinishTraverse()
|
||||
{
|
||||
if (mCycleCollectionContext)
|
||||
if (mCycleCollectionContext) {
|
||||
JSContext *cx = mCycleCollectionContext->GetJSContext();
|
||||
mCycleCollectionContext = nsnull;
|
||||
JS_ClearContextThread(cx);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1057,6 +1057,18 @@ void XPCJSRuntime::SystemIsBeingShutDown(JSContext* cx)
|
||||
Enumerate(DetachedWrappedNativeProtoShutdownMarker, cx);
|
||||
}
|
||||
|
||||
JSContext *
|
||||
XPCJSRuntime::GetJSCycleCollectionContext()
|
||||
{
|
||||
if(!mJSCycleCollectionContext) {
|
||||
mJSCycleCollectionContext = JS_NewContext(mJSRuntime, 0);
|
||||
if(!mJSCycleCollectionContext)
|
||||
return nsnull;
|
||||
JS_ClearContextThread(mJSCycleCollectionContext);
|
||||
}
|
||||
return mJSCycleCollectionContext;
|
||||
}
|
||||
|
||||
XPCJSRuntime::~XPCJSRuntime()
|
||||
{
|
||||
if (mWatchdogWakeup)
|
||||
@ -1077,6 +1089,12 @@ XPCJSRuntime::~XPCJSRuntime()
|
||||
mWatchdogWakeup = nsnull;
|
||||
}
|
||||
|
||||
if(mJSCycleCollectionContext)
|
||||
{
|
||||
JS_SetContextThread(mJSCycleCollectionContext);
|
||||
JS_DestroyContextNoGC(mJSCycleCollectionContext);
|
||||
}
|
||||
|
||||
#ifdef XPC_DUMP_AT_SHUTDOWN
|
||||
{
|
||||
// count the total JSContexts in use
|
||||
@ -1905,6 +1923,7 @@ DiagnosticMemoryCallback(void *ptr, size_t size)
|
||||
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
: mXPConnect(aXPConnect),
|
||||
mJSRuntime(nsnull),
|
||||
mJSCycleCollectionContext(nsnull),
|
||||
mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)),
|
||||
mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_SIZE)),
|
||||
mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_SIZE)),
|
||||
|
@ -654,6 +654,7 @@ public:
|
||||
|
||||
JSRuntime* GetJSRuntime() const {return mJSRuntime;}
|
||||
nsXPConnect* GetXPConnect() const {return mXPConnect;}
|
||||
JSContext* GetJSCycleCollectionContext();
|
||||
|
||||
JSObject2WrappedJSMap* GetWrappedJSMap() const
|
||||
{return mWrappedJSMap;}
|
||||
@ -800,8 +801,9 @@ private:
|
||||
jsid mStrIDs[IDX_TOTAL_COUNT];
|
||||
jsval mStrJSVals[IDX_TOTAL_COUNT];
|
||||
|
||||
nsXPConnect* mXPConnect;
|
||||
JSRuntime* mJSRuntime;
|
||||
nsXPConnect* mXPConnect;
|
||||
JSRuntime* mJSRuntime;
|
||||
JSContext* mJSCycleCollectionContext;
|
||||
JSObject2WrappedJSMap* mWrappedJSMap;
|
||||
IID2WrappedJSClassMap* mWrappedJSClassMap;
|
||||
IID2NativeInterfaceMap* mIID2NativeInterfaceMap;
|
||||
|
Loading…
Reference in New Issue
Block a user