<!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" />
<title>[196217] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { 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 #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#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>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/196217">196217</a></dd>
<dt>Author</dt> <dd>akling@apple.com</dd>
<dt>Date</dt> <dd>2016-02-06 09:00:30 -0800 (Sat, 06 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS] Throw away linked code when navigating to a new page.
&lt;https://webkit.org/b/153851&gt;

Reviewed by Gavin Barraclough.

Source/JavaScriptCore:

Add a VM API for throwing away linked code only.

* runtime/VM.cpp:
(JSC::VM::deleteAllLinkedCode):
* runtime/VM.h:

Source/WebCore:

When navigating to a new page, tell JSC to throw out any linked code it has lying around.
Linked code is tied to a specific global object, and as we're creating a new one for the
new page, none of it is useful to us here.

In the event that the user navigates back, the cost of relinking some code will be far
lower than the memory cost of keeping all of it around.

This landed previously but was rolled out due to a Speedometer regression. I've made one
minor but important change here: only throw away code if we're navigating away from an
existing history item. Or in other words, don't throw away code for &quot;force peeks&quot; or any
other navigations that are not traditional top-level main frame navigations.

* bindings/js/GCController.cpp:
(WebCore::GCController::deleteAllLinkedCode):
* bindings/js/GCController.h:
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::commitProvisionalLoad):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsGCControllercpp">trunk/Source/WebCore/bindings/js/GCController.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsGCControllerh">trunk/Source/WebCore/bindings/js/GCController.h</a></li>
<li><a href="#trunkSourceWebCoreloaderFrameLoadercpp">trunk/Source/WebCore/loader/FrameLoader.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (196216 => 196217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-02-06 13:44:34 UTC (rev 196216)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-02-06 17:00:30 UTC (rev 196217)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-02-06  Andreas Kling  &lt;akling@apple.com&gt;
+
+        [iOS] Throw away linked code when navigating to a new page.
+        &lt;https://webkit.org/b/153851&gt;
+
+        Reviewed by Gavin Barraclough.
+
+        Add a VM API for throwing away linked code only.
+
+        * runtime/VM.cpp:
+        (JSC::VM::deleteAllLinkedCode):
+        * runtime/VM.h:
+
</ins><span class="cx"> 2016-02-06  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r196104.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (196216 => 196217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2016-02-06 13:44:34 UTC (rev 196216)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2016-02-06 17:00:30 UTC (rev 196217)
</span><span class="lines">@@ -542,6 +542,14 @@
</span><span class="cx">     entryScope-&gt;addDidPopListener(callback);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void VM::deleteAllLinkedCode()
+{
+    whenIdle([this]() {
+        heap.deleteAllCodeBlocks();
+        heap.reportAbandonedObjectGraph();
+    });
+}
+
</ins><span class="cx"> void VM::deleteAllCode()
</span><span class="cx"> {
</span><span class="cx">     whenIdle([this]() {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (196216 => 196217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2016-02-06 13:44:34 UTC (rev 196216)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2016-02-06 17:00:30 UTC (rev 196217)
</span><span class="lines">@@ -574,6 +574,7 @@
</span><span class="cx">     JS_EXPORT_PRIVATE void whenIdle(std::function&lt;void()&gt;);
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void deleteAllCode();
</span><ins>+    JS_EXPORT_PRIVATE void deleteAllLinkedCode();
</ins><span class="cx"> 
</span><span class="cx">     void registerWatchpointForImpureProperty(const Identifier&amp;, Watchpoint*);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (196216 => 196217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-02-06 13:44:34 UTC (rev 196216)
+++ trunk/Source/WebCore/ChangeLog        2016-02-06 17:00:30 UTC (rev 196217)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2016-02-06  Andreas Kling  &lt;akling@apple.com&gt;
+
+        [iOS] Throw away linked code when navigating to a new page.
+        &lt;https://webkit.org/b/153851&gt;
+
+        Reviewed by Gavin Barraclough.
+
+        When navigating to a new page, tell JSC to throw out any linked code it has lying around.
+        Linked code is tied to a specific global object, and as we're creating a new one for the
+        new page, none of it is useful to us here.
+
+        In the event that the user navigates back, the cost of relinking some code will be far
+        lower than the memory cost of keeping all of it around.
+
+        This landed previously but was rolled out due to a Speedometer regression. I've made one
+        minor but important change here: only throw away code if we're navigating away from an
+        existing history item. Or in other words, don't throw away code for &quot;force peeks&quot; or any
+        other navigations that are not traditional top-level main frame navigations.
+
+        * bindings/js/GCController.cpp:
+        (WebCore::GCController::deleteAllLinkedCode):
+        * bindings/js/GCController.h:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::commitProvisionalLoad):
+
</ins><span class="cx"> 2016-02-06  Konstantin Tokarev  &lt;annulen@yandex.ru&gt;
</span><span class="cx"> 
</span><span class="cx">         Added implementations of AXObjectCache methods for !HAVE(ACCESSIBILITY).
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsGCControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/GCController.cpp (196216 => 196217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/GCController.cpp        2016-02-06 13:44:34 UTC (rev 196216)
+++ trunk/Source/WebCore/bindings/js/GCController.cpp        2016-02-06 17:00:30 UTC (rev 196217)
</span><span class="lines">@@ -122,4 +122,10 @@
</span><span class="cx">     JSDOMWindow::commonVM().deleteAllCode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void GCController::deleteAllLinkedCode()
+{
+    JSLockHolder lock(JSDOMWindow::commonVM());
+    JSDOMWindow::commonVM().deleteAllLinkedCode();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsGCControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/GCController.h (196216 => 196217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/GCController.h        2016-02-06 13:44:34 UTC (rev 196216)
+++ trunk/Source/WebCore/bindings/js/GCController.h        2016-02-06 17:00:30 UTC (rev 196217)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx">     WEBCORE_EXPORT void garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone); // Used for stress testing.
</span><span class="cx">     WEBCORE_EXPORT void setJavaScriptGarbageCollectorTimerEnabled(bool);
</span><span class="cx">     WEBCORE_EXPORT void deleteAllCode();
</span><ins>+    WEBCORE_EXPORT void deleteAllLinkedCode();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     GCController(); // Use singleton() instead.
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFrameLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (196216 => 196217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FrameLoader.cpp        2016-02-06 13:44:34 UTC (rev 196216)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp        2016-02-06 17:00:30 UTC (rev 196217)
</span><span class="lines">@@ -66,6 +66,7 @@
</span><span class="cx"> #include &quot;FrameNetworkingContext.h&quot;
</span><span class="cx"> #include &quot;FrameTree.h&quot;
</span><span class="cx"> #include &quot;FrameView.h&quot;
</span><ins>+#include &quot;GCController.h&quot;
</ins><span class="cx"> #include &quot;HTMLAnchorElement.h&quot;
</span><span class="cx"> #include &quot;HTMLFormElement.h&quot;
</span><span class="cx"> #include &quot;HTMLInputElement.h&quot;
</span><span class="lines">@@ -1756,11 +1757,18 @@
</span><span class="cx"> 
</span><span class="cx">     willTransitionToCommitted();
</span><span class="cx"> 
</span><del>-    // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
-    // We are doing this here because we know for sure that a new page is about to be loaded.
-    if (!m_frame.tree().parent() &amp;&amp; history().currentItem())
</del><ins>+    if (!m_frame.tree().parent() &amp;&amp; history().currentItem()) {
+        // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
+        // We are doing this here because we know for sure that a new page is about to be loaded.
</ins><span class="cx">         PageCache::singleton().addIfCacheable(*history().currentItem(), m_frame.page());
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+        // For top-level navigations, have JSC throw away linked code. The immediate memory savings far
+        // outweigh the cost of recompiling in the case of a future backwards navigation.
+        GCController::singleton().deleteAllLinkedCode();
+#endif
+    }
+
</ins><span class="cx">     if (m_loadType != FrameLoadType::Replace)
</span><span class="cx">         closeOldDataSources();
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>