Commit 405c082a authored by haraken@chromium.org's avatar haraken@chromium.org

Bindings: Distinguish four types of V8 GC callbacks

After landing https://codereview.chromium.org/1298113003/, we have four types
of GC callbacks:

- A callback for a minor GC
- A callback for incremental marking of a major GC
- A callback for atomic pause of a major GC
- A callback for weak processing

This CL distinguishes the four types of GC callbacks in V8GCController::gcPrologue/gcEpilogue.

This CL basically just moves code around. No substantial changes in behavior.

BUG=521946

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

git-svn-id: svn://svn.chromium.org/blink/trunk@201098 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent cb4809f7
...@@ -331,72 +331,124 @@ static unsigned long long usedHeapSize(v8::Isolate* isolate) ...@@ -331,72 +331,124 @@ static unsigned long long usedHeapSize(v8::Isolate* isolate)
return heapStatistics.used_heap_size(); return heapStatistics.used_heap_size();
} }
void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags) namespace {
void objectGroupingForMinorGC(v8::Isolate* isolate)
{ {
// FIXME: It would be nice if the GC callbacks passed the Isolate directly.... ASSERT(isMainThread());
v8::Isolate* isolate = v8::Isolate::GetCurrent(); MinorGCWrapperVisitor visitor(isolate);
if (type == v8::kGCTypeScavenge) { v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
// Finish Oilpan's complete sweeping before running a V8 minor GC. visitor.notifyFinished();
// This will let the minor GC collect more V8 objects.
ThreadState::current()->completeSweep();
minorGCPrologue(isolate);
} else if (type == v8::kGCTypeMarkSweepCompact) {
majorGCPrologue(isolate, flags & v8::kGCCallbackFlagConstructRetainedObjectInfos);
}
} }
void V8GCController::minorGCPrologue(v8::Isolate* isolate) void objectGroupingForMajorGC(v8::Isolate* isolate, bool constructRetainedObjectInfos)
{
MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos);
v8::V8::VisitHandlesWithClassIds(isolate, &visitor);
visitor.notifyFinished();
}
void gcPrologueForMajorGC(v8::Isolate* isolate, bool constructRetainedObjectInfos)
{ {
TRACE_EVENT_BEGIN1("devtools.timeline,v8", "MinorGC", "usedHeapSizeBefore", usedHeapSize(isolate));
if (isMainThread()) { if (isMainThread()) {
ScriptForbiddenScope::enter();
{ {
TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMMinorGC"); TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMMajorGC");
v8::HandleScope scope(isolate); objectGroupingForMajorGC(isolate, constructRetainedObjectInfos);
MinorGCWrapperVisitor visitor(isolate);
v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
visitor.notifyFinished();
} }
V8PerIsolateData::from(isolate)->setPreviousSamplingState(TRACE_EVENT_GET_SAMPLING_STATE()); V8PerIsolateData::from(isolate)->setPreviousSamplingState(TRACE_EVENT_GET_SAMPLING_STATE());
TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8MinorGC"); TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8MajorGC");
} else {
objectGroupingForMajorGC(isolate, constructRetainedObjectInfos);
} }
} }
// Create object groups for DOM tree nodes. }
void V8GCController::majorGCPrologue(v8::Isolate* isolate, bool constructRetainedObjectInfos)
void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags)
{ {
v8::HandleScope scope(isolate);
TRACE_EVENT_BEGIN1("devtools.timeline,v8", "MajorGC", "usedHeapSizeBefore", usedHeapSize(isolate));
if (isMainThread()) { if (isMainThread()) {
ScriptForbiddenScope::enter(); ScriptForbiddenScope::enter();
{ }
TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMMajorGC");
MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos); // TODO(haraken): It would be nice if the GC callbacks passed the Isolate
v8::V8::VisitHandlesWithClassIds(isolate, &visitor); // directly.
visitor.notifyFinished(); v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope scope(isolate);
switch (type) {
case 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();
TRACE_EVENT_BEGIN1("devtools.timeline,v8", "MinorGC", "usedHeapSizeBefore", usedHeapSize(isolate));
if (isMainThread()) {
{
TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMMinorGC");
objectGroupingForMinorGC(isolate);
}
V8PerIsolateData::from(isolate)->setPreviousSamplingState(TRACE_EVENT_GET_SAMPLING_STATE());
TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8MinorGC");
} }
V8PerIsolateData::from(isolate)->setPreviousSamplingState(TRACE_EVENT_GET_SAMPLING_STATE()); break;
TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8MajorGC"); case v8::kGCTypeMarkSweepCompact:
} else { TRACE_EVENT_BEGIN2("devtools.timeline,v8", "MajorGC", "usedHeapSizeBefore", usedHeapSize(isolate), "type", "atomic pause");
MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos); gcPrologueForMajorGC(isolate, flags & v8::kGCCallbackFlagConstructRetainedObjectInfos);
v8::V8::VisitHandlesWithClassIds(isolate, &visitor); break;
visitor.notifyFinished(); case v8::kGCTypeIncrementalMarking:
TRACE_EVENT_BEGIN2("devtools.timeline,v8", "MajorGC", "usedHeapSizeBefore", usedHeapSize(isolate), "type", "incremental marking");
gcPrologueForMajorGC(isolate, flags & v8::kGCCallbackFlagConstructRetainedObjectInfos);
break;
case v8::kGCTypeProcessWeakCallbacks:
TRACE_EVENT_BEGIN2("devtools.timeline,v8", "MajorGC", "usedHeapSizeBefore", usedHeapSize(isolate), "type", "weak processing");
if (isMainThread()) {
V8PerIsolateData::from(isolate)->setPreviousSamplingState(TRACE_EVENT_GET_SAMPLING_STATE());
TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMMajorGC");
}
break;
default:
ASSERT_NOT_REACHED();
} }
} }
void V8GCController::gcEpilogue(v8::GCType type, v8::GCCallbackFlags flags) void V8GCController::gcEpilogue(v8::GCType type, v8::GCCallbackFlags flags)
{ {
// FIXME: It would be nice if the GC callbacks passed the Isolate directly.... // TODO(haraken): It would be nice if the GC callbacks passed the Isolate
// directly.
v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (type == v8::kGCTypeScavenge) { switch (type) {
minorGCEpilogue(isolate); case v8::kGCTypeScavenge:
TRACE_EVENT_END1("devtools.timeline,v8", "MinorGC", "usedHeapSizeAfter", usedHeapSize(isolate));
if (isMainThread()) {
TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(V8PerIsolateData::from(isolate)->previousSamplingState());
}
ThreadState::current()->scheduleV8FollowupGCIfNeeded(); ThreadState::current()->scheduleV8FollowupGCIfNeeded();
} else if (type == v8::kGCTypeMarkSweepCompact) { break;
majorGCEpilogue(isolate); case v8::kGCTypeMarkSweepCompact:
} else if (type == v8::kGCTypeProcessWeakCallbacks) { TRACE_EVENT_END1("devtools.timeline,v8", "MajorGC", "usedHeapSizeAfter", usedHeapSize(isolate));
if (isMainThread()) {
TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(V8PerIsolateData::from(isolate)->previousSamplingState());
}
break;
case v8::kGCTypeIncrementalMarking:
TRACE_EVENT_END1("devtools.timeline,v8", "MajorGC", "usedHeapSizeAfter", usedHeapSize(isolate));
if (isMainThread()) {
TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(V8PerIsolateData::from(isolate)->previousSamplingState());
}
break;
case v8::kGCTypeProcessWeakCallbacks:
TRACE_EVENT_END1("devtools.timeline,v8", "MajorGC", "usedHeapSizeAfter", usedHeapSize(isolate));
if (isMainThread()) {
TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(V8PerIsolateData::from(isolate)->previousSamplingState());
}
ThreadState::current()->scheduleV8FollowupGCIfNeeded(); ThreadState::current()->scheduleV8FollowupGCIfNeeded();
break;
default:
ASSERT_NOT_REACHED();
} }
if (isMainThread())
ScriptForbiddenScope::exit();
// v8::kGCCallbackFlagForced forces a Blink heap garbage collection // v8::kGCCallbackFlagForced forces a Blink heap garbage collection
// when a garbage collection was forced from V8. This is either used // when a garbage collection was forced from V8. This is either used
// for tests that force GCs from JavaScript to verify that objects die // for tests that force GCs from JavaScript to verify that objects die
...@@ -421,24 +473,6 @@ void V8GCController::gcEpilogue(v8::GCType type, v8::GCCallbackFlags flags) ...@@ -421,24 +473,6 @@ void V8GCController::gcEpilogue(v8::GCType type, v8::GCCallbackFlags flags)
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data()); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data());
} }
void V8GCController::minorGCEpilogue(v8::Isolate* isolate)
{
TRACE_EVENT_END1("devtools.timeline,v8", "MinorGC", "usedHeapSizeAfter", usedHeapSize(isolate));
if (isMainThread()) {
TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(V8PerIsolateData::from(isolate)->previousSamplingState());
ScriptForbiddenScope::exit();
}
}
void V8GCController::majorGCEpilogue(v8::Isolate* isolate)
{
TRACE_EVENT_END1("devtools.timeline,v8", "MajorGC", "usedHeapSizeAfter", usedHeapSize(isolate));
if (isMainThread()) {
TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(V8PerIsolateData::from(isolate)->previousSamplingState());
ScriptForbiddenScope::exit();
}
}
void V8GCController::collectGarbage(v8::Isolate* isolate) void V8GCController::collectGarbage(v8::Isolate* isolate)
{ {
v8::HandleScope handleScope(isolate); v8::HandleScope handleScope(isolate);
......
...@@ -45,10 +45,6 @@ class CORE_EXPORT V8GCController { ...@@ -45,10 +45,6 @@ class CORE_EXPORT V8GCController {
public: public:
static void gcPrologue(v8::GCType, v8::GCCallbackFlags); static void gcPrologue(v8::GCType, v8::GCCallbackFlags);
static void gcEpilogue(v8::GCType, v8::GCCallbackFlags); static void gcEpilogue(v8::GCType, v8::GCCallbackFlags);
static void minorGCPrologue(v8::Isolate*);
static void minorGCEpilogue(v8::Isolate*);
static void majorGCPrologue(v8::Isolate*, bool constructRetainedObjectInfos);
static void majorGCEpilogue(v8::Isolate*);
static void collectGarbage(v8::Isolate*); static void collectGarbage(v8::Isolate*);
......
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