void JSSVGElementInstance::markChildren(MarkStack& markStack)
{
    Base::markChildren(markStack);

    // Mark the wrapper for our corresponding element, so it can mark its event handlers.
    markDOMNodeWrapper(markStack, impl()->correspondingElement()->document(), impl()->correspondingElement());
}
void JSNamedNodeMap::markChildren(MarkStack& markStack)
{
    Base::markChildren(markStack);

    // Mark the element so that this will work to access the attribute even if the last
    // other reference goes away.
    if (Element* element = impl()->element())
        markDOMNodeWrapper(markStack, element->document(), element);
}
Example #3
0
void JSNode::markChildren(MarkStack& markStack)
{
    Base::markChildren(markStack);

    Node* node = m_impl.get();
    node->markJSEventListeners(markStack);

    // Nodes in the document are kept alive by JSDocument::mark, so, if we're in
    // the document, we need to mark the document, but we don't need to explicitly
    // mark any other nodes.
    if (node->inDocument()) {
        // FIXME: Do we really want to call a virtual function, ownerDocument here,
        // when the non-virtual inline function, document, is so much faster?!
        if (Document* doc = node->ownerDocument())
            markDOMNodeWrapper(markStack, doc, doc);
        return;
    }

    // This is a node outside the document.
    // Find the the root, and the highest ancestor with a wrapper.
    Node* root = node;
    Node* outermostNodeWithWrapper = node;
    for (Node* current = m_impl.get(); current; current = current->parentNode()) {
        root = current;
        if (hasCachedDOMNodeWrapperUnchecked(current->document(), current))
            outermostNodeWithWrapper = current;
    }

    // Only nodes that have no ancestors with wrappers mark the subtree. In the common
    // case, the root of the detached subtree has a wrapper, so the tree will only
    // get marked once. Nodes that aren't outermost need to mark the outermost
    // in case it is otherwise unreachable.
    // FIXME: In the non-common case of root not having a wrapper, this is still an O(n^2) algorithm,
    // as we will traverse the whole tree as many times as there are nodes with wrappers in it.
    if (node != outermostNodeWithWrapper) {
        markDOMNodeWrapper(markStack, m_impl->document(), outermostNodeWithWrapper);
        return;
    }

    // Mark the whole tree subtree.
    for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode())
        markDOMNodeWrapper(markStack, m_impl->document(), nodeToMark);
}
void JSNode::markChildren(MarkStack& markStack)
{
    Base::markChildren(markStack);

    Node* node = m_impl.get();
    node->markJSEventListeners(markStack);

    // Nodes in the document are kept alive by JSDocument::mark, so, if we're in
    // the document, we need to mark the document, but we don't need to explicitly
    // mark any other nodes.
    if (node->inDocument()) {
        if (Document* doc = node->ownerDocument())
            markDOMNodeWrapper(markStack, doc, doc);
        return;
    }

    // This is a node outside the document.
    // Find the the root, and the highest ancestor with a wrapper.
    Node* root = node;
    Node* outermostNodeWithWrapper = node;
    for (Node* current = m_impl.get(); current; current = current->parentNode()) {
        root = current;
        if (hasCachedDOMNodeWrapperUnchecked(current->document(), current))
            outermostNodeWithWrapper = current;
    }

    // Only nodes that have no ancestors with wrappers mark the subtree. In the common
    // case, the root of the detached subtree has a wrapper, so the tree will only
    // get marked once. Nodes that aren't outermost need to mark the outermost
    // in case it is otherwise unreachable.
    if (node != outermostNodeWithWrapper) {
        markDOMNodeWrapper(markStack, m_impl->document(), outermostNodeWithWrapper);
        return;
    }

    // Mark the whole tree subtree.
    for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode())
        markDOMNodeWrapper(markStack, m_impl->document(), nodeToMark);
}
void JSStyleSheet::markChildren(MarkStack& markStack)
{
    Base::markChildren(markStack);

    StyleSheet* sheet = impl();
    JSGlobalData& globalData = *Heap::heap(this)->globalData();

    unsigned length = sheet->length();
    for (unsigned i = 0; i < length; ++i)
        markDOMObjectWrapper(markStack, globalData, sheet->item(i));

    // This prevents us from having a style sheet with a dangling ownerNode pointer.
    // A better solution would be to handle this on the DOM side -- if the style sheet
    // is kept around, then we want the node to stay around too. One possibility would
    // be to make ref/deref on the style sheet ref/deref the node instead, but there's
    // a lot of disentangling of the CSS DOM objects that would need to happen first.
    if (Node* ownerNode = sheet->ownerNode())
        markDOMNodeWrapper(markStack, ownerNode->document(), ownerNode);
}