namespace internal {
const double GCIdleTimeHandler::kConservativeTimeRatio = 0.9;
-const size_t GCIdleTimeHandler::kMaxMarkCompactTimeInMs = 1000000;
size_t GCIdleTimeHandler::EstimateMarkingStepSize(
if (marking_step_size > kMaximumMarkingStepSize)
return kMaximumMarkingStepSize;
- return static_cast<size_t>(marking_step_size *
- GCIdleTimeHandler::kConservativeTimeRatio);
+ return static_cast<size_t>(marking_step_size * kConservativeTimeRatio);
}
}
-GCIdleTimeAction GCIdleTimeHandler::Compute(int idle_time_in_ms,
+GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
HeapState heap_state,
GCTracer* gc_tracer) {
if (IsIdleRoundFinished()) {
if (heap_state.incremental_marking_stopped) {
size_t speed =
static_cast<size_t>(gc_tracer->MarkCompactSpeedInBytesPerMillisecond());
- if (idle_time_in_ms >= static_cast<int>(EstimateMarkCompactTime(
- heap_state.size_of_objects, speed))) {
+ if (idle_time_in_ms >=
+ EstimateMarkCompactTime(heap_state.size_of_objects, speed)) {
// 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.
return GCIdleTimeAction::Nothing();
}
}
+ // TODO(hpayer): Estimate finalize sweeping time.
+ if (heap_state.sweeping_in_progress &&
+ idle_time_in_ms >= kMinTimeForFinalizeSweeping) {
+ return GCIdleTimeAction::FinalizeSweeping();
+ }
+
intptr_t speed = gc_tracer->IncrementalMarkingSpeedInBytesPerMillisecond();
size_t step_size =
static_cast<size_t>(EstimateMarkingStepSize(idle_time_in_ms, speed));
DO_NOTHING,
DO_INCREMENTAL_MARKING,
DO_SCAVENGE,
- DO_FULL_GC
+ DO_FULL_GC,
+ DO_FINALIZE_SWEEPING
};
result.parameter = 0;
return result;
}
+
static GCIdleTimeAction IncrementalMarking(intptr_t step_size) {
GCIdleTimeAction result;
result.type = DO_INCREMENTAL_MARKING;
result.parameter = step_size;
return result;
}
+
static GCIdleTimeAction Scavenge() {
GCIdleTimeAction result;
result.type = DO_SCAVENGE;
result.parameter = 0;
return result;
}
+
static GCIdleTimeAction FullGC() {
GCIdleTimeAction result;
result.type = DO_FULL_GC;
return result;
}
+ static GCIdleTimeAction FinalizeSweeping() {
+ GCIdleTimeAction result;
+ result.type = DO_FINALIZE_SWEEPING;
+ result.parameter = 0;
+ return result;
+ }
+
GCIdleTimeActionType type;
intptr_t parameter;
};
static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
// Maximum mark-compact time returned by EstimateMarkCompactTime.
- static const size_t kMaxMarkCompactTimeInMs;
+ static const size_t kMaxMarkCompactTimeInMs = 1000000;
+
+ // Minimum time to finalize sweeping phase. The main thread may wait for
+ // sweeper threads.
+ static const size_t kMinTimeForFinalizeSweeping = 100;
struct HeapState {
int contexts_disposed;
size_t size_of_objects;
bool incremental_marking_stopped;
bool can_start_incremental_marking;
+ bool sweeping_in_progress;
};
GCIdleTimeHandler()
: mark_compacts_since_idle_round_started_(0),
scavenges_since_last_idle_round_(0) {}
- GCIdleTimeAction Compute(int idle_time_in_ms, HeapState heap_state,
+ GCIdleTimeAction Compute(size_t idle_time_in_ms, HeapState heap_state,
GCTracer* gc_tracer);
void NotifyIdleMarkCompact() {
heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
// TODO(ulan): Start incremental marking only for large heaps.
heap_state.can_start_incremental_marking = true;
+ heap_state.sweeping_in_progress =
+ mark_compact_collector()->sweeping_in_progress();
GCIdleTimeAction action =
gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state, tracer());
case DO_SCAVENGE:
CollectGarbage(NEW_SPACE, "idle notification: scavenge");
break;
+ case DO_FINALIZE_SWEEPING:
+ mark_compact_collector()->EnsureSweepingCompleted();
case DO_NOTHING:
result = true;
break;
}
- // 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 result;
}