Title: [138735] trunk/Source/WebCore
Revision
138735
Author
[email protected]
Date
2013-01-03 13:39:11 -0800 (Thu, 03 Jan 2013)

Log Message

[Refactoring] Replace Node's Document pointer with a TreeScope pointer
https://bugs.webkit.org/show_bug.cgi?id=59816

Patch by Elliott Sprehn <[email protected]> on 2013-01-03
Reviewed by Ryosuke Niwa.

Instead of giving every node in a shadow a rare data, which can be quite
large, we replace the Document pointer in Node with a TreeScope pointer
and we give TreeScope a pointer to it's document scope.

This introduces no branches in document() because in the common
case document() becomes equivalent to m_treeScope->m_documentScope where
the documentScope is actually m_treeScope so this shouldn't introduce a
perf regression.

Note also that TreeScope can never be null after r136328, and the document
pointer is only null for DocumentType nodes so we can use a special
no-document TreeScope for this case that always returns null from
documentScope().

My original patch in r137524 for this did not correctly handle the case
where the Document is being destroyed and we would then call guardDeref on
ourself in the middle of the Document destructor causing asserts. To fix
this we need to go back to the original model where Document passes
null to it's super constructor for the Document pointer and assigns
it's tree scope later, and we also need to clear the tree scope pointer
in Document's destructor.

No new tests, no change in behavior.

* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::~Document):
(WebCore::Document::suggestedMIMEType):
* dom/Document.h:
(WebCore::Node::isDocumentNode):
(WebCore::Node::Node):
* dom/Element.cpp:
(WebCore::Element::createRareData):
* dom/ElementRareData.h:
(ElementRareData):
(WebCore::ElementRareData::ElementRareData):
* dom/Node.cpp:
(WebCore::Node::~Node):
(WebCore::Node::createRareData):
(WebCore::Node::attach):
(WebCore::Node::reportMemoryUsage):
* dom/Node.h:
(WebCore::NodeRareDataBase::NodeRareDataBase):
(NodeRareDataBase):
(WebCore::Node::treeScope):
(WebCore::Node::inDocument):
(WebCore::Node::documentInternal):
(WebCore::Node::setTreeScope):
(Node):
* dom/NodeRareData.cpp:
(SameSizeAsNodeRareData):
(WebCore::NodeRareData::reportMemoryUsage):
* dom/NodeRareData.h:
(WebCore::NodeRareData::NodeRareData):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::ShadowRoot):
* dom/TreeScope.cpp:
(SameSizeAsTreeScope):
(WebCore::TreeScope::TreeScope):
(WebCore::TreeScope::clearDocumentScope):
    Needed to clear the document scope during Document destruction
    so the Node destructor does not guardDeref the document that is
    already being destroyed.
(WebCore::TreeScope::setParentTreeScope):
* dom/TreeScope.h:
(TreeScope):
(WebCore::TreeScope::documentScope):
(WebCore::TreeScope::noDocumentInstance):
    Special shared tree scope that has a document scope that is always
    null. This is needed for DocType nodes, and also for Documents
    during construction.
(WebCore::TreeScope::setDocumentScope):
* dom/TreeScopeAdopter.cpp:
(WebCore::TreeScopeAdopter::moveTreeToNewScope):
(WebCore::TreeScopeAdopter::moveNodeToNewDocument):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (138734 => 138735)


--- trunk/Source/WebCore/ChangeLog	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/ChangeLog	2013-01-03 21:39:11 UTC (rev 138735)
@@ -1,3 +1,86 @@
+2013-01-03  Elliott Sprehn  <[email protected]>
+
+        [Refactoring] Replace Node's Document pointer with a TreeScope pointer
+        https://bugs.webkit.org/show_bug.cgi?id=59816
+
+        Reviewed by Ryosuke Niwa.
+
+        Instead of giving every node in a shadow a rare data, which can be quite
+        large, we replace the Document pointer in Node with a TreeScope pointer
+        and we give TreeScope a pointer to it's document scope.
+
+        This introduces no branches in document() because in the common
+        case document() becomes equivalent to m_treeScope->m_documentScope where
+        the documentScope is actually m_treeScope so this shouldn't introduce a
+        perf regression.
+
+        Note also that TreeScope can never be null after r136328, and the document
+        pointer is only null for DocumentType nodes so we can use a special
+        no-document TreeScope for this case that always returns null from
+        documentScope().
+
+        My original patch in r137524 for this did not correctly handle the case 
+        where the Document is being destroyed and we would then call guardDeref on
+        ourself in the middle of the Document destructor causing asserts. To fix
+        this we need to go back to the original model where Document passes
+        null to it's super constructor for the Document pointer and assigns
+        it's tree scope later, and we also need to clear the tree scope pointer
+        in Document's destructor.
+
+        No new tests, no change in behavior.
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::~Document):
+        (WebCore::Document::suggestedMIMEType):
+        * dom/Document.h:
+        (WebCore::Node::isDocumentNode):
+        (WebCore::Node::Node):
+        * dom/Element.cpp:
+        (WebCore::Element::createRareData):
+        * dom/ElementRareData.h:
+        (ElementRareData):
+        (WebCore::ElementRareData::ElementRareData):
+        * dom/Node.cpp:
+        (WebCore::Node::~Node):
+        (WebCore::Node::createRareData):
+        (WebCore::Node::attach):
+        (WebCore::Node::reportMemoryUsage):
+        * dom/Node.h:
+        (WebCore::NodeRareDataBase::NodeRareDataBase):
+        (NodeRareDataBase):
+        (WebCore::Node::treeScope):
+        (WebCore::Node::inDocument):
+        (WebCore::Node::documentInternal):
+        (WebCore::Node::setTreeScope):
+        (Node):
+        * dom/NodeRareData.cpp:
+        (SameSizeAsNodeRareData):
+        (WebCore::NodeRareData::reportMemoryUsage):
+        * dom/NodeRareData.h:
+        (WebCore::NodeRareData::NodeRareData):
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::ShadowRoot):
+        * dom/TreeScope.cpp:
+        (SameSizeAsTreeScope):
+        (WebCore::TreeScope::TreeScope):
+        (WebCore::TreeScope::clearDocumentScope):
+            Needed to clear the document scope during Document destruction
+            so the Node destructor does not guardDeref the document that is
+            already being destroyed.
+        (WebCore::TreeScope::setParentTreeScope):
+        * dom/TreeScope.h:
+        (TreeScope):
+        (WebCore::TreeScope::documentScope):
+        (WebCore::TreeScope::noDocumentInstance):
+            Special shared tree scope that has a document scope that is always
+            null. This is needed for DocType nodes, and also for Documents
+            during construction.
+        (WebCore::TreeScope::setDocumentScope):
+        * dom/TreeScopeAdopter.cpp:
+        (WebCore::TreeScopeAdopter::moveTreeToNewScope):
+        (WebCore::TreeScopeAdopter::moveNodeToNewDocument):
+
 2013-01-03  Adam Klein  <[email protected]>
 
         Unreviewed build fix.

Modified: trunk/Source/WebCore/dom/Document.cpp (138734 => 138735)


--- trunk/Source/WebCore/dom/Document.cpp	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/Document.cpp	2013-01-03 21:39:11 UTC (rev 138735)
@@ -507,7 +507,7 @@
     , m_didDispatchViewportPropertiesChanged(false)
 #endif
 {
-    m_document = this;
+    setTreeScope(this);
 
     m_printing = false;
     m_paginatedForScreen = false;
@@ -670,7 +670,7 @@
     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
         ASSERT(!m_nodeListCounts[i]);
 
-    m_document = 0;
+    clearDocumentScope();
 
     InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
 }
@@ -1346,13 +1346,13 @@
 
 String Document::suggestedMIMEType() const
 {
-    if (m_document->isXHTMLDocument())
+    if (isXHTMLDocument())
         return "application/xhtml+xml";
-    if (m_document->isSVGDocument())
+    if (isSVGDocument())
         return "image/svg+xml";
-    if (m_document->xmlStandalone())
+    if (xmlStandalone())
         return "text/xml";
-    if (m_document->isHTMLDocument())
+    if (isHTMLDocument())
         return "text/html";
 
     if (DocumentLoader* documentLoader = loader())

Modified: trunk/Source/WebCore/dom/Document.h (138734 => 138735)


--- trunk/Source/WebCore/dom/Document.h	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/Document.h	2013-01-03 21:39:11 UTC (rev 138735)
@@ -1586,22 +1586,20 @@
 
 inline bool Node::isDocumentNode() const
 {
-    return this == m_document;
+    return this == documentInternal();
 }
 
-inline TreeScope* Node::treeScope() const
-{
-    return hasRareData() ? m_data.m_rareData->treeScope() : documentInternal();
-}
-
 inline Node::Node(Document* document, ConstructionType type)
     : m_nodeFlags(type)
-    , m_document(document)
+    , m_treeScope(document)
     , m_previous(0)
     , m_next(0)
 {
     if (document)
         document->guardRef();
+    else
+        m_treeScope = TreeScope::noDocumentInstance();
+
 #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
     trackForDebugging();
 #endif

Modified: trunk/Source/WebCore/dom/Element.cpp (138734 => 138735)


--- trunk/Source/WebCore/dom/Element.cpp	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/Element.cpp	2013-01-03 21:39:11 UTC (rev 138735)
@@ -217,7 +217,7 @@
 
 PassOwnPtr<NodeRareData> Element::createRareData()
 {
-    return adoptPtr(new ElementRareData(documentInternal()));
+    return adoptPtr(new ElementRareData());
 }
 
 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);

Modified: trunk/Source/WebCore/dom/ElementRareData.h (138734 => 138735)


--- trunk/Source/WebCore/dom/ElementRareData.h	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/ElementRareData.h	2013-01-03 21:39:11 UTC (rev 138735)
@@ -35,7 +35,7 @@
 
 class ElementRareData : public NodeRareData {
 public:
-    ElementRareData(Document*);
+    ElementRareData();
     virtual ~ElementRareData();
 
     void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
@@ -141,9 +141,8 @@
     return IntSize(LayoutUnit::max(), LayoutUnit::max());
 }
 
-inline ElementRareData::ElementRareData(Document* document)
-    : NodeRareData(document)
-    , m_minimumSizeForResizing(defaultMinimumSizeForResizing())
+inline ElementRareData::ElementRareData()
+    : m_minimumSizeForResizing(defaultMinimumSizeForResizing())
     , m_generatedBefore(0)
     , m_generatedAfter(0)
 {

Modified: trunk/Source/WebCore/dom/Node.cpp (138734 => 138735)


--- trunk/Source/WebCore/dom/Node.cpp	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/Node.cpp	2013-01-03 21:39:11 UTC (rev 138735)
@@ -414,10 +414,12 @@
     if (hasRareData())
         clearRareData();
 
+    Document* doc = documentInternal();
+
     if (hasEventTargetData()) {
 #if ENABLE(TOUCH_EVENT_TRACKING)
-        if (m_document)
-            m_document->didRemoveEventTargetNode(this);
+        if (doc)
+            doc->didRemoveEventTargetNode(this);
 #endif
         clearEventTargetData();
     }
@@ -425,7 +427,6 @@
     if (renderer())
         detach();
 
-    Document* doc = m_document;
     if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists() && !isContainerNode())
         doc->axObjectCache()->remove(this);
     
@@ -440,25 +441,6 @@
     InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
 }
 
-void Node::setDocument(Document* document)
-{
-    ASSERT(!inDocument() || m_document == document);
-    if (inDocument() || m_document == document)
-        return;
-
-    m_document = document;
-}
-
-void Node::setTreeScope(TreeScope* scope)
-{
-    ASSERT(!isShadowRoot());
-
-    if (!hasRareData() && scope->rootNode()->isDocumentNode())
-        return;
-
-    ensureRareData()->setTreeScope(scope);
-}
-
 NodeRareData* Node::rareData() const
 {
     ASSERT(hasRareData());
@@ -480,7 +462,7 @@
 
 PassOwnPtr<NodeRareData> Node::createRareData()
 {
-    return adoptPtr(new NodeRareData(documentInternal()));
+    return adoptPtr(new NodeRareData());
 }
 
 void Node::clearRareData()
@@ -1105,7 +1087,7 @@
     setAttached();
     clearNeedsStyleRecalc();
 
-    Document* doc = m_document;
+    Document* doc = documentInternal();
     if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists())
         doc->axObjectCache()->updateCacheAfterNodeIsAttached(this);
 }
@@ -2606,7 +2588,7 @@
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
     TreeShared<Node, ContainerNode>::reportMemoryUsage(memoryObjectInfo);
     ScriptWrappable::reportMemoryUsage(memoryObjectInfo);
-    info.addMember(m_document);
+    info.addMember(m_treeScope);
     info.addMember(m_next);
     info.addMember(m_previous);
     info.addMember(this->renderer());

Modified: trunk/Source/WebCore/dom/Node.h (138734 => 138735)


--- trunk/Source/WebCore/dom/Node.h	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/Node.h	2013-01-03 21:39:11 UTC (rev 138735)
@@ -33,6 +33,7 @@
 #include "RenderStyleConstants.h"
 #include "ScriptWrappable.h"
 #include "SimulatedClickOptions.h"
+#include "TreeScope.h"
 #include "TreeShared.h"
 #include <wtf/Forward.h>
 #include <wtf/ListHashSet.h>
@@ -85,7 +86,6 @@
 class RenderStyle;
 class ShadowRoot;
 class TagNodeList;
-class TreeScope;
 
 #if ENABLE(GESTURE_EVENTS)
 class PlatformGestureEvent;
@@ -115,18 +115,11 @@
     RenderObject* renderer() const { return m_renderer; }
     void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
 
-    TreeScope* treeScope() const { return m_treeScope; }
-    void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
-
     virtual ~NodeRareDataBase() { }
 protected:
-    NodeRareDataBase(TreeScope* scope)
-        : m_treeScope(scope)
-    {
-    }
+    NodeRareDataBase() { }
 private:
     RenderObject* m_renderer;
-    TreeScope* m_treeScope;
 };
 
 class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node, ContainerNode> {
@@ -468,13 +461,13 @@
         return documentInternal();
     }
 
-    TreeScope* treeScope() const;
+    TreeScope* treeScope() const { return m_treeScope; }
 
     // Returns true if this node is associated with a document and is in its associated document's
     // node tree, false otherwise.
     bool inDocument() const 
     { 
-        ASSERT(m_document || !getFlag(InDocumentFlag));
+        ASSERT(documentInternal() || !getFlag(InDocumentFlag));
         return getFlag(InDocumentFlag);
     }
     bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
@@ -770,17 +763,14 @@
 
     void setHasCustomCallbacks() { setFlag(true, HasCustomCallbacksFlag); }
 
-    Document* documentInternal() const { return m_document; }
+    Document* documentInternal() const { return treeScope()->documentScope(); }
+    void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
 
 private:
     friend class TreeShared<Node, ContainerNode>;
 
     void removedLastRef();
 
-    // These API should be only used for a tree scope migration.
-    void setTreeScope(TreeScope*);
-    void setDocument(Document*);
-
     enum EditableLevel { Editable, RichlyEditable };
     bool rendererIsEditable(EditableLevel, UserSelectAllTreatment = UserSelectAllIsAlwaysNonEditable) const;
     bool isEditableToAccessibility(EditableLevel) const;
@@ -823,7 +813,7 @@
 #endif
 
     mutable uint32_t m_nodeFlags;
-    Document* m_document;
+    TreeScope* m_treeScope;
     Node* m_previous;
     Node* m_next;
     // When a node has rare data we move the renderer into the rare data.

Modified: trunk/Source/WebCore/dom/NodeRareData.cpp (138734 => 138735)


--- trunk/Source/WebCore/dom/NodeRareData.cpp	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/NodeRareData.cpp	2013-01-03 21:39:11 UTC (rev 138735)
@@ -39,7 +39,7 @@
 namespace WebCore {
 
 struct SameSizeAsNodeRareData {
-    void* m_pointer[4];
+    void* m_pointer[3];
     unsigned m_indicesAndBitfields[2];
 
 #if ENABLE(MUTATION_OBSERVERS)
@@ -64,7 +64,6 @@
 void NodeRareData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
-    info.addMember(treeScope());
     info.addMember(m_nodeLists);
 
 #if ENABLE(MUTATION_OBSERVERS)

Modified: trunk/Source/WebCore/dom/NodeRareData.h (138734 => 138735)


--- trunk/Source/WebCore/dom/NodeRareData.h	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/NodeRareData.h	2013-01-03 21:39:11 UTC (rev 138735)
@@ -246,9 +246,8 @@
 #endif
 
 public:    
-    NodeRareData(Document* document)
-        : NodeRareDataBase(document)
-        , m_tabIndex(0)
+    NodeRareData()
+        : m_tabIndex(0)
         , m_childIndex(0)
         , m_tabIndexWasSetExplicitly(false)
         , m_needsFocusAppearanceUpdateSoonAfterAttach(false)

Modified: trunk/Source/WebCore/dom/ShadowRoot.cpp (138734 => 138735)


--- trunk/Source/WebCore/dom/ShadowRoot.cpp	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/ShadowRoot.cpp	2013-01-03 21:39:11 UTC (rev 138735)
@@ -65,7 +65,7 @@
 
 ShadowRoot::ShadowRoot(Document* document)
     : DocumentFragment(document, CreateShadowRoot)
-    , TreeScope(this)
+    , TreeScope(this, document)
     , m_prev(0)
     , m_next(0)
     , m_numberOfStyles(0)
@@ -75,12 +75,7 @@
     , m_registeredWithParentShadowRoot(false)
 {
     ASSERT(document);
-    
-    // Assume document as parent scope.
-    setParentTreeScope(document);
-    // Shadow tree scopes have the scope pointer point to themselves.
-    // This way, direct children will receive the correct scope pointer.
-    ensureRareData()->setTreeScope(this);
+    setTreeScope(this);
 }
 
 ShadowRoot::~ShadowRoot()

Modified: trunk/Source/WebCore/dom/TreeScope.cpp (138734 => 138735)


--- trunk/Source/WebCore/dom/TreeScope.cpp	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/TreeScope.cpp	2013-01-03 21:39:11 UTC (rev 138735)
@@ -58,21 +58,40 @@
 
 struct SameSizeAsTreeScope {
     virtual ~SameSizeAsTreeScope();
-    void* pointers[7];
+    void* pointers[8];
 };
 
 COMPILE_ASSERT(sizeof(TreeScope) == sizeof(SameSizeAsTreeScope), treescope_should_stay_small);
 
 using namespace HTMLNames;
 
-TreeScope::TreeScope(ContainerNode* rootNode)
+TreeScope::TreeScope(ContainerNode* rootNode, Document* document)
     : m_rootNode(rootNode)
-    , m_parentTreeScope(0)
+    , m_documentScope(document)
+    , m_parentTreeScope(document)
     , m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
 {
     ASSERT(rootNode);
+    ASSERT(document);
+    ASSERT(rootNode != document);
 }
 
+TreeScope::TreeScope(Document* document)
+    : m_rootNode(document)
+    , m_documentScope(document)
+    , m_parentTreeScope(0)
+    , m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
+{
+    ASSERT(document);
+}
+
+TreeScope::TreeScope()
+    : m_rootNode(0)
+    , m_documentScope(0)
+    , m_parentTreeScope(0)
+{
+}
+
 TreeScope::~TreeScope()
 {
     if (m_selection) {
@@ -88,6 +107,12 @@
     m_labelsByForAttribute.clear();
 }
 
+void TreeScope::clearDocumentScope()
+{
+    ASSERT(rootNode()->isDocumentNode());
+    m_documentScope = 0;
+}
+
 void TreeScope::setParentTreeScope(TreeScope* newParentScope)
 {
     // A document node cannot be re-parented.
@@ -96,6 +121,7 @@
     ASSERT(newParentScope);
 
     m_parentTreeScope = newParentScope;
+    setDocumentScope(newParentScope->documentScope());
 }
 
 Element* TreeScope::getElementById(const AtomicString& elementId) const

Modified: trunk/Source/WebCore/dom/TreeScope.h (138734 => 138735)


--- trunk/Source/WebCore/dom/TreeScope.h	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/TreeScope.h	2013-01-03 21:39:11 UTC (rev 138735)
@@ -48,6 +48,7 @@
 // the destructor.
 class TreeScope {
     friend class Document;
+    friend class TreeScopeAdopter;
 
 public:
     TreeScope* parentTreeScope() const { return m_parentTreeScope; }
@@ -60,6 +61,8 @@
     void addElementById(const AtomicString& elementId, Element*);
     void removeElementById(const AtomicString& elementId, Element*);
 
+    Document* documentScope() const { return m_documentScope; }
+
     Node* ancestorInThisScope(Node*) const;
 
     void addImageMap(HTMLMapElement*);
@@ -95,14 +98,31 @@
 
     virtual void reportMemoryUsage(MemoryObjectInfo*) const;
 
+    static TreeScope* noDocumentInstance()
+    {
+        DEFINE_STATIC_LOCAL(TreeScope, instance, ());
+        return &instance;
+    }
+
 protected:
-    explicit TreeScope(ContainerNode*);
+    TreeScope(ContainerNode*, Document*);
+    TreeScope(Document*);
     virtual ~TreeScope();
 
     void destroyTreeScopeData();
+    void clearDocumentScope();
+    void setDocumentScope(Document* document)
+    {
+        ASSERT(document);
+        ASSERT(this != noDocumentInstance());
+        m_documentScope = document;
+    }
 
 private:
+    TreeScope();
+
     ContainerNode* m_rootNode;
+    Document* m_documentScope;
     TreeScope* m_parentTreeScope;
 
     OwnPtr<DocumentOrderedMap> m_elementsById;

Modified: trunk/Source/WebCore/dom/TreeScopeAdopter.cpp (138734 => 138735)


--- trunk/Source/WebCore/dom/TreeScopeAdopter.cpp	2013-01-03 21:32:04 UTC (rev 138734)
+++ trunk/Source/WebCore/dom/TreeScopeAdopter.cpp	2013-01-03 21:39:11 UTC (rev 138735)
@@ -43,14 +43,15 @@
     // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
     // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
     // we ensure that the collection cache will be invalidated as needed when the element is moved back.
-    Document* oldDocument = m_oldScope ? m_oldScope->rootNode()->document() : 0;
-    Document* newDocument = m_newScope->rootNode()->document();
+    Document* oldDocument = m_oldScope->documentScope();
+    Document* newDocument = m_newScope->documentScope();
     bool willMoveToNewDocument = oldDocument != newDocument;
     if (oldDocument && willMoveToNewDocument)
         oldDocument->incDOMTreeVersion();
 
     for (Node* node = root; node; node = NodeTraversal::next(node, root)) {
         node->setTreeScope(m_newScope);
+
         if (node->hasRareData()) {
             NodeRareData* rareData = node->rareData();
             if (rareData->nodeLists())
@@ -97,7 +98,8 @@
     if (oldDocument)
         oldDocument->moveNodeIteratorsToNewDocument(node, newDocument);
 
-    node->setDocument(newDocument);
+    if (node->isShadowRoot())
+        toShadowRoot(node)->setDocumentScope(newDocument);
 
 #ifndef NDEBUG
     didMoveToNewDocumentWasCalled = false;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to