<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[164195] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/164195">164195</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2014-02-16 14:18:13 -0800 (Sun, 16 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Move document life time management from TreeScope to Document
https://bugs.webkit.org/show_bug.cgi?id=128877

Reviewed by Andreas Kling.

Document life time is managed in confusing manner by TreeScopes which are also inherited to ShadowRoots.
        
This patches moves the life time management to Document. Nodes in shadow trees selfOnlyRef the Document instead
of the ShadowRoot. ShadowRoot is treated like any other node and selfOnlyRefs the Document as well (which it
also did earlier, indirectly).
        
TreeScope is devirtualized.

* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::collectMatchingRules):
        
    Author stylesheets never match in UA shadow trees.

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::~ContainerNode):
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::~Document):
(WebCore::Document::removedLastRef):
* dom/Document.h:
(WebCore::Document::selfOnlyRef):
(WebCore::Document::selfOnlyDeref):

    To avoid branches Document self-refs itself like all other Nodes. This is why deletion will now happen on ref count of 1.

(WebCore::Node::isDocumentNode):
(WebCore::Node::Node):
* dom/DocumentOrderedMap.cpp:
(WebCore::DocumentOrderedMap::add):
* dom/Element.cpp:
(WebCore::Element::insertedInto):
(WebCore::Element::removedFrom):
* dom/Node.cpp:
(WebCore::Node::~Node):
(WebCore::Node::removedLastRef):
* dom/Node.h:
(WebCore::Node::document):
(WebCore::Node::inDocument):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::~ShadowRoot):
* dom/ShadowRoot.h:
* dom/TreeScope.cpp:
(WebCore::TreeScope::TreeScope):
(WebCore::TreeScope::~TreeScope):
(WebCore::TreeScope::setParentTreeScope):
* dom/TreeScope.h:
(WebCore::TreeScope::documentScope):
        
    Document can no longer ever be null.

(WebCore::TreeScope::rootNode):
(WebCore::TreeScope::setDocumentScope):
* dom/TreeScopeAdopter.cpp:
(WebCore::TreeScopeAdopter::moveTreeToNewScope):
(WebCore::TreeScopeAdopter::moveShadowTreeToNewDocument):
        
    Manage Document selfOnlyRefs for nodes in shadow trees too.

(WebCore::TreeScopeAdopter::updateTreeScope):
(WebCore::TreeScopeAdopter::moveNodeToNewDocument):
* dom/TreeScopeAdopter.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssElementRuleCollectorcpp">trunk/Source/WebCore/css/ElementRuleCollector.cpp</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodecpp">trunk/Source/WebCore/dom/ContainerNode.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumenth">trunk/Source/WebCore/dom/Document.h</a></li>
<li><a href="#trunkSourceWebCoredomDocumentOrderedMapcpp">trunk/Source/WebCore/dom/DocumentOrderedMap.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCoredomNodecpp">trunk/Source/WebCore/dom/Node.cpp</a></li>
<li><a href="#trunkSourceWebCoredomNodeh">trunk/Source/WebCore/dom/Node.h</a></li>
<li><a href="#trunkSourceWebCoredomShadowRootcpp">trunk/Source/WebCore/dom/ShadowRoot.cpp</a></li>
<li><a href="#trunkSourceWebCoredomShadowRooth">trunk/Source/WebCore/dom/ShadowRoot.h</a></li>
<li><a href="#trunkSourceWebCoredomTreeScopecpp">trunk/Source/WebCore/dom/TreeScope.cpp</a></li>
<li><a href="#trunkSourceWebCoredomTreeScopeh">trunk/Source/WebCore/dom/TreeScope.h</a></li>
<li><a href="#trunkSourceWebCoredomTreeScopeAdoptercpp">trunk/Source/WebCore/dom/TreeScopeAdopter.cpp</a></li>
<li><a href="#trunkSourceWebCoredomTreeScopeAdopterh">trunk/Source/WebCore/dom/TreeScopeAdopter.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/ChangeLog        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -1,3 +1,73 @@
</span><ins>+2014-02-15  Antti Koivisto  &lt;antti@apple.com&gt;
+
+        Move document life time management from TreeScope to Document
+        https://bugs.webkit.org/show_bug.cgi?id=128877
+
+        Reviewed by Andreas Kling.
+
+        Document life time is managed in confusing manner by TreeScopes which are also inherited to ShadowRoots.
+        
+        This patches moves the life time management to Document. Nodes in shadow trees selfOnlyRef the Document instead
+        of the ShadowRoot. ShadowRoot is treated like any other node and selfOnlyRefs the Document as well (which it
+        also did earlier, indirectly).
+        
+        TreeScope is devirtualized.
+
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::collectMatchingRules):
+        
+            Author stylesheets never match in UA shadow trees.
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::~ContainerNode):
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::~Document):
+        (WebCore::Document::removedLastRef):
+        * dom/Document.h:
+        (WebCore::Document::selfOnlyRef):
+        (WebCore::Document::selfOnlyDeref):
+
+            To avoid branches Document self-refs itself like all other Nodes. This is why deletion will now happen on ref count of 1.
+
+        (WebCore::Node::isDocumentNode):
+        (WebCore::Node::Node):
+        * dom/DocumentOrderedMap.cpp:
+        (WebCore::DocumentOrderedMap::add):
+        * dom/Element.cpp:
+        (WebCore::Element::insertedInto):
+        (WebCore::Element::removedFrom):
+        * dom/Node.cpp:
+        (WebCore::Node::~Node):
+        (WebCore::Node::removedLastRef):
+        * dom/Node.h:
+        (WebCore::Node::document):
+        (WebCore::Node::inDocument):
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::ShadowRoot):
+        (WebCore::ShadowRoot::~ShadowRoot):
+        * dom/ShadowRoot.h:
+        * dom/TreeScope.cpp:
+        (WebCore::TreeScope::TreeScope):
+        (WebCore::TreeScope::~TreeScope):
+        (WebCore::TreeScope::setParentTreeScope):
+        * dom/TreeScope.h:
+        (WebCore::TreeScope::documentScope):
+        
+            Document can no longer ever be null.
+
+        (WebCore::TreeScope::rootNode):
+        (WebCore::TreeScope::setDocumentScope):
+        * dom/TreeScopeAdopter.cpp:
+        (WebCore::TreeScopeAdopter::moveTreeToNewScope):
+        (WebCore::TreeScopeAdopter::moveShadowTreeToNewDocument):
+        
+            Manage Document selfOnlyRefs for nodes in shadow trees too.
+
+        (WebCore::TreeScopeAdopter::updateTreeScope):
+        (WebCore::TreeScopeAdopter::moveNodeToNewDocument):
+        * dom/TreeScopeAdopter.h:
+
</ins><span class="cx"> 2014-02-16  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         setSelectionRange shouldn't directly instantiate VisibleSelection
</span></span></pre></div>
<a id="trunkSourceWebCorecssElementRuleCollectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/ElementRuleCollector.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -154,11 +154,8 @@
</span><span class="cx">     if (m_element.isWebVTTElement())
</span><span class="cx">         collectMatchingRulesForList(matchRequest.ruleSet-&gt;cuePseudoRules(), matchRequest, ruleRange);
</span><span class="cx"> #endif
</span><del>-    // Check whether other types of rules are applicable in the current tree scope. Criteria for this:
-    // a) it's a UA rule
-    // b) the tree scope allows author rules
-    if (!MatchingUARulesScope::isMatchingUARules()
-        &amp;&amp; !m_element.treeScope().applyAuthorStyles())
</del><ins>+    // Only match UA rules in shadow tree.
+    if (!MatchingUARulesScope::isMatchingUARules() &amp;&amp; m_element.treeScope().rootNode()-&gt;isShadowRoot())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // We need to collect the rules for id, class, tag, and everything else into a buffer and
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -150,8 +150,7 @@
</span><span class="cx"> 
</span><span class="cx"> ContainerNode::~ContainerNode()
</span><span class="cx"> {
</span><del>-    if (Document* document = documentInternal())
-        willBeDeletedFrom(document);
</del><ins>+    willBeDeletedFrom(&amp;document());
</ins><span class="cx">     removeDetachedChildren();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/Document.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -393,8 +393,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> Document::Document(Frame* frame, const URL&amp; url, unsigned documentClasses, unsigned constructionFlags)
</span><del>-    : ContainerNode(nullptr, CreateDocument)
-    , TreeScope(this)
</del><ins>+    : ContainerNode(this, CreateDocument)
+    , TreeScope(*this)
+    , m_selfOnlyRefCount(1)
</ins><span class="cx"> #if ENABLE(TOUCH_EVENTS) &amp;&amp; PLATFORM(IOS)
</span><span class="cx">     , m_handlingTouchEvent(false)
</span><span class="cx">     , m_touchEventRegionsDirty(false)
</span><span class="lines">@@ -633,43 +634,59 @@
</span><span class="cx">     for (unsigned i = 0; i &lt; WTF_ARRAY_LENGTH(m_nodeListAndCollectionCounts); ++i)
</span><span class="cx">         ASSERT(!m_nodeListAndCollectionCounts[i]);
</span><span class="cx"> 
</span><del>-    clearDocumentScope();
-
</del><span class="cx">     InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Document::dropChildren()
</del><ins>+void Document::removedLastRef()
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!m_deletionHasBegun);
</span><ins>+    ASSERT(m_selfOnlyRefCount);
+    if (m_selfOnlyRefCount &gt; 1) {
+        // If removing a child removes the last self-only ref, we don't want the scope to be destroyed
+        // until after removeDetachedChildren returns, so we protect ourselves with an extra self-only ref.
+        selfOnlyRef();
</ins><span class="cx"> 
</span><del>-    // We must make sure not to be retaining any of our children through
-    // these extra pointers or we will create a reference cycle.
-    m_focusedElement = nullptr;
-    m_hoveredElement = nullptr;
-    m_activeElement = nullptr;
-    m_titleElement = nullptr;
-    m_documentElement = nullptr;
-    m_userActionElements.documentDidRemoveLastRef();
</del><ins>+        // We must make sure not to be retaining any of our children through
+        // these extra pointers or we will create a reference cycle.
+        m_focusedElement = nullptr;
+        m_hoveredElement = nullptr;
+        m_activeElement = nullptr;
+        m_titleElement = nullptr;
+        m_documentElement = nullptr;
+        m_userActionElements.documentDidRemoveLastRef();
</ins><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span><del>-    m_fullScreenElement = nullptr;
-    m_fullScreenElementStack.clear();
</del><ins>+        m_fullScreenElement = nullptr;
+        m_fullScreenElementStack.clear();
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    detachParser();
</del><ins>+        detachParser();
</ins><span class="cx"> 
</span><del>-    // removeDetachedChildren() doesn't always unregister IDs,
-    // so tear down scope information up front to avoid having
-    // stale references in the map.
</del><ins>+        // removeDetachedChildren() doesn't always unregister IDs,
+        // so tear down scope information up front to avoid having
+        // stale references in the map.
</ins><span class="cx"> 
</span><del>-    destroyTreeScopeData();
-    removeDetachedChildren();
-    m_formController.clear();
</del><ins>+        destroyTreeScopeData();
+        removeDetachedChildren();
+        m_formController.clear();
+        
+        m_markers-&gt;detach();
+        
+        m_cssCanvasElements.clear();
+        
+        commonTeardown();
</ins><span class="cx"> 
</span><del>-    m_markers-&gt;detach();
-
-    m_cssCanvasElements.clear();
-
-    commonTeardown();
</del><ins>+#ifndef NDEBUG
+        // We need to do this right now since selfOnlyDeref() can delete this.
+        m_inRemovedLastRefFunction = false;
+#endif
+        selfOnlyDeref();
+    } else {
+#ifndef NDEBUG
+        m_inRemovedLastRefFunction = false;
+        m_deletionHasBegun = true;
+#endif
+        delete this;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Document::commonTeardown()
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/Document.h        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -263,6 +263,31 @@
</span><span class="cx"> 
</span><span class="cx">     virtual ~Document();
</span><span class="cx"> 
</span><ins>+    // Nodes belonging to this document hold self-only references -
+    // these are enough to keep the document from being destroyed, but
+    // not enough to keep it from removing its children. This allows a
+    // node that outlives its scope to still have a valid document
+    // pointer without introducing reference cycles.
+    void selfOnlyRef()
+    {
+        ASSERT(!m_deletionHasBegun);
+        ++m_selfOnlyRefCount;
+    }
+
+    void selfOnlyDeref()
+    {
+        ASSERT(!m_deletionHasBegun || m_selfOnlyRefCount == 1);
+        --m_selfOnlyRefCount;
+        if (m_selfOnlyRefCount == 1 &amp;&amp; !refCount()) {
+#if !ASSERT_DISABLED
+            m_deletionHasBegun = true;
+#endif
+            delete this;
+        }
+    }
+
+    void removedLastRef();
+
</ins><span class="cx">     MediaQueryMatcher&amp; mediaQueryMatcher();
</span><span class="cx"> 
</span><span class="cx">     using ContainerNode::ref;
</span><span class="lines">@@ -1254,8 +1279,6 @@
</span><span class="cx">     void createRenderTree();
</span><span class="cx">     void detachParser();
</span><span class="cx"> 
</span><del>-    virtual void dropChildren() override;
-
</del><span class="cx">     typedef void (*ArgumentsCallback)(const String&amp; keyString, const String&amp; valueString, Document*, void* data);
</span><span class="cx">     void processArguments(const String&amp; features, void* data, ArgumentsCallback);
</span><span class="cx"> 
</span><span class="lines">@@ -1320,6 +1343,9 @@
</span><span class="cx">     void didAssociateFormControlsTimerFired(Timer&lt;Document&gt;&amp;);
</span><span class="cx"> 
</span><span class="cx">     void styleResolverThrowawayTimerFired(DeferrableOneShotTimer&lt;Document&gt;&amp;);
</span><ins>+
+    unsigned m_selfOnlyRefCount;
+
</ins><span class="cx">     DeferrableOneShotTimer&lt;Document&gt; m_styleResolverThrowawayTimer;
</span><span class="cx"> 
</span><span class="cx">     OwnPtr&lt;StyleResolver&gt; m_styleResolver;
</span><span class="lines">@@ -1679,17 +1705,17 @@
</span><span class="cx"> 
</span><span class="cx"> inline bool Node::isDocumentNode() const
</span><span class="cx"> {
</span><del>-    return this == documentInternal();
</del><ins>+    return this == &amp;document();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline Node::Node(Document* document, ConstructionType type)
</span><span class="cx">     : m_nodeFlags(type)
</span><span class="cx">     , m_parentNode(0)
</span><del>-    , m_treeScope(document ? document : &amp;TreeScope::noDocumentInstance())
</del><ins>+    , m_treeScope(document)
</ins><span class="cx">     , m_previous(0)
</span><span class="cx">     , m_next(0)
</span><span class="cx"> {
</span><del>-    m_treeScope-&gt;selfOnlyRef();
</del><ins>+    document-&gt;selfOnlyRef();
</ins><span class="cx"> 
</span><span class="cx"> #if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) &amp;&amp; DUMP_NODE_STATISTICS)
</span><span class="cx">     trackForDebugging();
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentOrderedMapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/DocumentOrderedMap.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/DocumentOrderedMap.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/DocumentOrderedMap.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -89,9 +89,10 @@
</span><span class="cx"> 
</span><span class="cx"> void DocumentOrderedMap::add(const AtomicStringImpl&amp; key, Element&amp; element, const TreeScope&amp; treeScope)
</span><span class="cx"> {
</span><ins>+    UNUSED_PARAM(treeScope);
</ins><span class="cx">     ASSERT_WITH_SECURITY_IMPLICATION(element.isInTreeScope());
</span><span class="cx">     ASSERT_WITH_SECURITY_IMPLICATION(treeScope.rootNode()-&gt;containsIncludingShadowDOM(&amp;element));
</span><del>-    if (!element.isInTreeScope() || &amp;element.document() != treeScope.documentScope())
</del><ins>+    if (!element.isInTreeScope())
</ins><span class="cx">         return;
</span><span class="cx">     Map::AddResult addResult = m_map.add(&amp;key, MapEntry(&amp;element));
</span><span class="cx">     if (addResult.isNewEntry)
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/Element.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -1353,9 +1353,9 @@
</span><span class="cx">         elementRareData()-&gt;clearClassListValueForQuirksMode();
</span><span class="cx"> 
</span><span class="cx">     TreeScope* newScope = &amp;insertionPoint.treeScope();
</span><del>-    HTMLDocument* newDocument = !wasInDocument &amp;&amp; inDocument() &amp;&amp; newScope-&gt;documentScope()-&gt;isHTMLDocument() ? toHTMLDocument(newScope-&gt;documentScope()) : 0;
</del><ins>+    HTMLDocument* newDocument = !wasInDocument &amp;&amp; inDocument() &amp;&amp; newScope-&gt;documentScope().isHTMLDocument() ? toHTMLDocument(&amp;newScope-&gt;documentScope()) : nullptr;
</ins><span class="cx">     if (newScope != &amp;treeScope())
</span><del>-        newScope = 0;
</del><ins>+        newScope = nullptr;
</ins><span class="cx"> 
</span><span class="cx">     const AtomicString&amp; idValue = getIdAttribute();
</span><span class="cx">     if (!idValue.isNull()) {
</span><span class="lines">@@ -1396,9 +1396,9 @@
</span><span class="cx"> 
</span><span class="cx">     if (insertionPoint.isInTreeScope()) {
</span><span class="cx">         TreeScope* oldScope = &amp;insertionPoint.treeScope();
</span><del>-        HTMLDocument* oldDocument = inDocument() &amp;&amp; oldScope-&gt;documentScope()-&gt;isHTMLDocument() ? toHTMLDocument(oldScope-&gt;documentScope()) : 0;
</del><ins>+        HTMLDocument* oldDocument = inDocument() &amp;&amp; oldScope-&gt;documentScope().isHTMLDocument() ? toHTMLDocument(&amp;oldScope-&gt;documentScope()) : nullptr;
</ins><span class="cx">         if (oldScope != &amp;treeScope())
</span><del>-            oldScope = 0;
</del><ins>+            oldScope = nullptr;
</ins><span class="cx"> 
</span><span class="cx">         const AtomicString&amp; idValue = getIdAttribute();
</span><span class="cx">         if (!idValue.isNull()) {
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/Node.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -305,12 +305,10 @@
</span><span class="cx">     if (hasRareData())
</span><span class="cx">         clearRareData();
</span><span class="cx"> 
</span><del>-    if (!isContainerNode()) {
-        if (Document* document = documentInternal())
-            willBeDeletedFrom(document);
-    }
</del><ins>+    if (!isContainerNode())
+        willBeDeletedFrom(&amp;document());
</ins><span class="cx"> 
</span><del>-    m_treeScope-&gt;selfOnlyDeref();
</del><ins>+    document().selfOnlyDeref();
</ins><span class="cx"> 
</span><span class="cx">     InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
</span><span class="cx"> }
</span><span class="lines">@@ -2190,31 +2188,6 @@
</span><span class="cx">     return hasEventListeners(eventNames().mousewheelEvent);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// This is here so it can be inlined into Node::removedLastRef.
-// FIXME: Really? Seems like this could be inlined into Node::removedLastRef if it was in TreeScope.h.
-// FIXME: It also not seem important to inline this. Is this really hot?
-inline void TreeScope::removedLastRefToScope()
-{
-    ASSERT(!deletionHasBegun());
-    if (m_selfOnlyRefCount) {
-        // If removing a child removes the last self-only ref, we don't want the scope to be destroyed
-        // until after removeDetachedChildren returns, so we protect ourselves with an extra self-only ref.
-        selfOnlyRef();
-        dropChildren();
-#ifndef NDEBUG
-        // We need to do this right now since selfOnlyDeref() can delete this.
-        rootNode()-&gt;m_inRemovedLastRefFunction = false;
-#endif
-        selfOnlyDeref();
-    } else {
-#ifndef NDEBUG
-        rootNode()-&gt;m_inRemovedLastRefFunction = false;
-        beginDeletion();
-#endif
-        delete this;
-    }
-}
-
</del><span class="cx"> // It's important not to inline removedLastRef, because we don't want to inline the code to
</span><span class="cx"> // delete a Node at each deref call site.
</span><span class="cx"> void Node::removedLastRef()
</span><span class="lines">@@ -2222,8 +2195,8 @@
</span><span class="cx">     // An explicit check for Document here is better than a virtual function since it is
</span><span class="cx">     // faster for non-Document nodes, and because the call to removedLastRef that is inlined
</span><span class="cx">     // at all deref call sites is smaller if it's a non-virtual function.
</span><del>-    if (isTreeScope()) {
-        treeScope().removedLastRefToScope();
</del><ins>+    if (isDocumentNode()) {
+        toDocument(*this).removedLastRef();
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.h (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.h        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/Node.h        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -382,8 +382,7 @@
</span><span class="cx">     Document&amp; document() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(this);
</span><del>-        ASSERT(documentInternal());
-        return *documentInternal();
</del><ins>+        return treeScope().documentScope();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     TreeScope&amp; treeScope() const
</span><span class="lines">@@ -396,7 +395,6 @@
</span><span class="cx">     // node tree, false otherwise.
</span><span class="cx">     bool inDocument() const 
</span><span class="cx">     { 
</span><del>-        ASSERT(documentInternal() || !getFlag(InDocumentFlag));
</del><span class="cx">         return getFlag(InDocumentFlag);
</span><span class="cx">     }
</span><span class="cx">     bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
</span><span class="lines">@@ -644,7 +642,6 @@
</span><span class="cx"> 
</span><span class="cx">     void setNeedsNodeRenderingTraversalSlowPath(bool flag) { setFlag(flag, NeedsNodeRenderingTraversalSlowPathFlag); }
</span><span class="cx"> 
</span><del>-    Document* documentInternal() const { return treeScope().documentScope(); }
</del><span class="cx">     void setTreeScope(TreeScope&amp; scope) { m_treeScope = &amp;scope; }
</span><span class="cx"> 
</span><span class="cx">     void setStyleChange(StyleChangeType changeType) { m_nodeFlags = (m_nodeFlags &amp; ~StyleChangeMask) | changeType; }
</span></span></pre></div>
<a id="trunkSourceWebCoredomShadowRootcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ShadowRoot.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ShadowRoot.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/ShadowRoot.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -52,9 +52,8 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> ShadowRoot::ShadowRoot(Document&amp; document, ShadowRootType type)
</span><del>-    : DocumentFragment(0, CreateShadowRoot)
-    , TreeScope(this, &amp;document)
-    , m_applyAuthorStyles(false)
</del><ins>+    : DocumentFragment(&amp;document, CreateShadowRoot)
+    , TreeScope(*this, document)
</ins><span class="cx">     , m_resetStyleInheritance(false)
</span><span class="cx">     , m_type(type)
</span><span class="cx">     , m_hostElement(0)
</span><span class="lines">@@ -67,24 +66,14 @@
</span><span class="cx">     // for this ShadowRoot instance because TreeScope destructor
</span><span class="cx">     // clears Node::m_treeScope thus ContainerNode is no longer able
</span><span class="cx">     // to access it Document reference after that.
</span><del>-    willBeDeletedFrom(documentInternal());
</del><ins>+    willBeDeletedFrom(&amp;document());
</ins><span class="cx"> 
</span><span class="cx">     // We must remove all of our children first before the TreeScope destructor
</span><span class="cx">     // runs so we don't go through TreeScopeAdopter for each child with a
</span><span class="cx">     // destructed tree scope in each descendant.
</span><span class="cx">     removeDetachedChildren();
</span><del>-
-    // We must call clearRareData() here since a ShadowRoot class inherits TreeScope
-    // as well as Node. See a comment on TreeScope.h for the reason.
-    if (hasRareData())
-        clearRareData();
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ShadowRoot::dropChildren()
-{
-    removeDetachedChildren();
-}
-
</del><span class="cx"> PassRefPtr&lt;Node&gt; ShadowRoot::cloneNode(bool, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     ec = DATA_CLONE_ERR;
</span><span class="lines">@@ -122,17 +111,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ShadowRoot::setApplyAuthorStyles(bool value)
-{
-    if (isOrphan())
-        return;
-
-    if (m_applyAuthorStyles != value) {
-        m_applyAuthorStyles = value;
-        hostElement()-&gt;setNeedsStyleRecalc();
-    }
-}
-
</del><span class="cx"> void ShadowRoot::setResetStyleInheritance(bool value)
</span><span class="cx"> {
</span><span class="cx">     if (isOrphan())
</span></span></pre></div>
<a id="trunkSourceWebCoredomShadowRooth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ShadowRoot.h (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ShadowRoot.h        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/ShadowRoot.h        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -50,8 +50,6 @@
</span><span class="cx"> 
</span><span class="cx">     virtual ~ShadowRoot();
</span><span class="cx"> 
</span><del>-    virtual bool applyAuthorStyles() const override { return m_applyAuthorStyles; }
-    void setApplyAuthorStyles(bool);
</del><span class="cx">     bool resetStyleInheritance() const { return m_resetStyleInheritance; }
</span><span class="cx">     void setResetStyleInheritance(bool);
</span><span class="cx"> 
</span><span class="lines">@@ -75,7 +73,6 @@
</span><span class="cx"> private:
</span><span class="cx">     ShadowRoot(Document&amp;, ShadowRootType);
</span><span class="cx"> 
</span><del>-    virtual void dropChildren() override;
</del><span class="cx">     virtual bool childTypeAllowed(NodeType) const override;
</span><span class="cx">     virtual void childrenChanged(const ChildChange&amp;) override;
</span><span class="cx"> 
</span><span class="lines">@@ -85,7 +82,6 @@
</span><span class="cx">     // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
</span><span class="cx">     bool isOrphan() const { return !hostElement(); }
</span><span class="cx"> 
</span><del>-    unsigned m_applyAuthorStyles : 1;
</del><span class="cx">     unsigned m_resetStyleInheritance : 1;
</span><span class="cx">     unsigned m_type : 1;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomTreeScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/TreeScope.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/TreeScope.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/TreeScope.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -49,60 +49,37 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> struct SameSizeAsTreeScope {
</span><del>-    virtual ~SameSizeAsTreeScope();
</del><span class="cx">     void* pointers[9];
</span><del>-    int ints[1];
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> COMPILE_ASSERT(sizeof(TreeScope) == sizeof(SameSizeAsTreeScope), treescope_should_stay_small);
</span><span class="cx"> 
</span><span class="cx"> using namespace HTMLNames;
</span><span class="cx"> 
</span><del>-TreeScope::TreeScope(ContainerNode* rootNode, Document* document)
-    : m_rootNode(rootNode)
-    , m_documentScope(document)
-    , m_parentTreeScope(document)
-    , m_selfOnlyRefCount(0)
</del><ins>+TreeScope::TreeScope(ShadowRoot&amp; shadowRoot, Document&amp; document)
+    : m_rootNode(shadowRoot)
+    , m_documentScope(&amp;document)
+    , m_parentTreeScope(&amp;document)
</ins><span class="cx">     , m_idTargetObserverRegistry(std::make_unique&lt;IdTargetObserverRegistry&gt;())
</span><span class="cx"> {
</span><del>-    ASSERT(rootNode);
-    ASSERT(document);
-    ASSERT(rootNode != document);
-    m_parentTreeScope-&gt;selfOnlyRef();
-    m_rootNode-&gt;setTreeScope(*this);
</del><ins>+    shadowRoot.setTreeScope(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-TreeScope::TreeScope(Document* document)
</del><ins>+TreeScope::TreeScope(Document&amp; document)
</ins><span class="cx">     : m_rootNode(document)
</span><del>-    , m_documentScope(document)
</del><ins>+    , m_documentScope(&amp;document)
</ins><span class="cx">     , m_parentTreeScope(nullptr)
</span><del>-    , m_selfOnlyRefCount(0)
</del><span class="cx">     , m_idTargetObserverRegistry(std::make_unique&lt;IdTargetObserverRegistry&gt;())
</span><span class="cx"> {
</span><del>-    ASSERT(document);
-    m_rootNode-&gt;setTreeScope(*this);
</del><ins>+    document.setTreeScope(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-TreeScope::TreeScope()
-    : m_rootNode(nullptr)
-    , m_documentScope(nullptr)
-    , m_parentTreeScope(nullptr)
-    , m_selfOnlyRefCount(0)
-{
-}
-
</del><span class="cx"> TreeScope::~TreeScope()
</span><span class="cx"> {
</span><del>-    ASSERT(!m_selfOnlyRefCount);
-    m_rootNode-&gt;setTreeScope(noDocumentInstance());
-
</del><span class="cx">     if (m_selection) {
</span><span class="cx">         m_selection-&gt;clearTreeScope();
</span><span class="cx">         m_selection = nullptr;
</span><span class="cx">     }
</span><del>-
-    if (m_parentTreeScope)
-        m_parentTreeScope-&gt;selfOnlyDeref();
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TreeScope::destroyTreeScopeData()
</span><span class="lines">@@ -112,12 +89,6 @@
</span><span class="cx">     m_labelsByForAttribute = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TreeScope::clearDocumentScope()
-{
-    ASSERT(rootNode()-&gt;isDocumentNode());
-    m_documentScope = nullptr;
-}
-
</del><span class="cx"> void TreeScope::setParentTreeScope(TreeScope* newParentScope)
</span><span class="cx"> {
</span><span class="cx">     // A document node cannot be re-parented.
</span><span class="lines">@@ -125,11 +96,8 @@
</span><span class="cx">     // Every scope other than document needs a parent scope.
</span><span class="cx">     ASSERT(newParentScope);
</span><span class="cx"> 
</span><del>-    newParentScope-&gt;selfOnlyRef();
-    if (m_parentTreeScope)
-        m_parentTreeScope-&gt;selfOnlyDeref();
</del><span class="cx">     m_parentTreeScope = newParentScope;
</span><del>-    setDocumentScope(newParentScope-&gt;documentScope());
</del><ins>+    setDocumentScope(&amp;newParentScope-&gt;documentScope());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Element* TreeScope::getElementById(const AtomicString&amp; elementId) const
</span><span class="lines">@@ -345,11 +313,6 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool TreeScope::applyAuthorStyles() const
-{
-    return true;
-}
-
</del><span class="cx"> void TreeScope::adoptIfNeeded(Node* node)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(this);
</span><span class="lines">@@ -426,24 +389,4 @@
</span><span class="cx">     return treeScopesA[indexA] == treeScopesB[indexB] ? treeScopesA[indexA] : nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#ifndef NDEBUG
-bool TreeScope::deletionHasBegun()
-{
-    return rootNode() &amp;&amp; rootNode()-&gt;m_deletionHasBegun;
-}
-
-void TreeScope::beginDeletion()
-{
-    ASSERT(this != &amp;noDocumentInstance());
-    rootNode()-&gt;m_deletionHasBegun = true;
-}
-#endif
-
-int TreeScope::refCount() const
-{
-    if (Node* root = rootNode())
-        return root-&gt;refCount();
-    return 0;
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoredomTreeScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/TreeScope.h (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/TreeScope.h        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/TreeScope.h        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -43,10 +43,8 @@
</span><span class="cx"> class LayoutPoint;
</span><span class="cx"> class IdTargetObserverRegistry;
</span><span class="cx"> class Node;
</span><ins>+class ShadowRoot;
</ins><span class="cx"> 
</span><del>-// A class which inherits both Node and TreeScope must call clearRareData() in its destructor
-// so that the Node destructor no longer does problematic NodeList cache manipulation in
-// the destructor.
</del><span class="cx"> class TreeScope {
</span><span class="cx">     friend class Document;
</span><span class="cx">     friend class TreeScopeAdopter;
</span><span class="lines">@@ -69,7 +67,7 @@
</span><span class="cx">     void addElementByName(const AtomicStringImpl&amp;, Element&amp;);
</span><span class="cx">     void removeElementByName(const AtomicStringImpl&amp;, Element&amp;);
</span><span class="cx"> 
</span><del>-    Document* documentScope() const { return m_documentScope; }
</del><ins>+    Document&amp; documentScope() const { return *m_documentScope; }
</ins><span class="cx"> 
</span><span class="cx">     Node* ancestorInThisScope(Node*) const;
</span><span class="cx"> 
</span><span class="lines">@@ -94,76 +92,29 @@
</span><span class="cx">     // quirks mode for historical compatibility reasons.
</span><span class="cx">     Element* findAnchor(const String&amp; name);
</span><span class="cx"> 
</span><del>-    virtual bool applyAuthorStyles() const;
-
</del><span class="cx">     // Used by the basic DOM mutation methods (e.g., appendChild()).
</span><span class="cx">     void adoptIfNeeded(Node*);
</span><span class="cx"> 
</span><del>-    ContainerNode* rootNode() const { return m_rootNode; }
</del><ins>+    ContainerNode* rootNode() const { return &amp;m_rootNode; }
</ins><span class="cx"> 
</span><span class="cx">     IdTargetObserverRegistry&amp; idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); }
</span><span class="cx"> 
</span><del>-    static TreeScope&amp; noDocumentInstance()
-    {
-        DEFINE_STATIC_LOCAL(TreeScope, instance, ());
-        return instance;
-    }
-
-    // Nodes belonging to this scope hold self-only references -
-    // these are enough to keep the scope from being destroyed, but
-    // not enough to keep it from removing its children. This allows a
-    // node that outlives its scope to still have a valid document
-    // pointer without introducing reference cycles.
-    void selfOnlyRef()
-    {
-        ASSERT(!deletionHasBegun());
-        ++m_selfOnlyRefCount;
-    }
-
-    void selfOnlyDeref()
-    {
-        ASSERT(!deletionHasBegun());
-        --m_selfOnlyRefCount;
-        if (!m_selfOnlyRefCount &amp;&amp; !refCount() &amp;&amp; this != &amp;noDocumentInstance()) {
-            beginDeletion();
-            delete this;
-        }
-    }
-
-    void removedLastRefToScope();
-
</del><span class="cx"> protected:
</span><del>-    TreeScope(ContainerNode*, Document*);
-    explicit TreeScope(Document*);
-    virtual ~TreeScope();
</del><ins>+    TreeScope(ShadowRoot&amp;, Document&amp;);
+    explicit TreeScope(Document&amp;);
+    ~TreeScope();
</ins><span class="cx"> 
</span><span class="cx">     void destroyTreeScopeData();
</span><del>-    void clearDocumentScope();
</del><span class="cx">     void setDocumentScope(Document* document)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(document);
</span><del>-        ASSERT(this != &amp;noDocumentInstance());
</del><span class="cx">         m_documentScope = document;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    TreeScope();
-
-    virtual void dropChildren() { }
-
-    int refCount() const;
-#ifndef NDEBUG
-    bool deletionHasBegun();
-    void beginDeletion();
-#else
-    bool deletionHasBegun() { return false; }
-    void beginDeletion() { }
-#endif
-
-    ContainerNode* m_rootNode;
</del><ins>+    ContainerNode&amp; m_rootNode;
</ins><span class="cx">     Document* m_documentScope;
</span><span class="cx">     TreeScope* m_parentTreeScope;
</span><del>-    unsigned m_selfOnlyRefCount;
</del><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;DocumentOrderedMap&gt; m_elementsById;
</span><span class="cx">     std::unique_ptr&lt;DocumentOrderedMap&gt; m_elementsByName;
</span></span></pre></div>
<a id="trunkSourceWebCoredomTreeScopeAdoptercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/TreeScopeAdopter.cpp (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/TreeScopeAdopter.cpp        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/TreeScopeAdopter.cpp        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -32,27 +32,28 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+// FIXME: Do we ever change tree scopes except between documents?
</ins><span class="cx"> void TreeScopeAdopter::moveTreeToNewScope(Node* root) const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(needsScopeChange());
</span><span class="cx"> 
</span><del>-    m_oldScope.selfOnlyRef();
-
</del><span class="cx">     // If an element is moved from a document and then eventually back again the collection cache for
</span><span class="cx">     // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
</span><span class="cx">     // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
</span><span class="cx">     // we ensure that the collection cache will be invalidated as needed when the element is moved back.
</span><del>-    Document* oldDocument = m_oldScope.documentScope();
-    Document* newDocument = m_newScope.documentScope();
-    bool willMoveToNewDocument = oldDocument != newDocument;
-    if (oldDocument &amp;&amp; willMoveToNewDocument)
-        oldDocument-&gt;incDOMTreeVersion();
</del><ins>+    Document&amp; oldDocument = m_oldScope.documentScope();
+    Document&amp; newDocument = m_newScope.documentScope();
+    bool willMoveToNewDocument = &amp;oldDocument != &amp;newDocument;
+    if (willMoveToNewDocument) {
+        oldDocument.selfOnlyRef();
+        oldDocument.incDOMTreeVersion();
+    }
</ins><span class="cx"> 
</span><span class="cx">     for (Node* node = root; node; node = NodeTraversal::next(node, root)) {
</span><span class="cx">         updateTreeScope(node);
</span><span class="cx"> 
</span><span class="cx">         if (willMoveToNewDocument)
</span><del>-            moveNodeToNewDocument(node, oldDocument, newDocument);
</del><ins>+            moveNodeToNewDocument(node, &amp;oldDocument, &amp;newDocument);
</ins><span class="cx">         else if (node-&gt;hasRareData()) {
</span><span class="cx">             NodeRareData* rareData = node-&gt;rareData();
</span><span class="cx">             if (rareData-&gt;nodeLists())
</span><span class="lines">@@ -71,19 +72,20 @@
</span><span class="cx">         if (ShadowRoot* shadow = node-&gt;shadowRoot()) {
</span><span class="cx">             shadow-&gt;setParentTreeScope(&amp;m_newScope);
</span><span class="cx">             if (willMoveToNewDocument)
</span><del>-                moveTreeToNewDocument(shadow, oldDocument, newDocument);
</del><ins>+                moveShadowTreeToNewDocument(shadow, &amp;oldDocument, &amp;newDocument);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_oldScope.selfOnlyDeref();
</del><ins>+    if (willMoveToNewDocument)
+        oldDocument.selfOnlyDeref();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TreeScopeAdopter::moveTreeToNewDocument(Node* root, Document* oldDocument, Document* newDocument) const
</del><ins>+void TreeScopeAdopter::moveShadowTreeToNewDocument(ShadowRoot* shadowRoot, Document* oldDocument, Document* newDocument) const
</ins><span class="cx"> {
</span><del>-    for (Node* node = root; node; node = NodeTraversal::next(node, root)) {
</del><ins>+    for (Node* node = shadowRoot; node; node = NodeTraversal::next(node, shadowRoot)) {
</ins><span class="cx">         moveNodeToNewDocument(node, oldDocument, newDocument);
</span><span class="cx">         if (ShadowRoot* shadow = node-&gt;shadowRoot())
</span><del>-            moveTreeToNewDocument(shadow, oldDocument, newDocument);
</del><ins>+            moveShadowTreeToNewDocument(shadow, oldDocument, newDocument);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -103,8 +105,6 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!node-&gt;isTreeScope());
</span><span class="cx">     ASSERT(&amp;node-&gt;treeScope() == &amp;m_oldScope);
</span><del>-    m_newScope.selfOnlyRef();
-    m_oldScope.selfOnlyDeref();
</del><span class="cx">     node-&gt;setTreeScope(m_newScope);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -112,6 +112,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!node-&gt;inDocument() || oldDocument != newDocument);
</span><span class="cx"> 
</span><ins>+    newDocument-&gt;selfOnlyRef();
+    oldDocument-&gt;selfOnlyDeref();
+
</ins><span class="cx">     if (node-&gt;hasRareData()) {
</span><span class="cx">         NodeRareData* rareData = node-&gt;rareData();
</span><span class="cx">         if (rareData-&gt;nodeLists())
</span></span></pre></div>
<a id="trunkSourceWebCoredomTreeScopeAdopterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/TreeScopeAdopter.h (164194 => 164195)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/TreeScopeAdopter.h        2014-02-16 22:00:21 UTC (rev 164194)
+++ trunk/Source/WebCore/dom/TreeScopeAdopter.h        2014-02-16 22:18:13 UTC (rev 164195)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx"> private:
</span><span class="cx">     void updateTreeScope(Node*) const;
</span><span class="cx">     void moveTreeToNewScope(Node*) const;
</span><del>-    void moveTreeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
</del><ins>+    void moveShadowTreeToNewDocument(ShadowRoot*, Document* oldDocument, Document* newDocument) const;
</ins><span class="cx">     void moveNodeToNewDocument(Node*, Document* oldDocument, Document* newDocument) const;
</span><span class="cx"> 
</span><span class="cx">     Node* m_toAdopt;
</span></span></pre>
</div>
</div>

</body>
</html>