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

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

Issue 1090963002: Use smaller heap growing factor in idle notification to start incremental marking when there is idl… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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/heap.h ('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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 raw_allocations_hash_(0), 94 raw_allocations_hash_(0),
95 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc), 95 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc),
96 ms_count_(0), 96 ms_count_(0),
97 gc_count_(0), 97 gc_count_(0),
98 remembered_unmapped_pages_index_(0), 98 remembered_unmapped_pages_index_(0),
99 unflattened_strings_length_(0), 99 unflattened_strings_length_(0),
100 #ifdef DEBUG 100 #ifdef DEBUG
101 allocation_timeout_(0), 101 allocation_timeout_(0),
102 #endif // DEBUG 102 #endif // DEBUG
103 old_generation_allocation_limit_(initial_old_generation_size_), 103 old_generation_allocation_limit_(initial_old_generation_size_),
104 min_old_generation_growing_factor_(1.1),
105 max_old_generation_growing_factor_(4.0),
106 idle_old_generation_growing_factor_(1.5),
107 current_old_generation_growing_factor_(
108 max_old_generation_growing_factor_),
104 old_gen_exhausted_(false), 109 old_gen_exhausted_(false),
105 inline_allocation_disabled_(false), 110 inline_allocation_disabled_(false),
106 store_buffer_rebuilder_(store_buffer()), 111 store_buffer_rebuilder_(store_buffer()),
107 hidden_string_(NULL), 112 hidden_string_(NULL),
108 gc_safe_size_of_old_object_(NULL), 113 gc_safe_size_of_old_object_(NULL),
109 total_regexp_code_generated_(0), 114 total_regexp_code_generated_(0),
110 tracer_(this), 115 tracer_(this),
111 high_survival_rate_period_length_(0), 116 high_survival_rate_period_length_(0),
112 promoted_objects_size_(0), 117 promoted_objects_size_(0),
113 promotion_ratio_(0), 118 promotion_ratio_(0),
(...skipping 4427 matching lines...) Expand 10 before | Expand all | Expand 10 after
4541 final_incremental_mark_compact_speed_in_bytes_per_ms))) { 4546 final_incremental_mark_compact_speed_in_bytes_per_ms))) {
4542 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); 4547 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
4543 return true; 4548 return true;
4544 } 4549 }
4545 return false; 4550 return false;
4546 } 4551 }
4547 4552
4548 4553
4549 bool Heap::WorthActivatingIncrementalMarking() { 4554 bool Heap::WorthActivatingIncrementalMarking() {
4550 return incremental_marking()->IsStopped() && 4555 return incremental_marking()->IsStopped() &&
4551 incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull(); 4556 incremental_marking()->ShouldActivate();
4552 } 4557 }
4553 4558
4554 4559
4555 static double MonotonicallyIncreasingTimeInMs() { 4560 static double MonotonicallyIncreasingTimeInMs() {
4556 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() * 4561 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
4557 static_cast<double>(base::Time::kMillisecondsPerSecond); 4562 static_cast<double>(base::Time::kMillisecondsPerSecond);
4558 } 4563 }
4559 4564
4560 4565
4561 bool Heap::IdleNotification(int idle_time_in_ms) { 4566 bool Heap::IdleNotification(int idle_time_in_ms) {
4562 return IdleNotification( 4567 return IdleNotification(
4563 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() + 4568 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() +
4564 (static_cast<double>(idle_time_in_ms) / 4569 (static_cast<double>(idle_time_in_ms) /
4565 static_cast<double>(base::Time::kMillisecondsPerSecond))); 4570 static_cast<double>(base::Time::kMillisecondsPerSecond)));
4566 } 4571 }
4567 4572
4568 4573
4569 bool Heap::IdleNotification(double deadline_in_seconds) { 4574 bool Heap::IdleNotification(double deadline_in_seconds) {
4570 CHECK(HasBeenSetUp()); // http://crbug.com/425035 4575 CHECK(HasBeenSetUp()); // http://crbug.com/425035
4571 double deadline_in_ms = 4576 double deadline_in_ms =
4572 deadline_in_seconds * 4577 deadline_in_seconds *
4573 static_cast<double>(base::Time::kMillisecondsPerSecond); 4578 static_cast<double>(base::Time::kMillisecondsPerSecond);
4574 HistogramTimerScope idle_notification_scope( 4579 HistogramTimerScope idle_notification_scope(
4575 isolate_->counters()->gc_idle_notification()); 4580 isolate_->counters()->gc_idle_notification());
4581 double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
4576 4582
4577 GCIdleTimeHandler::HeapState heap_state; 4583 GCIdleTimeHandler::HeapState heap_state;
4578 heap_state.contexts_disposed = contexts_disposed_; 4584 heap_state.contexts_disposed = contexts_disposed_;
4579 heap_state.contexts_disposal_rate = 4585 heap_state.contexts_disposal_rate =
4580 tracer()->ContextDisposalRateInMilliseconds(); 4586 tracer()->ContextDisposalRateInMilliseconds();
4581 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); 4587 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
4582 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); 4588 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
4583 // TODO(ulan): Start incremental marking only for large heaps. 4589 // TODO(ulan): Start incremental marking only for large heaps.
4590 intptr_t limit = old_generation_allocation_limit_;
4591 if (static_cast<size_t>(idle_time_in_ms) >
4592 GCIdleTimeHandler::kMaxFrameRenderingIdleTime) {
4593 limit =
ulan 2015/04/16 14:17:21 Instead of storing current_old_generation_growing_
Hannes Payer (out of office) 2015/04/16 14:46:45 Done.
4594 static_cast<intptr_t>((limit / current_old_generation_growing_factor_) *
4595 idle_old_generation_growing_factor_);
4596 }
4597
4584 heap_state.can_start_incremental_marking = 4598 heap_state.can_start_incremental_marking =
4585 incremental_marking()->ShouldActivate() && FLAG_incremental_marking && 4599 incremental_marking()->WorthActivating() &&
4600 NextGCIsLikelyToBeFull(limit) && FLAG_incremental_marking &&
4586 !mark_compact_collector()->sweeping_in_progress(); 4601 !mark_compact_collector()->sweeping_in_progress();
4587 heap_state.sweeping_in_progress = 4602 heap_state.sweeping_in_progress =
4588 mark_compact_collector()->sweeping_in_progress(); 4603 mark_compact_collector()->sweeping_in_progress();
4589 heap_state.sweeping_completed = 4604 heap_state.sweeping_completed =
4590 mark_compact_collector()->IsSweepingCompleted(); 4605 mark_compact_collector()->IsSweepingCompleted();
4591 heap_state.mark_compact_speed_in_bytes_per_ms = 4606 heap_state.mark_compact_speed_in_bytes_per_ms =
4592 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); 4607 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond());
4593 heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>( 4608 heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>(
4594 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); 4609 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond());
4595 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = 4610 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms =
4596 static_cast<size_t>( 4611 static_cast<size_t>(
4597 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); 4612 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond());
4598 heap_state.scavenge_speed_in_bytes_per_ms = 4613 heap_state.scavenge_speed_in_bytes_per_ms =
4599 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); 4614 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond());
4600 heap_state.used_new_space_size = new_space_.Size(); 4615 heap_state.used_new_space_size = new_space_.Size();
4601 heap_state.new_space_capacity = new_space_.Capacity(); 4616 heap_state.new_space_capacity = new_space_.Capacity();
4602 heap_state.new_space_allocation_throughput_in_bytes_per_ms = 4617 heap_state.new_space_allocation_throughput_in_bytes_per_ms =
4603 static_cast<size_t>( 4618 static_cast<size_t>(
4604 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); 4619 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond());
4605 4620
4606 double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
4607 GCIdleTimeAction action = 4621 GCIdleTimeAction action =
4608 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); 4622 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
4609 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( 4623 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4610 static_cast<int>(idle_time_in_ms)); 4624 static_cast<int>(idle_time_in_ms));
4611 4625
4612 bool result = false; 4626 bool result = false;
4613 switch (action.type) { 4627 switch (action.type) {
4614 case DONE: 4628 case DONE:
4615 result = true; 4629 result = true;
4616 break; 4630 break;
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
5100 if (FLAG_semi_space_growth_factor < 2) { 5114 if (FLAG_semi_space_growth_factor < 2) {
5101 FLAG_semi_space_growth_factor = 2; 5115 FLAG_semi_space_growth_factor = 2;
5102 } 5116 }
5103 5117
5104 // The old generation is paged and needs at least one page for each space. 5118 // The old generation is paged and needs at least one page for each space.
5105 int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1; 5119 int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
5106 max_old_generation_size_ = 5120 max_old_generation_size_ =
5107 Max(static_cast<intptr_t>(paged_space_count * Page::kPageSize), 5121 Max(static_cast<intptr_t>(paged_space_count * Page::kPageSize),
5108 max_old_generation_size_); 5122 max_old_generation_size_);
5109 5123
5124
5125 // We set the old generation growing factor to 2 to grow the heap slower on
5126 // memory-constrained devices.
5127 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
5128 max_old_generation_growing_factor_ = 2;
5129 }
5130
5110 if (FLAG_initial_old_space_size > 0) { 5131 if (FLAG_initial_old_space_size > 0) {
5111 initial_old_generation_size_ = FLAG_initial_old_space_size * MB; 5132 initial_old_generation_size_ = FLAG_initial_old_space_size * MB;
5112 } else { 5133 } else {
5113 initial_old_generation_size_ = 5134 initial_old_generation_size_ =
5114 max_old_generation_size_ / kInitalOldGenerationLimitFactor; 5135 max_old_generation_size_ / kInitalOldGenerationLimitFactor;
5115 } 5136 }
5116 old_generation_allocation_limit_ = initial_old_generation_size_; 5137 old_generation_allocation_limit_ = initial_old_generation_size_;
5117 5138
5118 // We rely on being able to allocate new arrays in paged spaces. 5139 // We rely on being able to allocate new arrays in paged spaces.
5119 DCHECK(Page::kMaxRegularHeapObjectSize >= 5140 DCHECK(Page::kMaxRegularHeapObjectSize >=
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
5175 return 0; 5196 return 0;
5176 return amount_of_external_allocated_memory_ - 5197 return amount_of_external_allocated_memory_ -
5177 amount_of_external_allocated_memory_at_last_global_gc_; 5198 amount_of_external_allocated_memory_at_last_global_gc_;
5178 } 5199 }
5179 5200
5180 5201
5181 intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size, 5202 intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size,
5182 int freed_global_handles) { 5203 int freed_global_handles) {
5183 const int kMaxHandles = 1000; 5204 const int kMaxHandles = 1000;
5184 const int kMinHandles = 100; 5205 const int kMinHandles = 100;
5185 double min_factor = 1.1; 5206
5186 double max_factor = 1.5;
5187 // We set the old generation growing factor to 2 to grow the heap slower on
5188 // memory-constrained devices.
5189 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
5190 max_factor = 1.5;
5191 }
5192 // If there are many freed global handles, then the next full GC will 5207 // If there are many freed global handles, then the next full GC will
5193 // likely collect a lot of garbage. Choose the heap growing factor 5208 // likely collect a lot of garbage. Choose the heap growing factor
5194 // depending on freed global handles. 5209 // depending on freed global handles.
5195 // TODO(ulan, hpayer): Take into account mutator utilization. 5210 // TODO(ulan, hpayer): Take into account mutator utilization.
5211 // TODO(hpayer): The idle factor could make the handles heuristic obsolete.
5212 // Look into that.
5196 double factor; 5213 double factor;
5197 if (freed_global_handles <= kMinHandles) { 5214 if (freed_global_handles <= kMinHandles) {
5198 factor = max_factor; 5215 factor = max_old_generation_growing_factor_;
5199 } else if (freed_global_handles >= kMaxHandles) { 5216 } else if (freed_global_handles >= kMaxHandles) {
5200 factor = min_factor; 5217 factor = min_old_generation_growing_factor_;
5201 } else { 5218 } else {
5202 // Compute factor using linear interpolation between points 5219 // Compute factor using linear interpolation between points
5203 // (kMinHandles, max_factor) and (kMaxHandles, min_factor). 5220 // (kMinHandles, max_factor) and (kMaxHandles, min_factor).
5204 factor = max_factor - 5221 factor = max_old_generation_growing_factor_ -
5205 (freed_global_handles - kMinHandles) * (max_factor - min_factor) / 5222 (freed_global_handles - kMinHandles) *
5223 (max_old_generation_growing_factor_ -
5224 min_old_generation_growing_factor_) /
5206 (kMaxHandles - kMinHandles); 5225 (kMaxHandles - kMinHandles);
5207 } 5226 }
5208 5227
5209 if (FLAG_stress_compaction || 5228 if (FLAG_stress_compaction ||
5210 mark_compact_collector()->reduce_memory_footprint_) { 5229 mark_compact_collector()->reduce_memory_footprint_) {
5211 factor = min_factor; 5230 factor = min_old_generation_growing_factor_;
5212 } 5231 }
5213 5232
5233 // When the limit is taken from halfway_to_the_max, the current factor
5234 // does not correspond to the original old generation size. However, it
5235 // may be close.
Erik Corry Chromium.org 2015/04/16 14:16:44 But it may not be close. I'm not very happy with
Hannes Payer (out of office) 2015/04/16 14:46:45 Done.
5236 current_old_generation_growing_factor_ = factor;
ulan 2015/04/16 14:17:22 Since it is used for just for the idle limit compu
Hannes Payer (out of office) 2015/04/16 14:46:45 Done.
5237
5214 intptr_t limit = static_cast<intptr_t>(old_gen_size * factor); 5238 intptr_t limit = static_cast<intptr_t>(old_gen_size * factor);
5215 limit = Max(limit, kMinimumOldGenerationAllocationLimit); 5239 limit = Max(limit, kMinimumOldGenerationAllocationLimit);
5216 limit += new_space_.Capacity(); 5240 limit += new_space_.Capacity();
5217 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2; 5241 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
5218 return Min(limit, halfway_to_the_max); 5242 return Min(limit, halfway_to_the_max);
5219 } 5243 }
5220 5244
5221 5245
5222 void Heap::EnableInlineAllocation() { 5246 void Heap::EnableInlineAllocation() {
5223 if (!inline_allocation_disabled_) return; 5247 if (!inline_allocation_disabled_) return;
(...skipping 1085 matching lines...) Expand 10 before | Expand all | Expand 10 after
6309 static_cast<int>(object_sizes_last_time_[index])); 6333 static_cast<int>(object_sizes_last_time_[index]));
6310 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6334 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6311 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6335 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6312 6336
6313 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6337 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6314 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6338 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6315 ClearObjectStats(); 6339 ClearObjectStats();
6316 } 6340 }
6317 } 6341 }
6318 } // namespace v8::internal 6342 } // namespace v8::internal
OLDNEW
« src/heap/heap.h ('K') | « src/heap/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698