Commit 1ecc9304 authored by haraken@chromium.org's avatar haraken@chromium.org

Oilpan: Give a chance to schedule a precise GC after V8 minor and major GCs

I manually created more than 80 Chromium builds with various GC parameters and investigated a way to reduce the peak memory increase in memory.top_7_stress. This CL reduces the peak memory of Blogger by 6%, WordPress by 3% etc.

This CL does the following two things:

- Finish completeSweep() before starting a V8 minor GC.
- Give a chance to schedule a precise GC after V8 minor and major GCs.

BUG=474470

Review URL: https://codereview.chromium.org/1308163003

git-svn-id: svn://svn.chromium.org/blink/trunk@201050 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent e94b1849
......@@ -335,10 +335,14 @@ void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags)
{
// FIXME: It would be nice if the GC callbacks passed the Isolate directly....
v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (type == v8::kGCTypeScavenge)
if (type == v8::kGCTypeScavenge) {
// Finish Oilpan's complete sweeping before running a V8 minor GC.
// This will let the minor GC collect more V8 objects.
ThreadState::current()->completeSweep();
minorGCPrologue(isolate);
else if (type == v8::kGCTypeMarkSweepCompact)
} else if (type == v8::kGCTypeMarkSweepCompact) {
majorGCPrologue(isolate, flags & v8::kGCCallbackFlagConstructRetainedObjectInfos);
}
}
void V8GCController::minorGCPrologue(v8::Isolate* isolate)
......@@ -386,8 +390,11 @@ void V8GCController::gcEpilogue(v8::GCType type, v8::GCCallbackFlags flags)
v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (type == v8::kGCTypeScavenge) {
minorGCEpilogue(isolate);
ThreadState::current()->scheduleV8FollowupGCIfNeeded();
} else if (type == v8::kGCTypeMarkSweepCompact) {
majorGCEpilogue(isolate);
} else if (type == v8::kGCTypeProcessWeakCallbacks) {
ThreadState::current()->scheduleV8FollowupGCIfNeeded();
}
// v8::kGCCallbackFlagForced forces a Blink heap garbage collection
......@@ -429,22 +436,6 @@ void V8GCController::majorGCEpilogue(v8::Isolate* isolate)
if (isMainThread()) {
TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(V8PerIsolateData::from(isolate)->previousSamplingState());
ScriptForbiddenScope::exit();
// Schedule an Oilpan GC to avoid the following scenario:
// (1) A DOM object X holds a v8::Persistent to a V8 object.
// Assume that X is small but the V8 object is huge.
// The v8::Persistent is released when X is destructed.
// (2) X's DOM wrapper is created.
// (3) The DOM wrapper becomes unreachable.
// (4) V8 triggers a GC. The V8's GC collects the DOM wrapper.
// However, X is not collected until a next Oilpan's GC is
// triggered.
// (5) If a lot of such DOM objects are created, we end up with
// a situation where V8's GC collects the DOM wrappers but
// the DOM objects are not collected forever. (Note that
// Oilpan's GC is not triggered unless Oilpan's heap gets full.)
// (6) V8 hits OOM.
ThreadState::current()->scheduleGCIfNeeded();
}
}
......
......@@ -657,6 +657,11 @@ bool ThreadState::shouldSchedulePreciseGC()
#endif
}
bool ThreadState::shouldScheduleV8FollowupGC()
{
return judgeGCThreshold(32 * 1024 * 1024, 1.5);
}
bool ThreadState::shouldSchedulePageNavigationGC(float estimatedRemovalRatio)
{
return judgeGCThreshold(1024 * 1024, 1.5 * (1 - estimatedRemovalRatio));
......@@ -668,6 +673,21 @@ bool ThreadState::shouldForceConservativeGC()
return judgeGCThreshold(32 * 1024 * 1024, 5.0);
}
void ThreadState::scheduleV8FollowupGCIfNeeded()
{
ASSERT(checkThread());
if (isGCForbidden())
return;
if (isSweepingInProgress())
return;
ASSERT(!sweepForbidden());
Heap::reportMemoryUsageForTracing();
if (shouldScheduleV8FollowupGC())
schedulePreciseGC();
}
void ThreadState::schedulePageNavigationGCIfNeeded(float estimatedRemovalRatio)
{
ASSERT(checkThread());
......
......@@ -328,6 +328,7 @@ public:
void scheduleIdleGC();
void scheduleIdleLazySweep();
void schedulePreciseGC();
void scheduleV8FollowupGCIfNeeded();
void schedulePageNavigationGCIfNeeded(float estimatedRemovalRatio);
void schedulePageNavigationGC();
void scheduleGCIfNeeded();
......@@ -689,6 +690,11 @@ private:
bool shouldScheduleIdleGC();
bool shouldSchedulePreciseGC();
bool shouldForceConservativeGC();
// V8 minor or major GC is likely to drop a lot of references to objects
// on Oilpan's heap. We give a chance to schedule a GC.
bool shouldScheduleV8FollowupGC();
// Page navigation is likely to drop a lot of references to objects
// on Oilpan's heap. We give a chance to schedule a GC.
// estimatedRemovalRatio is the estimated ratio of objects that will be no
// longer necessary due to the navigation.
bool shouldSchedulePageNavigationGC(float estimatedRemovalRatio);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment