Title: [202166] trunk/Source/WebCore
Revision
202166
Author
[email protected]
Date
2016-06-17 06:35:32 -0700 (Fri, 17 Jun 2016)

Log Message

[iOS] Throw away linked code when navigating to a new page.
<https://webkit.org/b/153851>

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:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (202165 => 202166)


--- 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)
@@ -1,3 +1,30 @@
+2016-06-17  Andreas Kling  <[email protected]>
+
+        [iOS] Throw away linked code when navigating to a new page.
+        <https://webkit.org/b/153851>
+
+        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:
+
 2016-06-17  Youenn Fablet  <[email protected]>
 
         CORS preflight with a non-200 response should be a preflight failure

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (202165 => 202166)


--- 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)
@@ -1786,6 +1786,8 @@
         // 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.
         PageCache::singleton().addIfCacheable(*history().currentItem(), m_frame.page());
+        
+        MemoryPressureHandler::singleton().jettisonExpensiveObjectsOnTopLevelNavigation();
     }
 
     if (m_loadType != FrameLoadType::Replace)

Modified: trunk/Source/WebCore/platform/MemoryPressureHandler.cpp (202165 => 202166)


--- 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)
@@ -41,6 +41,7 @@
 #include "StyledElement.h"
 #include "WorkerThread.h"
 #include <_javascript_Core/IncrementalSweeper.h>
+#include <chrono>
 #include <wtf/CurrentTime.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/StdLibExtras.h>
@@ -159,6 +160,26 @@
     });
 }
 
+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 >= 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
+}
+
 void MemoryPressureHandler::releaseMemory(Critical critical, Synchronous synchronous)
 {
     if (critical == Critical::Yes)

Modified: trunk/Source/WebCore/platform/MemoryPressureHandler.h (202165 => 202166)


--- 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)
@@ -69,6 +69,8 @@
         m_lowMemoryHandler = handler;
     }
 
+    void jettisonExpensiveObjectsOnTopLevelNavigation();
+
     bool isUnderMemoryPressure() const { return m_underMemoryPressure; }
     void setUnderMemoryPressure(bool b) { m_underMemoryPressure = b; }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to