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

Side by Side Diff: src/heap/heap.cc

Issue 1163143009: Compute the heap growing factor based on mutator utilization and allocation throughput. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Comments Created 5 years, 6 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
« src/heap/gc-tracer.cc ('K') | « src/heap/heap.h ('k') | 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 } 1212 }
1213 1213
1214 if (collector == MARK_COMPACTOR) { 1214 if (collector == MARK_COMPACTOR) {
1215 UpdateOldGenerationAllocationCounter(); 1215 UpdateOldGenerationAllocationCounter();
1216 // Perform mark-sweep with optional compaction. 1216 // Perform mark-sweep with optional compaction.
1217 MarkCompact(); 1217 MarkCompact();
1218 sweep_generation_++; 1218 sweep_generation_++;
1219 old_gen_exhausted_ = false; 1219 old_gen_exhausted_ = false;
1220 old_generation_size_configured_ = true; 1220 old_generation_size_configured_ = true;
1221 // This should be updated before PostGarbageCollectionProcessing, which can 1221 // This should be updated before PostGarbageCollectionProcessing, which can
1222 // cause another GC. 1222 // cause another GC. Take into account the objects promoted during GC.
1223 old_generation_allocation_counter_ +=
1224 static_cast<size_t>(promoted_objects_size_);
1223 old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects(); 1225 old_generation_size_at_last_gc_ = PromotedSpaceSizeOfObjects();
1224 } else { 1226 } else {
1225 Scavenge(); 1227 Scavenge();
1226 } 1228 }
1227 1229
1228 1230
1229 UpdateSurvivalStatistics(start_new_space_size); 1231 UpdateSurvivalStatistics(start_new_space_size);
1230 ConfigureInitialOldGenerationSize(); 1232 ConfigureInitialOldGenerationSize();
1231 1233
1232 isolate_->counters()->objs_since_last_young()->Set(0); 1234 isolate_->counters()->objs_since_last_young()->Set(0);
(...skipping 21 matching lines...) Expand all
1254 1256
1255 isolate_->eternal_handles()->PostGarbageCollectionProcessing(this); 1257 isolate_->eternal_handles()->PostGarbageCollectionProcessing(this);
1256 1258
1257 // Update relocatables. 1259 // Update relocatables.
1258 Relocatable::PostGarbageCollectionProcessing(isolate_); 1260 Relocatable::PostGarbageCollectionProcessing(isolate_);
1259 1261
1260 if (collector == MARK_COMPACTOR) { 1262 if (collector == MARK_COMPACTOR) {
1261 // Register the amount of external allocated memory. 1263 // Register the amount of external allocated memory.
1262 amount_of_external_allocated_memory_at_last_global_gc_ = 1264 amount_of_external_allocated_memory_at_last_global_gc_ =
1263 amount_of_external_allocated_memory_; 1265 amount_of_external_allocated_memory_;
1264 SetOldGenerationAllocationLimit( 1266 double gc_speed = tracer()->CombinedMarkCompactSpeedInBytesPerMillisecond();
1265 PromotedSpaceSizeOfObjects(), 1267 double mutator_speed = static_cast<double>(
1266 tracer()->CurrentAllocationThroughputInBytesPerMillisecond()); 1268 tracer()
1269 ->CurrentOldGenerationAllocationThroughputInBytesPerMillisecond());
1270 intptr_t old_gen_size = PromotedSpaceSizeOfObjects();
1271 SetOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed);
1267 } 1272 }
1268 1273
1269 { 1274 {
1270 GCCallbacksScope scope(this); 1275 GCCallbacksScope scope(this);
1271 if (scope.CheckReenter()) { 1276 if (scope.CheckReenter()) {
1272 AllowHeapAllocation allow_allocation; 1277 AllowHeapAllocation allow_allocation;
1273 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); 1278 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
1274 VMState<EXTERNAL> state(isolate_); 1279 VMState<EXTERNAL> state(isolate_);
1275 HandleScope handle_scope(isolate_); 1280 HandleScope handle_scope(isolate_);
1276 CallGCEpilogueCallbacks(gc_type, gc_callback_flags); 1281 CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
(...skipping 4002 matching lines...) Expand 10 before | Expand all | Expand 10 after
5279 5284
5280 int64_t Heap::PromotedExternalMemorySize() { 5285 int64_t Heap::PromotedExternalMemorySize() {
5281 if (amount_of_external_allocated_memory_ <= 5286 if (amount_of_external_allocated_memory_ <=
5282 amount_of_external_allocated_memory_at_last_global_gc_) 5287 amount_of_external_allocated_memory_at_last_global_gc_)
5283 return 0; 5288 return 0;
5284 return amount_of_external_allocated_memory_ - 5289 return amount_of_external_allocated_memory_ -
5285 amount_of_external_allocated_memory_at_last_global_gc_; 5290 amount_of_external_allocated_memory_at_last_global_gc_;
5286 } 5291 }
5287 5292
5288 5293
5294 const double Heap::kMinHeapGrowingFactor = 1.1;
5295 const double Heap::kMaxHeapGrowingFactor = 4.0;
5296 const double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0;
5297 const double Heap::kMaxHeapGrowingFactorIdle = 1.5;
5298 const double Heap::kTargetMutatorUtilization = 0.97;
5299
5300
5301 // Given GC speed in bytes per ms, the allocation throughput in bytes per ms
5302 // (mutator speed), this functions returns the heap growing factor that will
5303 // achive the kTargetMutatorUtilisation if the GC speed and the mutator speed
5304 // remain the same until the next GC. For details and explanation see
5305 // https://goo.gl/LLGvBs.
Hannes Payer (out of office) 2015/06/11 01:33:57 Instead of posting a link, can we add the necessar
ulan 2015/06/11 08:49:37 Done.
5306 double Heap::HeapGrowingFactor(double gc_speed, double mutator_speed) {
5307 double max_factor = kMaxHeapGrowingFactor;
5308 // We set the old generation growing factor to 2 to grow the heap slower on
5309 // memory-constrained devices.
5310 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
Hannes Payer (out of office) 2015/06/11 01:33:57 If we would not access max_old_generation_size_, t
ulan 2015/06/11 08:49:37 Done. The first function to be unit-tested in Heap
5311 max_factor = kMaxHeapGrowingFactorMemoryConstrained;
5312 }
5313
5314 if (gc_speed == 0 || mutator_speed == 0) return max_factor;
5315
5316 const double speed_ratio = gc_speed / mutator_speed;
5317 const double mu = kTargetMutatorUtilization;
5318
5319 const double a = speed_ratio * (1 - mu);
5320 const double b = speed_ratio * (1 - mu) - mu;
5321
5322 // The factor is a / b, but we need to check for small b first.
5323 double factor = (a < b * max_factor) ? a / b : max_factor;
5324 factor = Min(factor, max_factor);
5325 factor = Max(factor, kMinHeapGrowingFactor);
5326 if (FLAG_trace_gc_verbose) {
5327 PrintIsolate(isolate_,
5328 "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f "
5329 "(gc=%.f, mutator=%.f)\n",
5330 factor, mu, speed_ratio, gc_speed, mutator_speed);
5331 }
5332 return factor;
5333 }
5334
5335
5289 intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor, 5336 intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor,
5290 intptr_t old_gen_size) { 5337 intptr_t old_gen_size) {
5291 CHECK(factor > 1.0); 5338 CHECK(factor > 1.0);
5292 CHECK(old_gen_size > 0); 5339 CHECK(old_gen_size > 0);
5293 intptr_t limit = static_cast<intptr_t>(old_gen_size * factor); 5340 intptr_t limit = static_cast<intptr_t>(old_gen_size * factor);
5294 limit = Max(limit, old_gen_size + kMinimumOldGenerationAllocationLimit); 5341 limit = Max(limit, old_gen_size + kMinimumOldGenerationAllocationLimit);
5295 limit += new_space_.Capacity(); 5342 limit += new_space_.Capacity();
5296 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2; 5343 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
5297 return Min(limit, halfway_to_the_max); 5344 return Min(limit, halfway_to_the_max);
5298 } 5345 }
5299 5346
5300 5347
5301 void Heap::SetOldGenerationAllocationLimit( 5348 void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
5302 intptr_t old_gen_size, size_t current_allocation_throughput) { 5349 double gc_speed,
5303 // Allocation throughput on Android devices is typically lower than on 5350 double mutator_speed) {
5304 // non-mobile devices. 5351 double factor = HeapGrowingFactor(gc_speed, mutator_speed);
5305 #if V8_OS_ANDROID
5306 const size_t kHighThroughput = 2500;
5307 const size_t kLowThroughput = 250;
5308 #else
5309 const size_t kHighThroughput = 10000;
5310 const size_t kLowThroughput = 1000;
5311 #endif
5312 const double min_scaling_factor = 1.1;
5313 const double max_scaling_factor = 1.5;
5314 double max_factor = 4;
5315 const double idle_max_factor = 1.5;
5316 // We set the old generation growing factor to 2 to grow the heap slower on
5317 // memory-constrained devices.
5318 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
5319 max_factor = 2;
5320 }
5321
5322 double factor;
5323 double idle_factor;
5324 if (current_allocation_throughput == 0 ||
5325 current_allocation_throughput >= kHighThroughput) {
5326 factor = max_factor;
5327 } else if (current_allocation_throughput <= kLowThroughput) {
5328 factor = min_scaling_factor;
5329 } else {
5330 // Compute factor using linear interpolation between points
5331 // (kHighThroughput, max_scaling_factor) and (kLowThroughput, min_factor).
5332 factor = min_scaling_factor +
5333 (current_allocation_throughput - kLowThroughput) *
5334 (max_scaling_factor - min_scaling_factor) /
5335 (kHighThroughput - kLowThroughput);
5336 }
5337 5352
5338 if (FLAG_stress_compaction || 5353 if (FLAG_stress_compaction ||
5339 mark_compact_collector()->reduce_memory_footprint_) { 5354 mark_compact_collector()->reduce_memory_footprint_) {
5340 factor = min_scaling_factor; 5355 factor = kMinHeapGrowingFactor;
5341 } 5356 }
5342 5357
5343 // TODO(hpayer): Investigate if idle_old_generation_allocation_limit_ is still 5358 // TODO(hpayer): Investigate if idle_old_generation_allocation_limit_ is still
5344 // needed after taking the allocation rate for the old generation limit into 5359 // needed after taking the allocation rate for the old generation limit into
5345 // account. 5360 // account.
5346 idle_factor = Min(factor, idle_max_factor); 5361 double idle_factor = Min(factor, kMaxHeapGrowingFactorIdle);
5347 5362
5348 old_generation_allocation_limit_ = 5363 old_generation_allocation_limit_ =
5349 CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5364 CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5350 idle_old_generation_allocation_limit_ = 5365 idle_old_generation_allocation_limit_ =
5351 CalculateOldGenerationAllocationLimit(idle_factor, old_gen_size); 5366 CalculateOldGenerationAllocationLimit(idle_factor, old_gen_size);
5352 5367
5353 if (FLAG_trace_gc_verbose) { 5368 if (FLAG_trace_gc_verbose) {
5354 PrintIsolate( 5369 PrintIsolate(
5355 isolate_, 5370 isolate_,
5356 "Grow: old size: %" V8_PTR_PREFIX "d KB, new limit: %" V8_PTR_PREFIX 5371 "Grow: old size: %" V8_PTR_PREFIX "d KB, new limit: %" V8_PTR_PREFIX
(...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after
6573 *object_type = "CODE_TYPE"; \ 6588 *object_type = "CODE_TYPE"; \
6574 *object_sub_type = "CODE_AGE/" #name; \ 6589 *object_sub_type = "CODE_AGE/" #name; \
6575 return true; 6590 return true;
6576 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) 6591 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME)
6577 #undef COMPARE_AND_RETURN_NAME 6592 #undef COMPARE_AND_RETURN_NAME
6578 } 6593 }
6579 return false; 6594 return false;
6580 } 6595 }
6581 } // namespace internal 6596 } // namespace internal
6582 } // namespace v8 6597 } // namespace v8
OLDNEW
« src/heap/gc-tracer.cc ('K') | « src/heap/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698