<!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>[202166] trunk/Source/WebCore</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/202166">202166</a></dd>
<dt>Author</dt> <dd>akling@apple.com</dd>
<dt>Date</dt> <dd>2016-06-17 06:35:32 -0700 (Fri, 17 Jun 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 Antti Koivisto.

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 was in-tree before but was rolled out due to regressing JSBench. It was a slowdown
due to the benchmark harness using top-level navigations to drive the tests.
This new version avoids that problem by only throwing out code if we haven't navigated
in the last 2 seconds. This also prevents excessive work in response to redirects.

I've also moved this into MemoryPressureHandler so we don't make a mess in FrameLoader.

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::commitProvisionalLoad):
* platform/MemoryPressureHandler.cpp:
(WebCore::MemoryPressureHandler::jettisonExpensiveObjectsOnTopLevelNavigation):
* platform/MemoryPressureHandler.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreloaderFrameLoadercpp">trunk/Source/WebCore/loader/FrameLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformMemoryPressureHandlercpp">trunk/Source/WebCore/platform/MemoryPressureHandler.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformMemoryPressureHandlerh">trunk/Source/WebCore/platform/MemoryPressureHandler.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (202165 => 202166)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-06-17 11:50:53 UTC (rev 202165)
+++ trunk/Source/WebCore/ChangeLog        2016-06-17 13:35:32 UTC (rev 202166)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2016-06-17  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 Antti Koivisto.
+
+        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 was in-tree before but was rolled out due to regressing JSBench. It was a slowdown
+        due to the benchmark harness using top-level navigations to drive the tests.
+        This new version avoids that problem by only throwing out code if we haven't navigated
+        in the last 2 seconds. This also prevents excessive work in response to redirects.
+
+        I've also moved this into MemoryPressureHandler so we don't make a mess in FrameLoader.
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::commitProvisionalLoad):
+        * platform/MemoryPressureHandler.cpp:
+        (WebCore::MemoryPressureHandler::jettisonExpensiveObjectsOnTopLevelNavigation):
+        * platform/MemoryPressureHandler.h:
+
</ins><span class="cx"> 2016-06-17  Youenn Fablet  &lt;youenn.fablet@crf.canon.fr&gt;
</span><span class="cx"> 
</span><span class="cx">         CORS preflight with a non-200 response should be a preflight failure
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderFrameLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (202165 => 202166)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/FrameLoader.cpp        2016-06-17 11:50:53 UTC (rev 202165)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp        2016-06-17 13:35:32 UTC (rev 202166)
</span><span class="lines">@@ -1786,6 +1786,8 @@
</span><span class="cx">         // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
</span><span class="cx">         // We are doing this here because we know for sure that a new page is about to be loaded.
</span><span class="cx">         PageCache::singleton().addIfCacheable(*history().currentItem(), m_frame.page());
</span><ins>+        
+        MemoryPressureHandler::singleton().jettisonExpensiveObjectsOnTopLevelNavigation();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (m_loadType != FrameLoadType::Replace)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformMemoryPressureHandlercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/MemoryPressureHandler.cpp (202165 => 202166)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/MemoryPressureHandler.cpp        2016-06-17 11:50:53 UTC (rev 202165)
+++ trunk/Source/WebCore/platform/MemoryPressureHandler.cpp        2016-06-17 13:35:32 UTC (rev 202166)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include &quot;StyledElement.h&quot;
</span><span class="cx"> #include &quot;WorkerThread.h&quot;
</span><span class="cx"> #include &lt;JavaScriptCore/IncrementalSweeper.h&gt;
</span><ins>+#include &lt;chrono&gt;
</ins><span class="cx"> #include &lt;wtf/CurrentTime.h&gt;
</span><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="lines">@@ -159,6 +160,26 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MemoryPressureHandler::jettisonExpensiveObjectsOnTopLevelNavigation()
+{
+#if PLATFORM(IOS)
+    // Protect against doing excessive jettisoning during repeated navigations.
+    const auto minimumTimeSinceNavigation = 2s;
+
+    static auto timeOfLastNavigation = std::chrono::steady_clock::now();
+    auto now = std::chrono::steady_clock::now();
+    bool shouldJettison = now - timeOfLastNavigation &gt;= minimumTimeSinceNavigation;
+    timeOfLastNavigation = now;
+
+    if (!shouldJettison)
+        return;
+
+    // Throw away linked JS code. Linked code is tied to a global object and is not reusable.
+    // The immediate memory savings outweigh the cost of recompilation in case we go back again.
+    GCController::singleton().deleteAllLinkedCode();
+#endif
+}
+
</ins><span class="cx"> void MemoryPressureHandler::releaseMemory(Critical critical, Synchronous synchronous)
</span><span class="cx"> {
</span><span class="cx">     if (critical == Critical::Yes)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformMemoryPressureHandlerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/MemoryPressureHandler.h (202165 => 202166)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/MemoryPressureHandler.h        2016-06-17 11:50:53 UTC (rev 202165)
+++ trunk/Source/WebCore/platform/MemoryPressureHandler.h        2016-06-17 13:35:32 UTC (rev 202166)
</span><span class="lines">@@ -69,6 +69,8 @@
</span><span class="cx">         m_lowMemoryHandler = handler;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void jettisonExpensiveObjectsOnTopLevelNavigation();
+
</ins><span class="cx">     bool isUnderMemoryPressure() const { return m_underMemoryPressure; }
</span><span class="cx">     void setUnderMemoryPressure(bool b) { m_underMemoryPressure = b; }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>