Bug 713462, don't traverse black content lists, r=mccr8
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 29 Dec 2011 23:21:33 +0200
changeset 85942 1d0a814ebf12fd72b68691dd6aa092e0be8644d6
parent 85941 95ccf0a6a95a3cd5f45d2e19a13f3ae993182f1d
child 85943 0d684c34d1e4e7c0bd6779711119edac141ae106
child 111779 2e59a622b0900d82c1e2a7fd0153ff22c7291f46
push id674
push userffxbld
push dateTue, 13 Mar 2012 21:17:50 +0000
treeherdermozilla-beta@e3c4c92dec31 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs713462
milestone12.0a1
first release with
nightly linux32
1d0a814ebf12 / 12.0a1 / 20111230031151 / files
nightly linux64
1d0a814ebf12 / 12.0a1 / 20111230031151 / files
nightly mac
1d0a814ebf12 / 12.0a1 / 20111230031151 / files
nightly win32
1d0a814ebf12 / 12.0a1 / 20111230031151 / files
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 713462, don't traverse black content lists, r=mccr8
content/base/src/nsContentList.cpp
content/base/src/nsGenericElement.cpp
dom/base/nsWrapperCache.h
dom/base/nsWrapperCacheInlines.h
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -42,19 +42,19 @@
  * getElementsByTagName, some properties on nsIDOMHTMLDocument, etc).
  */
 
 #include "nsContentList.h"
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "nsIDocument.h"
 #include "nsGenericElement.h"
-
+#include "nsWrapperCacheInlines.h"
 #include "nsContentUtils.h"
-
+#include "nsCCUncollectableMarker.h"
 #include "nsGkAtoms.h"
 
 #include "dombindings.h"
 
 // Form related includes
 #include "nsIDOMHTMLFormElement.h"
 
 #include "pldhash.h"
@@ -75,18 +75,21 @@ nsBaseContentList::~nsBaseContentList()
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsBaseContentList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBaseContentList)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mElements)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBaseContentList)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+  if (nsCCUncollectableMarker::sGeneration && tmp->IsBlack()) {
+    return NS_SUCCESS_INTERRUPTED_TRAVERSE;
+  }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mElements)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsBaseContentList)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 #define NS_CONTENT_LIST_INTERFACES(_class)                                    \
     NS_INTERFACE_TABLE_ENTRY(_class, nsINodeList)                             \
     NS_INTERFACE_TABLE_ENTRY(_class, nsIDOMNodeList)
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1203,23 +1203,16 @@ nsINode::GetContextForEventHandlers(nsre
 /* static */
 void
 nsINode::Trace(nsINode *tmp, TraceCallback cb, void *closure)
 {
   nsContentUtils::TraceWrapper(tmp, cb, closure);
 }
 
 static bool
-IsBlackNode(nsINode* aNode)
-{
-  JSObject* o = aNode->GetWrapperPreserveColor();
-  return o && !xpc_IsGrayGCThing(o);
-}
-
-static bool
 IsXBL(nsINode* aNode)
 {
   return aNode->IsElement() &&
          aNode->AsElement()->IsInNamespace(kNameSpaceID_XBL);
 }
 
 /* static */
 bool
@@ -1228,36 +1221,36 @@ nsINode::Traverse(nsINode *tmp, nsCycleC
   nsIDocument *currentDoc = tmp->GetCurrentDoc();
   if (currentDoc &&
       nsCCUncollectableMarker::InGeneration(cb, currentDoc->GetMarkedCCGeneration())) {
     return false;
   }
 
   if (nsCCUncollectableMarker::sGeneration) {
     // If we're black no need to traverse.
-    if (IsBlackNode(tmp)) {
+    if (tmp->IsBlack()) {
       return false;
     }
 
     const PtrBits problematicFlags =
       (NODE_IS_ANONYMOUS |
        NODE_IS_IN_ANONYMOUS_SUBTREE |
        NODE_IS_NATIVE_ANONYMOUS_ROOT |
        NODE_MAY_BE_IN_BINDING_MNGR |
        NODE_IS_INSERTION_PARENT);
 
     if (!tmp->HasFlag(problematicFlags) && !IsXBL(tmp)) {
       // If we're in a black document, return early.
-      if ((currentDoc && IsBlackNode(currentDoc))) {
+      if ((currentDoc && currentDoc->IsBlack())) {
         return false;
       }
       // If we're not in anonymous content and we have a black parent,
       // return early.
       nsIContent* parent = tmp->GetParent();
-      if (parent && !IsXBL(parent) && IsBlackNode(parent)) {
+      if (parent && !IsXBL(parent) && parent->IsBlack()) {
         NS_ABORT_IF_FALSE(parent->IndexOf(tmp) >= 0, "Parent doesn't own us?");
         return false;
       }
     }
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent())
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -185,16 +185,21 @@ public:
    */
   virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
                                bool *triedToWrap)
   {
     *triedToWrap = false;
     return nsnull;
   }
 
+  /**
+   * Returns true if the object has a non-gray wrapper.
+   */
+  bool IsBlack();
+
 private:
   // Only meant to be called by nsContentUtils.
   void SetPreservingWrapper(bool aPreserve)
   {
     if(aPreserve) {
       mWrapperPtrBits |= WRAPPER_BIT_PRESERVED;
     }
     else {
--- a/dom/base/nsWrapperCacheInlines.h
+++ b/dom/base/nsWrapperCacheInlines.h
@@ -134,9 +134,16 @@ nsWrapperCache::ClearWrapperIfProxy()
         return;
     }
 
     RemoveExpandoObject();
 
     SetWrapperBits(NULL);
 }
 
+inline bool
+nsWrapperCache::IsBlack()
+{
+  JSObject* o = GetWrapperPreserveColor();
+  return o && !xpc_IsGrayGCThing(o);
+}
+
 #endif /* nsWrapperCache_h___ */