<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[20719] branches/js-collector-tweaks/WebCore</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/20719">20719</a></dd>
<dt>Author</dt> <dd>mjs</dd>
<dt>Date</dt> <dd>2007-04-05 03:08:55 -0700 (Thu, 05 Apr 2007)</dd>
</dl>

<h3>Log Message</h3>
<pre>        Not reviewed - experimental work.

        - move most of Window's data members into a separate private object, to avoid needing
        to use the oversize allocator for it
        
        It was the only remaining JSObject subclass to use the ocersize
        allocator on 32-bit platforms, and having oversize objects around
        makes garbage collection slower so this would hurt performance
        with many tabs/windows open.
        
        No significant effect on JS iBench.

        * bindings/js/kjs_events.cpp:
        (KJS::JSUnprotectedEventListener::JSUnprotectedEventListener):
        (KJS::JSUnprotectedEventListener::~JSUnprotectedEventListener):
        (KJS::JSEventListener::JSEventListener):
        (KJS::JSEventListener::~JSEventListener):
        (KJS::JSLazyEventListener::parseCode):
        * bindings/js/kjs_window.cpp:
        (KJS::WindowPrivate::WindowPrivate):
        (KJS::Window::Window):
        (KJS::Window::~Window):
        (KJS::Window::location):
        (KJS::Window::selection):
        (KJS::Window::locationbar):
        (KJS::Window::menubar):
        (KJS::Window::personalbar):
        (KJS::Window::statusbar):
        (KJS::Window::toolbar):
        (KJS::Window::scrollbars):
        (KJS::Window::mark):
        (KJS::Window::getValueProperty):
        (KJS::Window::findJSEventListener):
        (KJS::Window::findJSUnprotectedEventListener):
        (KJS::Window::clearHelperObjectProperties):
        (KJS::Window::clear):
        (KJS::Window::setCurrentEvent):
        (KJS::Window::setReturnValueSlot):
        (KJS::Window::clearAllTimeouts):
        (KJS::Window::installTimeout):
        (KJS::Window::pauseTimeouts):
        (KJS::Window::resumeTimeouts):
        (KJS::Window::clearTimeout):
        (KJS::Window::timerFired):
        (KJS::Window::disconnectFrame):
        (KJS::Window::jsEventListeners):
        (KJS::Window::jsHTMLEventListeners):
        (KJS::Window::jsUnprotectedEventListeners):
        (KJS::Window::jsUnprotectedHTMLEventListeners):
        * bindings/js/kjs_window.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjscollectortweaksWebCoreChangeLog">branches/js-collector-tweaks/WebCore/ChangeLog</a></li>
<li><a href="#branchesjscollectortweaksWebCorebindingsjskjs_eventscpp">branches/js-collector-tweaks/WebCore/bindings/js/kjs_events.cpp</a></li>
<li><a href="#branchesjscollectortweaksWebCorebindingsjskjs_windowcpp">branches/js-collector-tweaks/WebCore/bindings/js/kjs_window.cpp</a></li>
<li><a href="#branchesjscollectortweaksWebCorebindingsjskjs_windowh">branches/js-collector-tweaks/WebCore/bindings/js/kjs_window.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjscollectortweaksWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/js-collector-tweaks/WebCore/ChangeLog (20718 => 20719)</h4>
<pre class="diff"><span>
<span class="info">--- branches/js-collector-tweaks/WebCore/ChangeLog        2007-04-05 10:03:02 UTC (rev 20718)
+++ branches/js-collector-tweaks/WebCore/ChangeLog        2007-04-05 10:08:55 UTC (rev 20719)
</span><span class="lines">@@ -1,3 +1,56 @@
</span><ins>+2007-04-05  Maciej Stachowiak  &lt;mjs@apple.com&gt;
+
+        Not reviewed - experimental work.
+
+        - move most of Window's data members into a separate private object, to avoid needing
+        to use the oversize allocator for it
+        
+        It was the only remaining JSObject subclass to use the ocersize
+        allocator on 32-bit platforms, and having oversize objects around
+        makes garbage collection slower so this would hurt performance
+        with many tabs/windows open.
+        
+        No significant effect on JS iBench.
+
+        * bindings/js/kjs_events.cpp:
+        (KJS::JSUnprotectedEventListener::JSUnprotectedEventListener):
+        (KJS::JSUnprotectedEventListener::~JSUnprotectedEventListener):
+        (KJS::JSEventListener::JSEventListener):
+        (KJS::JSEventListener::~JSEventListener):
+        (KJS::JSLazyEventListener::parseCode):
+        * bindings/js/kjs_window.cpp:
+        (KJS::WindowPrivate::WindowPrivate):
+        (KJS::Window::Window):
+        (KJS::Window::~Window):
+        (KJS::Window::location):
+        (KJS::Window::selection):
+        (KJS::Window::locationbar):
+        (KJS::Window::menubar):
+        (KJS::Window::personalbar):
+        (KJS::Window::statusbar):
+        (KJS::Window::toolbar):
+        (KJS::Window::scrollbars):
+        (KJS::Window::mark):
+        (KJS::Window::getValueProperty):
+        (KJS::Window::findJSEventListener):
+        (KJS::Window::findJSUnprotectedEventListener):
+        (KJS::Window::clearHelperObjectProperties):
+        (KJS::Window::clear):
+        (KJS::Window::setCurrentEvent):
+        (KJS::Window::setReturnValueSlot):
+        (KJS::Window::clearAllTimeouts):
+        (KJS::Window::installTimeout):
+        (KJS::Window::pauseTimeouts):
+        (KJS::Window::resumeTimeouts):
+        (KJS::Window::clearTimeout):
+        (KJS::Window::timerFired):
+        (KJS::Window::disconnectFrame):
+        (KJS::Window::jsEventListeners):
+        (KJS::Window::jsHTMLEventListeners):
+        (KJS::Window::jsUnprotectedEventListeners):
+        (KJS::Window::jsUnprotectedHTMLEventListeners):
+        * bindings/js/kjs_window.h:
+
</ins><span class="cx"> 2007-04-04  Alexey Proskuryakov  &lt;ap@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Reviewed by Darin.
</span></span></pre></div>
<a id="branchesjscollectortweaksWebCorebindingsjskjs_eventscpp"></a>
<div class="modfile"><h4>Modified: branches/js-collector-tweaks/WebCore/bindings/js/kjs_events.cpp (20718 => 20719)</h4>
<pre class="diff"><span>
<span class="info">--- branches/js-collector-tweaks/WebCore/bindings/js/kjs_events.cpp        2007-04-05 10:03:02 UTC (rev 20718)
+++ branches/js-collector-tweaks/WebCore/bindings/js/kjs_events.cpp        2007-04-05 10:08:55 UTC (rev 20719)
</span><span class="lines">@@ -165,8 +165,8 @@
</span><span class="cx">   , win(_win)
</span><span class="cx"> {
</span><span class="cx">     if (_listener) {
</span><del>-        Window::UnprotectedListenersMap&amp; listeners = _html
-            ? _win-&gt;jsUnprotectedHTMLEventListeners : _win-&gt;jsUnprotectedEventListeners;
</del><ins>+        Window::UnprotectedListenersMap&amp; listeners = _html 
+            ? _win-&gt;jsUnprotectedHTMLEventListeners() : _win-&gt;jsUnprotectedEventListeners();
</ins><span class="cx">         listeners.set(_listener, this);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -175,7 +175,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (listener &amp;&amp; win) {
</span><span class="cx">         Window::UnprotectedListenersMap&amp; listeners = isHTMLEventListener()
</span><del>-            ? win-&gt;jsUnprotectedHTMLEventListeners : win-&gt;jsUnprotectedEventListeners;
</del><ins>+            ? win-&gt;jsUnprotectedHTMLEventListeners() : win-&gt;jsUnprotectedEventListeners();
</ins><span class="cx">         listeners.remove(listener);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -228,7 +228,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (_listener) {
</span><span class="cx">         Window::ListenersMap&amp; listeners = _html
</span><del>-            ? _win-&gt;jsHTMLEventListeners : _win-&gt;jsEventListeners;
</del><ins>+            ? _win-&gt;jsHTMLEventListeners() : _win-&gt;jsEventListeners();
</ins><span class="cx">         listeners.set(_listener, this);
</span><span class="cx">     }
</span><span class="cx"> #ifndef NDEBUG
</span><span class="lines">@@ -240,7 +240,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (listener &amp;&amp; win) {
</span><span class="cx">         Window::ListenersMap&amp; listeners = isHTMLEventListener()
</span><del>-            ? win-&gt;jsHTMLEventListeners : win-&gt;jsEventListeners;
</del><ins>+            ? win-&gt;jsHTMLEventListeners() : win-&gt;jsEventListeners();
</ins><span class="cx">         listeners.remove(listener);
</span><span class="cx">     }
</span><span class="cx"> #ifndef NDEBUG
</span><span class="lines">@@ -342,7 +342,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (listener) {
</span><span class="cx">         Window::ListenersMap&amp; listeners = isHTMLEventListener()
</span><del>-            ? windowObj()-&gt;jsHTMLEventListeners : windowObj()-&gt;jsEventListeners;
</del><ins>+            ? windowObj()-&gt;jsHTMLEventListeners() : windowObj()-&gt;jsEventListeners();
</ins><span class="cx">         listeners.set(listener, const_cast&lt;JSLazyEventListener*&gt;(this));
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchesjscollectortweaksWebCorebindingsjskjs_windowcpp"></a>
<div class="modfile"><h4>Modified: branches/js-collector-tweaks/WebCore/bindings/js/kjs_window.cpp (20718 => 20719)</h4>
<pre class="diff"><span>
<span class="info">--- branches/js-collector-tweaks/WebCore/bindings/js/kjs_window.cpp        2007-04-05 10:03:02 UTC (rev 20718)
+++ branches/js-collector-tweaks/WebCore/bindings/js/kjs_window.cpp        2007-04-05 10:08:55 UTC (rev 20719)
</span><span class="lines">@@ -79,6 +79,45 @@
</span><span class="cx"> const int cMaxTimerNestingLevel = 5;
</span><span class="cx"> const double cMinimumTimerInterval = 0.010;
</span><span class="cx"> 
</span><ins>+struct WindowPrivate {
+    WindowPrivate() 
+        : screen(0)
+        , history(0)
+        , frames(0)
+        , loc(0)
+        , m_selection(0)
+        , m_locationbar(0)
+        , m_menubar(0)
+        , m_personalbar(0)
+        , m_scrollbars(0)
+        , m_statusbar(0)
+        , m_toolbar(0)
+        , m_evt(0)
+        , m_returnValueSlot(0)
+    {
+    }
+
+    Window::ListenersMap jsEventListeners;
+    Window::ListenersMap jsHTMLEventListeners;
+    Window::UnprotectedListenersMap jsUnprotectedEventListeners;
+    Window::UnprotectedListenersMap jsUnprotectedHTMLEventListeners;
+    mutable Screen* screen;
+    mutable History* history;
+    mutable FrameArray* frames;
+    mutable Location* loc;
+    mutable Selection* m_selection;
+    mutable BarInfo* m_locationbar;
+    mutable BarInfo* m_menubar;
+    mutable BarInfo* m_personalbar;
+    mutable BarInfo* m_scrollbars;
+    mutable BarInfo* m_statusbar;
+    mutable BarInfo* m_toolbar;
+    WebCore::Event *m_evt;
+    JSValue **m_returnValueSlot;
+    typedef HashMap&lt;int, DOMWindowTimer*&gt; TimeoutsMap;
+    TimeoutsMap m_timeouts;
+};
+
</ins><span class="cx"> class DOMWindowTimer : public TimerBase {
</span><span class="cx"> public:
</span><span class="cx">     DOMWindowTimer(int timeoutId, int nestingLevel, Window* o, ScheduledAction* a)
</span><span class="lines">@@ -331,19 +370,7 @@
</span><span class="cx"> 
</span><span class="cx"> Window::Window(DOMWindow* window)
</span><span class="cx">   : m_frame(window-&gt;frame())
</span><del>-  , screen(0)
-  , history(0)
-  , frames(0)
-  , loc(0)
-  , m_selection(0)
-  , m_locationbar(0)
-  , m_menubar(0)
-  , m_personalbar(0)
-  , m_scrollbars(0)
-  , m_statusbar(0)
-  , m_toolbar(0)
-  , m_evt(0)
-  , m_returnValueSlot(0)
</del><ins>+  , d(new WindowPrivate)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -353,21 +380,21 @@
</span><span class="cx"> 
</span><span class="cx">     // Clear any backpointers to the window
</span><span class="cx"> 
</span><del>-    ListenersMap::iterator i2 = jsEventListeners.begin();
-    ListenersMap::iterator e2 = jsEventListeners.end();
</del><ins>+    ListenersMap::iterator i2 = d-&gt;jsEventListeners.begin();
+    ListenersMap::iterator e2 = d-&gt;jsEventListeners.end();
</ins><span class="cx">     for (; i2 != e2; ++i2)
</span><span class="cx">         i2-&gt;second-&gt;clearWindowObj();
</span><del>-    i2 = jsHTMLEventListeners.begin();
-    e2 = jsHTMLEventListeners.end();
</del><ins>+    i2 = d-&gt;jsHTMLEventListeners.begin();
+    e2 = d-&gt;jsHTMLEventListeners.end();
</ins><span class="cx">     for (; i2 != e2; ++i2)
</span><span class="cx">         i2-&gt;second-&gt;clearWindowObj();
</span><span class="cx"> 
</span><del>-    UnprotectedListenersMap::iterator i1 = jsUnprotectedEventListeners.begin();
-    UnprotectedListenersMap::iterator e1 = jsUnprotectedEventListeners.end();
</del><ins>+    UnprotectedListenersMap::iterator i1 = d-&gt;jsUnprotectedEventListeners.begin();
+    UnprotectedListenersMap::iterator e1 = d-&gt;jsUnprotectedEventListeners.end();
</ins><span class="cx">     for (; i1 != e1; ++i1)
</span><span class="cx">         i1-&gt;second-&gt;clearWindowObj();
</span><del>-    i1 = jsUnprotectedHTMLEventListeners.begin();
-    e1 = jsUnprotectedHTMLEventListeners.end();
</del><ins>+    i1 = d-&gt;jsUnprotectedHTMLEventListeners.begin();
+    e1 = d-&gt;jsUnprotectedHTMLEventListeners.end();
</ins><span class="cx">     for (; i1 != e1; ++i1)
</span><span class="cx">         i1-&gt;second-&gt;clearWindowObj();
</span><span class="cx"> }
</span><span class="lines">@@ -408,16 +435,16 @@
</span><span class="cx"> 
</span><span class="cx"> Location *Window::location() const
</span><span class="cx"> {
</span><del>-  if (!loc)
-    loc = new Location(m_frame);
-  return loc;
</del><ins>+  if (!d-&gt;loc)
+    d-&gt;loc = new Location(m_frame);
+  return d-&gt;loc;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Selection *Window::selection() const
</span><span class="cx"> {
</span><del>-  if (!m_selection)
-    m_selection = new Selection(m_frame);
-  return m_selection;
</del><ins>+  if (!d-&gt;m_selection)
+    d-&gt;m_selection = new Selection(m_frame);
+  return d-&gt;m_selection;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool Window::find(const String&amp; string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const
</span><span class="lines">@@ -428,72 +455,72 @@
</span><span class="cx"> 
</span><span class="cx"> BarInfo *Window::locationbar(ExecState *exec) const
</span><span class="cx"> {
</span><del>-  if (!m_locationbar)
-    m_locationbar = new BarInfo(exec, m_frame, BarInfo::Locationbar);
-  return m_locationbar;
</del><ins>+  if (!d-&gt;m_locationbar)
+    d-&gt;m_locationbar = new BarInfo(exec, m_frame, BarInfo::Locationbar);
+  return d-&gt;m_locationbar;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BarInfo *Window::menubar(ExecState *exec) const
</span><span class="cx"> {
</span><del>-  if (!m_menubar)
-    m_menubar = new BarInfo(exec, m_frame, BarInfo::Menubar);
-  return m_menubar;
</del><ins>+  if (!d-&gt;m_menubar)
+    d-&gt;m_menubar = new BarInfo(exec, m_frame, BarInfo::Menubar);
+  return d-&gt;m_menubar;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BarInfo *Window::personalbar(ExecState *exec) const
</span><span class="cx"> {
</span><del>-  if (!m_personalbar)
-    m_personalbar = new BarInfo(exec, m_frame, BarInfo::Personalbar);
-  return m_personalbar;
</del><ins>+  if (!d-&gt;m_personalbar)
+    d-&gt;m_personalbar = new BarInfo(exec, m_frame, BarInfo::Personalbar);
+  return d-&gt;m_personalbar;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BarInfo *Window::statusbar(ExecState *exec) const
</span><span class="cx"> {
</span><del>-  if (!m_statusbar)
-    m_statusbar = new BarInfo(exec, m_frame, BarInfo::Statusbar);
-  return m_statusbar;
</del><ins>+  if (!d-&gt;m_statusbar)
+    d-&gt;m_statusbar = new BarInfo(exec, m_frame, BarInfo::Statusbar);
+  return d-&gt;m_statusbar;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BarInfo *Window::toolbar(ExecState *exec) const
</span><span class="cx"> {
</span><del>-  if (!m_toolbar)
-    m_toolbar = new BarInfo(exec, m_frame, BarInfo::Toolbar);
-  return m_toolbar;
</del><ins>+  if (!d-&gt;m_toolbar)
+    d-&gt;m_toolbar = new BarInfo(exec, m_frame, BarInfo::Toolbar);
+  return d-&gt;m_toolbar;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BarInfo *Window::scrollbars(ExecState *exec) const
</span><span class="cx"> {
</span><del>-  if (!m_scrollbars)
-    m_scrollbars = new BarInfo(exec, m_frame, BarInfo::Scrollbars);
-  return m_scrollbars;
</del><ins>+  if (!d-&gt;m_scrollbars)
+    d-&gt;m_scrollbars = new BarInfo(exec, m_frame, BarInfo::Scrollbars);
+  return d-&gt;m_scrollbars;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // reference our special objects during garbage collection
</span><span class="cx"> void Window::mark()
</span><span class="cx"> {
</span><span class="cx">   JSObject::mark();
</span><del>-  if (screen &amp;&amp; !screen-&gt;marked())
-    screen-&gt;mark();
-  if (history &amp;&amp; !history-&gt;marked())
-    history-&gt;mark();
-  if (frames &amp;&amp; !frames-&gt;marked())
-    frames-&gt;mark();
-  if (loc &amp;&amp; !loc-&gt;marked())
-    loc-&gt;mark();
-  if (m_selection &amp;&amp; !m_selection-&gt;marked())
-    m_selection-&gt;mark();
-  if (m_locationbar &amp;&amp; !m_locationbar-&gt;marked())
-    m_locationbar-&gt;mark();
-  if (m_menubar &amp;&amp; !m_menubar-&gt;marked())
-    m_menubar-&gt;mark();
-  if (m_personalbar &amp;&amp; !m_personalbar-&gt;marked())
-    m_personalbar-&gt;mark();
-  if (m_scrollbars &amp;&amp; !m_scrollbars-&gt;marked())
-    m_scrollbars-&gt;mark();
-  if (m_statusbar &amp;&amp; !m_statusbar-&gt;marked())
-    m_statusbar-&gt;mark();
-  if (m_toolbar &amp;&amp; !m_toolbar-&gt;marked())
-    m_toolbar-&gt;mark();
</del><ins>+  if (d-&gt;screen &amp;&amp; !d-&gt;screen-&gt;marked())
+    d-&gt;screen-&gt;mark();
+  if (d-&gt;history &amp;&amp; !d-&gt;history-&gt;marked())
+    d-&gt;history-&gt;mark();
+  if (d-&gt;frames &amp;&amp; !d-&gt;frames-&gt;marked())
+    d-&gt;frames-&gt;mark();
+  if (d-&gt;loc &amp;&amp; !d-&gt;loc-&gt;marked())
+    d-&gt;loc-&gt;mark();
+  if (d-&gt;m_selection &amp;&amp; !d-&gt;m_selection-&gt;marked())
+    d-&gt;m_selection-&gt;mark();
+  if (d-&gt;m_locationbar &amp;&amp; !d-&gt;m_locationbar-&gt;marked())
+    d-&gt;m_locationbar-&gt;mark();
+  if (d-&gt;m_menubar &amp;&amp; !d-&gt;m_menubar-&gt;marked())
+    d-&gt;m_menubar-&gt;mark();
+  if (d-&gt;m_personalbar &amp;&amp; !d-&gt;m_personalbar-&gt;marked())
+    d-&gt;m_personalbar-&gt;mark();
+  if (d-&gt;m_scrollbars &amp;&amp; !d-&gt;m_scrollbars-&gt;marked())
+    d-&gt;m_scrollbars-&gt;mark();
+  if (d-&gt;m_statusbar &amp;&amp; !d-&gt;m_statusbar-&gt;marked())
+    d-&gt;m_statusbar-&gt;mark();
+  if (d-&gt;m_toolbar &amp;&amp; !d-&gt;m_toolbar-&gt;marked())
+    d-&gt;m_toolbar-&gt;mark();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> UString Window::toString(ExecState *) const
</span><span class="lines">@@ -712,17 +739,17 @@
</span><span class="cx">    case Status:
</span><span class="cx">       return jsString(UString(m_frame-&gt;jsStatusBarText()));
</span><span class="cx">     case Frames:
</span><del>-      if (!frames)
-        frames = new FrameArray(exec, m_frame);
-      return frames;
</del><ins>+      if (!d-&gt;frames)
+        d-&gt;frames = new FrameArray(exec, m_frame);
+      return d-&gt;frames;
</ins><span class="cx">     case History_:
</span><del>-      if (!history)
-        history = new History(exec, m_frame);
-      return history;
</del><ins>+      if (!d-&gt;history)
+        d-&gt;history = new History(exec, m_frame);
+      return d-&gt;history;
</ins><span class="cx">     case Event_:
</span><del>-      if (!m_evt)
</del><ins>+      if (!d-&gt;m_evt)
</ins><span class="cx">         return jsUndefined();
</span><del>-      return toJS(exec, m_evt);
</del><ins>+      return toJS(exec, d-&gt;m_evt);
</ins><span class="cx">     case InnerHeight:
</span><span class="cx">       if (!m_frame-&gt;view())
</span><span class="cx">         return jsUndefined();
</span><span class="lines">@@ -803,9 +830,9 @@
</span><span class="cx">     case Top:
</span><span class="cx">       return retrieve(m_frame-&gt;page()-&gt;mainFrame());
</span><span class="cx">     case Screen_:
</span><del>-      if (!screen)
-        screen = new Screen(exec, m_frame);
-      return screen;
</del><ins>+      if (!d-&gt;screen)
+        d-&gt;screen = new Screen(exec, m_frame);
+      return d-&gt;screen;
</ins><span class="cx">     case Image:
</span><span class="cx">       // FIXME: this property (and the few below) probably shouldn't create a new object every
</span><span class="cx">       // time
</span><span class="lines">@@ -1315,7 +1342,7 @@
</span><span class="cx">     if (!val-&gt;isObject())
</span><span class="cx">         return 0;
</span><span class="cx">     JSObject* object = static_cast&lt;JSObject*&gt;(val);
</span><del>-    ListenersMap&amp; listeners = html ? jsHTMLEventListeners : jsEventListeners;
</del><ins>+    ListenersMap&amp; listeners = html ? d-&gt;jsHTMLEventListeners : d-&gt;jsEventListeners;
</ins><span class="cx">     return listeners.get(object);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1338,7 +1365,7 @@
</span><span class="cx">     if (!val-&gt;isObject())
</span><span class="cx">         return 0;
</span><span class="cx">     JSObject* object = static_cast&lt;JSObject*&gt;(val);
</span><del>-    UnprotectedListenersMap&amp; listeners = html ? jsUnprotectedHTMLEventListeners : jsUnprotectedEventListeners;
</del><ins>+    UnprotectedListenersMap&amp; listeners = html ? d-&gt;jsUnprotectedHTMLEventListeners : d-&gt;jsUnprotectedEventListeners;
</ins><span class="cx">     return listeners.get(object);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1358,26 +1385,26 @@
</span><span class="cx"> 
</span><span class="cx"> void Window::clearHelperObjectProperties()
</span><span class="cx"> {
</span><del>-  screen = 0;
-  history = 0;
-  frames = 0;
-  loc = 0;
-  m_selection = 0;
-  m_locationbar = 0;
-  m_menubar = 0;
-  m_personalbar = 0;
-  m_scrollbars = 0;
-  m_statusbar = 0;
-  m_toolbar = 0;
-  m_evt = 0;
</del><ins>+  d-&gt;screen = 0;
+  d-&gt;history = 0;
+  d-&gt;frames = 0;
+  d-&gt;loc = 0;
+  d-&gt;m_selection = 0;
+  d-&gt;m_locationbar = 0;
+  d-&gt;m_menubar = 0;
+  d-&gt;m_personalbar = 0;
+  d-&gt;m_scrollbars = 0;
+  d-&gt;m_statusbar = 0;
+  d-&gt;m_toolbar = 0;
+  d-&gt;m_evt = 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Window::clear()
</span><span class="cx"> {
</span><span class="cx">   JSLock lock;
</span><span class="cx"> 
</span><del>-  if (m_returnValueSlot &amp;&amp; !*m_returnValueSlot)
-    *m_returnValueSlot = getDirect(&quot;returnValue&quot;);
</del><ins>+  if (d-&gt;m_returnValueSlot &amp;&amp; !*d-&gt;m_returnValueSlot)
+    *d-&gt;m_returnValueSlot = getDirect(&quot;returnValue&quot;);
</ins><span class="cx"> 
</span><span class="cx">   clearAllTimeouts();
</span><span class="cx">   clearProperties();
</span><span class="lines">@@ -1395,7 +1422,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Window::setCurrentEvent(Event *evt)
</span><span class="cx"> {
</span><del>-  m_evt = evt;
</del><ins>+  d-&gt;m_evt = evt;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void setWindowFeature(const String&amp; keyString, const String&amp; valueString, WindowFeatures&amp; windowFeatures)
</span><span class="lines">@@ -1856,6 +1883,11 @@
</span><span class="cx">     docimpl-&gt;updateLayoutIgnorePendingStylesheets();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Window::setReturnValueSlot(JSValue **slot)
+{ 
+    d-&gt;m_returnValueSlot = slot; 
+}
+
</ins><span class="cx"> ////////////////////// ScheduledAction ////////////////////////
</span><span class="cx"> 
</span><span class="cx"> void ScheduledAction::execute(Window* window)
</span><span class="lines">@@ -1909,8 +1941,8 @@
</span><span class="cx"> 
</span><span class="cx"> void Window::clearAllTimeouts()
</span><span class="cx"> {
</span><del>-    deleteAllValues(m_timeouts);
-    m_timeouts.clear();
</del><ins>+    deleteAllValues(d-&gt;m_timeouts);
+    d-&gt;m_timeouts.clear();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> int Window::installTimeout(ScheduledAction* a, int t, bool singleShot)
</span><span class="lines">@@ -1918,8 +1950,8 @@
</span><span class="cx">     int timeoutId = ++lastUsedTimeoutId;
</span><span class="cx">     int nestLevel = timerNestingLevel + 1;
</span><span class="cx">     DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, nestLevel, this, a);
</span><del>-    ASSERT(!m_timeouts.get(timeoutId));
-    m_timeouts.set(timeoutId, timer);
</del><ins>+    ASSERT(!d-&gt;m_timeouts.get(timeoutId));
+    d-&gt;m_timeouts.set(timeoutId, timer);
</ins><span class="cx">     // Use a minimum interval of 10 ms to match other browsers, but only once we've
</span><span class="cx">     // nested enough to notice that we're repeating.
</span><span class="cx">     // Faster timers might be &quot;better&quot;, but they're incompatible.
</span><span class="lines">@@ -1945,14 +1977,14 @@
</span><span class="cx"> 
</span><span class="cx"> PausedTimeouts* Window::pauseTimeouts()
</span><span class="cx"> {
</span><del>-    size_t count = m_timeouts.size();
</del><ins>+    size_t count = d-&gt;m_timeouts.size();
</ins><span class="cx">     if (count == 0)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="cx">     PausedTimeout* t = new PausedTimeout [count];
</span><span class="cx">     PausedTimeouts* result = new PausedTimeouts(t, count);
</span><span class="cx"> 
</span><del>-    TimeoutsMap::iterator it = m_timeouts.begin();
</del><ins>+    WindowPrivate::TimeoutsMap::iterator it = d-&gt;m_timeouts.begin();
</ins><span class="cx">     for (size_t i = 0; i != count; ++i, ++it) {
</span><span class="cx">         int timeoutId = it-&gt;first;
</span><span class="cx">         DOMWindowTimer* timer = it-&gt;second;
</span><span class="lines">@@ -1962,10 +1994,10 @@
</span><span class="cx">         t[i].repeatInterval = timer-&gt;repeatInterval();
</span><span class="cx">         t[i].action = timer-&gt;takeAction();
</span><span class="cx">     }
</span><del>-    ASSERT(it == m_timeouts.end());
</del><ins>+    ASSERT(it == d-&gt;m_timeouts.end());
</ins><span class="cx"> 
</span><del>-    deleteAllValues(m_timeouts);
-    m_timeouts.clear();
</del><ins>+    deleteAllValues(d-&gt;m_timeouts);
+    d-&gt;m_timeouts.clear();
</ins><span class="cx"> 
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -1979,7 +2011,7 @@
</span><span class="cx">     for (size_t i = 0; i != count; ++i) {
</span><span class="cx">         int timeoutId = array[i].timeoutId;
</span><span class="cx">         DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, array[i].nestingLevel, this, array[i].action);
</span><del>-        m_timeouts.set(timeoutId, timer);
</del><ins>+        d-&gt;m_timeouts.set(timeoutId, timer);
</ins><span class="cx">         timer-&gt;start(array[i].nextFireInterval, array[i].repeatInterval);
</span><span class="cx">     }
</span><span class="cx">     delete [] array;
</span><span class="lines">@@ -1987,11 +2019,11 @@
</span><span class="cx"> 
</span><span class="cx"> void Window::clearTimeout(int timeoutId, bool delAction)
</span><span class="cx"> {
</span><del>-    TimeoutsMap::iterator it = m_timeouts.find(timeoutId);
-    if (it == m_timeouts.end())
</del><ins>+    WindowPrivate::TimeoutsMap::iterator it = d-&gt;m_timeouts.find(timeoutId);
+    if (it == d-&gt;m_timeouts.end())
</ins><span class="cx">         return;
</span><span class="cx">     DOMWindowTimer* timer = it-&gt;second;
</span><del>-    m_timeouts.remove(it);
</del><ins>+    d-&gt;m_timeouts.remove(it);
</ins><span class="cx">     delete timer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2002,7 +2034,7 @@
</span><span class="cx">         int timeoutId = timer-&gt;timeoutId();
</span><span class="cx"> 
</span><span class="cx">         timer-&gt;action()-&gt;execute(this);
</span><del>-        if (m_timeouts.contains(timeoutId) &amp;&amp; timer-&gt;repeatInterval() &amp;&amp; timer-&gt;repeatInterval() &lt; cMinimumTimerInterval) {
</del><ins>+        if (d-&gt;m_timeouts.contains(timeoutId) &amp;&amp; timer-&gt;repeatInterval() &amp;&amp; timer-&gt;repeatInterval() &lt; cMinimumTimerInterval) {
</ins><span class="cx">             timer-&gt;setNestingLevel(timer-&gt;nestingLevel() + 1);
</span><span class="cx">             if (timer-&gt;nestingLevel() &gt;= cMaxTimerNestingLevel)
</span><span class="cx">                 timer-&gt;augmentRepeatInterval(cMinimumTimerInterval - timer-&gt;repeatInterval());
</span><span class="lines">@@ -2012,7 +2044,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Delete timer before executing the action for one-shot timers.
</span><span class="cx">     ScheduledAction* action = timer-&gt;takeAction();
</span><del>-    m_timeouts.remove(timer-&gt;timeoutId());
</del><ins>+    d-&gt;m_timeouts.remove(timer-&gt;timeoutId());
</ins><span class="cx">     delete timer;
</span><span class="cx">     action-&gt;execute(this);
</span><span class="cx">     
</span><span class="lines">@@ -2024,28 +2056,48 @@
</span><span class="cx"> {
</span><span class="cx">     clearAllTimeouts();
</span><span class="cx">     m_frame = 0;
</span><del>-    if (loc)
-        loc-&gt;m_frame = 0;
-    if (m_selection)
-        m_selection-&gt;m_frame = 0;
-    if (m_locationbar)
-        m_locationbar-&gt;m_frame = 0;
-    if (m_menubar)
-        m_menubar-&gt;m_frame = 0;
-    if (m_personalbar)
-        m_personalbar-&gt;m_frame = 0;
-    if (m_statusbar)
-        m_statusbar-&gt;m_frame = 0;
-    if (m_toolbar)
-        m_toolbar-&gt;m_frame = 0;
-    if (m_scrollbars)
-        m_scrollbars-&gt;m_frame = 0;
-    if (frames)
-        frames-&gt;disconnectFrame();
-    if (history)
-        history-&gt;disconnectFrame();
</del><ins>+    if (d-&gt;loc)
+        d-&gt;loc-&gt;m_frame = 0;
+    if (d-&gt;m_selection)
+        d-&gt;m_selection-&gt;m_frame = 0;
+    if (d-&gt;m_locationbar)
+        d-&gt;m_locationbar-&gt;m_frame = 0;
+    if (d-&gt;m_menubar)
+        d-&gt;m_menubar-&gt;m_frame = 0;
+    if (d-&gt;m_personalbar)
+        d-&gt;m_personalbar-&gt;m_frame = 0;
+    if (d-&gt;m_statusbar)
+        d-&gt;m_statusbar-&gt;m_frame = 0;
+    if (d-&gt;m_toolbar)
+        d-&gt;m_toolbar-&gt;m_frame = 0;
+    if (d-&gt;m_scrollbars)
+        d-&gt;m_scrollbars-&gt;m_frame = 0;
+    if (d-&gt;frames)
+        d-&gt;frames-&gt;disconnectFrame();
+    if (d-&gt;history)
+        d-&gt;history-&gt;disconnectFrame();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Window::ListenersMap&amp; Window::jsEventListeners()
+{
+    return d-&gt;jsEventListeners;
+}
+
+Window::ListenersMap&amp; Window::jsHTMLEventListeners()
+{
+    return d-&gt;jsHTMLEventListeners;
+}
+
+Window::UnprotectedListenersMap&amp; Window::jsUnprotectedEventListeners()
+{
+    return d-&gt;jsUnprotectedEventListeners;
+}
+
+Window::UnprotectedListenersMap&amp; Window::jsUnprotectedHTMLEventListeners()
+{
+    return d-&gt;jsUnprotectedHTMLEventListeners;
+}
+
</ins><span class="cx"> const ClassInfo FrameArray::info = { &quot;FrameArray&quot;, 0, &amp;FrameArrayTable, 0 };
</span><span class="cx"> 
</span><span class="cx"> /*
</span></span></pre></div>
<a id="branchesjscollectortweaksWebCorebindingsjskjs_windowh"></a>
<div class="modfile"><h4>Modified: branches/js-collector-tweaks/WebCore/bindings/js/kjs_window.h (20718 => 20719)</h4>
<pre class="diff"><span>
<span class="info">--- branches/js-collector-tweaks/WebCore/bindings/js/kjs_window.h        2007-04-05 10:03:02 UTC (rev 20718)
+++ branches/js-collector-tweaks/WebCore/bindings/js/kjs_window.h        2007-04-05 10:08:55 UTC (rev 20719)
</span><span class="lines">@@ -80,6 +80,8 @@
</span><span class="cx">     WebCore::Frame* m_frame;
</span><span class="cx">   };
</span><span class="cx"> 
</span><ins>+  class WindowPrivate;
+
</ins><span class="cx">   class Window : public DOMObject {
</span><span class="cx">     friend class Location;
</span><span class="cx">     friend class WindowFunc;
</span><span class="lines">@@ -156,14 +158,16 @@
</span><span class="cx">     void setCurrentEvent(WebCore::Event*);
</span><span class="cx"> 
</span><span class="cx">     // Set a place to put a dialog return value when the window is cleared.
</span><del>-    void setReturnValueSlot(JSValue **slot) { m_returnValueSlot = slot; }
</del><ins>+    void setReturnValueSlot(JSValue **slot);
</ins><span class="cx"> 
</span><span class="cx">     typedef HashMap&lt;JSObject*, JSEventListener*&gt; ListenersMap;
</span><span class="cx">     typedef HashMap&lt;JSObject*, JSUnprotectedEventListener*&gt; UnprotectedListenersMap;
</span><del>-    ListenersMap jsEventListeners;
-    ListenersMap jsHTMLEventListeners;
-    UnprotectedListenersMap jsUnprotectedEventListeners;
-    UnprotectedListenersMap jsUnprotectedHTMLEventListeners;
</del><ins>+    
+    ListenersMap&amp; jsEventListeners();
+    ListenersMap&amp; jsHTMLEventListeners();
+    UnprotectedListenersMap&amp; jsUnprotectedEventListeners();
+    UnprotectedListenersMap&amp; jsUnprotectedHTMLEventListeners();
+    
</ins><span class="cx">     virtual const ClassInfo* classInfo() const { return &amp;info; }
</span><span class="cx">     static const ClassInfo info;
</span><span class="cx">     enum { AToB, BToA, Closed, Crypto, DefaultStatus, Status, DOMException, Frames, History_, Event_, InnerHeight,
</span><span class="lines">@@ -198,21 +202,7 @@
</span><span class="cx">     int installTimeout(ScheduledAction*, int interval, bool singleShot);
</span><span class="cx"> 
</span><span class="cx">     WebCore::Frame* m_frame;
</span><del>-    mutable Screen* screen;
-    mutable History* history;
-    mutable FrameArray* frames;
-    mutable Location* loc;
-    mutable Selection* m_selection;
-    mutable BarInfo* m_locationbar;
-    mutable BarInfo* m_menubar;
-    mutable BarInfo* m_personalbar;
-    mutable BarInfo* m_scrollbars;
-    mutable BarInfo* m_statusbar;
-    mutable BarInfo* m_toolbar;
-    WebCore::Event *m_evt;
-    JSValue **m_returnValueSlot;
-    typedef HashMap&lt;int, DOMWindowTimer*&gt; TimeoutsMap;
-    TimeoutsMap m_timeouts;
</del><ins>+    OwnPtr&lt;WindowPrivate&gt; d;
</ins><span class="cx">   };
</span><span class="cx"> 
</span><span class="cx">   /**
</span></span></pre>
</div>
</div>

</body>
</html>