Bug 712743, if node is black, return early from ::Traverse, r=mccr8,sicking

This commit is contained in:
Olli Pettay 2011-12-24 00:28:58 +02:00
parent 3851d96683
commit f16cabefa6

View File

@ -1207,6 +1207,20 @@ 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
nsINode::Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb)
@ -1217,6 +1231,34 @@ nsINode::Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb)
return false;
}
if (nsCCUncollectableMarker::sGeneration) {
// If we're black no need to traverse.
if (IsBlackNode(tmp)) {
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))) {
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)) {
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())