Bug 794694 - Make sure to trace all the gray GCthings, not only wrapper, r=mccr8
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Sat, 29 Sep 2012 01:29:37 +0300
changeset 108410 b274e8e3479f556868412ea9fba4af4adf39deee
parent 108409 ed5f377741045a9caf858d4edff4685b50f11961
child 108500 b62b229a4d4191270e44bad30a8695c555eedadb
push id23563
push useropettay@mozilla.com
push dateFri, 28 Sep 2012 23:01:34 +0000
treeherdermozilla-central@b274e8e3479f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs794694
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 794694 - Make sure to trace all the gray GCthings, not only wrapper, r=mccr8
content/base/src/nsXMLHttpRequest.cpp
content/events/src/nsDOMEventTargetHelper.cpp
dom/base/nsWrapperCache.h
dom/base/nsWrapperCacheInlines.h
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -524,17 +524,18 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(
     if (!isBlack && tmp->PreservingWrapper()) {
       xpc_UnmarkGrayObject(tmp->GetWrapperPreserveColor());
     }
     return true;
   }
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsXMLHttpRequest)
-  return tmp->IsBlack();
+  return tmp->
+    IsBlackAndDoesNotNeedTracing(static_cast<nsDOMEventTargetHelper*>(tmp));
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsXMLHttpRequest)
   return tmp->IsBlack();
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
                                                   nsXHREventTarget)
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -48,17 +48,17 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(
     if (tmp->mListenerManager) {
       tmp->mListenerManager->UnmarkGrayJSListeners();
     }
     return true;
   }
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsDOMEventTargetHelper)
-  return tmp->IsBlack();
+  return tmp->IsBlackAndDoesNotNeedTracing(tmp);
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDOMEventTargetHelper)
   return tmp->IsBlack();
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventTargetHelper)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -154,16 +154,22 @@ public:
     return nullptr;
   }
 
   /**
    * Returns true if the object has a non-gray wrapper.
    */
   bool IsBlack();
 
+  /**
+   * Returns true if the object has a black wrapper,
+   * and all the GC things it is keeping alive are black too.
+   */
+  bool IsBlackAndDoesNotNeedTracing(nsISupports* aThis);
+
   // Only meant to be called by code that preserves a wrapper.
   void SetPreservingWrapper(bool aPreserve)
   {
     if(aPreserve) {
       mWrapperPtrBits |= WRAPPER_BIT_PRESERVED;
     }
     else {
       mWrapperPtrBits &= ~WRAPPER_BIT_PRESERVED;
--- a/dom/base/nsWrapperCacheInlines.h
+++ b/dom/base/nsWrapperCacheInlines.h
@@ -19,9 +19,31 @@ nsWrapperCache::GetWrapper() const
 
 inline bool
 nsWrapperCache::IsBlack()
 {
   JSObject* o = GetWrapperPreserveColor();
   return o && !xpc_IsGrayGCThing(o);
 }
 
+static void
+SearchGray(void* aGCThing, const char* aName, void* aClosure)
+{
+  bool* hasGrayObjects = static_cast<bool*>(aClosure);
+  if (!*hasGrayObjects && aGCThing && xpc_IsGrayGCThing(aGCThing)) {
+    *hasGrayObjects = true;
+  }
+}
+
+inline bool
+nsWrapperCache::IsBlackAndDoesNotNeedTracing(nsISupports* aThis)
+{
+  if (IsBlack()) {
+    nsXPCOMCycleCollectionParticipant* participant = nullptr;
+    CallQueryInterface(aThis, &participant);
+    bool hasGrayObjects = false;
+    participant->Trace(aThis, SearchGray, &hasGrayObjects);
+    return !hasGrayObjects;
+  }
+  return false;
+}
+
 #endif /* nsWrapperCache_h___ */