| 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/address_sanitizer.h" | 7 #include "platform/address_sanitizer.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/compiler_stats.h" | 9 #include "vm/compiler_stats.h" |
| 10 #include "vm/gc_marker.h" | 10 #include "vm/gc_marker.h" |
| (...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 const int garbage_ratio = static_cast<int>(k * 100); | 1196 const int garbage_ratio = static_cast<int>(k * 100); |
| 1197 heap_->RecordData(PageSpace::kGarbageRatio, garbage_ratio); | 1197 heap_->RecordData(PageSpace::kGarbageRatio, garbage_ratio); |
| 1198 | 1198 |
| 1199 // Define GC to be 'worthwhile' iff at least fraction t of heap is garbage. | 1199 // Define GC to be 'worthwhile' iff at least fraction t of heap is garbage. |
| 1200 double t = 1.0 - desired_utilization_; | 1200 double t = 1.0 - desired_utilization_; |
| 1201 // If we spend too much time in GC, strive for even more free space. | 1201 // If we spend too much time in GC, strive for even more free space. |
| 1202 if (gc_time_fraction > garbage_collection_time_ratio_) { | 1202 if (gc_time_fraction > garbage_collection_time_ratio_) { |
| 1203 t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0; | 1203 t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0; |
| 1204 } | 1204 } |
| 1205 | 1205 |
| 1206 const intptr_t grow_ratio = | 1206 // Number of pages we can allocate and still be within the desired growth |
| 1207 // ratio. |
| 1208 const intptr_t grow_pages = |
| 1207 (static_cast<intptr_t>(after.capacity_in_words / desired_utilization_) - | 1209 (static_cast<intptr_t>(after.capacity_in_words / desired_utilization_) - |
| 1208 after.capacity_in_words) / | 1210 after.capacity_in_words) / |
| 1209 PageSpace::kPageSizeInWords; | 1211 PageSpace::kPageSizeInWords; |
| 1210 if (garbage_ratio == 0) { | 1212 if (garbage_ratio == 0) { |
| 1211 // No garbage in the previous cycle so it would be hard to compute a | 1213 // No garbage in the previous cycle so it would be hard to compute a |
| 1212 // grow_heap_ size based on estimated garbage so we use growth ratio | 1214 // grow_heap_ size based on estimated garbage so we use growth ratio |
| 1213 // heuristics instead. | 1215 // heuristics instead. |
| 1214 grow_heap_ = | 1216 grow_heap_ = |
| 1215 Utils::Maximum(static_cast<intptr_t>(heap_growth_max_), grow_ratio); | 1217 Utils::Maximum(static_cast<intptr_t>(heap_growth_max_), grow_pages); |
| 1216 } else { | 1218 } else { |
| 1217 // Find minimum 'grow_heap_' such that after increasing capacity by | 1219 // Find minimum 'grow_heap_' such that after increasing capacity by |
| 1218 // 'grow_heap_' pages and filling them, we expect a GC to be worthwhile. | 1220 // 'grow_heap_' pages and filling them, we expect a GC to be worthwhile. |
| 1219 intptr_t max = heap_growth_max_; | 1221 intptr_t max = heap_growth_max_; |
| 1220 intptr_t min = 0; | 1222 intptr_t min = 0; |
| 1221 intptr_t local_grow_heap = 0; | 1223 intptr_t local_grow_heap = 0; |
| 1222 while (min < max) { | 1224 while (min < max) { |
| 1223 local_grow_heap = (max + min) / 2; | 1225 local_grow_heap = (max + min) / 2; |
| 1224 const intptr_t limit = after.capacity_in_words + | 1226 const intptr_t limit = after.capacity_in_words + |
| 1225 (local_grow_heap * PageSpace::kPageSizeInWords); | 1227 (local_grow_heap * PageSpace::kPageSizeInWords); |
| 1226 const intptr_t allocated_before_next_gc = limit - after.used_in_words; | 1228 const intptr_t allocated_before_next_gc = limit - after.used_in_words; |
| 1227 const double estimated_garbage = k * allocated_before_next_gc; | 1229 const double estimated_garbage = k * allocated_before_next_gc; |
| 1228 if (t <= estimated_garbage / limit) { | 1230 if (t <= estimated_garbage / limit) { |
| 1229 max = local_grow_heap - 1; | 1231 max = local_grow_heap - 1; |
| 1230 } else { | 1232 } else { |
| 1231 min = local_grow_heap + 1; | 1233 min = local_grow_heap + 1; |
| 1232 } | 1234 } |
| 1233 } | 1235 } |
| 1234 local_grow_heap = (max + min) / 2; | 1236 local_grow_heap = (max + min) / 2; |
| 1235 grow_heap_ = local_grow_heap; | 1237 grow_heap_ = local_grow_heap; |
| 1236 ASSERT(grow_heap_ >= 0); | 1238 ASSERT(grow_heap_ >= 0); |
| 1237 // If we are going to grow by heap_grow_max_ then ensure that we | 1239 // If we are going to grow by heap_grow_max_ then ensure that we |
| 1238 // will be growing the heap at least by the growth ratio heuristics. | 1240 // will be growing the heap at least by the growth ratio heuristics. |
| 1239 if (grow_heap_ >= heap_growth_max_) { | 1241 if (grow_heap_ >= heap_growth_max_) { |
| 1240 grow_heap_ = Utils::Maximum(grow_ratio, grow_heap_); | 1242 grow_heap_ = Utils::Maximum(grow_pages, grow_heap_); |
| 1241 } | 1243 } |
| 1242 } | 1244 } |
| 1243 } else { | 1245 } else { |
| 1244 heap_->RecordData(PageSpace::kGarbageRatio, 100); | 1246 heap_->RecordData(PageSpace::kGarbageRatio, 100); |
| 1245 grow_heap_ = 0; | 1247 grow_heap_ = 0; |
| 1246 } | 1248 } |
| 1247 heap_->RecordData(PageSpace::kPageGrowth, grow_heap_); | 1249 heap_->RecordData(PageSpace::kPageGrowth, grow_heap_); |
| 1248 | 1250 |
| 1249 // Limit shrinkage: allow growth by at least half the pages freed by GC. | 1251 // Limit shrinkage: allow growth by at least half the pages freed by GC. |
| 1250 const intptr_t freed_pages = | 1252 const intptr_t freed_pages = |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1276 return 0; | 1278 return 0; |
| 1277 } else { | 1279 } else { |
| 1278 ASSERT(total_time >= gc_time); | 1280 ASSERT(total_time >= gc_time); |
| 1279 int result = static_cast<int>( | 1281 int result = static_cast<int>( |
| 1280 (static_cast<double>(gc_time) / static_cast<double>(total_time)) * 100); | 1282 (static_cast<double>(gc_time) / static_cast<double>(total_time)) * 100); |
| 1281 return result; | 1283 return result; |
| 1282 } | 1284 } |
| 1283 } | 1285 } |
| 1284 | 1286 |
| 1285 } // namespace dart | 1287 } // namespace dart |
| OLD | NEW |