Changeset 266769 in webkit
- Timestamp:
- Sep 8, 2020 8:32:10 PM (4 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r266768 r266769 1 2020-09-08 Ryosuke Niwa <rniwa@webkit.org> 2 3 Having an iframe as a descendent node shouldn't require ElementRareData 4 https://bugs.webkit.org/show_bug.cgi?id=216264 5 6 Reviewed by Darin Adler. 7 8 Store the number of connected frames in the descendent nodes directly in Node using CompactUniquePtrTuple 9 in the same space as where we store the NodeRareData pointer. This avoids creating ElementRareData on every 10 ancestor element and shadow host / document of an iframe. 11 12 Also moved TabIndexState there to simply NodeFlags, and created CustomElementState to replace the existing 13 flags in NodeFlags to match the latest terminology used in the specification: 14 https://dom.spec.whatwg.org/#concept-element-custom-element-state 15 16 CustomElementState has four states: "uncustomized" (default; builtin elements), "undefined" (i.e. element has 17 a valid custom element but it hasn't been defined or upgraded yet), "custom" (a valid custom element instance), 18 and "failed" (upgrading has resulted in an error). Before this patch, "uncustomized" meant that neither 19 IsCustomElement nor IsEditingTextOrUndefinedCustomElementFlag is set, "undefined" had IsCustomElement 20 and IsEditingTextOrUndefinedCustomElementFlag set, and "custom" had IsCustomElement set but 21 IsEditingTextOrUndefinedCustomElementFlag unset whereas "failed" had the opposite. 22 23 No new tests since there should be no observable behavioral change. 24 25 * cssjit/SelectorCompiler.cpp: 26 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild): Mask out the bits stored in 27 the pointer in the 64-bit architecture. In the 32-bit architecture, the pointer is the first component 28 without any extra bits stored in it. 29 * dom/Element.cpp: 30 (WebCore::Node::setTabIndexState): Moved from Node.h. Updated to use the newly introduced bitfields. 31 (WebCore::Node::setCustomElementState): Added. 32 (WebCore::Element::setIsDefinedCustomElement): Now updates CustomElementState in the newly added bitfields. 33 (WebCore::Element::setIsFailedCustomElementWithoutClearingReactionQueue): Ditto. 34 (WebCore::Element::setIsCustomElementUpgradeCandidate): Ditto. 35 * dom/ElementRareData.cpp: 36 * dom/ElementRareData.h: 37 (WebCore::ElementRareData): Moved m_unusualTabIndex and m_childIndex to NodeRareData for better packing. 38 * dom/Node.cpp: 39 (WebCore::Node::materializeRareData): 40 (WebCore::Node::clearRareData): 41 (WebCore::Node::connectedSubframeCount const): Moved to the header file. 42 (WebCore::Node::incrementConnectedSubframeCount): Now updates the newly added bitfields. 43 (WebCore::Node::decrementConnectedSubframeCount): Ditto. 44 * dom/Node.h: 45 (WebCore::Node::isUndefinedCustomElement const): Now uses CustomElementState in the newly added bitfields. 46 (WebCore::Node::isCustomElementUpgradeCandidate const): Ditto. 47 (WebCore::Node::isDefinedCustomElement const): Ditto. 48 (WebCore::Node::isFailedCustomElement const): Ditto. 49 (WebCore::Node::isEditingText const): 50 (WebCore::Node::connectedSubframeCount const): Moved here from cpp file. 51 (WebCore::Node::rareDataMemoryOffset): 52 (WebCore::Node::rareDataPointerMask): Added. 53 (WebCore::Node::CustomElementState): Added. 54 (WebCore::Node::RareDataBitFields): Added. 55 (WebCore::Node::rareDataBitfields const): Added. 56 (WebCore::Node::setRareDataBitfields): Added. 57 (WebCore::Node::tabIndexState const): Updated to use rareDataBitfields. 58 (WebCore::Node::setTabIndexState): Moved to Element.cpp. 59 (WebCore::Node::customElementState const): Added. 60 (WebCore::Node::hasRareData const): 61 (WebCore::Node::rareData const): 62 * dom/NodeRareData.cpp: 63 * dom/NodeRareData.h: 64 (WebCore::NodeRareData::UseType): Removed ConnectedFrameCount. 65 (WebCore::NodeRareData::NodeRareData): 66 (WebCore::NodeRareData::useTypes const): 67 (WebCore::NodeRareData::connectedSubframeCount const): Deleted. 68 (WebCore::NodeRareData::incrementConnectedSubframeCount): Deleted. 69 (WebCore::NodeRareData::decrementConnectedSubframeCount): Deleted. 70 (WebCore::NodeRareData): Moved m_unusualTabIndex and m_childIndex here for better packing in 64-bit architecture. 71 1 72 2020-09-08 Tim Horton <timothy_horton@apple.com> 2 73 -
trunk/Source/WebCore/cssjit/SelectorCompiler.cpp
r263117 r266769 3583 3583 m_assembler.loadPtr(Assembler::Address(previousSibling, Node::rareDataMemoryOffset()), elementRareData); 3584 3584 3585 LocalRegister rareDataPointerMask(m_registerAllocator); 3586 m_assembler.move(Assembler::TrustedImmPtr(Node::rareDataPointerMask()), rareDataPointerMask); 3587 m_assembler.andPtr(rareDataPointerMask, elementRareData); 3588 3585 3589 noCachedChildIndexCases.append(m_assembler.branchTestPtr(Assembler::Zero, elementRareData)); 3586 3590 { -
trunk/Source/WebCore/dom/Element.cpp
r266714 r266769 242 242 } 243 243 244 inline void Node::setTabIndexState(TabIndexState state) 245 { 246 auto bitfields = rareDataBitfields(); 247 bitfields.tabIndexState = static_cast<uint16_t>(state); 248 setRareDataBitfields(bitfields); 249 } 250 244 251 void Element::setTabIndexExplicitly(Optional<int> tabIndex) 245 252 { … … 2423 2430 } 2424 2431 2432 inline void Node::setCustomElementState(CustomElementState state) 2433 { 2434 auto bitfields = rareDataBitfields(); 2435 bitfields.customElementState = static_cast<uint16_t>(state); 2436 setRareDataBitfields(bitfields); 2437 } 2438 2425 2439 void Element::setIsDefinedCustomElement(JSCustomElementInterface& elementInterface) 2426 2440 { 2427 clearFlag(IsEditingTextOrUndefinedCustomElementFlag); 2428 setFlag(IsCustomElement); 2441 setCustomElementState(CustomElementState::Custom); 2429 2442 auto& data = ensureElementRareData(); 2430 2443 if (!data.customElementReactionQueue()) … … 2443 2456 { 2444 2457 ASSERT(isUndefinedCustomElement()); 2445 ASSERT( getFlag(IsEditingTextOrUndefinedCustomElementFlag));2446 clearFlag(IsCustomElement);2458 ASSERT(customElementState() == CustomElementState::Undefined); 2459 setCustomElementState(CustomElementState::Failed); 2447 2460 InspectorInstrumentation::didChangeCustomElementState(*this); 2448 2461 } … … 2460 2473 void Element::setIsCustomElementUpgradeCandidate() 2461 2474 { 2462 ASSERT(!getFlag(IsCustomElement)); 2463 setFlag(IsCustomElement); 2464 setFlag(IsEditingTextOrUndefinedCustomElementFlag); 2475 ASSERT(customElementState() == CustomElementState::Uncustomized); 2476 setCustomElementState(CustomElementState::Undefined); 2465 2477 InspectorInstrumentation::didChangeCustomElementState(*this); 2466 2478 } -
trunk/Source/WebCore/dom/ElementRareData.cpp
r266714 r266769 35 35 36 36 struct SameSizeAsElementRareData : NodeRareData { 37 int tabIndex;38 unsigned short childIndex;39 37 LayoutSize sizeForResizing; 40 38 IntPoint savedLayerScrollPosition; -
trunk/Source/WebCore/dom/ElementRareData.h
r266714 r266769 159 159 160 160 private: 161 int m_unusualTabIndex { 0 };162 unsigned short m_childIndex { 0 };163 164 161 LayoutSize m_minimumSizeForResizing; 165 162 IntPoint m_savedLayerScrollPosition; -
trunk/Source/WebCore/dom/Node.cpp
r266714 r266769 414 414 { 415 415 if (is<Element>(*this)) 416 m_rareData = std::unique_ptr<NodeRareData, NodeRareDataDeleter>(new ElementRareData);416 m_rareDataWithBitfields.setPointer(std::unique_ptr<NodeRareData, NodeRareDataDeleter>(new ElementRareData)); 417 417 else 418 m_rareData = std::unique_ptr<NodeRareData, NodeRareDataDeleter>(new NodeRareData);418 m_rareDataWithBitfields.setPointer(std::unique_ptr<NodeRareData, NodeRareDataDeleter>(new NodeRareData)); 419 419 } 420 420 … … 432 432 ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty()); 433 433 434 m_rareData = nullptr;434 m_rareDataWithBitfields.setPointer(nullptr); 435 435 } 436 436 … … 2574 2574 } 2575 2575 2576 unsigned Node::connectedSubframeCount() const2577 {2578 return hasRareData() ? rareData()->connectedSubframeCount() : 0;2579 }2580 2581 2576 void Node::incrementConnectedSubframeCount(unsigned amount) 2582 2577 { 2578 static_assert(RareDataBitFields { Page::maxNumberOfFrames, 0, 0 }.connectedSubframeCount == Page::maxNumberOfFrames, "connectedSubframeCount must fit Page::maxNumberOfFrames"); 2579 2583 2580 ASSERT(isContainerNode()); 2584 ensureRareData().incrementConnectedSubframeCount(amount); 2581 auto bitfields = rareDataBitfields(); 2582 bitfields.connectedSubframeCount += amount; 2583 RELEASE_ASSERT(bitfields.connectedSubframeCount == rareDataBitfields().connectedSubframeCount + amount); 2584 setRareDataBitfields(bitfields); 2585 2585 } 2586 2586 2587 2587 void Node::decrementConnectedSubframeCount(unsigned amount) 2588 2588 { 2589 ASSERT(rareData()); 2590 if (!hasRareData()) 2591 return; // Defend against type confusion when the above assertion fails. See webkit.org/b/200300. 2592 rareData()->decrementConnectedSubframeCount(amount); 2589 ASSERT(isContainerNode()); 2590 auto bitfields = rareDataBitfields(); 2591 RELEASE_ASSERT(amount <= bitfields.connectedSubframeCount); 2592 bitfields.connectedSubframeCount -= amount; 2593 setRareDataBitfields(bitfields); 2593 2594 } 2594 2595 -
trunk/Source/WebCore/dom/Node.h
r266714 r266769 33 33 #include "TreeScope.h" 34 34 #include <wtf/CompactPointerTuple.h> 35 #include <wtf/CompactUniquePtrTuple.h> 35 36 #include <wtf/Forward.h> 36 37 #include <wtf/IsoMalloc.h> … … 230 231 HTMLSlotElement* assignedSlotForBindings() const; 231 232 232 bool isUndefinedCustomElement() const { return isElementNode() && getFlag(IsEditingTextOrUndefinedCustomElementFlag); }233 bool isCustomElementUpgradeCandidate() const { return getFlag(IsCustomElement) && getFlag(IsEditingTextOrUndefinedCustomElementFlag); }234 bool isDefinedCustomElement() const { return getFlag(IsCustomElement) && !getFlag(IsEditingTextOrUndefinedCustomElementFlag); }235 bool isFailedCustomElement() const { return isElementNode() && !getFlag(IsCustomElement) && getFlag(IsEditingTextOrUndefinedCustomElementFlag); }233 bool isUndefinedCustomElement() const { return customElementState() == CustomElementState::Undefined || customElementState() == CustomElementState::Failed; } 234 bool isCustomElementUpgradeCandidate() const { return customElementState() == CustomElementState::Undefined; } 235 bool isDefinedCustomElement() const { return customElementState() == CustomElementState::Custom; } 236 bool isFailedCustomElement() const { return customElementState() == CustomElementState::Failed; } 236 237 237 238 // Returns null, a child of ShadowRoot, or a legacy shadow root. … … 297 298 bool styleResolutionShouldRecompositeLayer() const { return hasStyleFlag(NodeStyleFlag::StyleResolutionShouldRecompositeLayer); } 298 299 bool childNeedsStyleRecalc() const { return hasStyleFlag(NodeStyleFlag::DescendantNeedsStyleResolution); } 299 bool isEditingText() const { return getFlag(IsTextFlag) && getFlag(IsEditingText OrUndefinedCustomElementFlag); }300 bool isEditingText() const { return getFlag(IsTextFlag) && getFlag(IsEditingText); } 300 301 301 302 void setChildNeedsStyleRecalc() { setStyleFlag(NodeStyleFlag::DescendantNeedsStyleResolution); } … … 492 493 void notifyMutationObserversNodeWillDetach(); 493 494 494 unsigned connectedSubframeCount() const ;495 unsigned connectedSubframeCount() const { return rareDataBitfields().connectedSubframeCount; } 495 496 void incrementConnectedSubframeCount(unsigned amount = 1); 496 497 void decrementConnectedSubframeCount(unsigned amount = 1); … … 500 501 #if ENABLE(JIT) 501 502 static ptrdiff_t nodeFlagsMemoryOffset() { return OBJECT_OFFSETOF(Node, m_nodeFlags); } 502 static ptrdiff_t rareDataMemoryOffset() { return OBJECT_OFFSETOF(Node, m_rareData); } 503 static ptrdiff_t rareDataMemoryOffset() { return OBJECT_OFFSETOF(Node, m_rareDataWithBitfields); } 504 #if CPU(ADDRESS64) 505 static uint64_t rareDataPointerMask() { return CompactPointerTuple<NodeRareData*, uint16_t>::pointerMask; } 506 #else 507 static uint32_t rareDataPointerMask() { return -1; } 508 #endif 503 509 static int32_t flagIsText() { return IsTextFlag; } 504 510 static int32_t flagIsContainer() { return IsContainerFlag; } … … 527 533 // UnusedFlag = 1 << 12, 528 534 // UnusedFlag = 1 << 13, 535 // UnusedFlag = 1 << 14, 529 536 530 537 // These bits are used by derived classes, pulled up here so they can 531 538 // be stored in the same memory word as the Node bits above. 532 IsEditingTextOrUndefinedCustomElementFlag = 1 << 14, // Text and Element 533 IsCustomElement = 1 << 15, // Element 534 HasFocusWithin = 1 << 16, 539 IsEditingText = 1 << 15, // Text 540 HasFocusWithin = 1 << 16, // Element 535 541 IsLinkFlag = 1 << 17, 536 542 IsUserActionElement = 1 << 18, … … 548 554 #endif 549 555 550 // Bits 27-29 are free. 551 // Bits 30-31: TabIndexState 556 // Bits 27-31 are free. 552 557 553 558 DefaultNodeFlags = IsParsingChildrenFinishedFlag 554 559 }; 555 560 556 static constexpr unsigned s_tabIndexStateBitOffset = 30;557 static constexpr uint32_t s_tabIndexStateBitMask = 3U << s_tabIndexStateBitOffset;558 561 enum class TabIndexState : uint8_t { 559 562 NotSet = 0, … … 563 566 }; 564 567 568 enum class CustomElementState : uint8_t { 569 Uncustomized = 0, 570 Undefined = 1, 571 Custom = 2, 572 Failed = 3, 573 }; 574 575 struct RareDataBitFields { 576 uint16_t connectedSubframeCount : 10; 577 uint16_t tabIndexState : 2; 578 uint16_t customElementState : 2; 579 }; 580 565 581 bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; } 566 582 void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); } … … 568 584 void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; } 569 585 570 TabIndexState tabIndexState() const { return static_cast<TabIndexState>((m_nodeFlags & s_tabIndexStateBitMask) >> s_tabIndexStateBitOffset); } 571 void setTabIndexState(TabIndexState state) { m_nodeFlags = (m_nodeFlags & ~s_tabIndexStateBitMask) | (static_cast<uint32_t>(state) << s_tabIndexStateBitOffset); } 586 RareDataBitFields rareDataBitfields() const { return bitwise_cast<RareDataBitFields>(m_rareDataWithBitfields.type()); } 587 void setRareDataBitfields(RareDataBitFields bitfields) { m_rareDataWithBitfields.setType(bitwise_cast<uint16_t>(bitfields)); } 588 589 TabIndexState tabIndexState() const { return static_cast<TabIndexState>(rareDataBitfields().tabIndexState); } 590 void setTabIndexState(TabIndexState); 591 592 CustomElementState customElementState() const { return static_cast<CustomElementState>(rareDataBitfields().customElementState); } 593 void setCustomElementState(CustomElementState); 572 594 573 595 bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); } … … 587 609 CreateMathMLElement = CreateElement | IsMathMLFlag, 588 610 CreateDocument = CreateContainer | IsDocumentNodeFlag | IsConnectedFlag, 589 CreateEditingText = CreateText | IsEditingText OrUndefinedCustomElementFlag,611 CreateEditingText = CreateText | IsEditingText, 590 612 }; 591 613 Node(Document&, ConstructionType); … … 649 671 virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const { } 650 672 651 bool hasRareData() const { return !!m_rareData ; }652 NodeRareData* rareData() const { return m_rareData .get(); }673 bool hasRareData() const { return !!m_rareDataWithBitfields.pointer(); } 674 NodeRareData* rareData() const { return m_rareDataWithBitfields.pointer(); } 653 675 NodeRareData& ensureRareData(); 654 676 void clearRareData(); … … 706 728 Node* m_next { nullptr }; 707 729 CompactPointerTuple<RenderObject*, uint16_t> m_rendererWithStyleFlags; 708 std::unique_ptr<NodeRareData, NodeRareDataDeleter> m_rareData;730 CompactUniquePtrTuple<NodeRareData, uint16_t, NodeRareDataDeleter> m_rareDataWithBitfields; 709 731 }; 710 732 -
trunk/Source/WebCore/dom/NodeRareData.cpp
r253987 r266769 37 37 38 38 struct SameSizeAsNodeRareData { 39 unsigned m_frameCountAndIsElementRareDataFlag; 39 uint32_t m_tabIndex; 40 uint32_t m_childIndexAndIsElementRareDataFlag; 40 41 void* m_pointer[2]; 41 42 }; -
trunk/Source/WebCore/dom/NodeRareData.h
r266714 r266769 246 246 #if defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS 247 247 enum class UseType : uint32_t { 248 ConnectedFrameCount = 1 << 0, 249 NodeList = 1 << 1, 250 MutationObserver = 1 << 2, 251 TabIndex = 1 << 3, 252 MinimumSize = 1 << 4, 253 ScrollingPosition = 1 << 5, 254 ComputedStyle = 1 << 6, 255 Dataset = 1 << 7, 256 ClassList = 1 << 8, 257 ShadowRoot = 1 << 9, 258 CustomElementQueue = 1 << 10, 259 AttributeMap = 1 << 11, 260 InteractionObserver = 1 << 12, 261 ResizeObserver = 1 << 13, 262 Animations = 1 << 14, 263 PseudoElements = 1 << 15, 264 StyleMap = 1 << 16, 265 PartList = 1 << 17, 266 PartNames = 1 << 18, 248 NodeList = 1 << 0, 249 MutationObserver = 1 << 1, 250 TabIndex = 1 << 2, 251 MinimumSize = 1 << 3, 252 ScrollingPosition = 1 << 4, 253 ComputedStyle = 1 << 5, 254 Dataset = 1 << 6, 255 ClassList = 1 << 7, 256 ShadowRoot = 1 << 8, 257 CustomElementQueue = 1 << 9, 258 AttributeMap = 1 << 10, 259 InteractionObserver = 1 << 11, 260 ResizeObserver = 1 << 12, 261 Animations = 1 << 13, 262 PseudoElements = 1 << 14, 263 StyleMap = 1 << 15, 264 PartList = 1 << 16, 265 PartNames = 1 << 17, 267 266 }; 268 267 #endif … … 271 270 272 271 NodeRareData(Type type = Type::Node) 273 : m_connectedFrameCount(0) 274 , m_isElementRareData(type == Type::Element) 272 : m_isElementRareData(type == Type::Element) 275 273 { 276 274 } … … 295 293 } 296 294 297 unsigned connectedSubframeCount() const { return m_connectedFrameCount; }298 void incrementConnectedSubframeCount(unsigned amount)299 {300 m_connectedFrameCount += amount;301 }302 void decrementConnectedSubframeCount(unsigned amount)303 {304 ASSERT(m_connectedFrameCount);305 ASSERT(amount <= m_connectedFrameCount);306 m_connectedFrameCount -= amount;307 }308 309 295 #if DUMP_NODE_STATISTICS 310 296 OptionSet<UseType> useTypes() const 311 297 { 312 298 OptionSet<UseType> result; 313 if (m_connectedFrameCount)314 result.add(UseType::ConnectedFrameCount);315 299 if (m_nodeLists) 316 300 result.add(UseType::NodeList); … … 321 305 #endif 322 306 307 protected: 308 // Used by ElementRareData. Defined here for better packing in 64-bit. 309 int m_unusualTabIndex { 0 }; 310 unsigned short m_childIndex { 0 }; 311 323 312 private: 324 unsigned m_connectedFrameCount : 31; // Must fit Page::maxNumberOfFrames. 325 unsigned m_isElementRareData : 1; 313 bool m_isElementRareData; 326 314 327 315 std::unique_ptr<NodeListsNodeData> m_nodeLists;
Note: See TracChangeset
for help on using the changeset viewer.