| Index: Source/bindings/core/v8/V8GCController.cpp
|
| diff --git a/Source/bindings/core/v8/V8GCController.cpp b/Source/bindings/core/v8/V8GCController.cpp
|
| index bf361334920664bf898ae1406214fc46c64510b5..ba589ea30307203035121e798cf4ac257028703a 100644
|
| --- a/Source/bindings/core/v8/V8GCController.cpp
|
| +++ b/Source/bindings/core/v8/V8GCController.cpp
|
| @@ -394,9 +394,26 @@ void V8GCController::gcEpilogue(v8::GCType type, v8::GCCallbackFlags flags)
|
| minorGCEpilogue(isolate);
|
| } else if (type == v8::kGCTypeMarkSweepCompact) {
|
| majorGCEpilogue(isolate);
|
| - ThreadState::current()->didV8MajorGC(forceGC);
|
| + if (!forceGC)
|
| + ThreadState::current()->didV8MajorGC();
|
| }
|
|
|
| + if (forceGC) {
|
| + // This single GC is not enough for two reasons:
|
| + // (1) The GC is not precise because the GC scans on-stack pointers conservatively.
|
| + // (2) One GC is not enough to break a chain of persistent handles. It's possible that
|
| + // some heap allocated objects own objects that contain persistent handles
|
| + // pointing to other heap allocated objects. To break the chain, we need multiple GCs.
|
| + //
|
| + // Regarding (1), we force a precise GC at the end of the current event loop. So if you want
|
| + // to collect all garbage, you need to wait until the next event loop.
|
| + // Regarding (2), it would be OK in practice to trigger only one GC per gcEpilogue, because
|
| + // GCController.collectAll() forces 7 V8's GC.
|
| + Heap::collectGarbage(ThreadState::HeapPointersOnStack, ThreadState::GCWithSweep, Heap::ForcedGC);
|
| +
|
| + // Forces a precise GC at the end of the current event loop.
|
| + ThreadState::current()->setGCState(ThreadState::FullGCScheduled);
|
| + }
|
| TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data());
|
| }
|
|
|
|
|