Changeset 21003 in webkit
- Timestamp:
- Apr 22, 2007 1:23:55 AM (17 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r21002 r21003 1 2007-04-22 Alexey Proskuryakov <ap@webkit.org> 2 3 Reviewed by Darin. 4 5 http://bugs.webkit.org/show_bug.cgi?id=13115 6 REGRESSION: 1000% performance regression in DOM access by index, which was already slow 7 8 * dom/NodeList.h: Move cached data into a separate class, so it can be shared. 9 10 * dom/Node.h: Replace the set of registered NodeLists with a struct that also 11 contains a shared NodeList::Caches (so the size of Node doesn't change). 12 13 * dom/NodeList.cpp: 14 (WebCore::NodeList::NodeList): 15 (WebCore::NodeList::~NodeList): 16 (WebCore::NodeList::recursiveLength): 17 (WebCore::NodeList::itemForwardsFromCurrent): 18 (WebCore::NodeList::itemBackwardsFromCurrent): 19 (WebCore::NodeList::recursiveItem): 20 (WebCore::NodeList::itemWithName): 21 (WebCore::NodeList::rootNodeChildrenChanged): 22 (WebCore::NodeList::NodeListInfo::NodeListInfo): 23 (WebCore::NodeList::NodeListInfo::reset): 24 * dom/ChildNodeList.cpp: 25 (WebCore::ChildNodeList::ChildNodeList): 26 (WebCore::ChildNodeList::length): 27 (WebCore::ChildNodeList::item): 28 (WebCore::ChildNodeList::nodeMatches): 29 * dom/ChildNodeList.h: 30 * dom/Node.cpp: 31 (WebCore::Node::childNodes): 32 (WebCore::Node::registerNodeList): 33 (WebCore::Node::unregisterNodeList): 34 (WebCore::Node::notifyLocalNodeListsAttributeChanged): 35 (WebCore::Node::notifyLocalNodeListsChildrenChanged): 36 Adjust for the above changes. 37 1 38 2007-04-21 Mitz Pettel <mitz@webkit.org> 2 39 -
trunk/WebCore/dom/ChildNodeList.cpp
r20214 r21003 31 31 namespace WebCore { 32 32 33 ChildNodeList::ChildNodeList( Node *n)34 : NodeList(n )33 ChildNodeList::ChildNodeList(Node* n, NodeList::Caches* info) 34 : NodeList(n, info) 35 35 { 36 36 } … … 38 38 unsigned ChildNodeList::length() const 39 39 { 40 if ( isLengthCacheValid)41 return cachedLength;40 if (m_caches->isLengthCacheValid) 41 return m_caches->cachedLength; 42 42 43 43 unsigned len = 0; 44 44 Node *n; 45 for (n =rootNode->firstChild(); n != 0; n = n->nextSibling())45 for (n = m_rootNode->firstChild(); n != 0; n = n->nextSibling()) 46 46 len++; 47 47 48 cachedLength = len;49 isLengthCacheValid = true;48 m_caches->cachedLength = len; 49 m_caches->isLengthCacheValid = true; 50 50 51 51 return len; 52 52 } 53 53 54 Node *ChildNodeList::item ( unsigned index) const54 Node *ChildNodeList::item(unsigned index) const 55 55 { 56 56 unsigned int pos = 0; 57 Node *n = rootNode->firstChild();57 Node *n = m_rootNode->firstChild(); 58 58 59 if ( isItemCacheValid) {60 if (index == lastItemOffset) {61 return lastItem;62 } else if (index >lastItemOffset) {63 n = lastItem;64 pos = lastItemOffset;59 if (m_caches->isItemCacheValid) { 60 if (index == m_caches->lastItemOffset) 61 return m_caches->lastItem; 62 if (index > m_caches->lastItemOffset) { 63 n = m_caches->lastItem; 64 pos = m_caches->lastItemOffset; 65 65 } 66 66 } … … 72 72 73 73 if (n) { 74 lastItem = n;75 lastItemOffset = pos;76 isItemCacheValid = true;74 m_caches->lastItem = n; 75 m_caches->lastItemOffset = pos; 76 m_caches->isItemCacheValid = true; 77 77 return n; 78 78 } … … 83 83 bool ChildNodeList::nodeMatches(Node *testNode) const 84 84 { 85 return testNode->parentNode() == rootNode;85 return testNode->parentNode() == m_rootNode; 86 86 } 87 87 -
trunk/WebCore/dom/ChildNodeList.h
r20214 r21003 32 32 class ChildNodeList : public NodeList { 33 33 public: 34 ChildNodeList(Node* );34 ChildNodeList(Node*, NodeList::Caches*); 35 35 36 36 virtual unsigned length() const; -
trunk/WebCore/dom/Node.cpp
r20997 r21003 48 48 using namespace HTMLNames; 49 49 50 typedef HashSet<NodeList*> NodeListSet; 51 struct NodeListsNodeData { 52 NodeListSet m_registeredLists; 53 NodeList::Caches m_childNodeListCaches; 54 }; 55 56 50 57 /** 51 58 * NodeList which lists all Nodes in a document with a given tag name … … 216 223 PassRefPtr<NodeList> Node::childNodes() 217 224 { 218 return new ChildNodeList(this); 225 if (!m_nodeLists) 226 m_nodeLists = new NodeListsNodeData; 227 228 return new ChildNodeList(this, &m_nodeLists->m_childNodeListCaches); 219 229 } 220 230 … … 431 441 { 432 442 if (!m_nodeLists) 433 m_nodeLists = new NodeList Set;434 m_nodeLists-> add(list);443 m_nodeLists = new NodeListsNodeData; 444 m_nodeLists->m_registeredLists.add(list); 435 445 } 436 446 … … 439 449 if (!m_nodeLists) 440 450 return; 441 m_nodeLists-> remove(list);451 m_nodeLists->m_registeredLists.remove(list); 442 452 } 443 453 … … 447 457 return; 448 458 449 NodeListSet::iterator end = m_nodeLists-> end();450 for (NodeListSet::iterator i = m_nodeLists-> begin(); i != end; ++i)459 NodeListSet::iterator end = m_nodeLists->m_registeredLists.end(); 460 for (NodeListSet::iterator i = m_nodeLists->m_registeredLists.begin(); i != end; ++i) 451 461 (*i)->rootNodeAttributeChanged(); 452 462 } … … 463 473 return; 464 474 465 NodeListSet::iterator end = m_nodeLists-> end();466 for (NodeListSet::iterator i = m_nodeLists-> begin(); i != end; ++i)475 NodeListSet::iterator end = m_nodeLists->m_registeredLists.end(); 476 for (NodeListSet::iterator i = m_nodeLists->m_registeredLists.begin(); i != end; ++i) 467 477 (*i)->rootNodeChildrenChanged(); 468 478 } -
trunk/WebCore/dom/Node.h
r20214 r21003 46 46 class NamedAttrMap; 47 47 class NodeList; 48 struct NodeListsNodeData; 48 49 class PlatformKeyboardEvent; 49 50 class PlatformMouseEvent; … … 457 458 458 459 protected: 459 typedef HashSet<NodeList*> NodeListSet; 460 NodeListSet* m_nodeLists; 460 NodeListsNodeData* m_nodeLists; 461 461 462 462 short m_tabIndex; -
trunk/WebCore/dom/NodeList.cpp
r20214 r21003 31 31 namespace WebCore { 32 32 33 NodeList::NodeList(PassRefPtr<Node> _rootNode)34 : rootNode(_rootNode),35 isLengthCacheValid(false),36 isItemCacheValid(false)33 NodeList::NodeList(PassRefPtr<Node> rootNode) 34 : m_rootNode(rootNode) 35 , m_caches(new Caches) 36 , m_ownsCaches(true) 37 37 { 38 rootNode->registerNodeList(this); 38 m_rootNode->registerNodeList(this); 39 } 40 41 NodeList::NodeList(PassRefPtr<Node> rootNode, NodeList::Caches* info) 42 : m_rootNode(rootNode) 43 , m_caches(info) 44 , m_ownsCaches(false) 45 { 46 m_rootNode->registerNodeList(this); 39 47 } 40 48 41 49 NodeList::~NodeList() 42 50 { 43 rootNode->unregisterNodeList(this); 51 m_rootNode->unregisterNodeList(this); 52 if (m_ownsCaches) 53 delete m_caches; 44 54 } 45 55 … … 47 57 { 48 58 if (!start) 49 start = rootNode.get();59 start = m_rootNode.get(); 50 60 51 if ( isLengthCacheValid && start ==rootNode)52 return cachedLength;61 if (m_caches->isLengthCacheValid && start == m_rootNode) 62 return m_caches->cachedLength; 53 63 54 64 unsigned len = 0; … … 61 71 } 62 72 63 if (start == rootNode) {64 cachedLength = len;65 isLengthCacheValid = true;73 if (start == m_rootNode) { 74 m_caches->cachedLength = len; 75 m_caches->isLengthCacheValid = true; 66 76 } 67 77 … … 73 83 ASSERT(remainingOffset >= 0); 74 84 75 for (Node *n = start; n; n = n->traverseNextNode( rootNode.get())) {85 for (Node *n = start; n; n = n->traverseNextNode(m_rootNode.get())) { 76 86 if (n->isElementNode()) { 77 87 if (nodeMatches(n)) { 78 88 if (!remainingOffset) { 79 lastItem = n;80 lastItemOffset = offset;81 isItemCacheValid = true;89 m_caches->lastItem = n; 90 m_caches->lastItemOffset = offset; 91 m_caches->isItemCacheValid = true; 82 92 return n; 83 93 } … … 93 103 { 94 104 ASSERT(remainingOffset < 0); 95 for (Node *n = start; n; n = n->traversePreviousNode( rootNode.get())) {105 for (Node *n = start; n; n = n->traversePreviousNode(m_rootNode.get())) { 96 106 if (n->isElementNode()) { 97 107 if (nodeMatches(n)) { 98 108 if (!remainingOffset) { 99 lastItem = n;100 lastItemOffset = offset;101 isItemCacheValid = true;109 m_caches->lastItem = n; 110 m_caches->lastItemOffset = offset; 111 m_caches->isItemCacheValid = true; 102 112 return n; 103 113 } … … 114 124 int remainingOffset = offset; 115 125 if (!start) { 116 start = rootNode->firstChild();117 if ( isItemCacheValid) {118 if (offset == lastItemOffset) {119 return lastItem;120 } else if (offset > lastItemOffset ||lastItemOffset - offset < offset) {121 start = lastItem;122 remainingOffset -= lastItemOffset;126 start = m_rootNode->firstChild(); 127 if (m_caches->isItemCacheValid) { 128 if (offset == m_caches->lastItemOffset) { 129 return m_caches->lastItem; 130 } else if (offset > m_caches->lastItemOffset || m_caches->lastItemOffset - offset < offset) { 131 start = m_caches->lastItem; 132 remainingOffset -= m_caches->lastItemOffset; 123 133 } 124 134 } … … 133 143 Node* NodeList::itemWithName(const AtomicString& elementId) const 134 144 { 135 if ( rootNode->isDocumentNode() ||rootNode->inDocument()) {136 Node* node = rootNode->document()->getElementById(elementId);145 if (m_rootNode->isDocumentNode() || m_rootNode->inDocument()) { 146 Node* node = m_rootNode->document()->getElementById(elementId); 137 147 138 148 if (!node || !nodeMatches(node)) … … 140 150 141 151 for (Node* p = node->parentNode(); p; p = p->parentNode()) 142 if (p == rootNode)152 if (p == m_rootNode) 143 153 return node; 144 154 … … 158 168 void NodeList::rootNodeChildrenChanged() 159 169 { 170 m_caches->reset(); 171 } 172 173 174 NodeList::Caches::Caches() 175 : lastItem(0) 176 , isLengthCacheValid(false) 177 , isItemCacheValid(false) 178 { 179 } 180 181 void NodeList::Caches::reset() 182 { 183 lastItem = 0; 160 184 isLengthCacheValid = false; 161 185 isItemCacheValid = false; 162 lastItem = 0;163 186 } 164 187 -
trunk/WebCore/dom/NodeList.h
r20214 r21003 38 38 class NodeList : public Shared<NodeList> { 39 39 public: 40 41 struct Caches { 42 Caches(); 43 void reset(); 44 45 int cachedLength; 46 Node* lastItem; 47 unsigned lastItemOffset; 48 bool isLengthCacheValid : 1; 49 bool isItemCacheValid : 1; 50 }; 51 40 52 NodeList(PassRefPtr<Node> rootNode); 53 NodeList(PassRefPtr<Node> rootNode, Caches*); 41 54 virtual ~NodeList(); 42 55 … … 56 69 virtual bool nodeMatches(Node* testNode) const = 0; 57 70 58 RefPtr<Node> rootNode; 59 mutable int cachedLength; 60 mutable Node* lastItem; 61 mutable unsigned lastItemOffset; 62 mutable bool isLengthCacheValid : 1; 63 mutable bool isItemCacheValid : 1; 71 RefPtr<Node> m_rootNode; 72 mutable Caches* m_caches; 73 bool m_ownsCaches; 64 74 65 75 private:
Note: See TracChangeset
for help on using the changeset viewer.