Changeset 28868

Show
Ignore:
Timestamp:
12/19/07 12:11:09 (12 months ago)
Author:
weinig@apple.com
Message:

Reviewed by Maciej.

http://bugs.webkit.org/show_bug.cgi?id=16511
Speed up ClassNodeList and NamedNodeList by using the caching mechanism employed by ChildNodeList.

  • dom/ChildNodeList.cpp: Use the caching NodeList constructor to turn on caching. (WebCore::ChildNodeList::ChildNodeList):
  • dom/ClassNodeList.cpp: (WebCore::ClassNodeList::ClassNodeList):
  • dom/ClassNodeList.h:

Move getElementsByName and getElementsByClassName to Node so they
can use easily employ the caching already used by ChildNodeLists. In the case of
getElementsByClassName, this reduces code duplication in Element as well

  • dom/Document.cpp:
  • dom/Document.h:

Move getElementsByClassName to Node.

  • dom/Element.cpp:
  • dom/Element.h:
  • dom/NameNodeList.cpp: Use the caching NodeList constructor to turn on caching. (WebCore::NameNodeList::NameNodeList): (WebCore::NameNodeList::item):
  • dom/NameNodeList.h:

Add maps of caches for ClassNodeLists and NameNodeList to NodeListsNodeData.

  • dom/Node.cpp: (WebCore::TagNodeList::TagNodeList): (WebCore::Node::Node): (WebCore::Node::~Node): (WebCore::Node::childNodes): (WebCore::Node::registerNodeList): (WebCore::Node::getElementsByName): (WebCore::Node::getElementsByClassName):
  • dom/Node.h: Make m_nodeLists an OwnPtr. Moved getElementsByName and getElementsByClassName here

Allow subclasses to choose whether they want to receive the notifications using a new bit.

  • dom/NodeList.cpp: (WebCore::NodeList::NodeList):
  • dom/NodeList.h: (WebCore::NodeList::needsNotifications):
Location:
trunk/WebCore
Files:
14 modified

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r28867 r28868  
     12007-12-19  Sam Weinig  <sam@webkit.org> 
     2 
     3        Reviewed by Maciej. 
     4 
     5        http://bugs.webkit.org/show_bug.cgi?id=16511 
     6        Speed up ClassNodeList and NamedNodeList by using the caching mechanism employed by ChildNodeList. 
     7        - This give a ~2.15x speedup on the native test @ http://ejohn.org/apps/classname/ 
     8 
     9        * dom/ChildNodeList.cpp: Use the caching NodeList constructor to turn on caching. 
     10        (WebCore::ChildNodeList::ChildNodeList): 
     11        * dom/ClassNodeList.cpp: 
     12        (WebCore::ClassNodeList::ClassNodeList): 
     13        * dom/ClassNodeList.h: 
     14 
     15        Move getElementsByName and getElementsByClassName to Node so they 
     16        can use easily employ the caching already used by ChildNodeLists.  In the case of  
     17        getElementsByClassName, this reduces code duplication in Element as well 
     18        * dom/Document.cpp: 
     19        * dom/Document.h: 
     20 
     21        Move getElementsByClassName to Node. 
     22        * dom/Element.cpp: 
     23        * dom/Element.h: 
     24 
     25        * dom/NameNodeList.cpp: Use the caching NodeList constructor to turn on caching. 
     26        (WebCore::NameNodeList::NameNodeList): 
     27        (WebCore::NameNodeList::item): 
     28        * dom/NameNodeList.h: 
     29 
     30        Add maps of caches for ClassNodeLists and NameNodeList to NodeListsNodeData. 
     31        * dom/Node.cpp: 
     32        (WebCore::TagNodeList::TagNodeList): 
     33        (WebCore::Node::Node): 
     34        (WebCore::Node::~Node): 
     35        (WebCore::Node::childNodes): 
     36        (WebCore::Node::registerNodeList): 
     37        (WebCore::Node::getElementsByName): 
     38        (WebCore::Node::getElementsByClassName): 
     39        * dom/Node.h: Make m_nodeLists an OwnPtr.  Moved getElementsByName and getElementsByClassName here 
     40 
     41        Allow subclasses to choose whether they want to receive the notifications using a new bit. 
     42        * dom/NodeList.cpp: 
     43        (WebCore::NodeList::NodeList): 
     44        * dom/NodeList.h: 
     45        (WebCore::NodeList::needsNotifications): 
     46 
    1472007-12-19  Dave Hyatt  <hyatt@apple.com> 
    248 
  • trunk/WebCore/dom/ChildNodeList.cpp

    r25754 r28868  
    3232 
    3333ChildNodeList::ChildNodeList(Node* n, NodeList::Caches* info) 
    34     : NodeList(n, info) 
     34    : NodeList(n, info, false) 
    3535{ 
    3636} 
  • trunk/WebCore/dom/ClassNodeList.cpp

    r28722 r28868  
    3737namespace WebCore { 
    3838 
    39 ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const AtomicString& className) 
    40     : NodeList(rootNode) 
     39ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames, NodeList::Caches* caches) 
     40    : NodeList(rootNode, caches, true) 
    4141{ 
    42     m_classNames.parseClassAttribute(className, m_rootNode->document()->inCompatMode()); 
     42    m_classNames.parseClassAttribute(classNames, m_rootNode->document()->inCompatMode()); 
    4343} 
    4444 
  • trunk/WebCore/dom/ClassNodeList.h

    r28722 r28868  
    3131#define ClassNodeList_h 
    3232 
    33 #include "AtomicString.h" 
    3433#include "ClassNames.h" 
    3534#include "NodeList.h" 
     
    3736namespace WebCore { 
    3837 
     38    class String; 
     39 
    3940    class ClassNodeList : public NodeList { 
    4041    public: 
    41         ClassNodeList(PassRefPtr<Node> rootNode, const AtomicString& className); 
     42        ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames, NodeList::Caches*); 
    4243 
    4344        virtual unsigned length() const; 
  • trunk/WebCore/dom/Document.cpp

    r28867 r28868  
    34973497} 
    34983498 
    3499 PassRefPtr<NameNodeList> Document::getElementsByName(const String& elementName) 
    3500 { 
    3501     return new NameNodeList(this, elementName); 
    3502 } 
    3503  
    3504 PassRefPtr<NodeList> Document::getElementsByClassName(const String& className) 
    3505 { 
    3506     return new ClassNodeList(this, className); 
    3507 } 
    3508  
    35093499void Document::finishedParsing() 
    35103500{ 
  • trunk/WebCore/dom/Document.h

    r28722 r28868  
    212212 
    213213    PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionCode&); 
    214      
    215     PassRefPtr<NameNodeList> getElementsByName(const String& elementName); 
    216     PassRefPtr<NodeList> getElementsByClassName(const String& className); 
    217214 
    218215    PassRefPtr<HTMLCollection> images(); 
  • trunk/WebCore/dom/Element.cpp

    r28722 r28868  
    11241124} 
    11251125 
    1126 PassRefPtr<NodeList> Element::getElementsByClassName(const String& className) 
    1127 { 
    1128     return new ClassNodeList(this, className); 
    1129 } 
    1130  
    11311126void Element::cancelFocusAppearanceUpdate() 
    11321127{ 
  • trunk/WebCore/dom/Element.h

    r28722 r28868  
    163163    virtual void updateFocusAppearance(bool restorePreviousSelection); 
    164164    void blur(); 
    165      
    166     PassRefPtr<NodeList> getElementsByClassName(const String&); 
    167165 
    168166#ifndef NDEBUG 
  • trunk/WebCore/dom/NameNodeList.cpp

    r28722 r28868  
    3131using namespace HTMLNames; 
    3232 
    33 NameNodeList::NameNodeList(Node* root, const String& name) 
    34     : NodeList(root) 
     33NameNodeList::NameNodeList(Node* root, const String& name, NodeList::Caches* caches) 
     34    : NodeList(root, caches, true) 
    3535    , m_nodeName(name) 
    3636{ 
     
    4242} 
    4343 
    44 Node* NameNodeList::item (unsigned index) const 
     44Node* NameNodeList::item(unsigned index) const 
    4545{ 
    4646    return recursiveItem(index); 
  • trunk/WebCore/dom/NameNodeList.h

    r28722 r28868  
    3434class NameNodeList : public NodeList { 
    3535public: 
    36     NameNodeList(Node* root, const String& name); 
     36    NameNodeList(Node* root, const String& name, NodeList::Caches*); 
    3737 
    3838    // DOM methods overridden from  parent classes 
     
    4242 
    4343    // Other methods (not part of DOM) 
     44     
    4445    virtual void rootNodeAttributeChanged() { NodeList::rootNodeChildrenChanged(); } 
    4546 
  • trunk/WebCore/dom/Node.cpp

    r28110 r28868  
    2727#include "CString.h" 
    2828#include "ChildNodeList.h" 
     29#include "ClassNodeList.h" 
    2930#include "DOMImplementation.h" 
    3031#include "Document.h" 
     
    3334#include "Frame.h" 
    3435#include "HTMLNames.h" 
     36#include "HTMLNames.h" 
    3537#include "KURL.h" 
    3638#include "Logging.h" 
     39#include "NameNodeList.h" 
    3740#include "NamedAttrMap.h" 
    3841#include "RenderObject.h" 
     
    5154    NodeListSet m_listsToNotify; 
    5255    NodeList::Caches m_childNodeListCaches; 
     56    HashMap<String, NodeList::Caches> m_classNodeListCaches; 
     57    HashMap<String, NodeList::Caches> m_nameNodeListCaches; 
    5358}; 
    5459 
     
    6974 
    7075inline TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName) 
    71     : NodeList(rootNode), m_namespaceURI(namespaceURI), m_localName(localName) 
     76    : NodeList(rootNode, true) 
     77    , m_namespaceURI(namespaceURI) 
     78    , m_localName(localName) 
    7279{ 
    7380    ASSERT(m_namespaceURI.isNull() || !m_namespaceURI.isEmpty()); 
     
    139146      m_next(0), 
    140147      m_renderer(0), 
    141       m_nodeLists(0), 
    142148      m_tabIndex(0), 
    143149      m_hasId(false), 
     
    192198    if (renderer()) 
    193199        detach(); 
    194     delete m_nodeLists; 
     200 
    195201    if (m_previous) 
    196202        m_previous->setNextSibling(0); 
     
    218224{ 
    219225    if (!m_nodeLists) 
    220         m_nodeLists = new NodeListsNodeData; 
     226        m_nodeLists.set(new NodeListsNodeData); 
    221227 
    222228    return new ChildNodeList(this, &m_nodeLists->m_childNodeListCaches); 
     
    439445{ 
    440446    if (!m_nodeLists) 
    441         m_nodeLists = new NodeListsNodeData; 
     447        m_nodeLists.set(new NodeListsNodeData); 
    442448    else if (!m_document->hasNodeLists()) 
    443449        // We haven't been receiving notifications while there were no registered lists, so the cache is invalid now. 
     
    12061212        name = localName.lower(); 
    12071213    return new TagNodeList(this, namespaceURI.isEmpty() ? nullAtom : AtomicString(namespaceURI), name); 
     1214} 
     1215 
     1216PassRefPtr<NodeList> Node::getElementsByName(const String& elementName) 
     1217{ 
     1218    if (!m_nodeLists) 
     1219        m_nodeLists.set(new NodeListsNodeData); 
     1220 
     1221    return new NameNodeList(this, elementName, &m_nodeLists->m_nameNodeListCaches.add(elementName, NodeList::Caches()).first->second); 
     1222} 
     1223 
     1224PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames) 
     1225{ 
     1226    if (!m_nodeLists) 
     1227        m_nodeLists.set(new NodeListsNodeData); 
     1228 
     1229    return new ClassNodeList(this, classNames, &m_nodeLists->m_classNodeListCaches.add(classNames, NodeList::Caches()).first->second); 
    12081230} 
    12091231 
  • trunk/WebCore/dom/Node.h

    r28110 r28868  
    2525#define Node_h 
    2626 
     27#include "DeprecatedString.h" 
    2728#include "DocPtr.h" 
    28 #include "DeprecatedString.h" 
    2929#include "PlatformString.h" 
    3030#include "TreeShared.h" 
    3131#include <wtf/Assertions.h> 
    3232#include <wtf/HashSet.h> 
     33#include <wtf/OwnPtr.h> 
    3334#include <wtf/PassRefPtr.h> 
    3435 
     
    4546class NamedAttrMap; 
    4647class NodeList; 
    47 struct NodeListsNodeData; 
    4848class PlatformKeyboardEvent; 
    4949class PlatformMouseEvent; 
     
    5555class RenderStyle; 
    5656class TextStream; 
     57struct NodeListsNodeData; 
    5758 
    5859typedef int ExceptionCode; 
     
    452453    PassRefPtr<NodeList> getElementsByTagNameNS(const String& namespaceURI, const String& localName); 
    453454 
     455    PassRefPtr<NodeList> getElementsByName(const String& elementName); 
     456    PassRefPtr<NodeList> getElementsByClassName(const String& classNames); 
     457 
    454458private: // members 
    455459    DocPtr<Document> m_document; 
     
    462466    virtual void didMoveToNewOwnerDocument() { } 
    463467     
    464     NodeListsNodeData* m_nodeLists; 
     468    OwnPtr<NodeListsNodeData> m_nodeLists; 
    465469 
    466470    short m_tabIndex; 
  • trunk/WebCore/dom/NodeList.cpp

    r25754 r28868  
    3131namespace WebCore { 
    3232 
    33 NodeList::NodeList(PassRefPtr<Node> rootNode) 
     33NodeList::NodeList(PassRefPtr<Node> rootNode, bool needsNotifications) 
    3434    : m_rootNode(rootNode) 
    3535    , m_caches(new Caches) 
    3636    , m_ownsCaches(true) 
     37    , m_needsNotifications(needsNotifications) 
    3738{ 
    3839    m_rootNode->registerNodeList(this); 
    3940}     
    4041 
    41 NodeList::NodeList(PassRefPtr<Node> rootNode, NodeList::Caches* info) 
     42NodeList::NodeList(PassRefPtr<Node> rootNode, NodeList::Caches* info, bool needsNotifications) 
    4243    : m_rootNode(rootNode) 
    4344    , m_caches(info) 
    4445    , m_ownsCaches(false) 
     46    , m_needsNotifications(needsNotifications) 
    4547{ 
    4648    m_rootNode->registerNodeList(this); 
  • trunk/WebCore/dom/NodeList.h

    r27983 r28868  
    5050    }; 
    5151 
    52     NodeList(PassRefPtr<Node> rootNode); 
    53     NodeList(PassRefPtr<Node> rootNode, Caches*); 
     52    NodeList(PassRefPtr<Node> rootNode, bool needsNotifications); 
     53    NodeList(PassRefPtr<Node> rootNode, Caches*, bool needsNotifications); 
    5454    virtual ~NodeList(); 
    5555 
    56     bool needsNotifications() const { return m_ownsCaches; } 
     56    bool needsNotifications() const { return m_needsNotifications; } 
    5757 
    5858    // DOM methods & attributes for NodeList 
     
    7474    mutable Caches* m_caches; 
    7575    bool m_ownsCaches; 
     76    bool m_needsNotifications; 
    7677 
    7778 private: