<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>12900</bug_id>
          
          <creation_ts>2007-02-26 13:15:51 -0800</creation_ts>
          <short_desc>Page tear-down forces garbage collection once per frame</short_desc>
          <delta_ts>2007-07-20 16:02:28 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WebCore JavaScript</component>
          <version>523.x (Safari 3)</version>
          <rep_platform>Mac</rep_platform>
          <op_sys>OS X 10.4</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Geoffrey Garen">ggaren</reporter>
          <assigned_to name="Geoffrey Garen">ggaren</assigned_to>
          <cc>ejalbert</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>21309</commentid>
    <comment_count>0</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2007-02-26 13:15:51 -0800</bug_when>
    <thetext>Forcing garbage collection only once, at the end of tearing down the whole page, would save a lot of work. In the common case, there&apos;s no script execution that would benefit from the extra GC&apos;s between frame tear-downs. 

This seems like low-hanging performance fruit.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>21288</commentid>
    <comment_count>1</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2007-02-26 22:33:10 -0800</bug_when>
    <thetext>This is actually pretty tricky, and my first shot at it caused a performance regression (even though it reduced the number of garbage collections). 

I think the key to the regression was the Frame keepAlive timer. Since frame tear-down is delayed, there may be value to guaranteeing a collection right after the Frame has torn down, rather than at page load time.

I&apos;m not sure there&apos;s a way to implement this optimization without eliminating the Frame keepAlive timer (and replacing it with a real RefPtr solution) or merging individual Frame keepAlive callbacks into a single callback, and collecting at the end of it.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>20783</commentid>
    <comment_count>2</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2007-03-01 08:46:53 -0800</bug_when>
    <thetext>I realized that a very simple way to fix this would be to schedule manual GC on a single zero-delay timer. That way, multiple manual GCs would coalesce. This would have the fortunate side-effect of doing GC when the stack was very small, reducing false positives in the conservative marking algorithm, and generally reducing marking overhead.

I tried this and it reduced the number of GCs during the PLT by 2/3. In the PLT, that didn&apos;t affect performance one way or the other. I suspect that&apos;s because there are very few live objects in the PLT when we GC.

In the pathological case of closing a tab containing many frames while many other JS-heavy tabs were open, I bet this would help a lot.

Not a priority right now, though, since it doesn&apos;t help page load performance.

(Sorry, but I lost the patch. It just changed Collector::collect() calls in WebCore to KJSProxy::garbageCollectSoon() calls. It implemented garbageCollectSoon() with GarbageCollectTimer : public TimerBase, that implemented fire() as Collector::collect().)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>4170</commentid>
    <comment_count>3</comment_count>
      <attachid>15608</attachid>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2007-07-20 14:36:30 -0700</bug_when>
    <thetext>Created attachment 15608
Pathological test case that demonstrates the value of this change</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>4156</commentid>
    <comment_count>4</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2007-07-20 16:02:28 -0700</bug_when>
    <thetext>Committed revision 24493.

</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>15608</attachid>
            <date>2007-07-20 14:36:30 -0700</date>
            <delta_ts>2007-07-20 14:36:30 -0700</delta_ts>
            <desc>Pathological test case that demonstrates the value of this change</desc>
            <filename>scratch.html</filename>
            <type>text/html</type>
            <size>1415</size>
            <attacher name="Geoffrey Garen">ggaren</attacher>
            
              <data encoding="base64">PHA+VGhpcyB0ZXN0IG1pbWljcyBhIHdvcnN0IGNhc2Ugc2NlbmFyaW8gb2YgaGF2aW5nIG1hbnkg
bGl2ZSBKUyBvYmplY3RzIChwZXJoYXBzCmluIHRhYnMpIGFuZCB0aGVuIG5hdmlnYXRpbmcgYXdh
eSBmcm9tIGEgcGFnZSB3aXRoIG1hbnkgZnJhbWVzLjwvcD4KCjxwcmUgaWQ9ImNvbnNvbGUiPjwv
cHJlPgoKPHNjcmlwdD4KZnVuY3Rpb24gbG9nKHMpCnsKICAgIGRvY3VtZW50LmdldEVsZW1lbnRC
eUlkKCJjb25zb2xlIikuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUocykpOwp9
CgpmdW5jdGlvbiBnY1Byb3RlY3QobykKewogICAgaWYgKCFnY1Byb3RlY3QuYXJyYXkpCiAgICAg
ICAgZ2NQcm90ZWN0LmFycmF5ID0gbmV3IEFycmF5OwogICAgZ2NQcm90ZWN0LmFycmF5LnB1c2go
byk7Cn0KCmZ1bmN0aW9uIGFkZElmcmFtZShlbGVtZW50KQp7CiAgICB2YXIgaWZyYW1lID0gZWxl
bWVudC5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImlmcmFtZSIpOwogICAgZWxlbWVudC5h
cHBlbmRDaGlsZChpZnJhbWUpOwp9CgpmdW5jdGlvbiBtYWluKCkKewogICAgLy8gc2ltdWxhdGUg
YSBidW5jaCBvZiBsaXZlIEphdmFTY3JpcHQgb2JqZWN0cwogICAgZm9yICh2YXIgaSA9IDA7IGkg
PCAxNTAwMDsgaSsrKSB7IC8vPgogICAgICAgIGdjUHJvdGVjdCh7eDoge30sIHk6IHt9LCB6OiB7
fX0pOwogICAgfQogICAgCiAgICB2YXIgc3RhcnQgPSBuZXcgRGF0ZTsKICAgIGJ1aWxkSWZyYW1l
KCk7CiAgICBkZXN0cm95SWZyYW1lKCk7CiAgICBsb2coIkVsYXBzZWQgdGVzdGluZyB0aW1lOiAi
ICsgU3RyaW5nKChuZXcgRGF0ZSkudmFsdWVPZigpIC0gc3RhcnQudmFsdWVPZigpKSk7Cn0KCmZ1
bmN0aW9uIGJ1aWxkSWZyYW1lKCkKewogICAgdmFyIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVs
ZW1lbnQoImlmcmFtZSIpOwogICAgaWZyYW1lLmlkID0gImlmcmFtZSI7CiAgICBpZnJhbWUuc3R5
bGUudmlzaWJpbGl0eSA9ICJoaWRkZW4iOwogICAgaWZyYW1lLnN0eWxlLndpZHRoID0gMDsKICAg
IGlmcmFtZS5zdHlsZS5oZWlnaHQgPSAwOwogICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChp
ZnJhbWUpOwogICAgCiAgICAvLyBzaW11bGF0ZSBhIHBhZ2Ugd2l0aCBhIGJ1bmNoIG9mIGZyYW1l
cwogICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaWZyYW1lIik7CiAg
ICBmb3IgKHZhciBpID0gMDsgaSA8IDEwMDsgaSsrKSB7IC8vPgogICAgICAgIGFkZElmcmFtZShl
bGVtZW50KTsKICAgIH0KfQoKZnVuY3Rpb24gZGVzdHJveUlmcmFtZSgpCnsKICAgIHZhciBpZnJh
bWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaWZyYW1lIik7CiAgICBpZnJhbWUucGFyZW50
Tm9kZS5yZW1vdmVDaGlsZChpZnJhbWUpOwp9CgptYWluKCk7Cjwvc2NyaXB0Pgo=
</data>

          </attachment>
      

    </bug>

</bugzilla>