Title: [103855] trunk
Revision
103855
Author
kl...@webkit.org
Date
2011-12-30 18:43:33 -0800 (Fri, 30 Dec 2011)

Log Message

Cache and reuse the HTMLSelectElement.options collection.
<http://webkit.org/b/75399>

Reviewed by Anders Carlsson.

Source/WebCore: 

Let HTMLSelectElement::options() cache the returned collection and tie it to the
lifetime of the form. This shrinks HTMLSelectElement by sizeof(CollectionCache)
minus one pointer.

Test: fast/dom/select-options-collection-idempotence.html
      fast/gc-9.html

* html/HTMLSelectElement.h:
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::options):

    Cache the HTMLOptionsCollection returned by options() on the HTMLSelectElement.
    Remove the per-select CollectionCache and let the collection manage that.

* html/HTMLOptionsCollection.h:
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::create):
(WebCore::HTMLOptionsCollection::HTMLOptionsCollection):

    Tell the base class constructor to not retain the back-pointer to the element.

* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::setRecalcListItems):
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::invalidateCache):

    Added so HTMLSelectElement can invalidate the collection without triggering
    unnecessary instantiation of a CollectionCache.

LayoutTests: 

- Update gc-9.html to document the new lifetime characteristics of HTMLSelectElement.options.
- Add a test to verify that HTMLSelectElement.options returns the same object when called repeatedly.

* fast/dom/gc-9-expected.txt:
* fast/dom/gc-9.html:
* fast/dom/select-options-collection-idempotence-expected.txt: Added.
* fast/dom/select-options-collection-idempotence.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (103854 => 103855)


--- trunk/LayoutTests/ChangeLog	2011-12-31 01:10:47 UTC (rev 103854)
+++ trunk/LayoutTests/ChangeLog	2011-12-31 02:43:33 UTC (rev 103855)
@@ -1,3 +1,18 @@
+2011-12-30  Andreas Kling  <awesomekl...@apple.com>
+
+        Cache and reuse the HTMLSelectElement.options collection.
+        <http://webkit.org/b/75399>
+
+        Reviewed by Anders Carlsson.
+
+        - Update gc-9.html to document the new lifetime characteristics of HTMLSelectElement.options.
+        - Add a test to verify that HTMLSelectElement.options returns the same object when called repeatedly.
+
+        * fast/dom/gc-9-expected.txt:
+        * fast/dom/gc-9.html:
+        * fast/dom/select-options-collection-idempotence-expected.txt: Added.
+        * fast/dom/select-options-collection-idempotence.html: Added.
+
 2011-12-30  Robert Hogan  <rob...@webkit.org>
 
         [Qt] fast/css/absolute-inline-alignment.html fails

Modified: trunk/LayoutTests/fast/dom/gc-9-expected.txt (103854 => 103855)


--- trunk/LayoutTests/fast/dom/gc-9-expected.txt	2011-12-31 01:10:47 UTC (rev 103854)
+++ trunk/LayoutTests/fast/dom/gc-9-expected.txt	2011-12-31 02:43:33 UTC (rev 103855)
@@ -13,7 +13,7 @@
 PASS: document.getElementsByTagName('canvas')[0].getContext('2d').myCustomProperty should be 1 and is.
 PASS: document.getElementsByTagName('canvas')[0].getContext('2d').createLinearGradient(0, 0, 0, 0).myCustomProperty should be undefined and is.
 PASS: document.getElementsByTagName('canvas')[0].getContext('2d').createPattern(new Image(), 'no-repeat').myCustomProperty should be undefined and is.
-PASS: document.getElementsByTagName('select')[0].options.myCustomProperty should be undefined and is.
+PASS: document.getElementsByTagName('select')[0].options.myCustomProperty should be 1 and is.
 PASS: document.body.childNodes.myCustomProperty should be undefined and is.
 PASS: document.all.myCustomProperty should be 1 and is.
 PASS: document.images.myCustomProperty should be 1 and is.
@@ -49,7 +49,7 @@
 PASS: document.getElementsByTagName('canvas')[0].getContext('2d').myCustomProperty should be 1 and is.
 PASS: document.getElementsByTagName('canvas')[0].getContext('2d').createLinearGradient(0, 0, 0, 0).myCustomProperty should be undefined and is.
 PASS: document.getElementsByTagName('canvas')[0].getContext('2d').createPattern(new Image(), 'no-repeat').myCustomProperty should be undefined and is.
-PASS: document.getElementsByTagName('select')[0].options.myCustomProperty should be undefined and is.
+PASS: document.getElementsByTagName('select')[0].options.myCustomProperty should be 1 and is.
 PASS: document.body.childNodes.myCustomProperty should be undefined and is.
 PASS: document.all.myCustomProperty should be 1 and is.
 PASS: document.images.myCustomProperty should be 1 and is.

Modified: trunk/LayoutTests/fast/dom/gc-9.html (103854 => 103855)


--- trunk/LayoutTests/fast/dom/gc-9.html	2011-12-31 01:10:47 UTC (rev 103854)
+++ trunk/LayoutTests/fast/dom/gc-9.html	2011-12-31 02:43:33 UTC (rev 103855)
@@ -122,7 +122,7 @@
     [ "document.getElementsByTagName('canvas')[0].getContext('2d')", "allow custom" ], // CanvasRenderingContext2D
     [ "document.getElementsByTagName('canvas')[0].getContext('2d').createLinearGradient(0, 0, 0, 0)" ], // CanvasGradient
     [ "document.getElementsByTagName('canvas')[0].getContext('2d').createPattern(new Image(), 'no-repeat')" ], // CanvasPattern
-    [ "document.getElementsByTagName('select')[0].options" ],
+    [ "document.getElementsByTagName('select')[0].options", "allow custom" ],
     [ "document.body.childNodes" ],
 
     [ "document.all", "allow custom" ],

Added: trunk/LayoutTests/fast/dom/select-options-collection-idempotence-expected.txt (0 => 103855)


--- trunk/LayoutTests/fast/dom/select-options-collection-idempotence-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/select-options-collection-idempotence-expected.txt	2011-12-31 02:43:33 UTC (rev 103855)
@@ -0,0 +1,11 @@
+This test verifies that HTMLSelectElement.options returns the same collection when called repeatedly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS selectElement.options is selectElement.options
+PASS selectElement.options === selectElement.options is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/select-options-collection-idempotence.html (0 => 103855)


--- trunk/LayoutTests/fast/dom/select-options-collection-idempotence.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/select-options-collection-idempotence.html	2011-12-31 02:43:33 UTC (rev 103855)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+</head>
+<body>
+<script>
+
+description("This test verifies that HTMLSelectElement.options returns the same collection when called repeatedly.");
+
+var selectElement = document.createElement("select");
+
+shouldBe("selectElement.options", "selectElement.options");
+shouldBeTrue("selectElement.options === selectElement.options");
+
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (103854 => 103855)


--- trunk/Source/WebCore/ChangeLog	2011-12-31 01:10:47 UTC (rev 103854)
+++ trunk/Source/WebCore/ChangeLog	2011-12-31 02:43:33 UTC (rev 103855)
@@ -1,3 +1,39 @@
+2011-12-30  Andreas Kling  <awesomekl...@apple.com>
+
+        Cache and reuse the HTMLSelectElement.options collection.
+        <http://webkit.org/b/75399>
+
+        Reviewed by Anders Carlsson.
+
+        Let HTMLSelectElement::options() cache the returned collection and tie it to the
+        lifetime of the form. This shrinks HTMLSelectElement by sizeof(CollectionCache)
+        minus one pointer.
+
+        Test: fast/dom/select-options-collection-idempotence.html
+              fast/gc-9.html
+
+        * html/HTMLSelectElement.h:
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::options):
+
+            Cache the HTMLOptionsCollection returned by options() on the HTMLSelectElement.
+            Remove the per-select CollectionCache and let the collection manage that.
+
+        * html/HTMLOptionsCollection.h:
+        * html/HTMLOptionsCollection.cpp:
+        (WebCore::HTMLOptionsCollection::create):
+        (WebCore::HTMLOptionsCollection::HTMLOptionsCollection):
+
+            Tell the base class constructor to not retain the back-pointer to the element.
+
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::setRecalcListItems):
+        * html/HTMLOptionsCollection.cpp:
+        (WebCore::HTMLOptionsCollection::invalidateCache):
+
+            Added so HTMLSelectElement can invalidate the collection without triggering
+            unnecessary instantiation of a CollectionCache.
+
 2011-12-30  Kentaro Hara  <hara...@chromium.org>
 
         Enable the [Supplemental] IDL on CMake

Modified: trunk/Source/WebCore/html/HTMLOptionsCollection.cpp (103854 => 103855)


--- trunk/Source/WebCore/html/HTMLOptionsCollection.cpp	2011-12-31 01:10:47 UTC (rev 103854)
+++ trunk/Source/WebCore/html/HTMLOptionsCollection.cpp	2011-12-31 02:43:33 UTC (rev 103855)
@@ -27,12 +27,12 @@
 
 namespace WebCore {
 
-HTMLOptionsCollection::HTMLOptionsCollection(PassRefPtr<HTMLSelectElement> select)
-    : HTMLCollection(select.get(), SelectOptions, select->collectionInfo())
+HTMLOptionsCollection::HTMLOptionsCollection(HTMLSelectElement* select)
+    : HTMLCollection(select, SelectOptions, 0, /* retainBaseNode */ false)
 {
 }
 
-PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(PassRefPtr<HTMLSelectElement> select)
+PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(HTMLSelectElement* select)
 {
     return adoptRef(new HTMLOptionsCollection(select));
 }
@@ -87,4 +87,10 @@
     toHTMLSelectElement(base())->setLength(length, ec);
 }
 
+void HTMLOptionsCollection::invalidateCache()
+{
+    if (info())
+        info()->reset();
+}
+
 } //namespace

Modified: trunk/Source/WebCore/html/HTMLOptionsCollection.h (103854 => 103855)


--- trunk/Source/WebCore/html/HTMLOptionsCollection.h	2011-12-31 01:10:47 UTC (rev 103854)
+++ trunk/Source/WebCore/html/HTMLOptionsCollection.h	2011-12-31 02:43:33 UTC (rev 103855)
@@ -35,7 +35,7 @@
 
 class HTMLOptionsCollection : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLOptionsCollection> create(PassRefPtr<HTMLSelectElement>);
+    static PassRefPtr<HTMLOptionsCollection> create(HTMLSelectElement*);
 
     void add(PassRefPtr<HTMLOptionElement>, ExceptionCode&);
     void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionCode&);
@@ -46,8 +46,10 @@
 
     void setLength(unsigned, ExceptionCode&);
 
+    void invalidateCache();
+
 private:
-    HTMLOptionsCollection(PassRefPtr<HTMLSelectElement>);
+    HTMLOptionsCollection(HTMLSelectElement*);
 };
 
 } //namespace

Modified: trunk/Source/WebCore/html/HTMLSelectElement.cpp (103854 => 103855)


--- trunk/Source/WebCore/html/HTMLSelectElement.cpp	2011-12-31 01:10:47 UTC (rev 103854)
+++ trunk/Source/WebCore/html/HTMLSelectElement.cpp	2011-12-31 02:43:33 UTC (rev 103855)
@@ -327,7 +327,9 @@
 
 PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
 {
-    return HTMLOptionsCollection::create(this);
+    if (!m_optionsCollection)
+        m_optionsCollection = HTMLOptionsCollection::create(this);
+    return m_optionsCollection;
 }
 
 void HTMLSelectElement::updateListItemSelectedStates()
@@ -680,8 +682,8 @@
     m_activeSelectionAnchorIndex = -1;
     setOptionsChangedOnRenderer();
     setNeedsStyleRecalc();
-    if (!inDocument())
-        m_collectionInfo.reset();
+    if (!inDocument() && m_optionsCollection)
+        m_optionsCollection->invalidateCache();
 }
 
 void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const

Modified: trunk/Source/WebCore/html/HTMLSelectElement.h (103854 => 103855)


--- trunk/Source/WebCore/html/HTMLSelectElement.h	2011-12-31 01:10:47 UTC (rev 103854)
+++ trunk/Source/WebCore/html/HTMLSelectElement.h	2011-12-31 02:43:33 UTC (rev 103855)
@@ -26,9 +26,9 @@
 #ifndef HTMLSelectElement_h
 #define HTMLSelectElement_h
 
-#include "CollectionCache.h"
 #include "Event.h"
 #include "HTMLFormControlElement.h"
+#include "HTMLOptionsCollection.h"
 #include <wtf/Vector.h>
 
 namespace WebCore {
@@ -84,8 +84,6 @@
     Node* namedItem(const AtomicString& name);
     Node* item(unsigned index);
 
-    CollectionCache* collectionInfo() { m_collectionInfo.checkConsistency(); return &m_collectionInfo; }
-
     void scrollToSelection();
 
     void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
@@ -176,7 +174,8 @@
 
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
-    CollectionCache m_collectionInfo;
+    RefPtr<HTMLOptionsCollection> m_optionsCollection;
+
     // m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and HTMLHRElement objects.
     mutable Vector<HTMLElement*> m_listItems;
     Vector<bool> m_lastOnChangeSelection;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to