gc-idle-time-handler.h revision 958fae7ec3f466955f8e5b50fa5b8d38b9e91675
1// Copyright 2014 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef V8_HEAP_GC_IDLE_TIME_HANDLER_H_ 6#define V8_HEAP_GC_IDLE_TIME_HANDLER_H_ 7 8#include "src/globals.h" 9 10namespace v8 { 11namespace internal { 12 13enum GCIdleTimeActionType { 14 DONE, 15 DO_NOTHING, 16 DO_INCREMENTAL_MARKING, 17 DO_SCAVENGE, 18 DO_FULL_GC, 19 DO_FINALIZE_SWEEPING 20}; 21 22 23class GCIdleTimeAction { 24 public: 25 static GCIdleTimeAction Done() { 26 GCIdleTimeAction result; 27 result.type = DONE; 28 result.parameter = 0; 29 result.additional_work = false; 30 return result; 31 } 32 33 static GCIdleTimeAction Nothing() { 34 GCIdleTimeAction result; 35 result.type = DO_NOTHING; 36 result.parameter = 0; 37 result.additional_work = false; 38 return result; 39 } 40 41 static GCIdleTimeAction IncrementalMarking(intptr_t step_size) { 42 GCIdleTimeAction result; 43 result.type = DO_INCREMENTAL_MARKING; 44 result.parameter = step_size; 45 result.additional_work = false; 46 return result; 47 } 48 49 static GCIdleTimeAction Scavenge() { 50 GCIdleTimeAction result; 51 result.type = DO_SCAVENGE; 52 result.parameter = 0; 53 result.additional_work = false; 54 return result; 55 } 56 57 static GCIdleTimeAction FullGC() { 58 GCIdleTimeAction result; 59 result.type = DO_FULL_GC; 60 result.parameter = 0; 61 result.additional_work = false; 62 return result; 63 } 64 65 static GCIdleTimeAction FinalizeSweeping() { 66 GCIdleTimeAction result; 67 result.type = DO_FINALIZE_SWEEPING; 68 result.parameter = 0; 69 result.additional_work = false; 70 return result; 71 } 72 73 void Print(); 74 75 GCIdleTimeActionType type; 76 intptr_t parameter; 77 bool additional_work; 78}; 79 80 81class GCTracer; 82 83// The idle time handler makes decisions about which garbage collection 84// operations are executing during IdleNotification. 85class GCIdleTimeHandler { 86 public: 87 // If we haven't recorded any incremental marking events yet, we carefully 88 // mark with a conservative lower bound for the marking speed. 89 static const size_t kInitialConservativeMarkingSpeed = 100 * KB; 90 91 // Maximum marking step size returned by EstimateMarkingStepSize. 92 static const size_t kMaximumMarkingStepSize = 700 * MB; 93 94 // We have to make sure that we finish the IdleNotification before 95 // idle_time_in_ms. Hence, we conservatively prune our workload estimate. 96 static const double kConservativeTimeRatio; 97 98 // If we haven't recorded any mark-compact events yet, we use 99 // conservative lower bound for the mark-compact speed. 100 static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB; 101 102 // If we haven't recorded any final incremental mark-compact events yet, we 103 // use conservative lower bound for the mark-compact speed. 104 static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed = 105 2 * MB; 106 107 // Maximum mark-compact time returned by EstimateMarkCompactTime. 108 static const size_t kMaxMarkCompactTimeInMs; 109 110 // Maximum final incremental mark-compact time returned by 111 // EstimateFinalIncrementalMarkCompactTime. 112 static const size_t kMaxFinalIncrementalMarkCompactTimeInMs; 113 114 // Minimum time to finalize sweeping phase. The main thread may wait for 115 // sweeper threads. 116 static const size_t kMinTimeForFinalizeSweeping; 117 118 // Number of idle mark-compact events, after which idle handler will finish 119 // idle round. 120 static const int kMaxMarkCompactsInIdleRound; 121 122 // Number of scavenges that will trigger start of new idle round. 123 static const int kIdleScavengeThreshold; 124 125 // That is the maximum idle time we will have during frame rendering. 126 static const size_t kMaxFrameRenderingIdleTime = 16; 127 128 // If we haven't recorded any scavenger events yet, we use a conservative 129 // lower bound for the scavenger speed. 130 static const size_t kInitialConservativeScavengeSpeed = 100 * KB; 131 132 // If contexts are disposed at a higher rate a full gc is triggered. 133 static const double kHighContextDisposalRate; 134 135 // Incremental marking step time. 136 static const size_t kIncrementalMarkingStepTimeInMs = 1; 137 138 class HeapState { 139 public: 140 void Print(); 141 142 int contexts_disposed; 143 double contexts_disposal_rate; 144 size_t size_of_objects; 145 bool incremental_marking_stopped; 146 bool can_start_incremental_marking; 147 bool sweeping_in_progress; 148 size_t mark_compact_speed_in_bytes_per_ms; 149 size_t incremental_marking_speed_in_bytes_per_ms; 150 size_t final_incremental_mark_compact_speed_in_bytes_per_ms; 151 size_t scavenge_speed_in_bytes_per_ms; 152 size_t used_new_space_size; 153 size_t new_space_capacity; 154 size_t new_space_allocation_throughput_in_bytes_per_ms; 155 }; 156 157 GCIdleTimeHandler() 158 : mark_compacts_since_idle_round_started_(0), 159 scavenges_since_last_idle_round_(0) {} 160 161 GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state); 162 163 void NotifyIdleMarkCompact() { 164 if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) { 165 ++mark_compacts_since_idle_round_started_; 166 if (mark_compacts_since_idle_round_started_ == 167 kMaxMarkCompactsInIdleRound) { 168 scavenges_since_last_idle_round_ = 0; 169 } 170 } 171 } 172 173 void NotifyScavenge() { ++scavenges_since_last_idle_round_; } 174 175 static size_t EstimateMarkingStepSize(size_t idle_time_in_ms, 176 size_t marking_speed_in_bytes_per_ms); 177 178 static size_t EstimateMarkCompactTime( 179 size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms); 180 181 static size_t EstimateFinalIncrementalMarkCompactTime( 182 size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms); 183 184 static bool ShouldDoMarkCompact(size_t idle_time_in_ms, 185 size_t size_of_objects, 186 size_t mark_compact_speed_in_bytes_per_ms); 187 188 static bool ShouldDoContextDisposalMarkCompact(int context_disposed, 189 double contexts_disposal_rate); 190 191 static bool ShouldDoFinalIncrementalMarkCompact( 192 size_t idle_time_in_ms, size_t size_of_objects, 193 size_t final_incremental_mark_compact_speed_in_bytes_per_ms); 194 195 static bool ShouldDoScavenge( 196 size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size, 197 size_t scavenger_speed_in_bytes_per_ms, 198 size_t new_space_allocation_throughput_in_bytes_per_ms); 199 200 private: 201 void StartIdleRound() { mark_compacts_since_idle_round_started_ = 0; } 202 bool IsMarkCompactIdleRoundFinished() { 203 return mark_compacts_since_idle_round_started_ == 204 kMaxMarkCompactsInIdleRound; 205 } 206 bool EnoughGarbageSinceLastIdleRound() { 207 return scavenges_since_last_idle_round_ >= kIdleScavengeThreshold; 208 } 209 210 int mark_compacts_since_idle_round_started_; 211 int scavenges_since_last_idle_round_; 212 213 DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler); 214}; 215 216} // namespace internal 217} // namespace v8 218 219#endif // V8_HEAP_GC_IDLE_TIME_HANDLER_H_ 220