diff --git a/js/xpconnect/src/XPCInlines.h b/js/xpconnect/src/XPCInlines.h index 91fd2f13af3f..27a4d53d1c74 100644 --- a/js/xpconnect/src/XPCInlines.h +++ b/js/xpconnect/src/XPCInlines.h @@ -582,11 +582,19 @@ inline void XPCNativeSet::ASSERT_NotMarked() /***************************************************************************/ inline -JSObject* XPCWrappedNativeTearOff::GetJSObject() const +JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const { return mJSObject; } +inline +JSObject* XPCWrappedNativeTearOff::GetJSObject() +{ + JSObject *obj = GetJSObjectPreserveColor(); + xpc_UnmarkGrayObject(obj); + return obj; +} + inline void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj) { @@ -596,7 +604,7 @@ void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj) inline XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff() { - NS_ASSERTION(!(GetInterface()||GetNative()||GetJSObject()), "tearoff not empty in dtor"); + NS_ASSERTION(!(GetInterface()||GetNative()||GetJSObjectPreserveColor()), "tearoff not empty in dtor"); } /***************************************************************************/ @@ -621,7 +629,7 @@ XPCWrappedNative::SweepTearOffs() // If this tearoff does not have a live dedicated JSObject, // then let's recycle it. - if (!to->GetJSObject()) { + if (!to->GetJSObjectPreserveColor()) { nsISupports* obj = to->GetNative(); if (obj) { obj->Release(); diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index 943c465b7270..93939fab1d89 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -171,7 +171,7 @@ XPCWrappedNative::NoteTearoffs(nsCycleCollectionTraversalCallback& cb) for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) { XPCWrappedNativeTearOff* to = chunk->mTearOffs; for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++) { - JSObject* jso = to->GetJSObject(); + JSObject* jso = to->GetJSObjectPreserveColor(); if (!jso) { NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "tearoff's mNative"); cb.NoteXPCOMChild(to->GetNative()); @@ -1259,7 +1259,7 @@ XPCWrappedNative::FlatJSObjectFinalized() for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) { XPCWrappedNativeTearOff* to = chunk->mTearOffs; for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++) { - JSObject* jso = to->GetJSObject(); + JSObject* jso = to->GetJSObjectPreserveColor(); if (jso) { NS_ASSERTION(JS_IsAboutToBeFinalized(jso), "bad!"); JS_SetPrivate(jso, nsnull); @@ -1363,8 +1363,8 @@ XPCWrappedNative::SystemIsBeingShutDown() for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) { XPCWrappedNativeTearOff* to = chunk->mTearOffs; for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++) { - if (to->GetJSObject()) { - JS_SetPrivate(to->GetJSObject(), nsnull); + if (JSObject *jso = to->GetJSObjectPreserveColor()) { + JS_SetPrivate(jso, nsnull); to->SetJSObject(nsnull); } // We leak the tearoff mNative @@ -1777,7 +1777,7 @@ XPCWrappedNative::FindTearOff(XPCCallContext& ccx, to < end; to++) { if (to->GetInterface() == aInterface) { - if (needJSObject && !to->GetJSObject()) { + if (needJSObject && !to->GetJSObjectPreserveColor()) { AutoMarkingWrappedNativeTearOffPtr tearoff(ccx, to); JSBool ok = InitTearOffJSObject(ccx, to); // During shutdown, we don't sweep tearoffs. So make sure diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp index 8d78c9e336b5..7dded7616a36 100644 --- a/js/xpconnect/src/XPCWrappedNativeScope.cpp +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -327,6 +327,8 @@ XPCWrappedNativeScope::GetPrototypeNoHelper(XPCCallContext& ccx) NS_ASSERTION(mPrototypeNoHelper, "Failed to create prototype for wrappers w/o a helper"); + } else { + xpc_UnmarkGrayObject(mPrototypeNoHelper); } return mPrototypeNoHelper; diff --git a/js/xpconnect/src/dombindings.cpp b/js/xpconnect/src/dombindings.cpp index 2ed5f3b75dda..88aa3229f56a 100644 --- a/js/xpconnect/src/dombindings.cpp +++ b/js/xpconnect/src/dombindings.cpp @@ -491,8 +491,10 @@ ListBase::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope) JSObject *interfacePrototype; if (cache.IsInitialized()) { - if (cache.Get(sInterfaceClass.name, &interfacePrototype)) + if (cache.Get(sInterfaceClass.name, &interfacePrototype)) { + xpc_UnmarkGrayObject(interfacePrototype); return interfacePrototype; + } } else if (!cache.Init()) { return NULL; } diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 532b0320886a..404704255d39 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2382,7 +2382,8 @@ public: XPCNativeInterface* GetInterface() const {return mInterface;} nsISupports* GetNative() const {return mNative;} - JSObject* GetJSObject() const; + JSObject* GetJSObject(); + JSObject* GetJSObjectPreserveColor() const; void SetInterface(XPCNativeInterface* Interface) {mInterface = Interface;} void SetNative(nsISupports* Native) {mNative = Native;} void SetJSObject(JSObject* JSObj); diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index d70333446bd0..ea3885707a53 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -103,8 +103,10 @@ WrapperFactory::WaiveXray(JSContext *cx, JSObject *obj) CompartmentPrivate *priv = (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(obj)); JSObject *wobj = nsnull; - if (priv && priv->waiverWrapperMap) + if (priv && priv->waiverWrapperMap) { wobj = priv->waiverWrapperMap->Find(obj); + xpc_UnmarkGrayObject(wobj); + } // No wrapper yet, make one. if (!wobj) {