Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(620)

Side by Side Diff: runtime/vm/pages.cc

Issue 2217833003: Fix for issue 25954. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Tweak the heap growth a bit for the case when there is garbage and we decide to grow by heap_growth… Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 grow_heap_); 1146 grow_heap_);
1147 } 1147 }
1148 return needs_gc; 1148 return needs_gc;
1149 } 1149 }
1150 1150
1151 1151
1152 void PageSpaceController::EvaluateGarbageCollection( 1152 void PageSpaceController::EvaluateGarbageCollection(
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 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 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 intptr_t garbage = before.used_in_words - after.used_in_words; 1163 ASSERT(allocated_since_previous_gc > 0);
1164 double k = garbage / static_cast<double>(allocated_since_previous_gc); 1164 const intptr_t garbage = before.used_in_words - after.used_in_words;
1165 heap_->RecordData(PageSpace::kGarbageRatio, static_cast<int>(k * 100)); 1165 ASSERT(garbage >= 0);
1166 const double k = garbage / static_cast<double>(allocated_since_previous_gc);
1167 const int garbage_ratio = static_cast<int>(k * 100);
1168 heap_->RecordData(PageSpace::kGarbageRatio, garbage_ratio);
1166 1169
1167 // 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.
1168 double t = 1.0 - desired_utilization_; 1171 double t = 1.0 - desired_utilization_;
1169 // 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.
1170 if (gc_time_fraction > garbage_collection_time_ratio_) { 1173 if (gc_time_fraction > garbage_collection_time_ratio_) {
1171 t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0; 1174 t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0;
1172 } 1175 }
1173 1176
1174 // Find minimum 'grow_heap_' such that after increasing capacity by 1177 const intptr_t grow_ratio = (
1175 // 'grow_heap_' pages and filling them, we expect a GC to be worthwhile. 1178 static_cast<intptr_t>(after.capacity_in_words / desired_utilization_) -
1176 for (grow_heap_ = 0; grow_heap_ < heap_growth_max_; ++grow_heap_) { 1179 after.capacity_in_words) / PageSpace::kPageSizeInWords;
1177 intptr_t limit = 1180 if (garbage_ratio == 0) {
1178 after.capacity_in_words + (grow_heap_ * PageSpace::kPageSizeInWords); 1181 // No garbage in the previous cycle so it would be hard to compute a
1179 intptr_t allocated_before_next_gc = limit - after.used_in_words; 1182 // grow_heap_ size based on estimated garbage so we use growth ratio
1180 double estimated_garbage = k * allocated_before_next_gc; 1183 // heuristics instead.
1181 if (t <= estimated_garbage / limit) { 1184 grow_heap_ = Utils::Maximum(static_cast<intptr_t>(heap_growth_max_),
1182 break; 1185 grow_ratio);
1186 } else {
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.
1189 intptr_t max = heap_growth_max_;
1190 intptr_t min = 0;
1191 intptr_t adjustment = 0;
1192 intptr_t local_grow_heap = 0;
1193 while (min < max) {
1194 local_grow_heap = (max + min) / 2;
1195 const intptr_t limit =
1196 after.capacity_in_words + (grow_heap_ * PageSpace::kPageSizeInWords);
1197 const intptr_t allocated_before_next_gc = limit - after.used_in_words;
1198 const double estimated_garbage = k * allocated_before_next_gc;
1199 if (t <= estimated_garbage / limit) {
1200 max = local_grow_heap - 1;
1201 adjustment = -1;
1202 } else {
1203 min = local_grow_heap + 1;
1204 adjustment = 1;
1205 }
1206 }
1207 grow_heap_ = local_grow_heap + adjustment;
1208 ASSERT(grow_heap_ >= 0);
1209 // If we are going to grow by heap_grow_max_ then ensure that we
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;
1183 } 1213 }
1184 } 1214 }
1185 heap_->RecordData(PageSpace::kPageGrowth, grow_heap_); 1215 heap_->RecordData(PageSpace::kPageGrowth, grow_heap_);
1186 1216
1187 // Limit shrinkage: allow growth by at least half the pages freed by GC. 1217 // Limit shrinkage: allow growth by at least half the pages freed by GC.
1188 intptr_t freed_pages = 1218 const intptr_t freed_pages =
1189 (before.capacity_in_words - after.capacity_in_words) / 1219 (before.capacity_in_words - after.capacity_in_words) /
1190 PageSpace::kPageSizeInWords; 1220 PageSpace::kPageSizeInWords;
1191 grow_heap_ = Utils::Maximum(grow_heap_, freed_pages / 2); 1221 grow_heap_ = Utils::Maximum(grow_heap_, freed_pages / 2);
1192 heap_->RecordData(PageSpace::kAllowedGrowth, grow_heap_); 1222 heap_->RecordData(PageSpace::kAllowedGrowth, grow_heap_);
1193 last_usage_ = after; 1223 last_usage_ = after;
1194 } 1224 }
1195 1225
1196 1226
1197 void PageSpaceGarbageCollectionHistory:: 1227 void PageSpaceGarbageCollectionHistory::
1198 AddGarbageCollectionTime(int64_t start, int64_t end) { 1228 AddGarbageCollectionTime(int64_t start, int64_t end) {
(...skipping 17 matching lines...) Expand all
1216 return 0; 1246 return 0;
1217 } else { 1247 } else {
1218 ASSERT(total_time >= gc_time); 1248 ASSERT(total_time >= gc_time);
1219 int result = static_cast<int>((static_cast<double>(gc_time) / 1249 int result = static_cast<int>((static_cast<double>(gc_time) /
1220 static_cast<double>(total_time)) * 100); 1250 static_cast<double>(total_time)) * 100);
1221 return result; 1251 return result;
1222 } 1252 }
1223 } 1253 }
1224 1254
1225 } // namespace dart 1255 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698