| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index 1c966b350d2aee49a480e56c4f1c53b8619f25bf..ab05f427df7a94b6f16c21cb2930cc3f58731022 100644
|
| --- a/src/heap/heap.cc
|
| +++ b/src/heap/heap.cc
|
| @@ -120,12 +120,7 @@ Heap::Heap()
|
| store_buffer_(this),
|
| marking_(this),
|
| incremental_marking_(this),
|
| - number_idle_notifications_(0),
|
| - last_idle_notification_gc_count_(0),
|
| - last_idle_notification_gc_count_init_(false),
|
| - mark_sweeps_since_idle_round_started_(0),
|
| gc_count_at_last_idle_gc_(0),
|
| - scavenges_since_last_idle_round_(kIdleScavengeThreshold),
|
| full_codegen_bytes_generated_(0),
|
| crankshaft_codegen_bytes_generated_(0),
|
| gcs_since_last_deopt_(0),
|
| @@ -1559,7 +1554,7 @@ void Heap::Scavenge() {
|
|
|
| gc_state_ = NOT_IN_GC;
|
|
|
| - scavenges_since_last_idle_round_++;
|
| + gc_idle_time_handler_.NotifyScavenge();
|
| }
|
|
|
|
|
| @@ -4264,12 +4259,7 @@ void Heap::MakeHeapIterable() {
|
| }
|
|
|
|
|
| -void Heap::AdvanceIdleIncrementalMarking(int idle_time_in_ms) {
|
| - intptr_t step_size =
|
| - static_cast<size_t>(GCIdleTimeHandler::EstimateMarkingStepSize(
|
| - idle_time_in_ms,
|
| - tracer_.IncrementalMarkingSpeedInBytesPerMillisecond()));
|
| -
|
| +void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
|
| incremental_marking()->Step(step_size,
|
| IncrementalMarking::NO_GC_VIA_STACK_GUARD, true);
|
|
|
| @@ -4282,7 +4272,7 @@ void Heap::AdvanceIdleIncrementalMarking(int idle_time_in_ms) {
|
| }
|
| CollectAllGarbage(kReduceMemoryFootprintMask,
|
| "idle notification: finalize incremental");
|
| - mark_sweeps_since_idle_round_started_++;
|
| + gc_idle_time_handler_.NotifyIdleMarkCompact();
|
| gc_count_at_last_idle_gc_ = gc_count_;
|
| if (uncommit) {
|
| new_space_.Shrink();
|
| @@ -4295,83 +4285,49 @@ void Heap::AdvanceIdleIncrementalMarking(int idle_time_in_ms) {
|
| bool Heap::IdleNotification(int idle_time_in_ms) {
|
| // If incremental marking is off, we do not perform idle notification.
|
| if (!FLAG_incremental_marking) return true;
|
| -
|
| - // Minimal hint that allows to do full GC.
|
| - const int kMinHintForFullGC = 100;
|
| isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
|
| idle_time_in_ms);
|
| HistogramTimerScope idle_notification_scope(
|
| isolate_->counters()->gc_idle_notification());
|
|
|
| - if (contexts_disposed_ > 0) {
|
| - contexts_disposed_ = 0;
|
| - int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000);
|
| - if (idle_time_in_ms >= mark_sweep_time && !FLAG_expose_gc &&
|
| - incremental_marking()->IsStopped()) {
|
| + GCIdleTimeAction action = gc_idle_time_handler_.Compute(
|
| + idle_time_in_ms, contexts_disposed_, static_cast<size_t>(SizeOfObjects()),
|
| + incremental_marking()->IsStopped(), tracer());
|
| + contexts_disposed_ = 0;
|
| + bool result = false;
|
| + switch (action.type) {
|
| + case DO_INCREMENTAL_MARKING:
|
| + if (incremental_marking()->IsStopped()) {
|
| + incremental_marking()->Start();
|
| + }
|
| + AdvanceIdleIncrementalMarking(action.parameter);
|
| + break;
|
| + case DO_FULL_GC: {
|
| HistogramTimerScope scope(isolate_->counters()->gc_context());
|
| - CollectAllGarbage(kReduceMemoryFootprintMask,
|
| - "idle notification: contexts disposed");
|
| - } else {
|
| - AdvanceIdleIncrementalMarking(idle_time_in_ms);
|
| - }
|
| -
|
| - // After context disposal there is likely a lot of garbage remaining, reset
|
| - // the idle notification counters in order to trigger more incremental GCs
|
| - // on subsequent idle notifications.
|
| - StartIdleRound();
|
| - return false;
|
| - }
|
| -
|
| - // By doing small chunks of GC work in each IdleNotification,
|
| - // perform a round of incremental GCs and after that wait until
|
| - // the mutator creates enough garbage to justify a new round.
|
| - // An incremental GC progresses as follows:
|
| - // 1. many incremental marking steps,
|
| - // 2. one old space mark-sweep-compact,
|
| - // Use mark-sweep-compact events to count incremental GCs in a round.
|
| -
|
| - if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
|
| - if (EnoughGarbageSinceLastIdleRound()) {
|
| - StartIdleRound();
|
| - } else {
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - int remaining_mark_sweeps =
|
| - kMaxMarkSweepsInIdleRound - mark_sweeps_since_idle_round_started_;
|
| -
|
| - if (incremental_marking()->IsStopped()) {
|
| - // If there are no more than two GCs left in this idle round and we are
|
| - // allowed to do a full GC, then make those GCs full in order to compact
|
| - // the code space.
|
| - // TODO(ulan): Once we enable code compaction for incremental marking,
|
| - // we can get rid of this special case and always start incremental marking.
|
| - if (remaining_mark_sweeps <= 2 && idle_time_in_ms >= kMinHintForFullGC) {
|
| - CollectAllGarbage(kReduceMemoryFootprintMask,
|
| - "idle notification: finalize idle round");
|
| - mark_sweeps_since_idle_round_started_++;
|
| - } else {
|
| - incremental_marking()->Start();
|
| + const char* message = contexts_disposed_
|
| + ? "idle notification: contexts disposed"
|
| + : "idle notification: finalize idle round";
|
| + CollectAllGarbage(kReduceMemoryFootprintMask, message);
|
| + gc_idle_time_handler_.NotifyIdleMarkCompact();
|
| + break;
|
| }
|
| + case DO_SCAVENGE:
|
| + CollectGarbage(NEW_SPACE, "idle notification: scavenge");
|
| + break;
|
| + case DO_NOTHING:
|
| + result = true;
|
| + break;
|
| }
|
| - if (!incremental_marking()->IsStopped()) {
|
| - AdvanceIdleIncrementalMarking(idle_time_in_ms);
|
| - }
|
| -
|
| - if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) {
|
| - FinishIdleRound();
|
| - return true;
|
| - }
|
| -
|
| // If the IdleNotifcation is called with a large hint we will wait for
|
| // the sweepter threads here.
|
| + // TODO(ulan): move this in GCIdleTimeHandler.
|
| + const int kMinHintForFullGC = 100;
|
| if (idle_time_in_ms >= kMinHintForFullGC &&
|
| mark_compact_collector()->sweeping_in_progress()) {
|
| mark_compact_collector()->EnsureSweepingCompleted();
|
| }
|
|
|
| - return false;
|
| + return result;
|
| }
|
|
|
|
|
|
|