Title: [136871] trunk/Source/WebCore
Revision
136871
Author
[email protected]
Date
2012-12-06 12:16:22 -0800 (Thu, 06 Dec 2012)

Log Message

Create only NodeRareDataBase when setting TreeScope
https://bugs.webkit.org/show_bug.cgi?id=104202

Patch by Elliott Sprehn <[email protected]> on 2012-12-06
Reviewed by Dimitri Glazkov.

Move many fields from NodeRareData into NodeRareDataBase and rename it
UncommonNodeData and add a flag to determine if a UncommonNodeData is
actually a full NodeRareData instance. By moving fields up from NodeRareData
we ensure that this new flag in the base class doesn't make NodeRareData
grow in size.

We then make setting the tree scope only allocate the UncommonNodeData
instead of creating the full NodeRareData or ElementRareData. This is
important because when putting nodes into ShadowRoot or any descendant
we must associate the node with a tree scope which adds rare data to the
node making NodeRareData and ElementRareData not very rare.

On 64bit, this reduces the overhead per element from 136 bytes to
32 bytes for a 76% savings, and on other nodes from 64 bytes to 32 bytes
for a 50% savings.

No new tests, no change in behavior.

* dom/Document.h:
(WebCore::Node::treeScope):
* dom/Element.cpp:
(WebCore::Element::createRareData):
* dom/ElementRareData.h:
(ElementRareData):
(WebCore::ElementRareData::ElementRareData):
* dom/Node.cpp:
(WebCore::Node::setTreeScope):
(WebCore::Node::ensureRareData):
(WebCore::Node::createRareData):
(WebCore::Node::clearRareData):
* dom/Node.h:
(WebCore::UncommonNodeData::create):
(UncommonNodeData):
(WebCore::UncommonNodeData::~UncommonNodeData):
(WebCore::UncommonNodeData::isNodeRareData):
(WebCore::UncommonNodeData::UncommonNodeData):
(WebCore::Node::renderer):
(WebCore::Node::setRenderer):
(Node):
(WebCore::Node::hasRareData):
(WebCore::Node::hasUncommonNodeData):
* dom/NodeRareData.h:
(WebCore::NodeRareData::NodeRareData):
(NodeRareData):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (136870 => 136871)


--- trunk/Source/WebCore/ChangeLog	2012-12-06 20:13:09 UTC (rev 136870)
+++ trunk/Source/WebCore/ChangeLog	2012-12-06 20:16:22 UTC (rev 136871)
@@ -1,3 +1,55 @@
+2012-12-06  Elliott Sprehn  <[email protected]>
+
+        Create only NodeRareDataBase when setting TreeScope
+        https://bugs.webkit.org/show_bug.cgi?id=104202
+
+        Reviewed by Dimitri Glazkov.
+
+        Move many fields from NodeRareData into NodeRareDataBase and rename it
+        UncommonNodeData and add a flag to determine if a UncommonNodeData is
+        actually a full NodeRareData instance. By moving fields up from NodeRareData
+        we ensure that this new flag in the base class doesn't make NodeRareData
+        grow in size.
+
+        We then make setting the tree scope only allocate the UncommonNodeData
+        instead of creating the full NodeRareData or ElementRareData. This is
+        important because when putting nodes into ShadowRoot or any descendant
+        we must associate the node with a tree scope which adds rare data to the
+        node making NodeRareData and ElementRareData not very rare.
+
+        On 64bit, this reduces the overhead per element from 136 bytes to
+        32 bytes for a 76% savings, and on other nodes from 64 bytes to 32 bytes
+        for a 50% savings.
+
+        No new tests, no change in behavior.
+
+        * dom/Document.h:
+        (WebCore::Node::treeScope):
+        * dom/Element.cpp:
+        (WebCore::Element::createRareData):
+        * dom/ElementRareData.h:
+        (ElementRareData):
+        (WebCore::ElementRareData::ElementRareData):
+        * dom/Node.cpp:
+        (WebCore::Node::setTreeScope):
+        (WebCore::Node::ensureRareData):
+        (WebCore::Node::createRareData):
+        (WebCore::Node::clearRareData):
+        * dom/Node.h:
+        (WebCore::UncommonNodeData::create):
+        (UncommonNodeData):
+        (WebCore::UncommonNodeData::~UncommonNodeData):
+        (WebCore::UncommonNodeData::isNodeRareData):
+        (WebCore::UncommonNodeData::UncommonNodeData):
+        (WebCore::Node::renderer):
+        (WebCore::Node::setRenderer):
+        (Node):
+        (WebCore::Node::hasRareData):
+        (WebCore::Node::hasUncommonNodeData):
+        * dom/NodeRareData.h:
+        (WebCore::NodeRareData::NodeRareData):
+        (NodeRareData):
+
 2012-12-06  Joshua Bell  <[email protected]>
 
         IndexedDB: Remove IDBDatabaseException.idl

Modified: trunk/Source/WebCore/dom/Document.h (136870 => 136871)


--- trunk/Source/WebCore/dom/Document.h	2012-12-06 20:13:09 UTC (rev 136870)
+++ trunk/Source/WebCore/dom/Document.h	2012-12-06 20:16:22 UTC (rev 136871)
@@ -1554,7 +1554,7 @@
 
 inline TreeScope* Node::treeScope() const
 {
-    return hasRareData() ? m_data.m_rareData->treeScope() : documentInternal();
+    return hasUncommonNodeData() ? m_data.m_rareData->treeScope() : documentInternal();
 }
 
 inline Node::Node(Document* document, ConstructionType type)

Modified: trunk/Source/WebCore/dom/Element.cpp (136870 => 136871)


--- trunk/Source/WebCore/dom/Element.cpp	2012-12-06 20:13:09 UTC (rev 136870)
+++ trunk/Source/WebCore/dom/Element.cpp	2012-12-06 20:16:22 UTC (rev 136871)
@@ -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 (136870 => 136871)


--- trunk/Source/WebCore/dom/ElementRareData.h	2012-12-06 20:13:09 UTC (rev 136870)
+++ trunk/Source/WebCore/dom/ElementRareData.h	2012-12-06 20:16:22 UTC (rev 136871)
@@ -35,7 +35,7 @@
 
 class ElementRareData : public NodeRareData {
 public:
-    ElementRareData(Document*);
+    ElementRareData();
     virtual ~ElementRareData();
 
     void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
@@ -130,9 +130,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 (136870 => 136871)


--- trunk/Source/WebCore/dom/Node.cpp	2012-12-06 20:13:09 UTC (rev 136870)
+++ trunk/Source/WebCore/dom/Node.cpp	2012-12-06 20:16:22 UTC (rev 136871)
@@ -441,10 +441,14 @@
 
 void Node::setTreeScope(TreeScope* scope)
 {
-    if (!hasRareData() && scope->rootNode()->isDocumentNode())
+    if (!hasUncommonNodeData() && scope->rootNode()->isDocumentNode())
         return;
 
-    ensureRareData()->setTreeScope(scope);
+    if (!hasUncommonNodeData()) {
+        m_data.m_rareData = UncommonNodeData::create(scope, m_data.m_renderer);
+        setFlag(HasUncommonNodeData);
+    } else
+        rareData()->setTreeScope(scope);
 }
 
 Node* Node::pseudoAwarePreviousSibling() const
@@ -488,15 +492,21 @@
 
     NodeRareData* data = ""
     ASSERT(data);
-    data->setRenderer(m_data.m_renderer);
+    data->setRenderer(renderer());
+    data->setTreeScope(treeScope());
+
+    if (hasUncommonNodeData())
+        delete m_data.m_rareData;
+
     m_data.m_rareData = data;
-    setFlag(HasRareDataFlag);
+    setFlag(HasUncommonNodeData);
+
     return data;
 }
 
 PassOwnPtr<NodeRareData> Node::createRareData()
 {
-    return adoptPtr(new NodeRareData(documentInternal()));
+    return adoptPtr(new NodeRareData());
 }
 
 void Node::clearRareData()
@@ -510,7 +520,7 @@
     RenderObject* renderer = m_data.m_rareData->renderer();
     delete m_data.m_rareData;
     m_data.m_renderer = renderer;
-    clearFlag(HasRareDataFlag);
+    clearFlag(HasUncommonNodeData);
 }
 
 Node* Node::toNode()

Modified: trunk/Source/WebCore/dom/Node.h (136870 => 136871)


--- trunk/Source/WebCore/dom/Node.h	2012-12-06 20:13:09 UTC (rev 136870)
+++ trunk/Source/WebCore/dom/Node.h	2012-12-06 20:16:22 UTC (rev 136871)
@@ -110,23 +110,85 @@
     SyntheticStyleChange = 3 << nodeStyleChangeShift
 };
 
-class NodeRareDataBase {
+class UncommonNodeData {
 public:
+    static UncommonNodeData* create(TreeScope* scope, RenderObject* renderer)
+    {
+        return new UncommonNodeData(scope, renderer);
+    }
+
     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() { }
+    virtual ~UncommonNodeData() { }
+
+    bool isNodeRareData() const { return m_isNodeRareData; }
+
 protected:
-    NodeRareDataBase(TreeScope* scope)
-        : m_treeScope(scope)
+    UncommonNodeData()
+        : m_tabIndex(0)
+        , m_childIndex(0)
+        , m_isNodeRareData(true)
+        , m_tabIndexWasSetExplicitly(false)
+        , m_isFocused(false)
+        , m_needsFocusAppearanceUpdateSoonAfterAttach(false)
+        , m_styleAffectedByEmpty(false)
+        , m_isInCanvasSubtree(false)
+#if ENABLE(FULLSCREEN_API)
+        , m_containsFullScreenElement(false)
+#endif
+#if ENABLE(DIALOG_ELEMENT)
+        , m_isInTopLayer(false)
+#endif
+        , m_childrenAffectedByHover(false)
+        , m_childrenAffectedByActive(false)
+        , m_childrenAffectedByDrag(false)
+        , m_childrenAffectedByFirstChildRules(false)
+        , m_childrenAffectedByLastChildRules(false)
+        , m_childrenAffectedByDirectAdjacentRules(false)
+        , m_childrenAffectedByForwardPositionalRules(false)
+        , m_childrenAffectedByBackwardPositionalRules(false)
     {
     }
 private:
+    UncommonNodeData(TreeScope* scope, RenderObject* renderer)
+        : m_renderer(renderer)
+        , m_treeScope(scope)
+        , m_isNodeRareData(false)
+    {
+    }
+
     RenderObject* m_renderer;
     TreeScope* m_treeScope;
+protected:
+    short m_tabIndex;
+    unsigned short m_childIndex;
+    bool m_isNodeRareData : 1;
+    bool m_tabIndexWasSetExplicitly : 1;
+    bool m_isFocused : 1;
+    bool m_needsFocusAppearanceUpdateSoonAfterAttach : 1;
+    bool m_styleAffectedByEmpty : 1;
+    bool m_isInCanvasSubtree : 1;
+#if ENABLE(FULLSCREEN_API)
+    bool m_containsFullScreenElement : 1;
+#endif
+#if ENABLE(DIALOG_ELEMENT)
+    bool m_isInTopLayer : 1;
+#endif
+    bool m_childrenAffectedByHover : 1;
+    bool m_childrenAffectedByActive : 1;
+    bool m_childrenAffectedByDrag : 1;
+    // Bits for dynamic child matching.
+    // We optimize for :first-child and :last-child. The other positional child selectors like nth-child or
+    // *-child-of-type, we will just give up and re-evaluate whenever children change at all.
+    bool m_childrenAffectedByFirstChildRules : 1;
+    bool m_childrenAffectedByLastChildRules : 1;
+    bool m_childrenAffectedByDirectAdjacentRules : 1;
+    bool m_childrenAffectedByForwardPositionalRules : 1;
+    bool m_childrenAffectedByBackwardPositionalRules : 1;
 };
 
 class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node, ContainerNode> {
@@ -523,10 +585,10 @@
     // Integration with rendering tree
 
     // As renderer() includes a branch you should avoid calling it repeatedly in hot code paths.
-    RenderObject* renderer() const { return hasRareData() ? m_data.m_rareData->renderer() : m_data.m_renderer; };
+    RenderObject* renderer() const { return hasUncommonNodeData() ? m_data.m_rareData->renderer() : m_data.m_renderer; };
     void setRenderer(RenderObject* renderer)
     {
-        if (hasRareData())
+        if (hasUncommonNodeData())
             m_data.m_rareData->setRenderer(renderer);
         else
             m_data.m_renderer = renderer;
@@ -710,7 +772,7 @@
         IsActiveFlag = 1 << 10,
         IsHoveredFlag = 1 << 11,
         InActiveChainFlag = 1 << 12,
-        HasRareDataFlag = 1 << 13,
+        HasUncommonNodeData = 1 << 13,
         IsDocumentFragmentFlag = 1 << 14,
 
         // These bits are used by derived classes, pulled up here so they can
@@ -774,9 +836,9 @@
     virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
     void setTabIndexExplicitly(short);
     void clearTabIndexExplicitly();
-    
-    bool hasRareData() const { return getFlag(HasRareDataFlag); }
 
+    bool hasRareData() const { return hasUncommonNodeData() && m_data.m_rareData->isNodeRareData(); }
+
     NodeRareData* rareData() const;
     NodeRareData* ensureRareData();
     void clearRareData();
@@ -808,6 +870,7 @@
     virtual void refEventTarget();
     virtual void derefEventTarget();
 
+    bool hasUncommonNodeData() const { return getFlag(HasUncommonNodeData); }
     virtual PassOwnPtr<NodeRareData> createRareData();
     bool rareDataFocused() const;
 
@@ -844,7 +907,7 @@
     union DataUnion {
         DataUnion() : m_renderer(0) { }
         RenderObject* m_renderer;
-        NodeRareDataBase* m_rareData;
+        UncommonNodeData* m_rareData;
     } m_data;
 
 protected:

Modified: trunk/Source/WebCore/dom/NodeRareData.h (136870 => 136871)


--- trunk/Source/WebCore/dom/NodeRareData.h	2012-12-06 20:13:09 UTC (rev 136870)
+++ trunk/Source/WebCore/dom/NodeRareData.h	2012-12-06 20:16:22 UTC (rev 136871)
@@ -196,33 +196,11 @@
     TagNodeListCacheNS m_tagNodeListCacheNS;
 };
 
-class NodeRareData : public NodeRareDataBase {
+class NodeRareData : public UncommonNodeData {
     WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED;
 public:    
-    NodeRareData(Document* document)
-        : NodeRareDataBase(document)
-        , m_childNodeList(0)
-        , m_tabIndex(0)
-        , m_childIndex(0)
-        , m_tabIndexWasSetExplicitly(false)
-        , m_isFocused(false)
-        , m_needsFocusAppearanceUpdateSoonAfterAttach(false)
-        , m_styleAffectedByEmpty(false)
-        , m_isInCanvasSubtree(false)
-#if ENABLE(FULLSCREEN_API)
-        , m_containsFullScreenElement(false)
-#endif
-#if ENABLE(DIALOG_ELEMENT)
-        , m_isInTopLayer(false)
-#endif
-        , m_childrenAffectedByHover(false)
-        , m_childrenAffectedByActive(false)
-        , m_childrenAffectedByDrag(false)
-        , m_childrenAffectedByFirstChildRules(false)
-        , m_childrenAffectedByLastChildRules(false)
-        , m_childrenAffectedByDirectAdjacentRules(false)
-        , m_childrenAffectedByForwardPositionalRules(false)
-        , m_childrenAffectedByBackwardPositionalRules(false)
+    NodeRareData()
+        : m_childNodeList(0)
     {
     }
 
@@ -326,33 +304,9 @@
 
     virtual void reportMemoryUsage(MemoryObjectInfo*) const;
 
-protected:
+private:
     OwnPtr<NodeListsNodeData> m_nodeLists;
     ChildNodeList* m_childNodeList;
-    short m_tabIndex;
-    unsigned short m_childIndex;
-    bool m_tabIndexWasSetExplicitly : 1;
-    bool m_isFocused : 1;
-    bool m_needsFocusAppearanceUpdateSoonAfterAttach : 1;
-    bool m_styleAffectedByEmpty : 1;
-    bool m_isInCanvasSubtree : 1;
-#if ENABLE(FULLSCREEN_API)
-    bool m_containsFullScreenElement : 1;
-#endif
-#if ENABLE(DIALOG_ELEMENT)
-    bool m_isInTopLayer : 1;
-#endif
-    bool m_childrenAffectedByHover : 1;
-    bool m_childrenAffectedByActive : 1;
-    bool m_childrenAffectedByDrag : 1;
-    // Bits for dynamic child matching.
-    // We optimize for :first-child and :last-child. The other positional child selectors like nth-child or
-    // *-child-of-type, we will just give up and re-evaluate whenever children change at all.
-    bool m_childrenAffectedByFirstChildRules : 1;
-    bool m_childrenAffectedByLastChildRules : 1;
-    bool m_childrenAffectedByDirectAdjacentRules : 1;
-    bool m_childrenAffectedByForwardPositionalRules : 1;
-    bool m_childrenAffectedByBackwardPositionalRules : 1;
 
 #if ENABLE(MUTATION_OBSERVERS)
     OwnPtr<Vector<OwnPtr<MutationObserverRegistration> > > m_mutationObserverRegistry;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to