Commit 6f8dfd30 authored by Olli Pettay's avatar Olli Pettay
Browse files

Bug 794694 - Make sure to trace all the gray GCthings, not only wrapper, r=mccr8

parent 86c3d29f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -529,7 +529,8 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsXMLHttpRequest)
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)
+1 −1
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDOMEventTargetHelper)
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)
+6 −0
Original line number Diff line number Diff line
@@ -159,6 +159,12 @@ public:
   */
  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)
  {
+22 −0
Original line number Diff line number Diff line
@@ -24,4 +24,26 @@ nsWrapperCache::IsBlack()
  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___ */