diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp index 1bd7cff60ec..48d80fb9d2f 100644 --- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -434,8 +434,15 @@ XPCCycleCollectGCCallback(JSContext *cx, JSGCStatus status) nsXPConnect::GetRuntime()-> TraceXPConnectRoots(cx->runtime->gcMarkingTracer); } + else if(status == JSGC_END) + nsXPConnect::GetRuntime()->RestoreContextGlobals(); - return gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE; + PRBool ok = gOldJSGCCallback ? gOldJSGCCallback(cx, status) : JS_TRUE; + + if(status == JSGC_BEGIN) + nsXPConnect::GetRuntime()->UnsetContextGlobals(); + + return ok; } PRUint32 @@ -500,9 +507,7 @@ nsXPConnect::Collect() JSContext *cx = mCycleCollectionContext->GetJSContext(); gOldJSGCCallback = JS_SetGCCallback(cx, XPCCycleCollectGCCallback); - GetRuntime()->UnsetContextGlobals(); JS_GC(cx); - GetRuntime()->RestoreContextGlobals(); JS_SetGCCallback(cx, gOldJSGCCallback); gOldJSGCCallback = nsnull; diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp index baa756aeb5e..19e821874cc 100644 --- a/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/js/src/xpconnect/src/xpcjsruntime.cpp @@ -443,12 +443,10 @@ void XPCJSRuntime::AddXPConnectRoots(JSContext* cx, void XPCJSRuntime::UnsetContextGlobals() { - if(!JS_DHashTableInit(&mClearedGlobalObjects, JS_DHashGetStubOps(), nsnull, - sizeof(ClearedGlobalObject), JS_DHASH_MIN_SIZE)) - { - mClearedGlobalObjects.ops = nsnull; + if(!mClearedGlobalObjects.ops) return; - } + + RestoreContextGlobals(); JSContext *iter = nsnull, *acx; while((acx = JS_ContextIterator(GetJSRuntime(), &iter))) @@ -470,9 +468,16 @@ void XPCJSRuntime::UnsetContextGlobals() } } +JSDHashOperator +RemoveContextGlobal(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number, + void *arg) +{ + return JS_DHASH_REMOVE; +} + void XPCJSRuntime::RestoreContextGlobals() { - if(!mClearedGlobalObjects.ops) + if(!mClearedGlobalObjects.ops || mClearedGlobalObjects.entryCount == 0) return; JSContext *iter = nsnull, *acx; @@ -487,8 +492,7 @@ void XPCJSRuntime::RestoreContextGlobals() acx->globalObject = clearedGlobal->mGlobalObject; } } - JS_DHashTableFinish(&mClearedGlobalObjects); - mClearedGlobalObjects.ops = nsnull; + JS_DHashTableEnumerate(&mClearedGlobalObjects, RemoveContextGlobal, nsnull); } JSObject* XPCJSRuntime::GetUnsetContextGlobal(JSContext* cx) @@ -1032,6 +1036,11 @@ XPCJSRuntime::~XPCJSRuntime() JS_DHashTableFinish(&mJSHolders); mJSHolders.ops = nsnull; } + if(mClearedGlobalObjects.ops) + { + JS_DHashTableFinish(&mClearedGlobalObjects); + mClearedGlobalObjects.ops = nsnull; + } } XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect, @@ -1088,7 +1097,9 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect, if(!JS_DHashTableInit(&mJSHolders, JS_DHashGetStubOps(), nsnull, sizeof(ObjectHolder), 512)) mJSHolders.ops = nsnull; - mClearedGlobalObjects.ops = nsnull; + if(!JS_DHashTableInit(&mClearedGlobalObjects, JS_DHashGetStubOps(), nsnull, + sizeof(ClearedGlobalObject), JS_DHASH_MIN_SIZE)) + mClearedGlobalObjects.ops = nsnull; // Install a JavaScript 'debugger' keyword handler in debug builds only #ifdef DEBUG