Changeset 120979 in webkit


Ignore:
Timestamp:
Jun 21, 2012 4:37:56 PM (12 years ago)
Author:
rniwa@webkit.org
Message:

Shrink NodeListsNodeData
https://bugs.webkit.org/show_bug.cgi?id=89036

Reviewed by Andreas Kling.

Replaced 6 hash maps of AtomicString, String, and RefPtr<QualifiedName::QualifiedNameImpl> and a raw pointer
by 3 hash maps of std::pair<unsigned short, AtomicString>, std::pair<unsigned short, String>, and QualifiedName,
to halve the NodeListsNodeData's size (Reduced from 7 pointers to 3 pointers). Made those hash maps private and
added addCacheWith* and removeCacheWith* member functions to reduce the code duplication.

Also got rid of removeCached*NodeList member functions from Node and Document now that DynamicSubtreeNodeList can
simply call nodeLists()->removeCacheWith* on m_node.

  • dom/ChildNodeList.cpp:

(WebCore::ChildNodeList::ChildNodeList):

  • dom/ClassNodeList.cpp:

(WebCore::ClassNodeList::~ClassNodeList):

  • dom/Document.cpp:

(WebCore::Document::getItems): Use addCacheWithName.

  • dom/Document.h: Got rid of removeCachedMicroDataItemList.

(Document):

  • dom/DynamicNodeList.cpp:

(WebCore): Moved the constructor to the header file.

  • dom/DynamicNodeList.h: Added NodeListType and InvalidationType to be used in NodeListsNodeData.

(WebCore::DynamicNodeList::DynamicNodeList): Takes the invalidation type.
(WebCore::DynamicNodeList::document): Added.
(WebCore::DynamicNodeList::shouldInvalidateOnAttributeChange): Added.
(WebCore::DynamicNodeList::Caches::Caches): Added shouldInvalidateOnAttributeChange to retain the invalidation type.
(Caches):
(WebCore::DynamicSubtreeNodeList::DynamicSubtreeNodeList):

  • dom/MicroDataItemList.cpp:

(WebCore::MicroDataItemList::~MicroDataItemList):

  • dom/NameNodeList.cpp:

(WebCore::NameNodeList::NameNodeList):
(WebCore::NameNodeList::~NameNodeList):
(WebCore::NameNodeList::nodeMatches):

  • dom/NameNodeList.h:

(WebCore):
(NameNodeList):
(WebCore::NameNodeList::create):

  • dom/Node.cpp:

(WebCore::Node::nodeLists): Added so that node lists can directly call removeCacheWith*.
(WebCore::Node::getElementsByTagName):
(WebCore::Node::getElementsByTagNameNS):
(WebCore::Node::getElementsByName):
(WebCore::Node::getElementsByClassName):
(WebCore::Node::radioNodeList):
(WebCore::NodeListsNodeData::invalidateCaches): Merged invalidateCachesThatDependOnAttributes. The function takes
the attribute name to avoid invalidating tag node lists when only attributes are modified. Also, now we have exactly
three hash maps to invalidate: m_atomicNameCaches, m_nameCaches, and m_tagNodeListCacheNS.
(WebCore): NodeListsNodeData::isEmpty is moved to NodeRareData.h.

  • dom/Node.h:

(WebCore):
(Node):

  • dom/NodeRareData.h:

(NodeListsNodeData):
(WebCore::NodeListsNodeData::addCacheWithAtomicName):
(WebCore::NodeListsNodeData::addCacheWithName):
(WebCore::NodeListsNodeData::addCacheWithQualifiedName):
(WebCore::NodeListsNodeData::removeCacheWithAtomicName):
(WebCore::NodeListsNodeData::removeCacheWithName):
(WebCore::NodeListsNodeData::removeCacheWithQualifiedName):
(WebCore::NodeListsNodeData::isEmpty): Moved from Node.cpp now that this function is much shorter.
(WebCore::NodeListsNodeData::NodeListsNodeData):
(WebCore::NodeListsNodeData::namedNodeListKey): Helper member functions to obtain the key for AtomicString and
String hash maps.

  • dom/TagNodeList.cpp:

(WebCore::TagNodeList::TagNodeList):
(WebCore::TagNodeList::~TagNodeList):
(WebCore::HTMLTagNodeList::HTMLTagNodeList): Hard code namespaceURI = starAtom since other values are never used.
(WebCore::HTMLTagNodeList::nodeMatches): Given that, assert m_namespace == starAtom.

  • dom/TagNodeList.h:

(WebCore::TagNodeList::create): Add a new version of create that doesn't take namespace (assume starAtom) so that
addCacheWithAtomicName works with this class.
(WebCore::HTMLTagNodeList::create): Removed namespaceURI from the argument list since it's always starAtom.
(HTMLTagNodeList):

  • html/LabelableElement.cpp:

(WebCore::LabelableElement::labels):

  • html/LabelsNodeList.cpp:

(WebCore::LabelsNodeList::LabelsNodeList): Removed redundant m_forNode (identical to m_node in DynamicNodeList).
(WebCore::LabelsNodeList::~LabelsNodeList):
(WebCore::LabelsNodeList::nodeMatches):

  • html/LabelsNodeList.h:

(WebCore::LabelsNodeList::create):
(LabelsNodeList):

  • html/RadioNodeList.cpp:

(WebCore::RadioNodeList::RadioNodeList): Removed redundant m_baseElement (identical to m_node in DynamicNodeList).
Also changed the first argument's type from Element* to Node* so that it works better with new template member
functions of NodeListsNodeData.
(WebCore::RadioNodeList::~RadioNodeList):
(WebCore::RadioNodeList::checkElementMatchesRadioNodeListFilter):

  • html/RadioNodeList.h:

(WebCore::RadioNodeList::create):
(RadioNodeList):

Location:
trunk/Source/WebCore
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r120978 r120979  
     12012-06-20  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Shrink NodeListsNodeData
     4        https://bugs.webkit.org/show_bug.cgi?id=89036
     5
     6        Reviewed by Andreas Kling.
     7
     8        Replaced 6 hash maps of AtomicString, String, and RefPtr<QualifiedName::QualifiedNameImpl> and a raw pointer
     9        by 3 hash maps of std::pair<unsigned short, AtomicString>, std::pair<unsigned short, String>, and QualifiedName,
     10        to halve the NodeListsNodeData's size (Reduced from 7 pointers to 3 pointers). Made those hash maps private and
     11        added addCacheWith* and removeCacheWith* member functions to reduce the code duplication.
     12
     13        Also got rid of removeCached*NodeList member functions from Node and Document now that DynamicSubtreeNodeList can
     14        simply call nodeLists()->removeCacheWith* on m_node.
     15
     16        * dom/ChildNodeList.cpp:
     17        (WebCore::ChildNodeList::ChildNodeList):
     18        * dom/ClassNodeList.cpp:
     19        (WebCore::ClassNodeList::~ClassNodeList):
     20        * dom/Document.cpp:
     21        (WebCore::Document::getItems): Use addCacheWithName.
     22        * dom/Document.h: Got rid of removeCachedMicroDataItemList.
     23        (Document):
     24        * dom/DynamicNodeList.cpp:
     25        (WebCore): Moved the constructor to the header file.
     26        * dom/DynamicNodeList.h: Added NodeListType and InvalidationType to be used in NodeListsNodeData.
     27        (WebCore::DynamicNodeList::DynamicNodeList): Takes the invalidation type.
     28        (WebCore::DynamicNodeList::document): Added.
     29        (WebCore::DynamicNodeList::shouldInvalidateOnAttributeChange): Added.
     30        (WebCore::DynamicNodeList::Caches::Caches): Added shouldInvalidateOnAttributeChange to retain the invalidation type.
     31        (Caches):
     32        (WebCore::DynamicSubtreeNodeList::DynamicSubtreeNodeList):
     33        * dom/MicroDataItemList.cpp:
     34        (WebCore::MicroDataItemList::~MicroDataItemList):
     35        * dom/NameNodeList.cpp:
     36        (WebCore::NameNodeList::NameNodeList):
     37        (WebCore::NameNodeList::~NameNodeList):
     38        (WebCore::NameNodeList::nodeMatches):
     39        * dom/NameNodeList.h:
     40        (WebCore):
     41        (NameNodeList):
     42        (WebCore::NameNodeList::create):
     43        * dom/Node.cpp:
     44        (WebCore::Node::nodeLists): Added so that node lists can directly call removeCacheWith*.
     45        (WebCore::Node::getElementsByTagName):
     46        (WebCore::Node::getElementsByTagNameNS):
     47        (WebCore::Node::getElementsByName):
     48        (WebCore::Node::getElementsByClassName):
     49        (WebCore::Node::radioNodeList):
     50        (WebCore::NodeListsNodeData::invalidateCaches): Merged invalidateCachesThatDependOnAttributes. The function takes
     51        the attribute name to avoid invalidating tag node lists when only attributes are modified. Also, now we have exactly
     52        three hash maps to invalidate: m_atomicNameCaches, m_nameCaches, and m_tagNodeListCacheNS.
     53        (WebCore): NodeListsNodeData::isEmpty is moved to NodeRareData.h.
     54        * dom/Node.h:
     55        (WebCore):
     56        (Node):
     57        * dom/NodeRareData.h:
     58        (NodeListsNodeData):
     59        (WebCore::NodeListsNodeData::addCacheWithAtomicName):
     60        (WebCore::NodeListsNodeData::addCacheWithName):
     61        (WebCore::NodeListsNodeData::addCacheWithQualifiedName):
     62        (WebCore::NodeListsNodeData::removeCacheWithAtomicName):
     63        (WebCore::NodeListsNodeData::removeCacheWithName):
     64        (WebCore::NodeListsNodeData::removeCacheWithQualifiedName):
     65        (WebCore::NodeListsNodeData::isEmpty): Moved from Node.cpp now that this function is much shorter.
     66        (WebCore::NodeListsNodeData::NodeListsNodeData):
     67        (WebCore::NodeListsNodeData::namedNodeListKey): Helper member functions to obtain the key for AtomicString and
     68        String hash maps.
     69        * dom/TagNodeList.cpp:
     70        (WebCore::TagNodeList::TagNodeList):
     71        (WebCore::TagNodeList::~TagNodeList):
     72        (WebCore::HTMLTagNodeList::HTMLTagNodeList): Hard code namespaceURI = starAtom since other values are never used.
     73        (WebCore::HTMLTagNodeList::nodeMatches): Given that, assert m_namespace == starAtom.
     74        * dom/TagNodeList.h:
     75        (WebCore::TagNodeList::create): Add a new version of create that doesn't take namespace (assume starAtom) so that
     76        addCacheWithAtomicName works with this class.
     77        (WebCore::HTMLTagNodeList::create): Removed namespaceURI from the argument list since it's always starAtom.
     78        (HTMLTagNodeList):
     79        * html/LabelableElement.cpp:
     80        (WebCore::LabelableElement::labels):
     81        * html/LabelsNodeList.cpp:
     82        (WebCore::LabelsNodeList::LabelsNodeList): Removed redundant m_forNode (identical to m_node in DynamicNodeList).
     83        (WebCore::LabelsNodeList::~LabelsNodeList):
     84        (WebCore::LabelsNodeList::nodeMatches):
     85        * html/LabelsNodeList.h:
     86        (WebCore::LabelsNodeList::create):
     87        (LabelsNodeList):
     88        * html/RadioNodeList.cpp:
     89        (WebCore::RadioNodeList::RadioNodeList): Removed redundant m_baseElement (identical to m_node in DynamicNodeList).
     90        Also changed the first argument's type from Element* to Node* so that it works better with new template member
     91        functions of NodeListsNodeData.
     92        (WebCore::RadioNodeList::~RadioNodeList):
     93        (WebCore::RadioNodeList::checkElementMatchesRadioNodeListFilter):
     94        * html/RadioNodeList.h:
     95        (WebCore::RadioNodeList::create):
     96        (RadioNodeList):
     97
    1982012-06-21  Sheriff Bot  <webkit.review.bot@gmail.com>
    299
  • trunk/Source/WebCore/dom/ChildNodeList.cpp

    r105408 r120979  
    2929
    3030ChildNodeList::ChildNodeList(PassRefPtr<Node> node)
    31     : DynamicNodeList(node)
     31    : DynamicNodeList(node, RootedAtNode, DoNotInvalidateOnAttributeChange)
    3232{
    3333}
  • trunk/Source/WebCore/dom/ClassNodeList.cpp

    r120367 r120979  
    3232
    3333#include "Document.h"
     34#include "NodeRareData.h"
    3435#include "StyledElement.h"
    3536
     
    4546ClassNodeList::~ClassNodeList()
    4647{
    47     node()->removeCachedClassNodeList(this, m_originalClassNames);
     48    node()->nodeLists()->removeCacheWithName(this, DynamicNodeList::ClassNodeListType, m_originalClassNames);
    4849}
    4950
  • trunk/Source/WebCore/dom/Document.cpp

    r120885 r120979  
    59275927PassRefPtr<NodeList> Document::getItems(const String& typeNames)
    59285928{
    5929     NodeListsNodeData* nodeLists = ensureRareData()->ensureNodeLists(this);
    5930 
    59315929    // Since documet.getItem() is allowed for microdata, typeNames will be null string.
    59325930    // In this case we need to create an unique string identifier to map such request in the cache.
    59335931    String localTypeNames = typeNames.isNull() ? String("http://webkit.org/microdata/undefinedItemType") : typeNames;
    59345932
    5935     NodeListsNodeData::MicroDataItemListCache::AddResult result = nodeLists->m_microDataItemListCache.add(localTypeNames, 0);
    5936     if (!result.isNewEntry)
    5937         return PassRefPtr<NodeList>(result.iterator->second);
    5938 
    5939     RefPtr<MicroDataItemList> list = MicroDataItemList::create(this, typeNames);
    5940     result.iterator->second = list.get();
    5941     return list.release();
    5942 }
    5943 
    5944 void Document::removeCachedMicroDataItemList(MicroDataItemList* list, const String& typeNames)
    5945 {
    5946     ASSERT(rareData());
    5947     ASSERT(rareData()->nodeLists());
    5948 
    5949     NodeListsNodeData* data = rareData()->nodeLists();
    5950 
    5951     String localTypeNames = typeNames.isNull() ? String("http://webkit.org/microdata/undefinedItemType") : typeNames;
    5952     ASSERT_UNUSED(list, list == data->m_microDataItemListCache.get(localTypeNames));
    5953     data->m_microDataItemListCache.remove(localTypeNames);
     5933    return ensureRareData()->ensureNodeLists(this)->addCacheWithName<MicroDataItemList>(this, DynamicNodeList::MicroDataItemListType, localTypeNames);
    59545934}
    59555935#endif
  • trunk/Source/WebCore/dom/Document.h

    r120868 r120979  
    11091109#if ENABLE(MICRODATA)
    11101110    PassRefPtr<NodeList> getItems(const String& typeNames);
    1111     void removeCachedMicroDataItemList(MicroDataItemList*, const String&);
    11121111#endif
    11131112   
  • trunk/Source/WebCore/dom/DynamicNodeList.cpp

    r120367 r120979  
    2828
    2929namespace WebCore {
    30 
    31 DynamicSubtreeNodeList::DynamicSubtreeNodeList(PassRefPtr<Node> node, RootType rootType)
    32     : DynamicNodeList(node, rootType)
    33 {
    34 }
    3530
    3631DynamicSubtreeNodeList::~DynamicSubtreeNodeList()
  • trunk/Source/WebCore/dom/DynamicNodeList.h

    r120868 r120979  
    3737class DynamicNodeList : public NodeList {
    3838public:
     39    enum NodeListType {
     40        ChildNodeListType,
     41        ClassNodeListType,
     42        NameNodeListType,
     43        TagNodeListType,
     44        RadioNodeListType,
     45        LabelsNodeListType,
     46        MicroDataItemListType,
     47    };
    3948    enum RootType {
    4049        RootedAtNode,
    4150        RootedAtDocument,
    4251    };
    43 
    44     DynamicNodeList(PassRefPtr<Node> node, RootType rootType = RootedAtNode)
     52    enum InvalidationType {
     53        AlwaysInvalidate,
     54        DoNotInvalidateOnAttributeChange,
     55    };
     56    DynamicNodeList(PassRefPtr<Node> node, RootType rootType, InvalidationType invalidationType)
    4557        : m_node(node)
    46         , m_caches(rootType)
     58        , m_caches(rootType, invalidationType)
    4759    { }
    4860    virtual ~DynamicNodeList() { }
     
    6072        return m_node.get();
    6173    }
     74    Document* document() { return m_node->document(); }
     75
     76    bool shouldInvalidateOnAttributeChange() const { return m_caches.shouldInvalidateOnAttributeChange; }
    6277
    6378    void invalidateCache() { m_caches.reset(); }
     
    6782
    6883    struct Caches {
    69         Caches(RootType rootType)
     84        Caches(RootType rootType, InvalidationType invalidationType)
    7085            : rootedAtDocument(rootType == RootedAtDocument)
     86            , shouldInvalidateOnAttributeChange(invalidationType == AlwaysInvalidate)
    7187        {
    7288            reset();
     
    8298        Node* lastItem;
    8399        unsigned cachedLength;
    84         unsigned lastItemOffset : 29; // Borrow 3-bits for bit fields
     100        unsigned lastItemOffset;
    85101        unsigned isLengthCacheValid : 1;
    86102        unsigned isItemCacheValid : 1;
     103
     104        // Following flags should belong in DynamicSubtreeNode but are here for bit-packing.
     105        unsigned type : 4;
    87106        unsigned rootedAtDocument : 1;
     107        unsigned shouldInvalidateOnAttributeChange : 1;
    88108    };
    89109
     
    102122
    103123protected:
    104     DynamicSubtreeNodeList(PassRefPtr<Node>, RootType = RootedAtNode);
     124    DynamicSubtreeNodeList(PassRefPtr<Node> node, RootType rootType = RootedAtNode, InvalidationType invalidationType = AlwaysInvalidate)
     125        : DynamicNodeList(node, rootType, invalidationType)
     126    { }
    105127
    106128private:
  • trunk/Source/WebCore/dom/MicroDataItemList.cpp

    r105655 r120979  
    3333#include "HTMLElement.h"
    3434#include "HTMLNames.h"
     35#include "NodeRareData.h"
    3536
    3637namespace WebCore {
     
    4748MicroDataItemList::~MicroDataItemList()
    4849{
    49     rootNode()->document()->removeCachedMicroDataItemList(this, m_originalTypeNames);
     50    String localTypeNames = m_originalTypeNames.isNull() ? String("http://webkit.org/microdata/undefinedItemType") : m_originalTypeNames;
     51    m_node->nodeLists()->removeCacheWithName(this, DynamicNodeList::MicroDataItemListType, localTypeNames);
    5052}
    5153
  • trunk/Source/WebCore/dom/NameNodeList.cpp

    r120367 r120979  
    2626#include "Element.h"
    2727#include "HTMLNames.h"
     28#include "NodeRareData.h"
    2829#include <wtf/Assertions.h>
    2930
     
    3233using namespace HTMLNames;
    3334
    34 NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const String& name)
     35NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name)
    3536    : DynamicSubtreeNodeList(rootNode)
    36     , m_nodeName(name)
     37    , m_name(name)
    3738{
    3839}
     
    4041NameNodeList::~NameNodeList()
    4142{
    42     node()->removeCachedNameNodeList(this, m_nodeName);
     43    m_node->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::NameNodeListType, m_name);
    4344}
    4445
    4546bool NameNodeList::nodeMatches(Element* testNode) const
    4647{
    47     return testNode->getNameAttribute() == m_nodeName;
     48    return testNode->getNameAttribute() == m_name;
    4849}
    4950
  • trunk/Source/WebCore/dom/NameNodeList.h

    r102834 r120979  
    3131namespace WebCore {
    3232
    33     // NodeList which lists all Nodes in a Element with a given "name" attribute
    34     class NameNodeList : public DynamicSubtreeNodeList {
    35     public:
    36         static PassRefPtr<NameNodeList> create(PassRefPtr<Node> rootNode, const String& name)
    37         {
    38             return adoptRef(new NameNodeList(rootNode, name));
    39         }
     33// NodeList which lists all Nodes in a Element with a given "name" attribute
     34class NameNodeList : public DynamicSubtreeNodeList {
     35public:
     36    static PassRefPtr<NameNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& name)
     37    {
     38        return adoptRef(new NameNodeList(rootNode, name));
     39    }
    4040
    41         virtual ~NameNodeList();
     41    virtual ~NameNodeList();
    4242
    43     private:
    44         NameNodeList(PassRefPtr<Node> rootNode, const String& name);
     43private:
     44    NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name);
    4545
    46         virtual bool nodeMatches(Element*) const;
     46    virtual bool nodeMatches(Element*) const;
    4747
    48         AtomicString m_nodeName;
    49     };
     48    AtomicString m_name;
     49};
    5050
    5151} // namespace WebCore
  • trunk/Source/WebCore/dom/Node.cpp

    r120868 r120979  
    981981            continue;
    982982
    983         data->nodeLists()->invalidateCachesThatDependOnAttributes();
     983        data->nodeLists()->invalidateCaches(&attrName);
    984984    }
    985985}
     
    10061006}
    10071007
    1008 void Node::removeCachedClassNodeList(ClassNodeList* list, const String& className)
    1009 {
    1010     ASSERT(rareData());
    1011     ASSERT(rareData()->nodeLists());
    1012 
    1013     NodeListsNodeData* data = rareData()->nodeLists();
    1014     ASSERT_UNUSED(list, list == data->m_classNodeListCache.get(className));
    1015     data->m_classNodeListCache.remove(className);
    1016 }
    1017 
    1018 void Node::removeCachedNameNodeList(NameNodeList* list, const String& nodeName)
    1019 {
    1020     ASSERT(rareData());
    1021     ASSERT(rareData()->nodeLists());
    1022 
    1023     NodeListsNodeData* data = rareData()->nodeLists();
    1024     ASSERT_UNUSED(list, list == data->m_nameNodeListCache.get(nodeName));
    1025     data->m_nameNodeListCache.remove(nodeName);
    1026 }
    1027 
    1028 void Node::removeCachedTagNodeList(TagNodeList* list, const AtomicString& name)
    1029 {
    1030     ASSERT(rareData());
    1031     ASSERT(rareData()->nodeLists());
    1032 
    1033     NodeListsNodeData* data = rareData()->nodeLists();
    1034     ASSERT_UNUSED(list, list == data->m_tagNodeListCache.get(name.impl()));
    1035     data->m_tagNodeListCache.remove(name.impl());
    1036 }
    1037 
    1038 void Node::removeCachedTagNodeList(TagNodeList* list, const QualifiedName& name)
    1039 {
    1040     ASSERT(rareData());
    1041     ASSERT(rareData()->nodeLists());
    1042 
    1043     NodeListsNodeData* data = rareData()->nodeLists();
    1044     ASSERT_UNUSED(list, list == data->m_tagNodeListCacheNS.get(name.impl()));
    1045     data->m_tagNodeListCacheNS.remove(name.impl());
    1046 }
    1047 
    1048 void Node::removeCachedLabelsNodeList(DynamicSubtreeNodeList* list)
    1049 {
    1050     ASSERT(rareData());
    1051     ASSERT(rareData()->nodeLists());
    1052 
    1053     NodeListsNodeData* data = rareData()->nodeLists();
    1054     ASSERT_UNUSED(list, list == data->m_labelsNodeListCache);
    1055     data->m_labelsNodeListCache = 0;
     1008NodeListsNodeData* Node::nodeLists()
     1009{
     1010    return hasRareData() ? rareData()->nodeLists() : 0;
    10561011}
    10571012
     
    15931548        return 0;
    15941549
    1595     AtomicString localNameAtom = localName;
    1596 
    1597     NodeListsNodeData::TagNodeListCache::AddResult result = ensureRareData()->ensureNodeLists(this)->m_tagNodeListCache.add(localNameAtom, 0);
    1598     if (!result.isNewEntry)
    1599         return PassRefPtr<TagNodeList>(result.iterator->second);
    1600 
    1601     RefPtr<TagNodeList> list;
    16021550    if (document()->isHTMLDocument())
    1603         list = HTMLTagNodeList::create(this, starAtom, localNameAtom);
    1604     else
    1605         list = TagNodeList::create(this, starAtom, localNameAtom);
    1606     result.iterator->second = list.get();
    1607     return list.release();   
     1551        return ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<HTMLTagNodeList>(this, DynamicNodeList::TagNodeListType, localName);
     1552    return ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<TagNodeList>(this, DynamicNodeList::TagNodeListType, localName);
    16081553}
    16091554
     
    16161561        return getElementsByTagName(localName);
    16171562
    1618     AtomicString localNameAtom = localName;
    1619 
    1620     NodeListsNodeData::TagNodeListCacheNS::AddResult result
    1621         = ensureRareData()->ensureNodeLists(this)->m_tagNodeListCacheNS.add(QualifiedName(nullAtom, localNameAtom, namespaceURI).impl(), 0);
    1622     if (!result.isNewEntry)
    1623         return PassRefPtr<TagNodeList>(result.iterator->second);
    1624 
    1625     RefPtr<TagNodeList> list = TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom);
    1626     result.iterator->second = list.get();
    1627     return list.release();
     1563    return ensureRareData()->ensureNodeLists(this)->addCacheWithQualifiedName(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
    16281564}
    16291565
    16301566PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
    16311567{
    1632     NodeListsNodeData::NameNodeListCache::AddResult result = ensureRareData()->ensureNodeLists(this)->m_nameNodeListCache.add(elementName, 0);
    1633     if (!result.isNewEntry)
    1634         return PassRefPtr<NodeList>(result.iterator->second);
    1635 
    1636     RefPtr<NameNodeList> list = NameNodeList::create(this, elementName);
    1637     result.iterator->second = list.get();
    1638     return list.release();
     1568    return ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<NameNodeList>(this, DynamicNodeList::NameNodeListType, elementName);
    16391569}
    16401570
    16411571PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
    16421572{
    1643     NodeListsNodeData::ClassNodeListCache::AddResult result
    1644         = ensureRareData()->ensureNodeLists(this)->m_classNodeListCache.add(classNames, 0);
    1645     if (!result.isNewEntry)
    1646         return PassRefPtr<NodeList>(result.iterator->second);
    1647 
    1648     RefPtr<ClassNodeList> list = ClassNodeList::create(this, classNames);
    1649     result.iterator->second = list.get();
    1650     return list.release();
     1573    return ensureRareData()->ensureNodeLists(this)->addCacheWithName<ClassNodeList>(this, DynamicNodeList::ClassNodeListType, classNames);
     1574}
     1575
     1576PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name)
     1577{
     1578    ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
     1579    return ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<RadioNodeList>(this, DynamicNodeList::RadioNodeListType, name);
    16511580}
    16521581
     
    23102239// --------
    23112240
    2312 void NodeListsNodeData::invalidateCaches()
    2313 {
    2314     TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end();
    2315     for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it)
     2241void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName)
     2242{
     2243    NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
     2244    for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) {
     2245        if (!attrName || it->second->shouldInvalidateOnAttributeChange())
     2246            it->second->invalidateCache();
     2247    }
     2248
     2249    NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end();
     2250    for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) {
     2251        if (!attrName || it->second->shouldInvalidateOnAttributeChange())
     2252            it->second->invalidateCache();
     2253    }
     2254
     2255    if (!attrName)
     2256        return;
     2257
     2258    TagNodeListCacheNS::iterator tagCacheEnd = m_tagNodeListCacheNS.end();
     2259    for (TagNodeListCacheNS::iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheEnd; ++it)
    23162260        it->second->invalidateCache();
    2317     TagNodeListCacheNS::const_iterator tagCacheNSEnd = m_tagNodeListCacheNS.end();
    2318     for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheNSEnd; ++it)
    2319         it->second->invalidateCache();
    2320     invalidateCachesThatDependOnAttributes();
    2321 }
    2322 
    2323 void NodeListsNodeData::invalidateCachesThatDependOnAttributes()
    2324 {
    2325     ClassNodeListCache::iterator classCacheEnd = m_classNodeListCache.end();
    2326     for (ClassNodeListCache::iterator it = m_classNodeListCache.begin(); it != classCacheEnd; ++it)
    2327         it->second->invalidateCache();
    2328 
    2329     NameNodeListCache::iterator nameCacheEnd = m_nameNodeListCache.end();
    2330     for (NameNodeListCache::iterator it = m_nameNodeListCache.begin(); it != nameCacheEnd; ++it)
    2331         it->second->invalidateCache();
    2332     if (m_labelsNodeListCache)
    2333         m_labelsNodeListCache->invalidateCache();
    2334 
    2335 #if ENABLE(MICRODATA)
    2336     MicroDataItemListCache::iterator itemListCacheEnd = m_microDataItemListCache.end();
    2337     for (MicroDataItemListCache::iterator it = m_microDataItemListCache.begin(); it != itemListCacheEnd; ++it)
    2338         it->second->invalidateCache();
    2339 #endif
    2340 }
    2341 
    2342 bool NodeListsNodeData::isEmpty() const
    2343 {
    2344     if (!m_tagNodeListCache.isEmpty())
    2345         return false;
    2346     if (!m_tagNodeListCacheNS.isEmpty())
    2347         return false;
    2348     if (!m_classNodeListCache.isEmpty())
    2349         return false;
    2350     if (!m_nameNodeListCache.isEmpty())
    2351         return false;
    2352 #if ENABLE(MICRODATA)
    2353     if (!m_microDataItemListCache.isEmpty())
    2354         return false;
    2355 #endif
    2356 
    2357     if (m_labelsNodeListCache)
    2358         return false;
    2359 
    2360     if (!m_radioNodeListCache.isEmpty())
    2361         return false;
    2362 
    2363     return true;
    23642261}
    23652262
     
    28722769}
    28732770
    2874 PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name)
    2875 {
    2876     ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
    2877 
    2878     NodeListsNodeData* nodeLists = ensureRareData()->ensureNodeLists(this);
    2879 
    2880     NodeListsNodeData::RadioNodeListCache::AddResult result = nodeLists->m_radioNodeListCache.add(name, 0);
    2881     if (!result.isNewEntry)
    2882         return PassRefPtr<RadioNodeList>(result.iterator->second);
    2883 
    2884     RefPtr<RadioNodeList> list = RadioNodeList::create(toElement(this), name);
    2885     result.iterator->second = list.get();
    2886     return list.release();
    2887 }
    2888 
    2889 void Node::removeCachedRadioNodeList(RadioNodeList* list, const AtomicString& name)
    2890 {
    2891     ASSERT(rareData());
    2892     ASSERT(rareData()->nodeLists());
    2893 
    2894     NodeListsNodeData* data = rareData()->nodeLists();
    2895     ASSERT_UNUSED(list, list == data->m_radioNodeListCache.get(name));
    2896     data->m_radioNodeListCache.remove(name);
    2897 }
    2898 
    28992771// It's important not to inline removedLastRef, because we don't want to inline the code to
    29002772// delete a Node at each deref call site.
  • trunk/Source/WebCore/dom/Node.h

    r120367 r120979  
    7070class NameNodeList;
    7171class NodeList;
     72class NodeListsNodeData;
    7273class NodeRareData;
    7374class NodeRenderingContext;
     
    559560    void invalidateNodeListsCacheAfterAttributeChanged(const QualifiedName&, Element* attributeOwnerElement);
    560561    void invalidateNodeListsCacheAfterChildrenChanged();
    561     void removeCachedClassNodeList(ClassNodeList*, const String&);
    562 
    563     void removeCachedNameNodeList(NameNodeList*, const String&);
    564     void removeCachedTagNodeList(TagNodeList*, const AtomicString&);
    565     void removeCachedTagNodeList(TagNodeList*, const QualifiedName&);
    566     void removeCachedLabelsNodeList(DynamicSubtreeNodeList*);
    567 
     562    NodeListsNodeData* nodeLists();
    568563    void removeCachedChildNodeList();
    569 
    570     PassRefPtr<RadioNodeList> radioNodeList(const AtomicString&);
    571     void removeCachedRadioNodeList(RadioNodeList*, const AtomicString&);
    572     void resetCachedRadioNodeListRootNode();
    573564
    574565    PassRefPtr<NodeList> getElementsByTagName(const AtomicString&);
     
    576567    PassRefPtr<NodeList> getElementsByName(const String& elementName);
    577568    PassRefPtr<NodeList> getElementsByClassName(const String& classNames);
     569    PassRefPtr<RadioNodeList> radioNodeList(const AtomicString&);
    578570
    579571    PassRefPtr<Element> querySelector(const AtomicString& selectors, ExceptionCode&);
  • trunk/Source/WebCore/dom/NodeRareData.h

    r120868 r120979  
    2424
    2525#include "ChildNodeList.h"
    26 #include "ClassNodeList.h"
    2726#include "DOMSettableTokenList.h"
    2827#include "DynamicNodeList.h"
    2928#include "MutationObserverRegistration.h"
    30 #include "NameNodeList.h"
    3129#include "QualifiedName.h"
    3230#include "TagNodeList.h"
     
    5250    WTF_MAKE_NONCOPYABLE(NodeListsNodeData); WTF_MAKE_FAST_ALLOCATED;
    5351public:
    54     typedef HashMap<String, ClassNodeList*> ClassNodeListCache;
    55     ClassNodeListCache m_classNodeListCache;
    56 
    57     typedef HashMap<String, NameNodeList*> NameNodeListCache;
    58     NameNodeListCache m_nameNodeListCache;
    59  
    60     typedef HashMap<AtomicString, TagNodeList*> TagNodeListCache;
    61     TagNodeListCache m_tagNodeListCache;
    62 
    63     typedef HashMap<RefPtr<QualifiedName::QualifiedNameImpl>, TagNodeList*> TagNodeListCacheNS;
     52    typedef HashMap<std::pair<unsigned short, AtomicString>, DynamicSubtreeNodeList*> NodeListAtomicNameCacheMap;
     53    typedef HashMap<std::pair<unsigned short, String>, DynamicSubtreeNodeList*> NodeListNameCacheMap;
     54    typedef HashMap<QualifiedName, TagNodeList*> TagNodeListCacheNS;
     55
     56    template<typename T>
     57    PassRefPtr<T> addCacheWithAtomicName(Node* node, DynamicNodeList::NodeListType listType, const AtomicString& name)
     58    {
     59        NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(listType, name), 0);
     60        if (!result.isNewEntry)
     61            return static_cast<T*>(result.iterator->second);
     62
     63        RefPtr<T> list = T::create(node, name);
     64        result.iterator->second = list.get();
     65        return list.release();
     66    }
     67
     68    template<typename T>
     69    PassRefPtr<T> addCacheWithName(Node* node, DynamicNodeList::NodeListType listType, const String& name)
     70    {
     71        NodeListNameCacheMap::AddResult result = m_nameCaches.add(namedNodeListKey(listType, name), 0);
     72        if (!result.isNewEntry)
     73            return static_cast<T*>(result.iterator->second);
     74
     75        RefPtr<T> list = T::create(node, name);
     76        result.iterator->second = list.get();
     77        return list.release();
     78    }
     79
     80    PassRefPtr<TagNodeList> addCacheWithQualifiedName(Node* node, const AtomicString& namespaceURI, const AtomicString& localName)
     81    {
     82        QualifiedName name(nullAtom, localName, namespaceURI);
     83        TagNodeListCacheNS::AddResult result = m_tagNodeListCacheNS.add(name, 0);
     84        if (!result.isNewEntry)
     85            return result.iterator->second;
     86
     87        RefPtr<TagNodeList> list = TagNodeList::create(node, namespaceURI, localName);
     88        result.iterator->second = list.get();
     89        return list.release();
     90    }
     91
     92    void removeCacheWithAtomicName(DynamicSubtreeNodeList* list, DynamicNodeList::NodeListType listType, const AtomicString& name)
     93    {
     94        ASSERT_UNUSED(list, list == m_atomicNameCaches.get(namedNodeListKey(listType, name)));
     95        m_atomicNameCaches.remove(namedNodeListKey(listType, name));
     96    }
     97
     98    void removeCacheWithName(DynamicSubtreeNodeList* list, DynamicNodeList::NodeListType listType, const String& name)
     99    {
     100        ASSERT_UNUSED(list, list == m_nameCaches.get(namedNodeListKey(listType, name)));
     101        m_nameCaches.remove(namedNodeListKey(listType, name));
     102    }
     103
     104    void removeCacheWithQualifiedName(DynamicSubtreeNodeList* list, const AtomicString& namespaceURI, const AtomicString& localName)
     105    {
     106        QualifiedName name(nullAtom, localName, namespaceURI);
     107        ASSERT_UNUSED(list, list == m_tagNodeListCacheNS.get(name));
     108        m_tagNodeListCacheNS.remove(name);
     109    }
     110
     111    static PassOwnPtr<NodeListsNodeData> create()
     112    {
     113        return adoptPtr(new NodeListsNodeData);
     114    }
     115
     116    void invalidateCaches(const QualifiedName* attrName = 0);
     117    bool isEmpty() const
     118    {
     119        return m_atomicNameCaches.isEmpty() && m_nameCaches.isEmpty() && m_tagNodeListCacheNS.isEmpty();
     120    }
     121
     122private:
     123    NodeListsNodeData() { }
     124
     125    std::pair<unsigned short, AtomicString> namedNodeListKey(DynamicNodeList::NodeListType listType, const AtomicString& name)
     126    {
     127        return std::pair<unsigned short, AtomicString>(listType, name);
     128    }
     129
     130    std::pair<unsigned short, String> namedNodeListKey(DynamicNodeList::NodeListType listType, const String& name)
     131    {
     132        return std::pair<unsigned short, String>(listType, name);
     133    }
     134
     135    NodeListAtomicNameCacheMap m_atomicNameCaches;
     136    NodeListNameCacheMap m_nameCaches;
    64137    TagNodeListCacheNS m_tagNodeListCacheNS;
    65 
    66 #if ENABLE(MICRODATA)
    67     typedef HashMap<String, MicroDataItemList*> MicroDataItemListCache;
    68     MicroDataItemListCache m_microDataItemListCache;
    69 #endif
    70 
    71     LabelsNodeList* m_labelsNodeListCache;
    72 
    73     typedef HashMap<String, RadioNodeList*> RadioNodeListCache;
    74     RadioNodeListCache m_radioNodeListCache;
    75 
    76     static PassOwnPtr<NodeListsNodeData> create()
    77     {
    78         return adoptPtr(new NodeListsNodeData);
    79     }
    80 
    81     void invalidateCaches();
    82     void invalidateCachesThatDependOnAttributes();
    83 
    84     bool isEmpty() const;
    85 
    86 private:
    87     NodeListsNodeData() : m_labelsNodeListCache(0) {}
    88138};
    89139
  • trunk/Source/WebCore/dom/TagNodeList.cpp

    r120367 r120979  
    2626
    2727#include "Element.h"
     28#include "NodeRareData.h"
    2829#include <wtf/Assertions.h>
    2930
     
    3132
    3233TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
    33     : DynamicSubtreeNodeList(rootNode)
     34    : DynamicSubtreeNodeList(rootNode, RootedAtNode, DoNotInvalidateOnAttributeChange)
    3435    , m_namespaceURI(namespaceURI)
    3536    , m_localName(localName)
     
    4142{
    4243    if (m_namespaceURI == starAtom)
    43         node()->removeCachedTagNodeList(this, m_localName);
     44        m_node->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::TagNodeListType, m_localName);
    4445    else
    45         node()->removeCachedTagNodeList(this, QualifiedName(nullAtom, m_localName, m_namespaceURI));
     46        m_node->nodeLists()->removeCacheWithQualifiedName(this, m_namespaceURI, m_localName);
    4647}
    4748
     
    5556}
    5657
    57 HTMLTagNodeList::HTMLTagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
    58     : TagNodeList(rootNode, namespaceURI, localName)
     58HTMLTagNodeList::HTMLTagNodeList(PassRefPtr<Node> rootNode, const AtomicString& localName)
     59    : TagNodeList(rootNode, starAtom, localName)
    5960    , m_loweredLocalName(localName.lower())
    6061{
     
    7071    }
    7172
    72     return m_namespaceURI == starAtom || m_namespaceURI == testNode->namespaceURI();
     73    ASSERT(m_namespaceURI == starAtom);
     74    return true;
    7375}
    7476
  • trunk/Source/WebCore/dom/TagNodeList.h

    r113710 r120979  
    3535        static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
    3636        {
     37            ASSERT(namespaceURI != starAtom);
    3738            return adoptRef(new TagNodeList(rootNode, namespaceURI, localName));
     39        }
     40
     41        static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& localName)
     42        {
     43            return adoptRef(new TagNodeList(rootNode, starAtom, localName));
    3844        }
    3945
     
    5157    class HTMLTagNodeList : public TagNodeList {
    5258    public:
    53         static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
     59        static PassRefPtr<HTMLTagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& localName)
    5460        {
    55             return adoptRef(new HTMLTagNodeList(rootNode, namespaceURI, localName));
     61            return adoptRef(new HTMLTagNodeList(rootNode, localName));
    5662        }
    5763
    5864    private:
    59         HTMLTagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName);
     65        HTMLTagNodeList(PassRefPtr<Node> rootNode, const AtomicString& localName);
    6066
    6167        virtual bool nodeMatches(Element*) const;
  • trunk/Source/WebCore/html/LabelableElement.cpp

    r110927 r120979  
    4848        return 0;
    4949
    50     NodeListsNodeData* nodeLists = Node::ensureRareData()->ensureNodeLists(this);
    51     if (nodeLists->m_labelsNodeListCache)
    52         return nodeLists->m_labelsNodeListCache;
    53 
    54     RefPtr<LabelsNodeList> list = LabelsNodeList::create(this);
    55     nodeLists->m_labelsNodeListCache = list.get();
    56     return list.release();
     50    return Node::ensureRareData()->ensureNodeLists(this)->addCacheWithAtomicName<LabelsNodeList>(this, DynamicNodeList::LabelsNodeListType, starAtom);
    5751}
    5852
  • trunk/Source/WebCore/html/LabelsNodeList.cpp

    r120367 r120979  
    2828#include "HTMLLabelElement.h"
    2929#include "HTMLNames.h"
     30#include "NodeRareData.h"
    3031
    3132namespace WebCore {
     
    3536LabelsNodeList::LabelsNodeList(Node* forNode)
    3637    : DynamicSubtreeNodeList(forNode, RootedAtDocument)
    37     , m_forNode(forNode)
    3838{
    39     m_forNode->document()->registerDynamicSubtreeNodeList(this);
     39    document()->registerDynamicSubtreeNodeList(this);
    4040}
    4141
    4242LabelsNodeList::~LabelsNodeList()
    4343{
    44     m_forNode->removeCachedLabelsNodeList(this);
    45     m_forNode->document()->unregisterDynamicSubtreeNodeList(this);
     44    m_node->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::LabelsNodeListType, starAtom);
     45    document()->unregisterDynamicSubtreeNodeList(this);
    4646}
    4747   
    4848bool LabelsNodeList::nodeMatches(Element* testNode) const
    4949{
    50     return testNode->hasTagName(labelTag) && static_cast<HTMLLabelElement*>(testNode)->control() == m_forNode;
     50    return testNode->hasTagName(labelTag) && static_cast<HTMLLabelElement*>(testNode)->control() == m_node;
    5151}
    5252
  • trunk/Source/WebCore/html/LabelsNodeList.h

    r102834 r120979  
    3333class LabelsNodeList : public DynamicSubtreeNodeList {
    3434public:
    35     static PassRefPtr<LabelsNodeList> create(Node* forNode)
     35    static PassRefPtr<LabelsNodeList> create(Node* forNode, const AtomicString&)
    3636    {
    3737        return adoptRef(new LabelsNodeList(forNode));
     
    4343
    4444    virtual bool nodeMatches(Element*) const;
    45 
    46 private:
    47     RefPtr<Node> m_forNode;
    4845};
    4946
  • trunk/Source/WebCore/html/RadioNodeList.cpp

    r120367 r120979  
    3232#include "HTMLNames.h"
    3333#include "HTMLObjectElement.h"
     34#include "NodeRareData.h"
    3435
    3536namespace WebCore {
     
    3738using namespace HTMLNames;
    3839
    39 RadioNodeList::RadioNodeList(Element* baseElement, const AtomicString& name)
    40     : DynamicSubtreeNodeList(baseElement, baseElement->hasTagName(formTag) ? RootedAtDocument : RootedAtNode)
     40RadioNodeList::RadioNodeList(Node* rootNode, const AtomicString& name)
     41    : DynamicSubtreeNodeList(rootNode, rootNode->hasTagName(formTag) ? RootedAtDocument : RootedAtNode)
    4142    , m_name(name)
    42     , m_baseElement(baseElement)
    4343{
    44     m_baseElement->document()->registerDynamicSubtreeNodeList(this);
     44    document()->registerDynamicSubtreeNodeList(this);
    4545}
    4646
    4747RadioNodeList::~RadioNodeList()
    4848{
    49     m_baseElement->removeCachedRadioNodeList(this, m_name);
    50     m_baseElement->document()->unregisterDynamicSubtreeNodeList(this);
     49    m_node->nodeLists()->removeCacheWithAtomicName(this, DynamicNodeList::RadioNodeListType, m_name);
     50    document()->unregisterDynamicSubtreeNodeList(this);
    5151}
    5252
     
    8787{
    8888    ASSERT(testElement->hasTagName(objectTag) || testElement->isFormControlElement());
    89     if (m_baseElement->hasTagName(formTag)) {
     89    if (m_node->hasTagName(formTag)) {
    9090        HTMLFormElement* formElement = 0;
    9191        if (testElement->hasTagName(objectTag))
     
    9393        else
    9494            formElement = static_cast<HTMLFormControlElement*>(testElement)->form();
    95         if (!formElement || formElement != m_baseElement)
     95        if (!formElement || formElement != m_node)
    9696            return false;
    9797    }
  • trunk/Source/WebCore/html/RadioNodeList.h

    r120367 r120979  
    3737class RadioNodeList : public DynamicSubtreeNodeList {
    3838public:
    39     static PassRefPtr<RadioNodeList> create(Element* baseElement, const AtomicString& name)
     39    static PassRefPtr<RadioNodeList> create(Node* rootNode, const AtomicString& name)
    4040    {
    41         return adoptRef(new RadioNodeList(baseElement, name));
     41        return adoptRef(new RadioNodeList(rootNode, name));
    4242    }
    4343
     
    5151
    5252private:
    53     RadioNodeList(Element*, const AtomicString& name);
     53    RadioNodeList(Node*, const AtomicString& name);
    5454    bool checkElementMatchesRadioNodeListFilter(Element*) const;
    5555
    5656    AtomicString m_name;
    57     RefPtr<Element> m_baseElement;
    5857};
    5958
Note: See TracChangeset for help on using the changeset viewer.