зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 475737 (Windows stay alive too long because nsJSContext doesn't unlink correctly). r=bent, sr=jst.
This commit is contained in:
Родитель
4fe354136f
Коммит
8443f4d14c
|
@ -1286,7 +1286,9 @@ nsJSContext::~nsJSContext()
|
|||
#endif
|
||||
NS_PRECONDITION(!mTerminations, "Shouldn't have termination funcs by now");
|
||||
|
||||
Unlink();
|
||||
mGlobalWrapperRef = nsnull;
|
||||
|
||||
DestroyJSContext();
|
||||
|
||||
--sContextCount;
|
||||
|
||||
|
@ -1303,7 +1305,7 @@ nsJSContext::~nsJSContext()
|
|||
}
|
||||
|
||||
void
|
||||
nsJSContext::Unlink()
|
||||
nsJSContext::DestroyJSContext()
|
||||
{
|
||||
if (!mContext)
|
||||
return;
|
||||
|
@ -1316,30 +1318,37 @@ nsJSContext::Unlink()
|
|||
JSOptionChangedCallback,
|
||||
this);
|
||||
|
||||
// Release mGlobalWrapperRef before the context is destroyed
|
||||
mGlobalWrapperRef = nsnull;
|
||||
PRBool do_gc = mGCOnDestruction && !sGCTimer && sReadyForGC;
|
||||
|
||||
// Let xpconnect destroy the JSContext when it thinks the time is right.
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
if (xpc) {
|
||||
PRBool do_gc = mGCOnDestruction && !sGCTimer && sReadyForGC;
|
||||
|
||||
xpc->ReleaseJSContext(mContext, !do_gc);
|
||||
} else {
|
||||
} else if (do_gc) {
|
||||
::JS_DestroyContext(mContext);
|
||||
} else {
|
||||
::JS_DestroyContextNoGC(mContext);
|
||||
}
|
||||
mContext = nsnull;
|
||||
}
|
||||
|
||||
// QueryInterface implementation for nsJSContext
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsJSContext)
|
||||
NS_ASSERTION(!tmp->mContext || tmp->mContext->outstandingRequests == 0,
|
||||
"Trying to unlink a context with outstanding requests.");
|
||||
tmp->mIsInitialized = PR_FALSE;
|
||||
tmp->mGCOnDestruction = PR_FALSE;
|
||||
tmp->DestroyJSContext();
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobalWrapperRef)
|
||||
tmp->Unlink();
|
||||
tmp->mIsInitialized = PR_FALSE;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_REFCNT(nsJSContext, tmp->GetCCRefcnt())
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mGlobalWrapperRef)
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mContext");
|
||||
nsContentUtils::XPConnect()->NoteJSContext(tmp->mContext, cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
@ -1353,6 +1362,12 @@ NS_INTERFACE_MAP_END
|
|||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsJSContext, nsIScriptContext)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsJSContext, nsIScriptContext)
|
||||
|
||||
nsrefcnt
|
||||
nsJSContext::GetCCRefcnt()
|
||||
{
|
||||
return mRefCnt.get() + mContext->outstandingRequests;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
|
||||
void *aScopeObject,
|
||||
|
|
|
@ -57,7 +57,8 @@ public:
|
|||
virtual ~nsJSContext();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsJSContext, nsIScriptContext)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSContext,
|
||||
nsIScriptContext)
|
||||
|
||||
virtual PRUint32 GetScriptTypeID()
|
||||
{ return nsIProgrammingLanguage::JAVASCRIPT; }
|
||||
|
@ -218,7 +219,9 @@ protected:
|
|||
// related to our exception.
|
||||
void ReportPendingException(PRBool aSetAsideFrameChain);
|
||||
private:
|
||||
void Unlink();
|
||||
void DestroyJSContext();
|
||||
|
||||
nsrefcnt GetCCRefcnt();
|
||||
|
||||
JSContext *mContext;
|
||||
PRUint32 mNumEvaluations;
|
||||
|
|
|
@ -594,6 +594,8 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
|
|||
#endif
|
||||
rt = cx->runtime;
|
||||
|
||||
JS_ASSERT_IF(rt->gcRunning, cx->outstandingRequests == 0);
|
||||
|
||||
if (mode != JSDCM_NEW_FAILED) {
|
||||
cxCallback = rt->cxCallback;
|
||||
if (cxCallback) {
|
||||
|
@ -629,6 +631,8 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
|
|||
|| cx->requestDepth != 0
|
||||
#endif
|
||||
) {
|
||||
JS_ASSERT(rt->gcLevel == 0);
|
||||
|
||||
JS_UNLOCK_GC(rt);
|
||||
|
||||
if (last) {
|
||||
|
|
|
@ -371,7 +371,6 @@ void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc, JSBool rootGlobals)
|
|||
}
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(!rootGlobals || mUnrootedGlobalCount == 0, "bad state");
|
||||
}
|
||||
|
||||
XPCWrappedNativeScope::TraceJS(trc, this);
|
||||
|
|
|
@ -309,7 +309,7 @@ _class::AggregatedQueryInterface(REFNSIID aIID, void** aInstancePtr) \
|
|||
"not the nsISupports pointer we expect"); \
|
||||
_class *tmp = static_cast<_class*>(Downcast(s)); \
|
||||
if (!tmp->IsPartOfAggregated()) \
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, tmp->mRefCnt.get())
|
||||
|
||||
#define NS_GENERIC_AGGREGATED_CONSTRUCTOR(_InstanceClass) \
|
||||
static NS_METHOD \
|
||||
|
|
|
@ -322,14 +322,14 @@ public:
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
#define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class) \
|
||||
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(_class), #_class);
|
||||
#define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, _refcnt) \
|
||||
cb.DescribeNode(RefCounted, _refcnt, sizeof(_class), #_class);
|
||||
#else
|
||||
#define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class) \
|
||||
cb.DescribeNode(RefCounted, tmp->mRefCnt.get());
|
||||
#define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, _refcnt) \
|
||||
cb.DescribeNode(RefCounted, _refcnt);
|
||||
#endif
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_REFCNT(_class, _refcnt) \
|
||||
NS_IMETHODIMP \
|
||||
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \
|
||||
(void *p, \
|
||||
|
@ -339,7 +339,10 @@ public:
|
|||
NS_ASSERTION(CheckForRightISupports(s), \
|
||||
"not the nsISupports pointer we expect"); \
|
||||
_class *tmp = Downcast(s); \
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, _refcnt)
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_REFCNT(_class, tmp->mRefCnt.get())
|
||||
|
||||
// Base class' CC participant should return NS_SUCCESS_INTERRUPTED_TRAVERSE
|
||||
// from Traverse if it wants derived classes to not traverse anything from
|
||||
|
@ -369,7 +372,7 @@ public:
|
|||
nsCycleCollectionTraversalCallback &cb) \
|
||||
{ \
|
||||
_class *tmp = static_cast<_class*>(p); \
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, tmp->mRefCnt.get())
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
#define NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(_cb, _name) \
|
||||
|
|
Загрузка…
Ссылка в новой задаче