Diff
Modified: trunk/Source/WebCore/ChangeLog (164771 => 164772)
--- trunk/Source/WebCore/ChangeLog 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/ChangeLog 2014-02-27 03:35:22 UTC (rev 164772)
@@ -1,5 +1,94 @@
2014-02-26 Ryosuke Niwa <rn...@webkit.org>
+ Extract named items caches in HTMLCollection as a class
+ https://bugs.webkit.org/show_bug.cgi?id=129365
+
+ Reviewed by Antti Koivisto.
+
+ Extracted CollectionNamedElementCache, like CollectionIndexCache, out of HTMLCollection.
+ We can move more named item related functions into this class in the future.
+
+ HTMLCollection's member variables m_isNameCacheValid, m_idCache, and m_nameCache were replaced by
+ a single unique_ptr that holds an instance of CollectionNamedElementCache since this object rarely
+ exists in most HTMLCollections.
+
+ Also removed m_isItemRefElementsCacheValid since it was only used by Microdata API removed in r153772
+ and renamed a whole bunch of member functions and variables for consistency.
+
+ * dom/Document.cpp:
+ (WebCore::Document::collectionCachedIdNameMap):
+ (WebCore::Document::collectionWillClearIdNameMap):
+ * dom/Document.h:
+ * dom/NodeRareData.h:
+ (WebCore::NodeListsNodeData::adoptDocument):
+ * html/HTMLAllCollection.cpp:
+ (WebCore::HTMLAllCollection::namedItemWithIndex):
+ * html/HTMLCollection.cpp:
+ (WebCore::HTMLCollection::HTMLCollection):
+ (WebCore::HTMLCollection::~HTMLCollection):
+ (WebCore::HTMLCollection::invalidateCache):
+ (WebCore::HTMLCollection::invalidateNamedElementCache): Renamed from invalidateIdNameCacheMaps.
+ (WebCore::HTMLCollection::namedItem):
+ (WebCore::HTMLCollection::updateNamedElementCache): Renamed from updateNameCache.
+ (WebCore::HTMLCollection::namedItems):
+
+ * html/HTMLCollection.h:
+ (WebCore::CollectionNamedElementCache::findElementsWithId): Renamed from HTMLCollection::idCache.
+ (WebCore::CollectionNamedElementCache::findElementsWithName): Renamed from HTMLCollection::nameCache.
+ (WebCore::CollectionNamedElementCache::appendIdCache): Moved from HTMLCollection.
+ (WebCore::CollectionNamedElementCache::appendNameCache): Ditto.
+ (WebCore::CollectionNamedElementCache::find): Ditto.
+ (WebCore::CollectionNamedElementCache::append): Ditto.
+
+ (WebCore::HTMLCollection::invalidateCache):
+ (WebCore::HTMLCollection::hasNamedElementCache): Renamed from hasIdNameCache.
+ (WebCore::HTMLCollection::createNameItemCache): Added.
+ (WebCore::HTMLCollection::namedItemCaches): Added.
+
+ * html/HTMLFormControlsCollection.cpp:
+ (WebCore::HTMLFormControlsCollection::updateNamedElementCache):
+ * html/HTMLFormControlsCollection.h:
+
+2014-02-26 Ryosuke Niwa <rn...@webkit.org>
+
+ Extract named items caches in HTMLCollection as a class
+ https://bugs.webkit.org/show_bug.cgi?id=129365
+
+ Reviewed by Antti Koivisto.
+
+ Extracted CollectionNamedItemCaches, like CollectionIndexCache, out of HTMLCollection.
+ We can move more named item related functions into this class in the future.
+
+ HTMLCollection's member variables m_isNameCacheValid, m_idCache, and m_nameCache were replaced by
+ a single unique_ptr that holds an instance of CollectionNamedItemCaches since this object rarely
+ exists in most HTMLCollections.
+
+ Also removed m_isItemRefElementsCacheValid since it was only used by Microdata API removed in r153772.
+
+ * html/HTMLAllCollection.cpp:
+ (WebCore::HTMLAllCollection::namedItemWithIndex):
+ * html/HTMLCollection.cpp:
+ (WebCore::HTMLCollection::HTMLCollection):
+ (WebCore::HTMLCollection::invalidateCache):
+ (WebCore::HTMLCollection::invalidateIdNameCacheMaps):
+ (WebCore::HTMLCollection::namedItem):
+ (WebCore::HTMLCollection::updateNameCache):
+ (WebCore::HTMLCollection::namedItems):
+ * html/HTMLCollection.h:
+ (WebCore::CollectionNamedItemCaches::idCache):
+ (WebCore::CollectionNamedItemCaches::nameCache):
+ (WebCore::CollectionNamedItemCaches::appendIdCache):
+ (WebCore::CollectionNamedItemCaches::appendNameCache):
+ (WebCore::CollectionNamedItemCaches::find):
+ (WebCore::CollectionNamedItemCaches::append):
+ (WebCore::HTMLCollection::hasIdNameCache):
+ (WebCore::HTMLCollection::createNameItemCaches):
+ (WebCore::HTMLCollection::namedItemCachesAssertingExistence):
+ * html/HTMLFormControlsCollection.cpp:
+ (WebCore::HTMLFormControlsCollection::updateNameCache):
+
+2014-02-26 Ryosuke Niwa <rn...@webkit.org>
+
Indenting an indented image element resulted in an extra indentation
https://bugs.webkit.org/show_bug.cgi?id=129201
Modified: trunk/Source/WebCore/dom/Document.cpp (164771 => 164772)
--- trunk/Source/WebCore/dom/Document.cpp 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/dom/Document.cpp 2014-02-27 03:35:22 UTC (rev 164772)
@@ -3479,13 +3479,13 @@
void Document::collectionCachedIdNameMap(const HTMLCollection& collection)
{
- ASSERT_UNUSED(collection, collection.hasIdNameCache());
+ ASSERT_UNUSED(collection, collection.hasNamedElementCache());
m_nodeListAndCollectionCounts[InvalidateOnIdNameAttrChange]++;
}
void Document::collectionWillClearIdNameMap(const HTMLCollection& collection)
{
- ASSERT_UNUSED(collection, collection.hasIdNameCache());
+ ASSERT_UNUSED(collection, collection.hasNamedElementCache());
ASSERT(m_nodeListAndCollectionCounts[InvalidateOnIdNameAttrChange]);
m_nodeListAndCollectionCounts[InvalidateOnIdNameAttrChange]--;
}
Modified: trunk/Source/WebCore/dom/Document.h (164771 => 164772)
--- trunk/Source/WebCore/dom/Document.h 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/dom/Document.h 2014-02-27 03:35:22 UTC (rev 164772)
@@ -761,8 +761,8 @@
void registerNodeList(LiveNodeList&);
void unregisterNodeList(LiveNodeList&);
- void registerCollection(HTMLCollection&, bool hasIdNameCache);
- void unregisterCollection(HTMLCollection&, bool hasIdNameCache);
+ void registerCollection(HTMLCollection&, bool hasNamedElementCache);
+ void unregisterCollection(HTMLCollection&, bool hasNamedElementCache);
void collectionCachedIdNameMap(const HTMLCollection&);
void collectionWillClearIdNameMap(const HTMLCollection&);
bool shouldInvalidateNodeListAndCollectionCaches(const QualifiedName* attrName = nullptr) const;
Modified: trunk/Source/WebCore/dom/NodeRareData.h (164771 => 164772)
--- trunk/Source/WebCore/dom/NodeRareData.h 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/dom/NodeRareData.h 2014-02-27 03:35:22 UTC (rev 164772)
@@ -254,8 +254,8 @@
for (auto it : m_cachedCollections) {
HTMLCollection& collection = *it.value;
- oldDocument->unregisterCollection(collection, collection.hasIdNameCache());
- newDocument->registerCollection(collection, collection.hasIdNameCache());
+ oldDocument->unregisterCollection(collection, collection.hasNamedElementCache());
+ newDocument->registerCollection(collection, collection.hasNamedElementCache());
collection.invalidateCache();
}
}
Modified: trunk/Source/WebCore/html/HTMLAllCollection.cpp (164771 => 164772)
--- trunk/Source/WebCore/html/HTMLAllCollection.cpp 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/html/HTMLAllCollection.cpp 2014-02-27 03:35:22 UTC (rev 164772)
@@ -46,17 +46,18 @@
Node* HTMLAllCollection::namedItemWithIndex(const AtomicString& name, unsigned index) const
{
- updateNameCache();
+ updateNamedElementCache();
+ const CollectionNamedElementCache& cache = namedItemCaches();
- if (Vector<Element*>* cache = idCache(name)) {
- if (index < cache->size())
- return cache->at(index);
- index -= cache->size();
+ if (const Vector<Element*>* elements = cache.findElementsWithId(name)) {
+ if (index < elements->size())
+ return elements->at(index);
+ index -= elements->size();
}
- if (Vector<Element*>* cache = nameCache(name)) {
- if (index < cache->size())
- return cache->at(index);
+ if (const Vector<Element*>* elements = cache.findElementsWithName(name)) {
+ if (index < elements->size())
+ return elements->at(index);
}
return 0;
Modified: trunk/Source/WebCore/html/HTMLCollection.cpp (164771 => 164772)
--- trunk/Source/WebCore/html/HTMLCollection.cpp 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/html/HTMLCollection.cpp 2014-02-27 03:35:22 UTC (rev 164772)
@@ -133,19 +133,17 @@
HTMLCollection::HTMLCollection(ContainerNode& ownerNode, CollectionType type, ElementTraversalType traversalType)
: m_ownerNode(ownerNode)
- , m_rootType(rootTypeFromCollectionType(type))
+ , m_collectionType(type)
, m_invalidationType(invalidationTypeExcludingIdAndNameAttributes(type))
+ , m_rootType(rootTypeFromCollectionType(type))
, m_shouldOnlyIncludeDirectChildren(shouldOnlyIncludeDirectChildren(type))
- , m_isNameCacheValid(false)
- , m_collectionType(type)
, m_usesCustomForwardOnlyTraversal(traversalType == CustomForwardOnlyTraversal)
- , m_isItemRefElementsCacheValid(false)
{
ASSERT(m_rootType == static_cast<unsigned>(rootTypeFromCollectionType(type)));
ASSERT(m_invalidationType == static_cast<unsigned>(invalidationTypeExcludingIdAndNameAttributes(type)));
ASSERT(m_collectionType == static_cast<unsigned>(type));
- document().registerCollection(*this, hasIdNameCache());
+ document().registerCollection(*this, hasNamedElementCache());
}
PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode& base, CollectionType type)
@@ -155,7 +153,7 @@
HTMLCollection::~HTMLCollection()
{
- document().unregisterCollection(*this, hasIdNameCache());
+ document().unregisterCollection(*this, hasNamedElementCache());
// HTMLNameCollection removes cache by itself.
if (type() != WindowNamedItems && type() != DocumentNamedItems)
ownerNode().nodeLists()->removeCachedCollection(this);
@@ -367,18 +365,15 @@
void HTMLCollection::invalidateCache() const
{
m_indexCache.invalidate();
- m_isItemRefElementsCacheValid = false;
- if (hasIdNameCache())
- invalidateIdNameCacheMaps();
+ if (hasNamedElementCache())
+ invalidateNamedElementCache();
}
-void HTMLCollection::invalidateIdNameCacheMaps() const
+void HTMLCollection::invalidateNamedElementCache() const
{
- ASSERT(hasIdNameCache());
+ ASSERT(hasNamedElementCache());
document().collectionWillClearIdNameMap(*this);
- m_isNameCacheValid = false;
- m_idCache.clear();
- m_nameCache.clear();
+ m_namedElementCache = nullptr;
}
Node* HTMLCollection::namedItem(const AtomicString& name) const
@@ -414,14 +409,15 @@
}
// The pathological case. We need to walk the entire subtree.
- updateNameCache();
+ updateNamedElementCache();
+ ASSERT(m_namedElementCache);
- if (Vector<Element*>* idResults = idCache(name)) {
+ if (const Vector<Element*>* idResults = m_namedElementCache->findElementsWithId(name)) {
if (idResults->size())
return idResults->at(0);
}
- if (Vector<Element*>* nameResults = nameCache(name)) {
+ if (const Vector<Element*>* nameResults = m_namedElementCache->findElementsWithName(name)) {
if (nameResults->size())
return nameResults->at(0);
}
@@ -429,26 +425,25 @@
return 0;
}
-void HTMLCollection::updateNameCache() const
+void HTMLCollection::updateNamedElementCache() const
{
- if (hasIdNameCache())
+ if (hasNamedElementCache())
return;
ContainerNode& root = rootNode();
+ CollectionNamedElementCache& cache = createNameItemCache();
unsigned count;
for (Element* element = firstElement(root); element; element = traverseForward(*element, 1, count, root)) {
const AtomicString& idAttrVal = element->getIdAttribute();
if (!idAttrVal.isEmpty())
- appendIdCache(idAttrVal, element);
+ cache.appendIdCache(idAttrVal, element);
if (!element->isHTMLElement())
continue;
const AtomicString& nameAttrVal = element->getNameAttribute();
if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != DocAll || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element))))
- appendNameCache(nameAttrVal, element);
+ cache.appendNameCache(nameAttrVal, element);
}
-
- setHasIdNameCache();
}
bool HTMLCollection::hasNamedItem(const AtomicString& name) const
@@ -463,10 +458,11 @@
if (name.isEmpty())
return;
- updateNameCache();
+ updateNamedElementCache();
+ ASSERT(m_namedElementCache);
- Vector<Element*>* idResults = idCache(name);
- Vector<Element*>* nameResults = nameCache(name);
+ const Vector<Element*>* idResults = m_namedElementCache->findElementsWithId(name);
+ const Vector<Element*>* nameResults = m_namedElementCache->findElementsWithName(name);
for (unsigned i = 0; idResults && i < idResults->size(); ++i)
result.append(*idResults->at(i));
@@ -480,12 +476,4 @@
return ownerNode().getElementsByTagName(name);
}
-void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element)
-{
- OwnPtr<Vector<Element*>>& vector = map.add(key.impl(), nullptr).iterator->value;
- if (!vector)
- vector = adoptPtr(new Vector<Element*>);
- vector->append(element);
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/html/HTMLCollection.h (164771 => 164772)
--- trunk/Source/WebCore/html/HTMLCollection.h 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/html/HTMLCollection.h 2014-02-27 03:35:22 UTC (rev 164772)
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (kn...@kde.org)
* (C) 1999 Antti Koivisto (koivi...@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -38,6 +38,32 @@
class Element;
+class CollectionNamedElementCache {
+public:
+ const Vector<Element*>* findElementsWithId(const AtomicString& id) const { return find(m_idToElementsMap, id); }
+ const Vector<Element*>* findElementsWithName(const AtomicString& name) const { return find(m_nameToElementsMap, name); }
+
+ void appendIdCache(const AtomicString& id, Element* element) { return append(m_idToElementsMap, id, element); }
+ void appendNameCache(const AtomicString& name, Element* element) { return append(m_nameToElementsMap, name, element); }
+
+private:
+ typedef HashMap<AtomicStringImpl*, Vector<Element*>> StringToElementsMap;
+
+ static const Vector<Element*>* find(const StringToElementsMap& map, const AtomicString& key)
+ {
+ auto it = map.find(key.impl());
+ return it != map.end() ? &it->value : nullptr;
+ }
+
+ static void append(StringToElementsMap& map, const AtomicString& key, Element* element)
+ {
+ map.add(key.impl(), Vector<Element*>()).iterator->value.append(element);
+ }
+
+ StringToElementsMap m_idToElementsMap;
+ StringToElementsMap m_nameToElementsMap;
+};
+
class HTMLCollection : public ScriptWrappable, public RefCounted<HTMLCollection> {
public:
static PassRefPtr<HTMLCollection> create(ContainerNode& base, CollectionType);
@@ -61,8 +87,8 @@
{
if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
invalidateCache();
- else if (hasIdNameCache() && (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr))
- invalidateIdNameCacheMaps();
+ else if (hasNamedElementCache() && (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr))
+ invalidateNamedElementCache();
}
virtual void invalidateCache() const;
@@ -73,60 +99,53 @@
Element* collectionTraverseBackward(Element&, unsigned count) const;
bool collectionCanTraverseBackward() const { return !m_usesCustomForwardOnlyTraversal; }
- bool hasIdNameCache() const { return m_isNameCacheValid; }
+ bool hasNamedElementCache() const { return !!m_namedElementCache; }
protected:
enum ElementTraversalType { NormalTraversal, CustomForwardOnlyTraversal };
HTMLCollection(ContainerNode& base, CollectionType, ElementTraversalType = NormalTraversal);
- void invalidateIdNameCacheMaps() const;
- virtual void updateNameCache() const;
+ virtual void updateNamedElementCache() const;
- typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<Element*>>> NodeCacheMap;
- Vector<Element*>* idCache(const AtomicString& name) const { return m_idCache.get(name.impl()); }
- Vector<Element*>* nameCache(const AtomicString& name) const { return m_nameCache.get(name.impl()); }
- void appendIdCache(const AtomicString& name, Element* element) const { append(m_idCache, name, element); }
- void appendNameCache(const AtomicString& name, Element* element) const { append(m_nameCache, name, element); }
-
Document& document() const { return m_ownerNode->document(); }
ContainerNode& rootNode() const;
bool usesCustomForwardOnlyTraversal() const { return m_usesCustomForwardOnlyTraversal; }
- bool isItemRefElementsCacheValid() const { return m_isItemRefElementsCacheValid; }
- void setItemRefElementsCacheValid() const { m_isItemRefElementsCacheValid = true; }
-
NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); }
- void setHasIdNameCache() const
+ CollectionNamedElementCache& createNameItemCache() const
{
- m_isNameCacheValid = true;
+ ASSERT(!m_namedElementCache);
+ m_namedElementCache = std::make_unique<CollectionNamedElementCache>();
document().collectionCachedIdNameMap(*this);
+ return *m_namedElementCache;
}
+ const CollectionNamedElementCache& namedItemCaches() const
+ {
+ ASSERT(!!m_namedElementCache);
+ return *m_namedElementCache;
+ }
+
private:
- static void append(NodeCacheMap&, const AtomicString&, Element*);
-
Element* iterateForPreviousElement(Element* current) const;
Element* firstElement(ContainerNode& root) const;
Element* traverseForward(Element& current, unsigned count, unsigned& traversedCount, ContainerNode& root) const;
virtual Element* customElementAfter(Element*) const { ASSERT_NOT_REACHED(); return nullptr; }
+
+ void invalidateNamedElementCache() const;
Ref<ContainerNode> m_ownerNode;
mutable CollectionIndexCache<HTMLCollection, Element> m_indexCache;
+ mutable std::unique_ptr<CollectionNamedElementCache> m_namedElementCache;
+ const unsigned m_collectionType : 5;
+ const unsigned m_invalidationType : 4;
const unsigned m_rootType : 1;
- const unsigned m_invalidationType : 4;
const unsigned m_shouldOnlyIncludeDirectChildren : 1;
-
- mutable unsigned m_isNameCacheValid : 1;
- const unsigned m_collectionType : 5;
const unsigned m_usesCustomForwardOnlyTraversal : 1;
- mutable unsigned m_isItemRefElementsCacheValid : 1;
-
- mutable NodeCacheMap m_idCache;
- mutable NodeCacheMap m_nameCache;
};
} // namespace
Modified: trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp (164771 => 164772)
--- trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/html/HTMLFormControlsCollection.cpp 2014-02-27 03:35:22 UTC (rev 164772)
@@ -135,13 +135,13 @@
return firstNamedItem(formControlElements(), imagesElements, nameAttr, name);
}
-void HTMLFormControlsCollection::updateNameCache() const
+void HTMLFormControlsCollection::updateNamedElementCache() const
{
- if (hasIdNameCache())
+ if (hasNamedElementCache())
return;
+ CollectionNamedElementCache& cache = createNameItemCache();
HashSet<AtomicStringImpl*> foundInputElements;
-
const Vector<FormAssociatedElement*>& elementsArray = formControlElements();
for (unsigned i = 0; i < elementsArray.size(); ++i) {
@@ -151,11 +151,11 @@
const AtomicString& idAttrVal = element.getIdAttribute();
const AtomicString& nameAttrVal = element.getNameAttribute();
if (!idAttrVal.isEmpty()) {
- appendIdCache(idAttrVal, &element);
+ cache.appendIdCache(idAttrVal, &element);
foundInputElements.add(idAttrVal.impl());
}
if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) {
- appendNameCache(nameAttrVal, &element);
+ cache.appendNameCache(nameAttrVal, &element);
foundInputElements.add(nameAttrVal.impl());
}
}
@@ -168,13 +168,11 @@
const AtomicString& idAttrVal = element.getIdAttribute();
const AtomicString& nameAttrVal = element.getNameAttribute();
if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl()))
- appendIdCache(idAttrVal, &element);
+ cache.appendIdCache(idAttrVal, &element);
if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && !foundInputElements.contains(nameAttrVal.impl()))
- appendNameCache(nameAttrVal, &element);
+ cache.appendNameCache(nameAttrVal, &element);
}
}
-
- setHasIdNameCache();
}
void HTMLFormControlsCollection::invalidateCache() const
Modified: trunk/Source/WebCore/html/HTMLFormControlsCollection.h (164771 => 164772)
--- trunk/Source/WebCore/html/HTMLFormControlsCollection.h 2014-02-27 03:01:24 UTC (rev 164771)
+++ trunk/Source/WebCore/html/HTMLFormControlsCollection.h 2014-02-27 03:35:22 UTC (rev 164772)
@@ -47,7 +47,7 @@
explicit HTMLFormControlsCollection(ContainerNode&);
virtual void invalidateCache() const override;
- virtual void updateNameCache() const override;
+ virtual void updateNamedElementCache() const override;
const Vector<FormAssociatedElement*>& formControlElements() const;
const Vector<HTMLImageElement*>& formImageElements() const;