Source/WebCore/ChangeLog

 12012-11-22 Ryosuke Niwa <rniwa@webkit.org>
 2
 3 REGRESSION(r135493): HTMLCollection and DynamicNodeList have two vtable pointers
 4 https://bugs.webkit.org/show_bug.cgi?id=103096
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Co-authored by Ilya Tikhonovsky.
 9
 10 Made DynamicNodeListCacheBase inherit from NodeList. While HTMLCollection doesn't inherit
 11 from NodeList in IDL, it makes a lot of sense for the C++ implementation to do so via
 12 DynamicNodeListCacheBase since HTMLCollection and live NodeList share a lot of code in
 13 DynamicNodeListCacheBase.
 14
 15 This lets remove proxies for item() and length() in DynamicNodeList and HTMLCollection
 16 and directly implement them in DynamicNodeListCacheBase which used to provide itemCommon()
 17 and lengthCommon().
 18
 19 Also renamed NodeList::itemWithName() to NodeList::namedItem() to match HTMLCollection's
 20 naming convention.
 21
 22 Finally, removed reportMemoryUsage in DynamicNodeList::reportMemoryUsage since DynamicNodeList
 23 now uses single inheritance.
 24
 25 * bindings/js/JSNodeListCustom.cpp:
 26 (WebCore::JSNodeList::canGetItemsForName): Calls namedItem, which has been renamed from
 27 itemWithName.
 28 (WebCore::JSNodeList::nameGetter): Ditto.
 29 * bindings/v8/custom/V8NodeListCustom.cpp:
 30 (WebCore::V8NodeList::namedPropertyGetter): Ditto.
 31 * bindings/v8/custom/V8NamedNodesCollection.cpp:
 32 (WebCore::V8NamedNodesCollection::namedItem): Renamed from itemWithName.
 33 * bindings/v8/custom/V8NamedNodesCollection.h:
 34 * dom/ChildNodeList.cpp:
 35 (WebCore::ChildNodeList::nodeMatches): Updated comment.
 36 * dom/DynamicNodeList.cpp:
 37 (WebCore::DynamicNodeList::namedItem): Renamed from itemWithName.
 38 * dom/DynamicNodeList.h:
 39 (DynamicNodeListCacheBase): Inhertis from NodeList and renamed lengthCommon and itemCommon
 40 to virtual length and item respectively.
 41 (DynamicNodeList): Now inherits from just DynamicNodeListCacheBase instead of NodeList
 42 and DynamicNodeListCacheBase since the former now inhertis from NodeList. Also removed
 43 length() and item() since they're implemented in DynamicNodeListCacheBase now and renamed
 44 itemWithName() to namedItem() to match HTMLCollection's naming convention.
 45 * dom/NodeList.h:
 46 (NodeList::namedItem): Renamed from itemWithName. Note that this member function is not
 47 exposed via IDL. It's merely used in the binding code.
 48 * dom/StaticHashSetNodeList.cpp:
 49 (WebCore::StaticHashSetNodeList::namedItem): Ditto.
 50 * dom/StaticHashSetNodeList.h:
 51 (StaticHashSetNodeList::namedItem): Ditto.
 52 * dom/StaticNodeList.cpp:
 53 (WebCore::StaticNodeList::namedItem): Ditto.
 54 * dom/StaticNodeList.h:
 55 (StaticNodeList::namedItem): Ditto.
 56 * html/HTMLCollection.cpp:
 57 (WebCore::DynamicNodeListCacheBase::length): Renamed from lengthCommon.
 58 (WebCore::DynamicNodeListCacheBase::item): Renamed from itemCommon.
 59 * html/HTMLCollection.h:
 60 (HTMLCollection): Inherits from DynamicNodeListCacheBase since DynamicNodeListCacheBase
 61 is already RefCount'ed and NodeList, from which DynamicNodeListCacheBase inherits,
 62 inherits from ScriptWrappable.
 63
1642012-11-22 John Mellor <johnme@chromium.org>
265
366 Text Autosizing: Improve handling of nested comments on reddit.com
135554

Source/WebCore/bindings/js/JSNodeListCustom.cpp

@@bool JSNodeListOwner::isReachableFromOpa
4848
4949bool JSNodeList::canGetItemsForName(ExecState*, NodeList* impl, PropertyName propertyName)
5050{
51  return impl->itemWithName(propertyNameToAtomicString(propertyName));
 51 return impl->namedItem(propertyNameToAtomicString(propertyName));
5252}
5353
5454JSValue JSNodeList::nameGetter(ExecState* exec, JSValue slotBase, PropertyName propertyName)
5555{
5656 JSNodeList* thisObj = jsCast<JSNodeList*>(asObject(slotBase));
57  return toJS(exec, thisObj->globalObject(), thisObj->impl()->itemWithName(propertyNameToAtomicString(propertyName)));
 57 return toJS(exec, thisObj->globalObject(), thisObj->impl()->namedItem(propertyNameToAtomicString(propertyName)));
5858}
5959
6060} // namespace WebCore
135533

Source/WebCore/bindings/v8/custom/V8NamedNodesCollection.cpp

@@Node* V8NamedNodesCollection::item(unsig
4242 return 0;
4343}
4444
45 Node* V8NamedNodesCollection::itemWithName(const AtomicString& id) const
 45Node* V8NamedNodesCollection::namedItem(const AtomicString& id) const
4646{
4747 for (unsigned i = 0; i < m_nodes.size(); ++i) {
4848 Node* node = m_nodes[i].get();
135533

Source/WebCore/bindings/v8/custom/V8NamedNodesCollection.h

@@namespace WebCore {
4646 return adoptRef(new V8NamedNodesCollection(nodes));
4747 }
4848
49  virtual unsigned length() const { return m_nodes.size(); }
50  virtual Node* item(unsigned) const;
51  virtual Node* itemWithName(const AtomicString&) const;
 49 virtual unsigned length() const OVERRIDE { return m_nodes.size(); }
 50 virtual Node* item(unsigned) const OVERRIDE;
 51 virtual Node* namedItem(const AtomicString&) const OVERRIDE;
5252
5353 private:
5454 explicit V8NamedNodesCollection(const Vector<RefPtr<Node> >& nodes)
135533

Source/WebCore/bindings/v8/custom/V8NodeListCustom.cpp

@@v8::Handle<v8::Value> V8NodeList::namedP
5353 if (key == length)
5454 return v8Integer(list->length(), info.GetIsolate());
5555
56  RefPtr<Node> result = list->itemWithName(key);
 56 RefPtr<Node> result = list->namedItem(key);
5757 if (!result)
5858 return v8Undefined();
5959
135533

Source/WebCore/dom/ChildNodeList.cpp

@@ChildNodeList::~ChildNodeList()
3939
4040bool ChildNodeList::nodeMatches(Element* testNode) const
4141{
42  // This function will be called only by DynamicNodeList::itemWithName,
 42 // This function will be called only by DynamicNodeList::namedItem,
4343 // for an element that was located with getElementById.
4444 return testNode->parentNode() == rootNode();
4545}
135533

Source/WebCore/dom/DynamicNodeList.cpp

@@void DynamicNodeListCacheBase::invalidat
8585void DynamicNodeListCacheBase::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
8686{
8787 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
 88 NodeList::reportMemoryUsage(memoryObjectInfo);
8889 info.addMember(m_ownerNode);
8990 info.addWeakPointer(m_cachedItem);
9091}
9192
92 void DynamicNodeList::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
93 {
94  MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
95  NodeList::reportMemoryUsage(memoryObjectInfo);
96  DynamicNodeListCacheBase::reportMemoryUsage(memoryObjectInfo);
97 }
98 
99 void DynamicSubtreeNodeList::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
100 {
101  MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
102  DynamicNodeList::reportMemoryUsage(memoryObjectInfo);
103 }
104 
105 unsigned DynamicNodeList::length() const
106 {
107  return lengthCommon();
108 }
109 
110 Node* DynamicNodeList::item(unsigned offset) const
111 {
112  return itemCommon(offset);
113 }
114 
115 Node* DynamicNodeList::itemWithName(const AtomicString& elementId) const
 93Node* DynamicNodeList::namedItem(const AtomicString& elementId) const
11694{
11795 Node* rootNode = this->rootNode();
11896
135534

Source/WebCore/dom/DynamicNodeList.h

@@enum NodeListRootType {
4141 NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr,
4242};
4343
44 class DynamicNodeListCacheBase {
 44class DynamicNodeListCacheBase : public NodeList {
4545public:
4646 enum ItemAfterOverrideType {
4747 OverridesItemAfter,

@@public:
6868 ASSERT(!m_overridesItemAfter || !isNodeList(collectionType));
6969 }
7070
71  virtual ~DynamicNodeListCacheBase() { }
72 
7371 virtual void reportMemoryUsage(MemoryObjectInfo*) const;
7472
75 public:
 73 // DOM API
 74 virtual unsigned length() const OVERRIDE;
 75 virtual Node* item(unsigned offset) const OVERRIDE;
 76
7677 ALWAYS_INLINE bool hasIdNameCache() const { return !isNodeList(type()); }
7778 ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument || m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr; }
7879 ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }

@@protected:
123124 bool hasNameCache() const { return m_isNameCacheValid; }
124125 void setHasNameCache() const { m_isNameCacheValid = true; }
125126
126  unsigned lengthCommon() const;
127  Node* itemCommon(unsigned offset) const;
128127 Node* itemBeforeOrAfterCachedItem(unsigned offset) const;
129128 Node* itemAfter(unsigned&, Node* previousItem) const;
130129

@@ALWAYS_INLINE bool DynamicNodeListCacheB
182181 return false;
183182}
184183
185 class DynamicNodeList : public NodeList, public DynamicNodeListCacheBase {
 184class DynamicNodeList : public DynamicNodeListCacheBase {
186185public:
187186 DynamicNodeList(PassRefPtr<Node> ownerNode, CollectionType collectionType, NodeListRootType rootType, NodeListInvalidationType invalidationType)
188187 : DynamicNodeListCacheBase(ownerNode.get(), rootType, invalidationType, collectionType == ChildNodeListType,

@@public:
190189 { }
191190 virtual ~DynamicNodeList() { }
192191
193  // DOM methods & attributes for NodeList
194  virtual unsigned length() const OVERRIDE;
195  virtual Node* item(unsigned offset) const OVERRIDE;
196  virtual Node* itemWithName(const AtomicString&) const;
197 
198192 // Other methods (not part of DOM)
 193 virtual Node* namedItem(const AtomicString&) const OVERRIDE;
199194 virtual bool nodeMatches(Element*) const = 0;
200195
201  virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
202 
203196private:
204197 virtual bool isDynamicNodeList() const OVERRIDE { return true; }
205198};

@@public:
211204 document()->unregisterNodeListCache(this);
212205 }
213206
214  virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
215 
216207protected:
217208 DynamicSubtreeNodeList(PassRefPtr<Node> node, CollectionType type, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode)
218209 : DynamicNodeList(node, type, rootType, invalidationType)
135534

Source/WebCore/dom/NodeList.h

@@namespace WebCore {
3939 // DOM methods & attributes for NodeList
4040 virtual unsigned length() const = 0;
4141 virtual Node* item(unsigned index) const = 0;
42  virtual Node* itemWithName(const AtomicString&) const = 0;
43 
 42 virtual Node* namedItem(const AtomicString&) const = 0;
 43
4444 // Other methods (not part of DOM)
4545 virtual bool isDynamicNodeList() const { return false; }
4646 };
135533

Source/WebCore/dom/StaticHashSetNodeList.cpp

@@Node* StaticHashSetNodeList::item(unsign
6363 return 0;
6464}
6565
66 Node* StaticHashSetNodeList::itemWithName(const AtomicString& elementId) const
 66Node* StaticHashSetNodeList::namedItem(const AtomicString& elementId) const
6767{
6868 ListHashSet<RefPtr<Node> >::const_iterator it = m_nodes.begin();
6969 ListHashSet<RefPtr<Node> >::const_iterator end = m_nodes.end();
135533

Source/WebCore/dom/StaticHashSetNodeList.h

@@public:
5555 return adoptRef(new StaticHashSetNodeList(nodes));
5656 }
5757
58  virtual unsigned length() const;
59  virtual Node* item(unsigned index) const;
60  virtual Node* itemWithName(const AtomicString&) const;
 58 virtual unsigned length() const OVERRIDE;
 59 virtual Node* item(unsigned index) const OVERRIDE;
 60 virtual Node* namedItem(const AtomicString&) const OVERRIDE;
6161
6262private:
6363 explicit StaticHashSetNodeList(ListHashSet<RefPtr<Node> >& nodes);
135533

Source/WebCore/dom/StaticNodeList.cpp

@@Node* StaticNodeList::item(unsigned inde
4545 return 0;
4646}
4747
48 Node* StaticNodeList::itemWithName(const AtomicString& elementId) const
 48Node* StaticNodeList::namedItem(const AtomicString& elementId) const
4949{
5050 size_t length = m_nodes.size();
5151 for (size_t i = 0; i < length; ++i) {
135533

Source/WebCore/dom/StaticNodeList.h

@@namespace WebCore {
4646 return adoptRef(new StaticNodeList(nodes));
4747 }
4848
49  virtual unsigned length() const;
50  virtual Node* item(unsigned index) const;
51  virtual Node* itemWithName(const AtomicString&) const;
 49 virtual unsigned length() const OVERRIDE;
 50 virtual Node* item(unsigned index) const OVERRIDE;
 51 virtual Node* namedItem(const AtomicString&) const OVERRIDE;
5252
5353 private:
5454 explicit StaticNodeList(Vector<RefPtr<Node> >& nodes)
135533

Source/WebCore/html/HTMLCollection.cpp

@@ALWAYS_INLINE void DynamicNodeListCacheB
369369 ASSERT(!elementsArrayOffset);
370370}
371371
372 unsigned DynamicNodeListCacheBase::lengthCommon() const
 372unsigned DynamicNodeListCacheBase::length() const
373373{
374374 if (isLengthCacheValid())
375375 return cachedLength();
376376
377  itemCommon(UINT_MAX);
 377 item(UINT_MAX);
378378 ASSERT(isLengthCacheValid());
379379
380380 return cachedLength();
381381}
382382
383 Node* DynamicNodeListCacheBase::itemCommon(unsigned offset) const
 383Node* DynamicNodeListCacheBase::item(unsigned offset) const
384384{
385385 if (isItemCacheValid() && cachedItemOffset() == offset)
386386 return cachedItem();
135534

Source/WebCore/html/HTMLCollection.h

3333
3434namespace WebCore {
3535
36 class HTMLCollection : public ScriptWrappable, public RefCounted<HTMLCollection>, public DynamicNodeListCacheBase {
 36class HTMLCollection : public DynamicNodeListCacheBase {
3737public:
3838 static PassRefPtr<HTMLCollection> create(Node* base, CollectionType);
3939 virtual ~HTMLCollection();
4040
4141 // DOM API
42  unsigned length() const { return lengthCommon(); }
43  Node* item(unsigned offset) const { return itemCommon(offset); }
4442 virtual Node* namedItem(const AtomicString& name) const;
4543 PassRefPtr<NodeList> tags(const String&);
4644

@@protected:
8179private:
8280 bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const;
8381
 82 virtual bool isDynamicNodeList() const OVERRIDE { ASSERT_NOT_REACHED(); return true; }
 83
8484 static void append(NodeCacheMap&, const AtomicString&, Element*);
8585
8686 mutable NodeCacheMap m_idCache;
135535