OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/pages.h" | 5 #include "vm/pages.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/compiler_stats.h" | 8 #include "vm/compiler_stats.h" |
9 #include "vm/gc_marker.h" | 9 #include "vm/gc_marker.h" |
10 #include "vm/gc_sweeper.h" | 10 #include "vm/gc_sweeper.h" |
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1153 SpaceUsage before, SpaceUsage after, int64_t start, int64_t end) { | 1153 SpaceUsage before, SpaceUsage after, int64_t start, int64_t end) { |
1154 ASSERT(end >= start); | 1154 ASSERT(end >= start); |
1155 history_.AddGarbageCollectionTime(start, end); | 1155 history_.AddGarbageCollectionTime(start, end); |
1156 const int gc_time_fraction = history_.GarbageCollectionTimeFraction(); | 1156 const int gc_time_fraction = history_.GarbageCollectionTimeFraction(); |
1157 heap_->RecordData(PageSpace::kGCTimeFraction, gc_time_fraction); | 1157 heap_->RecordData(PageSpace::kGCTimeFraction, gc_time_fraction); |
1158 | 1158 |
1159 // Assume garbage increases linearly with allocation: | 1159 // Assume garbage increases linearly with allocation: |
1160 // G = kA, and estimate k from the previous cycle. | 1160 // G = kA, and estimate k from the previous cycle. |
1161 const intptr_t allocated_since_previous_gc = | 1161 const intptr_t allocated_since_previous_gc = |
1162 before.used_in_words - last_usage_.used_in_words; | 1162 before.used_in_words - last_usage_.used_in_words; |
1163 ASSERT(allocated_since_previous_gc > 0); | 1163 if (allocated_since_previous_gc > 0) { |
1164 const intptr_t garbage = before.used_in_words - after.used_in_words; | 1164 const intptr_t garbage = before.used_in_words - after.used_in_words; |
1165 ASSERT(garbage >= 0); | 1165 ASSERT(garbage >= 0); |
1166 const double k = garbage / static_cast<double>(allocated_since_previous_gc); | 1166 const double k = garbage / static_cast<double>(allocated_since_previous_gc); |
1167 const int garbage_ratio = static_cast<int>(k * 100); | 1167 const int garbage_ratio = static_cast<int>(k * 100); |
1168 heap_->RecordData(PageSpace::kGarbageRatio, garbage_ratio); | 1168 heap_->RecordData(PageSpace::kGarbageRatio, garbage_ratio); |
1169 | 1169 |
1170 // Define GC to be 'worthwhile' iff at least fraction t of heap is garbage. | 1170 // Define GC to be 'worthwhile' iff at least fraction t of heap is garbage. |
1171 double t = 1.0 - desired_utilization_; | 1171 double t = 1.0 - desired_utilization_; |
1172 // If we spend too much time in GC, strive for even more free space. | 1172 // If we spend too much time in GC, strive for even more free space. |
1173 if (gc_time_fraction > garbage_collection_time_ratio_) { | 1173 if (gc_time_fraction > garbage_collection_time_ratio_) { |
1174 t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0; | 1174 t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0; |
1175 } | 1175 } |
1176 | 1176 |
1177 const intptr_t grow_ratio = ( | 1177 const intptr_t grow_ratio = ( |
1178 static_cast<intptr_t>(after.capacity_in_words / desired_utilization_) - | 1178 static_cast<intptr_t>(after.capacity_in_words / desired_utilization_) - |
1179 after.capacity_in_words) / PageSpace::kPageSizeInWords; | 1179 after.capacity_in_words) / PageSpace::kPageSizeInWords; |
1180 if (garbage_ratio == 0) { | 1180 if (garbage_ratio == 0) { |
1181 // No garbage in the previous cycle so it would be hard to compute a | 1181 // No garbage in the previous cycle so it would be hard to compute a |
1182 // grow_heap_ size based on estimated garbage so we use growth ratio | 1182 // grow_heap_ size based on estimated garbage so we use growth ratio |
1183 // heuristics instead. | 1183 // heuristics instead. |
1184 grow_heap_ = Utils::Maximum(static_cast<intptr_t>(heap_growth_max_), | 1184 grow_heap_ = Utils::Maximum(static_cast<intptr_t>(heap_growth_max_), |
1185 grow_ratio); | 1185 grow_ratio); |
1186 } else { | 1186 } else { |
1187 // Find minimum 'grow_heap_' such that after increasing capacity by | 1187 // Find minimum 'grow_heap_' such that after increasing capacity by |
1188 // 'grow_heap_' pages and filling them, we expect a GC to be worthwhile. | 1188 // 'grow_heap_' pages and filling them, we expect a GC to be worthwhile. |
1189 intptr_t max = heap_growth_max_; | 1189 intptr_t max = heap_growth_max_; |
1190 intptr_t min = 0; | 1190 intptr_t min = 0; |
1191 intptr_t adjustment = 0; | 1191 intptr_t local_grow_heap = 0; |
1192 intptr_t local_grow_heap = 0; | 1192 while (min < max) { |
1193 while (min < max) { | 1193 local_grow_heap = (max + min) / 2; |
1194 local_grow_heap = (max + min) / 2; | 1194 const intptr_t limit = after.capacity_in_words + |
1195 const intptr_t limit = | 1195 (grow_heap_ * PageSpace::kPageSizeInWords); |
1196 after.capacity_in_words + (grow_heap_ * PageSpace::kPageSizeInWords); | 1196 const intptr_t allocated_before_next_gc = limit - after.used_in_words; |
1197 const intptr_t allocated_before_next_gc = limit - after.used_in_words; | 1197 const double estimated_garbage = k * allocated_before_next_gc; |
1198 const double estimated_garbage = k * allocated_before_next_gc; | 1198 if (t <= estimated_garbage / limit) { |
1199 if (t <= estimated_garbage / limit) { | 1199 max = local_grow_heap - 1; |
1200 max = local_grow_heap - 1; | 1200 } else { |
1201 adjustment = -1; | 1201 min = local_grow_heap + 1; |
1202 } else { | 1202 } |
1203 min = local_grow_heap + 1; | 1203 } |
1204 adjustment = 1; | 1204 grow_heap_ = local_grow_heap; |
| 1205 ASSERT(grow_heap_ >= 0); |
| 1206 // If we are going to grow by heap_grow_max_ then ensure that we |
| 1207 // will be growing the heap at least by the growth ratio heuristics. |
| 1208 if ((grow_heap_ == heap_growth_max_) && (grow_ratio > grow_heap_)) { |
| 1209 grow_heap_ = grow_ratio; |
1205 } | 1210 } |
1206 } | 1211 } |
1207 grow_heap_ = local_grow_heap + adjustment; | 1212 } else { |
1208 ASSERT(grow_heap_ >= 0); | 1213 heap_->RecordData(PageSpace::kGarbageRatio, 100); |
1209 // If we are going to grow by heap_grow_max_ then ensure that we | 1214 grow_heap_ = 0; |
1210 // will be growing the heap at least by the growth ratio heuristics. | |
1211 if ((grow_heap_ == heap_growth_max_) && (grow_ratio > grow_heap_)) { | |
1212 grow_heap_ = grow_ratio; | |
1213 } | |
1214 } | 1215 } |
1215 heap_->RecordData(PageSpace::kPageGrowth, grow_heap_); | 1216 heap_->RecordData(PageSpace::kPageGrowth, grow_heap_); |
1216 | 1217 |
1217 // Limit shrinkage: allow growth by at least half the pages freed by GC. | 1218 // Limit shrinkage: allow growth by at least half the pages freed by GC. |
1218 const intptr_t freed_pages = | 1219 const intptr_t freed_pages = |
1219 (before.capacity_in_words - after.capacity_in_words) / | 1220 (before.capacity_in_words - after.capacity_in_words) / |
1220 PageSpace::kPageSizeInWords; | 1221 PageSpace::kPageSizeInWords; |
1221 grow_heap_ = Utils::Maximum(grow_heap_, freed_pages / 2); | 1222 grow_heap_ = Utils::Maximum(grow_heap_, freed_pages / 2); |
1222 heap_->RecordData(PageSpace::kAllowedGrowth, grow_heap_); | 1223 heap_->RecordData(PageSpace::kAllowedGrowth, grow_heap_); |
1223 last_usage_ = after; | 1224 last_usage_ = after; |
(...skipping 22 matching lines...) Expand all Loading... |
1246 return 0; | 1247 return 0; |
1247 } else { | 1248 } else { |
1248 ASSERT(total_time >= gc_time); | 1249 ASSERT(total_time >= gc_time); |
1249 int result = static_cast<int>((static_cast<double>(gc_time) / | 1250 int result = static_cast<int>((static_cast<double>(gc_time) / |
1250 static_cast<double>(total_time)) * 100); | 1251 static_cast<double>(total_time)) * 100); |
1251 return result; | 1252 return result; |
1252 } | 1253 } |
1253 } | 1254 } |
1254 | 1255 |
1255 } // namespace dart | 1256 } // namespace dart |
OLD | NEW |