Diff
Modified: trunk/Source/WebCore/ChangeLog (236240 => 236241)
--- trunk/Source/WebCore/ChangeLog 2018-09-20 05:54:27 UTC (rev 236240)
+++ trunk/Source/WebCore/ChangeLog 2018-09-20 06:14:59 UTC (rev 236241)
@@ -1,5 +1,29 @@
2018-09-19 Ryosuke Niwa <[email protected]>
+ Improve node statistics for rare data
+ https://bugs.webkit.org/show_bug.cgi?id=189775
+
+ Reviewed by Simon Fraser.
+
+ Report reasons we created NodeRareData and ElementRareData in node statistics.
+
+ Added NodeRareData::useTypes and ElementRareData::useTypes which returns OptionSet<NodeRareData::UseType>
+ indicating which instance member of the rare data is currently in use.
+
+ * dom/Element.cpp:
+ * dom/Element.h:
+ * dom/ElementRareData.h:
+ (WebCore::defaultMinimumSizeForResizing):
+ (WebCore::ElementRareData::useTypes const):
+ * dom/Node.cpp:
+ (WebCore::stringForRareDataUseType):
+ (WebCore::Node::dumpStatistics):
+ * dom/NodeRareData.cpp:
+ * dom/NodeRareData.h:
+ (WebCore::NodeRareData::useTypes const):
+
+2018-09-19 Ryosuke Niwa <[email protected]>
+
REGRESSION(r235917): 2% regression in Dromaeo CSS selector on MacBookPro11,4
https://bugs.webkit.org/show_bug.cgi?id=189738
Modified: trunk/Source/WebCore/dom/Element.cpp (236240 => 236241)
--- trunk/Source/WebCore/dom/Element.cpp 2018-09-20 05:54:27 UTC (rev 236240)
+++ trunk/Source/WebCore/dom/Element.cpp 2018-09-20 06:14:59 UTC (rev 236241)
@@ -3442,7 +3442,7 @@
}
#endif
-#ifdef DUMP_NODE_STATISTICS
+#if DUMP_NODE_STATISTICS
bool Element::hasNamedNodeMap() const
{
return hasRareData() && elementRareData()->attributeMap();
Modified: trunk/Source/WebCore/dom/Element.h (236240 => 236241)
--- trunk/Source/WebCore/dom/Element.h 2018-09-20 05:54:27 UTC (rev 236240)
+++ trunk/Source/WebCore/dom/Element.h 2018-09-20 06:14:59 UTC (rev 236241)
@@ -104,7 +104,7 @@
WEBCORE_EXPORT bool fastAttributeLookupAllowed(const QualifiedName&) const;
#endif
-#ifdef DUMP_NODE_STATISTICS
+#if DUMP_NODE_STATISTICS
bool hasNamedNodeMap() const;
#endif
WEBCORE_EXPORT bool hasAttributes() const;
Modified: trunk/Source/WebCore/dom/ElementRareData.h (236240 => 236241)
--- trunk/Source/WebCore/dom/ElementRareData.h 2018-09-20 05:54:27 UTC (rev 236240)
+++ trunk/Source/WebCore/dom/ElementRareData.h 2018-09-20 06:14:59 UTC (rev 236241)
@@ -33,6 +33,11 @@
namespace WebCore {
+inline IntSize defaultMinimumSizeForResizing()
+{
+ return IntSize(LayoutUnit::max(), LayoutUnit::max());
+}
+
class ElementRareData : public NodeRareData {
public:
explicit ElementRareData(RenderElement*);
@@ -122,6 +127,41 @@
void setIntersectionObserverData(std::unique_ptr<IntersectionObserverData>&& data) { m_intersectionObserverData = WTFMove(data); }
#endif
+#if DUMP_NODE_STATISTICS
+ OptionSet<UseType> useTypes() const
+ {
+ auto result = NodeRareData::useTypes();
+ if (m_tabIndexWasSetExplicitly)
+ result.add(UseType::TabIndex);
+ if (m_styleAffectedByActive || m_styleAffectedByEmpty || m_styleAffectedByFocusWithin || m_childrenAffectedByHover
+ || m_childrenAffectedByDrag || m_childrenAffectedByLastChildRules || m_childrenAffectedByForwardPositionalRules
+ || m_descendantsAffectedByForwardPositionalRules || m_childrenAffectedByBackwardPositionalRules
+ || m_descendantsAffectedByBackwardPositionalRules || m_childrenAffectedByPropertyBasedBackwardPositionalRules)
+ result.add(UseType::StyleFlags);
+ if (m_minimumSizeForResizing != defaultMinimumSizeForResizing())
+ result.add(UseType::MinimumSize);
+ if (!m_savedLayerScrollPosition.isZero())
+ result.add(UseType::ScrollingPosition);
+ if (m_computedStyle)
+ result.add(UseType::ComputedStyle);
+ if (m_dataset)
+ result.add(UseType::Dataset);
+ if (m_classList)
+ result.add(UseType::ClassList);
+ if (m_shadowRoot)
+ result.add(UseType::ShadowRoot);
+ if (m_customElementReactionQueue)
+ result.add(UseType::CustomElementQueue);
+ if (m_attributeMap)
+ result.add(UseType::AttributeMap);
+ if (m_intersectionObserverData)
+ result.add(UseType::InteractionObserver);
+ if (m_beforePseudoElement || m_afterPseudoElement)
+ result.add(UseType::PseudoElements);
+ return result;
+ }
+#endif
+
private:
int m_tabIndex;
unsigned short m_childIndex;
@@ -165,11 +205,6 @@
void releasePseudoElement(PseudoElement*);
};
-inline IntSize defaultMinimumSizeForResizing()
-{
- return IntSize(LayoutUnit::max(), LayoutUnit::max());
-}
-
inline ElementRareData::ElementRareData(RenderElement* renderer)
: NodeRareData(renderer)
, m_tabIndex(0)
Modified: trunk/Source/WebCore/dom/Node.cpp (236240 => 236241)
--- trunk/Source/WebCore/dom/Node.cpp 2018-09-20 05:54:27 UTC (rev 236240)
+++ trunk/Source/WebCore/dom/Node.cpp 2018-09-20 06:14:59 UTC (rev 236241)
@@ -91,6 +91,44 @@
static NeverDestroyed<HashSet<Node*>> liveNodes;
return liveNodes;
}
+
+static const char* stringForRareDataUseType(NodeRareData::UseType useType)
+{
+ switch (useType) {
+ case NodeRareData::UseType::ConnectedFrameCount:
+ return "ConnectedFrameCount";
+ case NodeRareData::UseType::NodeList:
+ return "NodeList";
+ case NodeRareData::UseType::MutationObserver:
+ return "MutationObserver";
+ case NodeRareData::UseType::TabIndex:
+ return "TabIndex";
+ case NodeRareData::UseType::StyleFlags:
+ return "StyleFlags";
+ case NodeRareData::UseType::MinimumSize:
+ return "MinimumSize";
+ case NodeRareData::UseType::ScrollingPosition:
+ return "ScrollingPosition";
+ case NodeRareData::UseType::ComputedStyle:
+ return "ComputedStyle";
+ case NodeRareData::UseType::Dataset:
+ return "Dataset";
+ case NodeRareData::UseType::ClassList:
+ return "ClassList";
+ case NodeRareData::UseType::ShadowRoot:
+ return "ShadowRoot";
+ case NodeRareData::UseType::CustomElementQueue:
+ return "CustomElementQueue";
+ case NodeRareData::UseType::AttributeMap:
+ return "AttributeMap";
+ case NodeRareData::UseType::InteractionObserver:
+ return "InteractionObserver";
+ case NodeRareData::UseType::PseudoElements:
+ return "PseudoElements";
+ }
+ return nullptr;
+}
+
#endif
void Node::dumpStatistics()
@@ -117,6 +155,9 @@
size_t elementsWithRareData = 0;
size_t elementsWithNamedNodeMap = 0;
+ HashMap<uint16_t, size_t> rareDataSingleUseTypeCounts;
+ size_t mixedRareDataUseCount = 0;
+
for (auto* node : liveNodeSet()) {
if (node->hasRareData()) {
++nodesWithRareData;
@@ -125,6 +166,18 @@
if (downcast<Element>(*node).hasNamedNodeMap())
++elementsWithNamedNodeMap;
}
+ auto* rareData = node->rareData();
+ auto useTypes = is<Element>(node) ? static_cast<ElementRareData*>(rareData)->useTypes() : rareData->useTypes();
+ unsigned useTypeCount = 0;
+ for (auto type : useTypes) {
+ UNUSED_PARAM(type);
+ useTypeCount++;
+ }
+ if (useTypeCount == 1) {
+ auto result = rareDataSingleUseTypeCounts.add(static_cast<uint16_t>(*useTypes.begin()), 0);
+ result.iterator->value++;
+ } else
+ mixedRareDataUseCount++;
}
switch (node->nodeType()) {
@@ -143,7 +196,7 @@
++elementsWithAttributeStorage;
for (unsigned i = 0; i < length; ++i) {
const Attribute& attr = elementData->attributeAt(i);
- if (!attr.isEmpty())
+ if (element.attrIfExists(attr.name()))
++attributesWithAttr;
}
}
@@ -188,8 +241,13 @@
}
printf("Number of Nodes: %d\n\n", liveNodeSet().size());
- printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData);
+ printf("Number of Nodes with RareData: %zu\n", nodesWithRareData);
+ printf(" Mixed use: %zu\n", mixedRareDataUseCount);
+ for (auto it : rareDataSingleUseTypeCounts)
+ printf(" %s: %zu\n", stringForRareDataUseType(static_cast<NodeRareData::UseType>(it.key)), it.value);
+ printf("\n");
+
printf("NodeType distribution:\n");
printf(" Number of Element nodes: %zu\n", elementNodes);
printf(" Number of Attribute nodes: %zu\n", attrNodes);
Modified: trunk/Source/WebCore/dom/NodeRareData.cpp (236240 => 236241)
--- trunk/Source/WebCore/dom/NodeRareData.cpp 2018-09-20 05:54:27 UTC (rev 236240)
+++ trunk/Source/WebCore/dom/NodeRareData.cpp 2018-09-20 06:14:59 UTC (rev 236241)
@@ -40,4 +40,7 @@
COMPILE_ASSERT(sizeof(NodeRareData) == sizeof(SameSizeAsNodeRareData), NodeRareDataShouldStaySmall);
+// Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
+static_assert(Page::maxNumberOfFrames < 1024, "Frame limit should fit in rare data count");
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/NodeRareData.h (236240 => 236241)
--- trunk/Source/WebCore/dom/NodeRareData.h 2018-09-20 05:54:27 UTC (rev 236240)
+++ trunk/Source/WebCore/dom/NodeRareData.h 2018-09-20 06:14:59 UTC (rev 236241)
@@ -26,7 +26,6 @@
#include "HTMLNames.h"
#include "LiveNodeList.h"
#include "MutationObserverRegistration.h"
-#include "Page.h"
#include "QualifiedName.h"
#include "TagCollection.h"
#include <wtf/HashSet.h>
@@ -250,6 +249,27 @@
class NodeRareData : public NodeRareDataBase {
WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED;
public:
+#if defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS
+ enum class UseType : uint16_t {
+ ConnectedFrameCount = 1 << 0,
+ NodeList = 1 << 1,
+ MutationObserver = 1 << 2,
+
+ TabIndex = 1 << 3,
+ StyleFlags = 1 << 4,
+ MinimumSize = 1 << 5,
+ ScrollingPosition = 1 << 6,
+ ComputedStyle = 1 << 7,
+ Dataset = 1 << 8,
+ ClassList = 1 << 9,
+ ShadowRoot = 1 << 10,
+ CustomElementQueue = 1 << 11,
+ AttributeMap = 1 << 12,
+ InteractionObserver = 1 << 13,
+ PseudoElements = 1 << 14,
+ };
+#endif
+
NodeRareData(RenderObject* renderer)
: NodeRareDataBase(renderer)
, m_connectedFrameCount(0)
@@ -284,6 +304,20 @@
m_connectedFrameCount -= amount;
}
+#if DUMP_NODE_STATISTICS
+ OptionSet<UseType> useTypes() const
+ {
+ OptionSet<UseType> result;
+ if (m_connectedFrameCount)
+ result.add(UseType::ConnectedFrameCount);
+ if (m_nodeLists)
+ result.add(UseType::NodeList);
+ if (m_mutationObserverData)
+ result.add(UseType::MutationObserver);
+ return result;
+ }
+#endif
+
private:
unsigned m_connectedFrameCount : 10; // Must fit Page::maxNumberOfFrames.
@@ -314,7 +348,4 @@
return *rareData();
}
-// Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
-static_assert(Page::maxNumberOfFrames < 1024, "Frame limit should fit in rare data count");
-
} // namespace WebCore