| Index: src/heap/gc-idle-time-handler.h
|
| diff --git a/src/heap/gc-idle-time-handler.h b/src/heap/gc-idle-time-handler.h
|
| index ed89b8bc770a07aac81313ddc21ce8487c67565d..ebb3b1cd857ddd9d6a17ae3478cc4c7a7f2e75cb 100644
|
| --- a/src/heap/gc-idle-time-handler.h
|
| +++ b/src/heap/gc-idle-time-handler.h
|
| @@ -27,6 +27,7 @@ class GCIdleTimeAction {
|
| result.type = DONE;
|
| result.parameter = 0;
|
| result.additional_work = false;
|
| + result.reduce_memory = false;
|
| return result;
|
| }
|
|
|
| @@ -35,14 +36,17 @@ class GCIdleTimeAction {
|
| result.type = DO_NOTHING;
|
| result.parameter = 0;
|
| result.additional_work = false;
|
| + result.reduce_memory = false;
|
| return result;
|
| }
|
|
|
| - static GCIdleTimeAction IncrementalMarking(intptr_t step_size) {
|
| + static GCIdleTimeAction IncrementalMarking(intptr_t step_size,
|
| + bool reduce_memory) {
|
| GCIdleTimeAction result;
|
| result.type = DO_INCREMENTAL_MARKING;
|
| result.parameter = step_size;
|
| result.additional_work = false;
|
| + result.reduce_memory = reduce_memory;
|
| return result;
|
| }
|
|
|
| @@ -51,14 +55,18 @@ class GCIdleTimeAction {
|
| result.type = DO_SCAVENGE;
|
| result.parameter = 0;
|
| result.additional_work = false;
|
| + // TODO(ulan): add reduce_memory argument and shrink new space size if
|
| + // reduce_memory = true.
|
| + result.reduce_memory = false;
|
| return result;
|
| }
|
|
|
| - static GCIdleTimeAction FullGC() {
|
| + static GCIdleTimeAction FullGC(bool reduce_memory) {
|
| GCIdleTimeAction result;
|
| result.type = DO_FULL_GC;
|
| result.parameter = 0;
|
| result.additional_work = false;
|
| + result.reduce_memory = reduce_memory;
|
| return result;
|
| }
|
|
|
| @@ -67,6 +75,7 @@ class GCIdleTimeAction {
|
| result.type = DO_FINALIZE_SWEEPING;
|
| result.parameter = 0;
|
| result.additional_work = false;
|
| + result.reduce_memory = false;
|
| return result;
|
| }
|
|
|
| @@ -75,6 +84,7 @@ class GCIdleTimeAction {
|
| GCIdleTimeActionType type;
|
| intptr_t parameter;
|
| bool additional_work;
|
| + bool reduce_memory;
|
| };
|
|
|
|
|
| @@ -111,13 +121,6 @@ class GCIdleTimeHandler {
|
| // EstimateFinalIncrementalMarkCompactTime.
|
| static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
|
|
|
| - // Number of idle mark-compact events, after which idle handler will finish
|
| - // idle round.
|
| - static const int kMaxMarkCompactsInIdleRound;
|
| -
|
| - // Number of scavenges that will trigger start of new idle round.
|
| - static const int kIdleScavengeThreshold;
|
| -
|
| // This is the maximum scheduled idle time. Note that it can be more than
|
| // 16.66 ms when there is currently no rendering going on.
|
| static const size_t kMaxScheduledIdleTime = 50;
|
| @@ -141,10 +144,22 @@ class GCIdleTimeHandler {
|
|
|
| static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
|
|
|
| - // Number of times we will return a Nothing action per Idle round despite
|
| - // having idle time available before we returning a Done action to ensure we
|
| - // don't keep scheduling idle tasks and making no progress.
|
| - static const int kMaxNoProgressIdleTimesPerIdleRound = 10;
|
| + // The number of idle MarkCompact GCs to perform before transitioning to
|
| + // the kDone mode.
|
| + static const int kMaxIdleMarkCompacts = 3;
|
| +
|
| + // The number of mutator GCs before transitioning to the kReduceLatency mode.
|
| + static const int kGCsBeforeMutatorIsActive = 7;
|
| +
|
| + // Mutator is considered idle if
|
| + // 1) there is an idle notification with time >= kLargeLongIdleTime,
|
| + // 2) or there are kLongIdleNotificationsBeforeMutatorIsIdle idle
|
| + // notifications
|
| + // with time >= kMinLongIdleTime and without any mutator GC in between.
|
| + static const int kMinLongIdleTime = kMaxFrameRenderingIdleTime + 1;
|
| + static const int kLargeLongIdleTime = 900;
|
| + static const int kLongIdleNotificationsBeforeMutatorIsIdle = 20;
|
| +
|
|
|
| class HeapState {
|
| public:
|
| @@ -167,23 +182,19 @@ class GCIdleTimeHandler {
|
| };
|
|
|
| GCIdleTimeHandler()
|
| - : mark_compacts_since_idle_round_started_(0),
|
| - scavenges_since_last_idle_round_(0),
|
| - idle_times_which_made_no_progress_since_last_idle_round_(0) {}
|
| + : idle_mark_compacts_(0),
|
| + mark_compacts_(0),
|
| + scavenges_(0),
|
| + long_idle_notifications_(0),
|
| + mode_(kReduceLatency) {}
|
|
|
| GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state);
|
|
|
| - void NotifyIdleMarkCompact() {
|
| - if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) {
|
| - ++mark_compacts_since_idle_round_started_;
|
| - if (mark_compacts_since_idle_round_started_ ==
|
| - kMaxMarkCompactsInIdleRound) {
|
| - scavenges_since_last_idle_round_ = 0;
|
| - }
|
| - }
|
| - }
|
| + void NotifyIdleMarkCompact() { ++idle_mark_compacts_; }
|
|
|
| - void NotifyScavenge() { ++scavenges_since_last_idle_round_; }
|
| + void NotifyMarkCompact() { ++mark_compacts_; }
|
| +
|
| + void NotifyScavenge() { ++scavenges_; }
|
|
|
| static size_t EstimateMarkingStepSize(size_t idle_time_in_ms,
|
| size_t marking_speed_in_bytes_per_ms);
|
| @@ -212,24 +223,27 @@ class GCIdleTimeHandler {
|
| size_t scavenger_speed_in_bytes_per_ms,
|
| size_t new_space_allocation_throughput_in_bytes_per_ms);
|
|
|
| - private:
|
| - GCIdleTimeAction NothingOrDone();
|
| + enum Mode { kReduceLatency, kReduceMemory, kDone };
|
|
|
| - void StartIdleRound() {
|
| - mark_compacts_since_idle_round_started_ = 0;
|
| - idle_times_which_made_no_progress_since_last_idle_round_ = 0;
|
| - }
|
| - bool IsMarkCompactIdleRoundFinished() {
|
| - return mark_compacts_since_idle_round_started_ ==
|
| - kMaxMarkCompactsInIdleRound;
|
| - }
|
| - bool EnoughGarbageSinceLastIdleRound() {
|
| - return scavenges_since_last_idle_round_ >= kIdleScavengeThreshold;
|
| - }
|
| + Mode mode() { return mode_; }
|
|
|
| - int mark_compacts_since_idle_round_started_;
|
| - int scavenges_since_last_idle_round_;
|
| - int idle_times_which_made_no_progress_since_last_idle_round_;
|
| + private:
|
| + bool IsMutatorActive(int contexts_disposed, int gcs);
|
| + bool IsMutatorIdle(int long_idle_notifications, int gcs);
|
| + void UpdateCounters(double idle_time_in_ms);
|
| + void ResetCounters();
|
| + Mode NextMode(const HeapState& heap_state);
|
| + GCIdleTimeAction Action(double idle_time_in_ms, const HeapState& heap_state,
|
| + bool reduce_memory);
|
| +
|
| + int idle_mark_compacts_;
|
| + int mark_compacts_;
|
| + int scavenges_;
|
| + // The number of long idle notifications with no mutator GC happening
|
| + // between the notifications.
|
| + int long_idle_notifications_;
|
| +
|
| + Mode mode_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
|
| };
|
|
|