Skip to content
Permalink
Browse files
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.


Canonical link: https://commits.webkit.org/159702@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@180192 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Andreas Kling committed Feb 17, 2015
1 parent 4109539 commit fd966e763cf5bc6e8c9ef153faee0551ac67cf7e
Showing with 56 additions and 12 deletions.
  1. +34 −0 Source/WebCore/ChangeLog
  2. +6 −5 Source/WebCore/bindings/js/GCController.cpp
  3. +1 −5 Source/WebCore/bindings/js/GCController.h
  4. +15 −2 Source/WebCore/bindings/js/ScriptController.cpp
@@ -1,3 +1,37 @@
2015-02-16 Andreas Kling <akling@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 <enrica@apple.com>

Emoji sequences do not render properly.
@@ -50,9 +50,7 @@ GCController& gcController()
}

GCController::GCController()
#if !USE(CF)
: m_GCTimer(*this, &GCController::gcTimerFired)
#endif
{
}

@@ -67,17 +65,20 @@ void GCController::garbageCollectSoon()
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()
{
@@ -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 @@ namespace WebCore {
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 @@ namespace WebCore {
private:
GCController(); // Use gcController() instead

#if !USE(CF)
void gcTimerFired();
Timer m_GCTimer;
#endif
};

// Function to obtain the global GC controller.
@@ -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 @@ using namespace JSC;

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 @@ ScriptController::~ScriptController()
iter->value->window()->setConsoleClient(nullptr);
destroyWindowShell(*iter->key);
}
gcController().garbageCollectSoon();
collectGarbageAfterWindowShellDestruction();
}
}

@@ -227,7 +240,7 @@ void ScriptController::clearWindowShell(DOMWindow* newDOMWindow, bool goingIntoP
// 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)

0 comments on commit fd966e7

Please sign in to comment.