Title: [180192] trunk/Source/WebCore
- Revision
- 180192
- Author
- akl...@apple.com
- Date
- 2015-02-16 17:06:45 -0800 (Mon, 16 Feb 2015)
Log Message
GC (almost) immediately when navigating under memory pressure.
<https://webkit.org/b/141663>
Reviewed by Geoffrey Garen.
Since the PageCache is already disabled in memory pressure situations,
we know that detaching the old window shell on navigation is basically
guaranteed to generate a bunch of garbage, we can soften the memory
peak a bit by doing a GC right away instead of scheduling one for soon(tm).
* bindings/js/GCController.cpp:
(WebCore::GCController::GCController):
(WebCore::GCController::garbageCollectSoon):
(WebCore::GCController::garbageCollectOnNextRunLoop):
(WebCore::GCController::gcTimerFired):
* bindings/js/GCController.h:
Add a GCController::garbageCollectOnNextRunLoop() complement to the
"soon" and "now" options. There was already a zero timer in here for
non-CF builds, so I just used that same timer to implement this
and have the non-CF code path call garbageCollectOnNextRunLoop().
* bindings/js/ScriptController.cpp:
(WebCore::collectGarbageAfterWindowShellDestruction):
(WebCore::ScriptController::~ScriptController):
(WebCore::ScriptController::clearWindowShell):
Under system memory pressure conditions, schedule a full GC on next
runloop iteration instead of just asking for it to happen soon.
We do it on next runloop to ensure that there's no pointer to the
window object on the stack.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (180191 => 180192)
--- trunk/Source/WebCore/ChangeLog 2015-02-17 01:05:28 UTC (rev 180191)
+++ trunk/Source/WebCore/ChangeLog 2015-02-17 01:06:45 UTC (rev 180192)
@@ -1,3 +1,37 @@
+2015-02-16 Andreas Kling <akl...@apple.com>
+
+ GC (almost) immediately when navigating under memory pressure.
+ <https://webkit.org/b/141663>
+
+ Reviewed by Geoffrey Garen.
+
+ Since the PageCache is already disabled in memory pressure situations,
+ we know that detaching the old window shell on navigation is basically
+ guaranteed to generate a bunch of garbage, we can soften the memory
+ peak a bit by doing a GC right away instead of scheduling one for soon(tm).
+
+ * bindings/js/GCController.cpp:
+ (WebCore::GCController::GCController):
+ (WebCore::GCController::garbageCollectSoon):
+ (WebCore::GCController::garbageCollectOnNextRunLoop):
+ (WebCore::GCController::gcTimerFired):
+ * bindings/js/GCController.h:
+
+ Add a GCController::garbageCollectOnNextRunLoop() complement to the
+ "soon" and "now" options. There was already a zero timer in here for
+ non-CF builds, so I just used that same timer to implement this
+ and have the non-CF code path call garbageCollectOnNextRunLoop().
+
+ * bindings/js/ScriptController.cpp:
+ (WebCore::collectGarbageAfterWindowShellDestruction):
+ (WebCore::ScriptController::~ScriptController):
+ (WebCore::ScriptController::clearWindowShell):
+
+ Under system memory pressure conditions, schedule a full GC on next
+ runloop iteration instead of just asking for it to happen soon.
+ We do it on next runloop to ensure that there's no pointer to the
+ window object on the stack.
+
2015-02-16 Enrica Casucci <enr...@apple.com>
Emoji sequences do not render properly.
Modified: trunk/Source/WebCore/bindings/js/GCController.cpp (180191 => 180192)
--- trunk/Source/WebCore/bindings/js/GCController.cpp 2015-02-17 01:05:28 UTC (rev 180191)
+++ trunk/Source/WebCore/bindings/js/GCController.cpp 2015-02-17 01:06:45 UTC (rev 180192)
@@ -50,9 +50,7 @@
}
GCController::GCController()
-#if !USE(CF)
: m_GCTimer(*this, &GCController::gcTimerFired)
-#endif
{
}
@@ -67,17 +65,20 @@
JSLockHolder lock(JSDOMWindow::commonVM());
JSDOMWindow::commonVM().heap.reportAbandonedObjectGraph();
#else
+ garbageCollectOnNextRunLoop();
+#endif
+}
+
+void GCController::garbageCollectOnNextRunLoop()
+{
if (!m_GCTimer.isActive())
m_GCTimer.startOneShot(0);
-#endif
}
-#if !USE(CF)
void GCController::gcTimerFired()
{
collect(nullptr);
}
-#endif
void GCController::garbageCollectNow()
{
Modified: trunk/Source/WebCore/bindings/js/GCController.h (180191 => 180192)
--- trunk/Source/WebCore/bindings/js/GCController.h 2015-02-17 01:05:28 UTC (rev 180191)
+++ trunk/Source/WebCore/bindings/js/GCController.h 2015-02-17 01:06:45 UTC (rev 180192)
@@ -26,12 +26,9 @@
#ifndef GCController_h
#define GCController_h
-#if USE(CF)
#include <wtf/FastMalloc.h>
#include <wtf/Noncopyable.h>
-#else
#include "Timer.h"
-#endif
namespace WebCore {
@@ -42,6 +39,7 @@
public:
WEBCORE_EXPORT void garbageCollectSoon();
WEBCORE_EXPORT void garbageCollectNow(); // It's better to call garbageCollectSoon, unless you have a specific reason not to.
+ void garbageCollectOnNextRunLoop();
WEBCORE_EXPORT void garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone); // Used for stress testing.
WEBCORE_EXPORT void releaseExecutableMemory();
@@ -51,10 +49,8 @@
private:
GCController(); // Use gcController() instead
-#if !USE(CF)
void gcTimerFired();
Timer m_GCTimer;
-#endif
};
// Function to obtain the global GC controller.
Modified: trunk/Source/WebCore/bindings/js/ScriptController.cpp (180191 => 180192)
--- trunk/Source/WebCore/bindings/js/ScriptController.cpp 2015-02-17 01:05:28 UTC (rev 180191)
+++ trunk/Source/WebCore/bindings/js/ScriptController.cpp 2015-02-17 01:06:45 UTC (rev 180192)
@@ -35,6 +35,7 @@
#include "JSDocument.h"
#include "JSMainThreadExecState.h"
#include "MainFrame.h"
+#include "MemoryPressureHandler.h"
#include "NP_jsobject.h"
#include "Page.h"
#include "PageConsoleClient.h"
@@ -60,6 +61,18 @@
namespace WebCore {
+static void collectGarbageAfterWindowShellDestruction()
+{
+ // Make sure to GC Extra Soon(tm) during memory pressure conditions
+ // to soften high peaks of memory usage during navigation.
+ if (memoryPressureHandler().isUnderMemoryPressure()) {
+ // NOTE: We do the collection on next runloop to ensure that there's no pointer
+ // to the window object on the stack.
+ gcController().garbageCollectOnNextRunLoop();
+ } else
+ gcController().garbageCollectSoon();
+}
+
void ScriptController::initializeThreading()
{
#if !PLATFORM(IOS)
@@ -98,7 +111,7 @@
iter->value->window()->setConsoleClient(nullptr);
destroyWindowShell(*iter->key);
}
- gcController().garbageCollectSoon();
+ collectGarbageAfterWindowShellDestruction();
}
}
@@ -227,7 +240,7 @@
// It's likely that resetting our windows created a lot of garbage, unless
// it went in a back/forward cache.
if (!goingIntoPageCache)
- gcController().garbageCollectSoon();
+ collectGarbageAfterWindowShellDestruction();
}
JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld& world)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes