Changeset 84586 in webkit
- Timestamp:
- Apr 21, 2011 6:42:11 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r84584 r84586 1 2011-04-21 Michael Saboff <msaboff@apple.com> 2 3 Reviewed by Maciej Stachowiak. 4 5 Qualified names used for all TagName access, yet namespace usage is rare 6 https://bugs.webkit.org/show_bug.cgi?id=58997 7 8 The methods getElementsByTagName and getElementsByTagNameNS where 9 always creating and using QualifiedNames. QualifiedName::init 10 was consistently in the top 3 routines when running the Dromaeo 11 DOM-query benchmark. Split out the functionality so that 12 getElementsByTagName uses just the local name, an implied "*" 13 namespace and a separate TagNodeListCache keyed by an atomic name 14 instead of a QualifiedName. Access to elements via 15 getElementsByTagNameNS that have "*" namespace are forwarded to 16 getElementsByTagName as well. This provides ~10% speed up in that 17 Dromaeo test. 18 19 No new tests added, existing tests have coverage. The changes are 20 an optimization of existing functionality. 21 22 * dom/Node.cpp: 23 (WebCore::Node::removeCachedTagNodeList): 24 (WebCore::Node::getElementsByTagName): 25 (WebCore::Node::getElementsByTagNameNS): 26 (WebCore::NodeListsNodeData::invalidateCaches): 27 (WebCore::NodeListsNodeData::isEmpty): 28 * dom/Node.h: 29 * dom/NodeRareData.h: 30 * dom/TagNodeList.cpp: 31 (WebCore::TagNodeList::~TagNodeList): 32 1 33 2011-04-21 Geoffrey Garen <ggaren@apple.com> 2 34 -
trunk/Source/WebCore/dom/Node.cpp
r84520 r84586 1093 1093 } 1094 1094 1095 void Node::removeCachedTagNodeList(TagNodeList* list, const QualifiedName& name)1095 void Node::removeCachedTagNodeList(TagNodeList* list, const AtomicString& name) 1096 1096 { 1097 1097 ASSERT(rareData()); … … 1102 1102 ASSERT_UNUSED(list, list == data->m_tagNodeListCache.get(name.impl())); 1103 1103 data->m_tagNodeListCache.remove(name.impl()); 1104 } 1105 1106 void Node::removeCachedTagNodeList(TagNodeList* list, const QualifiedName& name) 1107 { 1108 ASSERT(rareData()); 1109 ASSERT(rareData()->nodeLists()); 1110 ASSERT_UNUSED(list, list->hasOwnCaches()); 1111 1112 NodeListsNodeData* data = rareData()->nodeLists(); 1113 ASSERT_UNUSED(list, list == data->m_tagNodeListCacheNS.get(name.impl())); 1114 data->m_tagNodeListCacheNS.remove(name.impl()); 1104 1115 } 1105 1116 … … 1752 1763 // FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node. 1753 1764 1754 PassRefPtr<NodeList> Node::getElementsByTagName(const AtomicString& name) 1755 { 1756 return getElementsByTagNameNS(starAtom, name); 1757 } 1758 1759 PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName) 1765 PassRefPtr<NodeList> Node::getElementsByTagName(const AtomicString& localName) 1760 1766 { 1761 1767 if (localName.isNull()) 1762 1768 return 0; 1763 1769 1764 1770 NodeRareData* data = ensureRareData(); 1765 1771 if (!data->nodeLists()) { … … 1771 1777 if (document()->isHTMLDocument()) 1772 1778 name = localName.lower(); 1773 1779 1774 1780 AtomicString localNameAtom = name; 1775 1776 pair<NodeListsNodeData::TagNodeListCache::iterator, bool> result = data->nodeLists()->m_tagNodeListCache.add( QualifiedName(nullAtom, localNameAtom, namespaceURI).impl(), 0);1781 1782 pair<NodeListsNodeData::TagNodeListCache::iterator, bool> result = data->nodeLists()->m_tagNodeListCache.add(localNameAtom, 0); 1777 1783 if (!result.second) 1778 1784 return PassRefPtr<TagNodeList>(result.first->second); 1779 1785 1786 RefPtr<TagNodeList> list = TagNodeList::create(this, starAtom, localNameAtom); 1787 result.first->second = list.get(); 1788 return list.release(); 1789 } 1790 1791 PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName) 1792 { 1793 if (localName.isNull()) 1794 return 0; 1795 1796 if (namespaceURI == starAtom) 1797 return getElementsByTagName(localName); 1798 1799 NodeRareData* data = ensureRareData(); 1800 if (!data->nodeLists()) { 1801 data->setNodeLists(NodeListsNodeData::create()); 1802 document()->addNodeListCache(); 1803 } 1804 1805 String name = localName; 1806 if (document()->isHTMLDocument()) 1807 name = localName.lower(); 1808 1809 AtomicString localNameAtom = name; 1810 1811 pair<NodeListsNodeData::TagNodeListCacheNS::iterator, bool> result = data->nodeLists()->m_tagNodeListCacheNS.add(QualifiedName(nullAtom, localNameAtom, namespaceURI).impl(), 0); 1812 if (!result.second) 1813 return PassRefPtr<TagNodeList>(result.first->second); 1814 1780 1815 RefPtr<TagNodeList> list = TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom); 1781 1816 result.first->second = list.get(); … … 2458 2493 for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it) 2459 2494 it->second->invalidateCache(); 2495 TagNodeListCacheNS::const_iterator tagCacheNSEnd = m_tagNodeListCacheNS.end(); 2496 for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheNSEnd; ++it) 2497 it->second->invalidateCache(); 2460 2498 invalidateCachesThatDependOnAttributes(); 2461 2499 } … … 2484 2522 TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end(); 2485 2523 for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it) { 2524 if (it->second->refCount()) 2525 return false; 2526 } 2527 2528 TagNodeListCacheNS::const_iterator tagCacheNSEnd = m_tagNodeListCacheNS.end(); 2529 for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheNSEnd; ++it) { 2486 2530 if (it->second->refCount()) 2487 2531 return false; -
trunk/Source/WebCore/dom/Node.h
r84556 r84586 515 515 void removeCachedClassNodeList(ClassNodeList*, const String&); 516 516 void removeCachedNameNodeList(NameNodeList*, const String&); 517 void removeCachedTagNodeList(TagNodeList*, const AtomicString&); 517 518 void removeCachedTagNodeList(TagNodeList*, const QualifiedName&); 518 519 void removeCachedLabelsNodeList(DynamicNodeList*); 519 520 520 521 PassRefPtr<NodeList> getElementsByTagName(const AtomicString&); 521 522 PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName); -
trunk/Source/WebCore/dom/NodeRareData.h
r83349 r84586 50 50 typedef HashMap<String, NameNodeList*> NameNodeListCache; 51 51 NameNodeListCache m_nameNodeListCache; 52 53 typedef HashMap< RefPtr<QualifiedName::QualifiedNameImpl>, TagNodeList*> TagNodeListCache;52 53 typedef HashMap<AtomicString, TagNodeList*> TagNodeListCache; 54 54 TagNodeListCache m_tagNodeListCache; 55 55 56 typedef HashMap<RefPtr<QualifiedName::QualifiedNameImpl>, TagNodeList*> TagNodeListCacheNS; 57 TagNodeListCacheNS m_tagNodeListCacheNS; 58 56 59 RefPtr<DynamicNodeList> m_labelsNodeListCache; 57 60 58 61 static PassOwnPtr<NodeListsNodeData> create() 59 62 { -
trunk/Source/WebCore/dom/TagNodeList.cpp
r58526 r84586 40 40 TagNodeList::~TagNodeList() 41 41 { 42 m_rootNode->removeCachedTagNodeList(this, QualifiedName(nullAtom, m_localName, m_namespaceURI)); 43 } 42 if (m_namespaceURI == starAtom) 43 m_rootNode->removeCachedTagNodeList(this, m_localName); 44 else 45 m_rootNode->removeCachedTagNodeList(this, QualifiedName(nullAtom, m_localName, m_namespaceURI)); 46 } 44 47 45 48 bool TagNodeList::nodeMatches(Element* testNode) const
Note: See TracChangeset
for help on using the changeset viewer.