Changeset 94089 in webkit
- Timestamp:
- Aug 30, 2011 10:43:24 AM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 2 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r94011 r94089 569 569 dom/ScriptRunner.cpp 570 570 dom/SelectElement.cpp 571 dom/Selector NodeList.cpp571 dom/SelectorQuery.cpp 572 572 dom/ShadowContentElement.cpp 573 573 dom/ShadowInclusionSelector.cpp -
trunk/Source/WebCore/ChangeLog
r94088 r94089 1 2011-08-30 Antti Koivisto <antti@apple.com> 2 3 querySelector/querySelectorAll should use selector checker fast path 4 https://bugs.webkit.org/show_bug.cgi?id=67161 5 6 Reviewed by Sam Weinig. 7 8 Descendant and child selectors can be matches substantially faster using 9 SelectorChecker::fastCheckSelector() path. Currently it is used for style matching only. 10 11 Add SelectorQuery class that can do both querySelector and querySelectorAll efficiently using 12 fast path. Use inlined loop for DOM traversal. 13 14 The patch is ~25% speedup in the overall native score of http://www.webkit.org/perf/slickspeed/. 15 Some individual subtests (using child or descendant selectors) execute twice as fast. 16 17 * CMakeLists.txt: 18 * GNUmakefile.list.am: 19 * WebCore.gypi: 20 * WebCore.pro: 21 * WebCore.vcproj/WebCore.vcproj: 22 * WebCore.xcodeproj/project.pbxproj: 23 * css/CSSStyleSelector.cpp: 24 (WebCore::CSSStyleSelector::SelectorChecker::checkSelector): 25 (WebCore::CSSStyleSelector::SelectorChecker::isFastCheckableSelector): 26 (WebCore::RuleData::RuleData): 27 * css/CSSStyleSelector.h: 28 29 Make fast path checking available outside CSSStyleSelector. 30 31 * dom/DOMAllInOne.cpp: 32 * dom/Node.cpp: 33 (WebCore::Node::querySelector): 34 (WebCore::Node::querySelectorAll): 35 36 Switch to SelectorQuery. 37 38 * dom/SelectorNodeList.cpp: Removed. 39 * dom/SelectorNodeList.h: Removed. 40 41 SelectorQuery makes these obsolete. 42 43 * dom/SelectorQuery.cpp: Added. 44 (WebCore::SelectorQuery::SelectorQuery): 45 (WebCore::SelectorQuery::queryAll): 46 (WebCore::SelectorQuery::queryFirst): 47 (WebCore::SelectorQuery::canUseIdLookup): 48 (WebCore::SelectorQuery::execute): 49 * dom/SelectorQuery.h: Added. 50 51 Class for selector matching in tree. 52 1 53 2011-08-30 Dmitry Titov <dimich@chromium.org> 2 54 -
trunk/Source/WebCore/GNUmakefile.list.am
r94083 r94089 1285 1285 Source/WebCore/dom/SelectElement.cpp \ 1286 1286 Source/WebCore/dom/SelectElement.h \ 1287 Source/WebCore/dom/Selector NodeList.cpp \1288 Source/WebCore/dom/Selector NodeList.h \1287 Source/WebCore/dom/SelectorQuery.cpp \ 1288 Source/WebCore/dom/SelectorQuery.h \ 1289 1289 Source/WebCore/dom/ShadowContentElement.cpp \ 1290 1290 Source/WebCore/dom/ShadowContentElement.h \ -
trunk/Source/WebCore/WebCore.gypi
r94011 r94089 5355 5355 'dom/SelectElement.cpp', 5356 5356 'dom/SelectElement.h', 5357 'dom/Selector NodeList.cpp',5358 'dom/Selector NodeList.h',5357 'dom/SelectorQuery.cpp', 5358 'dom/SelectorQuery.h', 5359 5359 'dom/ShadowContentElement.cpp', 5360 5360 'dom/ShadowContentElement.h', -
trunk/Source/WebCore/WebCore.pro
r94011 r94089 543 543 dom/ScriptRunner.cpp \ 544 544 dom/SelectElement.cpp \ 545 dom/Selector NodeList.cpp \545 dom/SelectorQuery.cpp \ 546 546 dom/ShadowContentElement.cpp \ 547 547 dom/ShadowInclusionSelector.cpp \ … … 1537 1537 dom/ScriptExecutionContext.h \ 1538 1538 dom/SelectElement.h \ 1539 dom/Selector NodeList.h \1539 dom/SelectorQuery.h \ 1540 1540 dom/ShadowContentElement.h \ 1541 1541 dom/ShadowInclusionSelector.h \ -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r93951 r94089 48331 48331 </File> 48332 48332 <File 48333 RelativePath="..\dom\SelectorNodeList.cpp" 48334 > 48335 <FileConfiguration 48336 Name="Debug|Win32" 48337 ExcludedFromBuild="true" 48338 > 48339 <Tool 48340 Name="VCCLCompilerTool" 48341 /> 48342 </FileConfiguration> 48343 <FileConfiguration 48344 Name="Release|Win32" 48345 ExcludedFromBuild="true" 48346 > 48347 <Tool 48348 Name="VCCLCompilerTool" 48349 /> 48350 </FileConfiguration> 48351 <FileConfiguration 48352 Name="Debug_Cairo_CFLite|Win32" 48353 ExcludedFromBuild="true" 48354 > 48355 <Tool 48356 Name="VCCLCompilerTool" 48357 /> 48358 </FileConfiguration> 48359 <FileConfiguration 48360 Name="Release_Cairo_CFLite|Win32" 48361 ExcludedFromBuild="true" 48362 > 48363 <Tool 48364 Name="VCCLCompilerTool" 48365 /> 48366 </FileConfiguration> 48367 <FileConfiguration 48368 Name="Debug_All|Win32" 48369 ExcludedFromBuild="true" 48370 > 48371 <Tool 48372 Name="VCCLCompilerTool" 48373 /> 48374 </FileConfiguration> 48375 <FileConfiguration 48376 Name="Production|Win32" 48377 ExcludedFromBuild="true" 48378 > 48379 <Tool 48380 Name="VCCLCompilerTool" 48381 /> 48382 </FileConfiguration> 48383 </File> 48384 <File 48385 RelativePath="..\dom\SelectorNodeList.cpp" 48386 > 48387 <FileConfiguration 48388 Name="Debug|Win32" 48389 ExcludedFromBuild="true" 48390 > 48391 <Tool 48392 Name="VCCLCompilerTool" 48393 /> 48394 </FileConfiguration> 48395 <FileConfiguration 48396 Name="Release|Win32" 48397 ExcludedFromBuild="true" 48398 > 48399 <Tool 48400 Name="VCCLCompilerTool" 48401 /> 48402 </FileConfiguration> 48403 <FileConfiguration 48404 Name="Debug_Cairo_CFLite|Win32" 48405 ExcludedFromBuild="true" 48406 > 48407 <Tool 48408 Name="VCCLCompilerTool" 48409 /> 48410 </FileConfiguration> 48411 <FileConfiguration 48412 Name="Release_Cairo_CFLite|Win32" 48413 ExcludedFromBuild="true" 48414 > 48415 <Tool 48416 Name="VCCLCompilerTool" 48417 /> 48418 </FileConfiguration> 48419 <FileConfiguration 48420 Name="Debug_All|Win32" 48421 ExcludedFromBuild="true" 48422 > 48423 <Tool 48424 Name="VCCLCompilerTool" 48425 /> 48426 </FileConfiguration> 48427 <FileConfiguration 48428 Name="Production|Win32" 48429 ExcludedFromBuild="true" 48430 > 48431 <Tool 48432 Name="VCCLCompilerTool" 48433 /> 48434 </FileConfiguration> 48435 </File> 48436 <File 48437 RelativePath="..\dom\SelectorNodeList.h" 48438 > 48439 </File> 48440 <File 48441 RelativePath="..\dom\SelectorNodeList.h" 48333 RelativePath="..\dom\SelectorQuery.cpp" 48334 > 48335 <FileConfiguration 48336 Name="Debug|Win32" 48337 ExcludedFromBuild="true" 48338 > 48339 <Tool 48340 Name="VCCLCompilerTool" 48341 /> 48342 </FileConfiguration> 48343 <FileConfiguration 48344 Name="Release|Win32" 48345 ExcludedFromBuild="true" 48346 > 48347 <Tool 48348 Name="VCCLCompilerTool" 48349 /> 48350 </FileConfiguration> 48351 <FileConfiguration 48352 Name="Debug_Cairo_CFLite|Win32" 48353 ExcludedFromBuild="true" 48354 > 48355 <Tool 48356 Name="VCCLCompilerTool" 48357 /> 48358 </FileConfiguration> 48359 <FileConfiguration 48360 Name="Release_Cairo_CFLite|Win32" 48361 ExcludedFromBuild="true" 48362 > 48363 <Tool 48364 Name="VCCLCompilerTool" 48365 /> 48366 </FileConfiguration> 48367 <FileConfiguration 48368 Name="Debug_All|Win32" 48369 ExcludedFromBuild="true" 48370 > 48371 <Tool 48372 Name="VCCLCompilerTool" 48373 /> 48374 </FileConfiguration> 48375 <FileConfiguration 48376 Name="Production|Win32" 48377 ExcludedFromBuild="true" 48378 > 48379 <Tool 48380 Name="VCCLCompilerTool" 48381 /> 48382 </FileConfiguration> 48383 </File> 48384 <File 48385 RelativePath="..\dom\SelectorQuery.h" 48442 48386 > 48443 48387 </File> -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r94011 r94089 5099 5099 BC7FA62D0D1F0EFF00DB22A9 /* StaticNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA62B0D1F0EFF00DB22A9 /* StaticNodeList.h */; }; 5100 5100 BC7FA62E0D1F0EFF00DB22A9 /* StaticNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7FA62C0D1F0EFF00DB22A9 /* StaticNodeList.cpp */; }; 5101 BC7FA6810D1F167900DB22A9 /* SelectorNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA67F0D1F167900DB22A9 /* SelectorNodeList.h */; };5102 BC7FA6820D1F167900DB22A9 /* SelectorNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7FA6800D1F167900DB22A9 /* SelectorNodeList.cpp */; };5103 5101 BC80C9870CD294EE00A0B7B3 /* CSSTimingFunctionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC80C9850CD294EE00A0B7B3 /* CSSTimingFunctionValue.cpp */; }; 5104 5102 BC80C9880CD294EE00A0B7B3 /* CSSTimingFunctionValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC80C9860CD294EE00A0B7B3 /* CSSTimingFunctionValue.h */; }; … … 5653 5651 E44614510CD68A3500FADA75 /* RenderVideo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B41E330CBFB60900AF2ECE /* RenderVideo.cpp */; }; 5654 5652 E44614520CD68A3500FADA75 /* RenderVideo.h in Headers */ = {isa = PBXBuildFile; fileRef = E4B41E340CBFB60900AF2ECE /* RenderVideo.h */; }; 5653 E45322AB140CE267005A0F92 /* SelectorQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E45322A9140CE267005A0F92 /* SelectorQuery.cpp */; }; 5654 E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = E45322AA140CE267005A0F92 /* SelectorQuery.h */; }; 5655 5655 E462A4A1113E71BE004A4220 /* IntPointHash.h in Headers */ = {isa = PBXBuildFile; fileRef = E462A4A0113E71BE004A4220 /* IntPointHash.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5656 5656 E4778B7F115A581A00B5D372 /* JSCustomEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4778B7D115A581A00B5D372 /* JSCustomEvent.cpp */; }; … … 11818 11818 BC7FA62B0D1F0EFF00DB22A9 /* StaticNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticNodeList.h; sourceTree = "<group>"; }; 11819 11819 BC7FA62C0D1F0EFF00DB22A9 /* StaticNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticNodeList.cpp; sourceTree = "<group>"; }; 11820 BC7FA67F0D1F167900DB22A9 /* SelectorNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorNodeList.h; sourceTree = "<group>"; };11821 BC7FA6800D1F167900DB22A9 /* SelectorNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectorNodeList.cpp; sourceTree = "<group>"; };11822 11820 BC80C9850CD294EE00A0B7B3 /* CSSTimingFunctionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSSTimingFunctionValue.cpp; sourceTree = "<group>"; }; 11823 11821 BC80C9860CD294EE00A0B7B3 /* CSSTimingFunctionValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSTimingFunctionValue.h; sourceTree = "<group>"; }; … … 12406 12404 E44614120CD6826900FADA75 /* JSTimeRanges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTimeRanges.cpp; sourceTree = "<group>"; }; 12407 12405 E44614130CD6826900FADA75 /* JSTimeRanges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTimeRanges.h; sourceTree = "<group>"; }; 12406 E45322A9140CE267005A0F92 /* SelectorQuery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectorQuery.cpp; sourceTree = "<group>"; }; 12407 E45322AA140CE267005A0F92 /* SelectorQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectorQuery.h; sourceTree = "<group>"; }; 12408 12408 E462A4A0113E71BE004A4220 /* IntPointHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntPointHash.h; sourceTree = "<group>"; }; 12409 12409 E4778B7D115A581A00B5D372 /* JSCustomEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomEvent.cpp; sourceTree = "<group>"; }; … … 20063 20063 084AEBE20FB505FA0038483E /* SelectElement.cpp */, 20064 20064 084AEBE30FB505FA0038483E /* SelectElement.h */, 20065 BC7FA6800D1F167900DB22A9 /* SelectorNodeList.cpp */,20066 BC7FA67F0D1F167900DB22A9 /* SelectorNodeList.h */,20065 E45322A9140CE267005A0F92 /* SelectorQuery.cpp */, 20066 E45322AA140CE267005A0F92 /* SelectorQuery.h */, 20067 20067 A766CF8B13810E0C0011A0B3 /* ShadowContentElement.cpp */, 20068 20068 A74C2D3B13811E0D00F83572 /* ShadowContentElement.h */, … … 22840 22840 B2C3DA2F0D006C1D00EF6F26 /* SegmentedString.h in Headers */, 22841 22841 084AEBE50FB505FA0038483E /* SelectElement.h in Headers */, 22842 BC7FA6810D1F167900DB22A9 /* SelectorNodeList.h in Headers */,22843 22842 A75E497610752ACB00C9B896 /* SerializedScriptValue.h in Headers */, 22844 22843 93309E10099E64920056E581 /* SetNodeAttributeCommand.h in Headers */, … … 23449 23448 D0A3A7311405A39800FB8ED3 /* ResourceLoaderOptions.h in Headers */, 23450 23449 BCE43897140B0051005E437E /* EventConstructors.h in Headers */, 23450 E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */, 23451 23451 B10B6980140C174000BC1C26 /* WebVTTToken.h in Headers */, 23452 23452 B10B6982140C174000BC1C26 /* WebVTTTokenizer.h in Headers */, … … 25782 25782 B2C3DA2E0D006C1D00EF6F26 /* SegmentedString.cpp in Sources */, 25783 25783 084AEBE40FB505FA0038483E /* SelectElement.cpp in Sources */, 25784 BC7FA6820D1F167900DB22A9 /* SelectorNodeList.cpp in Sources */,25785 25784 A75E497710752ACB00C9B896 /* SerializedScriptValue.cpp in Sources */, 25786 25785 93309E0F099E64920056E581 /* SetNodeAttributeCommand.cpp in Sources */, … … 26260 26259 DF9AFD7313FC31D80015FEB7 /* MediaPlayerPrivateAVFoundationObjC.mm in Sources */, 26261 26260 BCE4389A140B0073005E437E /* JSEventConstructors.cpp in Sources */, 26261 E45322AB140CE267005A0F92 /* SelectorQuery.cpp in Sources */, 26262 26262 B10B6981140C174000BC1C26 /* WebVTTTokenizer.cpp in Sources */, 26263 26263 ); -
trunk/Source/WebCore/css/CSSStyleSelector.cpp
r94037 r94089 876 876 } 877 877 878 bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* element ) const878 bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* element, bool isFastCheckableSelector) const 879 879 { 880 880 PseudoId dynamicPseudo = NOPSEUDO; 881 if (isFastCheckableSelector && !element->isSVGElement()) { 882 // fastCheckSelector assumes class and id match for the top selector. 883 if (sel->m_match == CSSSelector::Class) { 884 if (!(element->hasClass() && static_cast<StyledElement*>(element)->classNames().contains(sel->value()))) 885 return false; 886 } else if (sel->m_match == CSSSelector::Id) { 887 if (!(element->hasID() && element->idForStyleResolution() == sel->value())) 888 return false; 889 } 890 return fastCheckSelector(sel, element); 891 } 881 892 return checkSelector(sel, element, dynamicPseudo, false, false) == SelectorMatches; 882 893 } … … 2013 2024 return namespaceURI == starAtom || namespaceURI == element->namespaceURI(); 2014 2025 } 2015 2016 inline bool isFastCheckableSelector(const CSSSelector* selector)2017 {2018 for (; selector; selector = selector->tagHistory()) {2019 if (selector->relation() != CSSSelector::Descendant && selector->relation() != CSSSelector::Child && selector->relation() != CSSSelector::SubSelector)2020 return false;2021 if (selector->m_match != CSSSelector::None && selector->m_match != CSSSelector::Id && selector->m_match != CSSSelector::Class)2022 return false;2023 }2024 return true;2025 }2026 2026 2027 2027 template <bool checkValue(const Element*, AtomicStringImpl*)> … … 2113 2113 ASSERT_NOT_REACHED(); 2114 2114 } 2115 } 2116 return true; 2117 } 2118 2119 bool CSSStyleSelector::SelectorChecker::isFastCheckableSelector(const CSSSelector* selector) 2120 { 2121 for (; selector; selector = selector->tagHistory()) { 2122 if (selector->relation() != CSSSelector::Descendant && selector->relation() != CSSSelector::Child && selector->relation() != CSSSelector::SubSelector) 2123 return false; 2124 if (selector->m_match != CSSSelector::None && selector->m_match != CSSSelector::Id && selector->m_match != CSSSelector::Class) 2125 return false; 2115 2126 } 2116 2127 return true; … … 3036 3047 , m_specificity(selector->specificity()) 3037 3048 , m_position(position) 3038 , m_hasFastCheckableSelector( isFastCheckableSelector(selector))3049 , m_hasFastCheckableSelector(CSSStyleSelector::SelectorChecker::isFastCheckableSelector(selector)) 3039 3050 , m_hasMultipartSelector(selector->tagHistory()) 3040 3051 , m_hasTopSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBasedOnRuleHash(selector)) -
trunk/Source/WebCore/css/CSSStyleSelector.h
r93218 r94089 276 276 SelectorChecker(Document*, bool strictParsing); 277 277 278 bool checkSelector(CSSSelector*, Element* ) const;278 bool checkSelector(CSSSelector*, Element*, bool isFastCheckableSelector = false) const; 279 279 SelectorMatch checkSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const; 280 280 bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle*, RenderStyle* elementParentStyle) const; 281 281 bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const; 282 static bool isFastCheckableSelector(const CSSSelector*); 282 283 static bool fastCheckSelector(const CSSSelector*, const Element*); 283 284 -
trunk/Source/WebCore/dom/DOMAllInOne.cpp
r93411 r94089 116 116 #include "ScriptableDocumentParser.cpp" 117 117 #include "SelectElement.cpp" 118 #include "Selector NodeList.cpp"118 #include "SelectorQuery.cpp" 119 119 #include "ShadowContentElement.cpp" 120 120 #include "ShadowInclusionSelector.cpp" -
trunk/Source/WebCore/dom/Node.cpp
r93481 r94089 82 82 #include "RenderView.h" 83 83 #include "ScopedEventQueue.h" 84 #include "Selector NodeList.h"84 #include "SelectorQuery.h" 85 85 #include "ShadowRoot.h" 86 86 #include "StaticNodeList.h" … … 1766 1766 return 0; 1767 1767 } 1768 1769 CSSStyleSelector::SelectorChecker selectorChecker(document(), strictParsing); 1770 1771 // FIXME: we could also optimize for the the [id="foo"] case 1772 if (strictParsing && inDocument() && querySelectorList.hasOneSelector() && querySelectorList.first()->m_match == CSSSelector::Id) { 1773 Element* element = treeScope()->getElementById(querySelectorList.first()->value()); 1774 if (element && (isDocumentNode() || element->isDescendantOf(this)) && selectorChecker.checkSelector(querySelectorList.first(), element)) 1775 return element; 1776 return 0; 1777 } 1778 1779 // FIXME: We can speed this up by implementing caching similar to the one use by getElementById 1780 for (Node* n = firstChild(); n; n = n->traverseNextNode(this)) { 1781 if (n->isElementNode()) { 1782 Element* element = static_cast<Element*>(n); 1783 for (CSSSelector* selector = querySelectorList.first(); selector; selector = CSSSelectorList::next(selector)) { 1784 if (selectorChecker.checkSelector(selector, element)) 1785 return element; 1786 } 1787 } 1788 } 1789 1790 return 0; 1768 1769 SelectorQuery selectorQuery(this, querySelectorList); 1770 return selectorQuery.queryFirst(); 1791 1771 } 1792 1772 … … 1814 1794 } 1815 1795 1816 return createSelectorNodeList(this, querySelectorList); 1796 SelectorQuery selectorQuery(this, querySelectorList); 1797 return selectorQuery.queryAll(); 1817 1798 } 1818 1799
Note: See TracChangeset
for help on using the changeset viewer.