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)
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....
v8::Isolate* isolate = v8::Isolate::GetCurrent();
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) {
majorGCPrologue(isolate, flags & v8::kGCCallbackFlagConstructRetainedObjectInfos);
}
ASSERT(isMainThread());
MinorGCWrapperVisitor visitor(isolate);
v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
visitor.notifyFinished();
}
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()) {
ScriptForbiddenScope::enter();
{
TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMMinorGC");
v8::HandleScope scope(isolate);
MinorGCWrapperVisitor visitor(isolate);
v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
visitor.notifyFinished();
TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMMajorGC");
objectGroupingForMajorGC(isolate, constructRetainedObjectInfos);
}
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()) {
ScriptForbiddenScope::enter();
{
TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMMajorGC");
MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos);
v8::V8::VisitHandlesWithClassIds(isolate, &visitor);
visitor.notifyFinished();
}
// TODO(haraken): It would be nice if the GC callbacks passed the Isolate
// directly.
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());
TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8MajorGC");
} else {
MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos);
v8::V8::VisitHandlesWithClassIds(isolate, &visitor);
visitor.notifyFinished();
break;
case v8::kGCTypeMarkSweepCompact:
TRACE_EVENT_BEGIN2("devtools.timeline,v8", "MajorGC", "usedHeapSizeBefore", usedHeapSize(isolate), "type", "atomic pause");
gcPrologueForMajorGC(isolate, flags & v8::kGCCallbackFlagConstructRetainedObjectInfos);
break;
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)
{
// 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();
if (type == v8::kGCTypeScavenge) {
minorGCEpilogue(isolate);
switch (type) {
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();
} else if (type == v8::kGCTypeMarkSweepCompact) {
majorGCEpilogue(isolate);
} else if (type == v8::kGCTypeProcessWeakCallbacks) {
break;
case v8::kGCTypeMarkSweepCompact:
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();
break;
default:
ASSERT_NOT_REACHED();
}
if (isMainThread())
ScriptForbiddenScope::exit();
// v8::kGCCallbackFlagForced forces a Blink heap garbage collection
// when a garbage collection was forced from V8. This is either used
// 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)
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)
{
v8::HandleScope handleScope(isolate);
......
......@@ -45,10 +45,6 @@ class CORE_EXPORT V8GCController {
public:
static void gcPrologue(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*);
......
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