@@ -104,6 +104,8 @@ Heap::Heap()
104104 allocation_timeout_ (0 ),
105105#endif // DEBUG
106106 old_generation_allocation_limit_ (initial_old_generation_size_),
107+ idle_old_generation_allocation_limit_(
108+ kMinimumOldGenerationAllocationLimit ),
107109 old_gen_exhausted_(false ),
108110 inline_allocation_disabled_(false ),
109111 store_buffer_rebuilder_(store_buffer()),
@@ -1159,8 +1161,7 @@ bool Heap::PerformGarbageCollection(
11591161 // Temporarily set the limit for case when PostGarbageCollectionProcessing
11601162 // allocates and triggers GC. The real limit is set at after
11611163 // PostGarbageCollectionProcessing.
1162- old_generation_allocation_limit_ =
1163- OldGenerationAllocationLimit (PromotedSpaceSizeOfObjects (), 0 );
1164+ SetOldGenerationAllocationLimit (PromotedSpaceSizeOfObjects (), 0 );
11641165 old_gen_exhausted_ = false ;
11651166 old_generation_size_configured_ = true ;
11661167 } else {
@@ -1194,8 +1195,8 @@ bool Heap::PerformGarbageCollection(
11941195 // Register the amount of external allocated memory.
11951196 amount_of_external_allocated_memory_at_last_global_gc_ =
11961197 amount_of_external_allocated_memory_;
1197- old_generation_allocation_limit_ = OldGenerationAllocationLimit (
1198- PromotedSpaceSizeOfObjects (), freed_global_handles);
1198+ SetOldGenerationAllocationLimit ( PromotedSpaceSizeOfObjects (),
1199+ freed_global_handles);
11991200 // We finished a marking cycle. We can uncommit the marking deque until
12001201 // we start marking again.
12011202 mark_compact_collector_.UncommitMarkingDeque ();
@@ -4558,7 +4559,7 @@ bool Heap::TryFinalizeIdleIncrementalMarking(
45584559
45594560bool Heap::WorthActivatingIncrementalMarking () {
45604561 return incremental_marking ()->IsStopped () &&
4561- incremental_marking ()->WorthActivating () && NextGCIsLikelyToBeFull ();
4562+ incremental_marking ()->ShouldActivate ();
45624563}
45634564
45644565
@@ -4583,6 +4584,7 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
45834584 static_cast <double >(base::Time::kMillisecondsPerSecond );
45844585 HistogramTimerScope idle_notification_scope (
45854586 isolate_->counters ()->gc_idle_notification ());
4587+ double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs ();
45864588
45874589 GCIdleTimeHandler::HeapState heap_state;
45884590 heap_state.contexts_disposed = contexts_disposed_;
@@ -4591,8 +4593,15 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
45914593 heap_state.size_of_objects = static_cast <size_t >(SizeOfObjects ());
45924594 heap_state.incremental_marking_stopped = incremental_marking ()->IsStopped ();
45934595 // TODO(ulan): Start incremental marking only for large heaps.
4596+ intptr_t limit = old_generation_allocation_limit_;
4597+ if (static_cast <size_t >(idle_time_in_ms) >
4598+ GCIdleTimeHandler::kMinIdleTimeToStartIncrementalMarking ) {
4599+ limit = idle_old_generation_allocation_limit_;
4600+ }
4601+
45944602 heap_state.can_start_incremental_marking =
4595- incremental_marking ()->ShouldActivate () && FLAG_incremental_marking;
4603+ incremental_marking ()->WorthActivating () &&
4604+ NextGCIsLikelyToBeFull (limit) && FLAG_incremental_marking;
45964605 heap_state.sweeping_in_progress =
45974606 mark_compact_collector ()->sweeping_in_progress ();
45984607 heap_state.mark_compact_speed_in_bytes_per_ms =
@@ -4610,7 +4619,6 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
46104619 static_cast <size_t >(
46114620 tracer ()->NewSpaceAllocationThroughputInBytesPerMillisecond ());
46124621
4613- double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs ();
46144622 GCIdleTimeAction action =
46154623 gc_idle_time_handler_.Compute (idle_time_in_ms, heap_state);
46164624 isolate ()->counters ()->gc_idle_time_allotted_in_ms ()->AddSample (
@@ -5358,21 +5366,37 @@ int64_t Heap::PromotedExternalMemorySize() {
53585366}
53595367
53605368
5361- intptr_t Heap::OldGenerationAllocationLimit (intptr_t old_gen_size,
5362- int freed_global_handles) {
5369+ intptr_t Heap::CalculateOldGenerationAllocationLimit (double factor,
5370+ intptr_t old_gen_size) {
5371+ CHECK (factor > 1.0 );
5372+ CHECK (old_gen_size > 0 );
5373+ intptr_t limit = static_cast <intptr_t >(old_gen_size * factor);
5374+ limit = Max (limit, kMinimumOldGenerationAllocationLimit );
5375+ limit += new_space_.Capacity ();
5376+ intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2 ;
5377+ return Min (limit, halfway_to_the_max);
5378+ }
5379+
5380+
5381+ void Heap::SetOldGenerationAllocationLimit (intptr_t old_gen_size,
5382+ int freed_global_handles) {
53635383 const int kMaxHandles = 1000 ;
53645384 const int kMinHandles = 100 ;
5365- double min_factor = 1.1 ;
5385+ const double min_factor = 1.1 ;
53665386 double max_factor = 4 ;
5387+ const double idle_max_factor = 1.5 ;
53675388 // We set the old generation growing factor to 2 to grow the heap slower on
53685389 // memory-constrained devices.
53695390 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice ) {
53705391 max_factor = 2 ;
53715392 }
5393+
53725394 // If there are many freed global handles, then the next full GC will
53735395 // likely collect a lot of garbage. Choose the heap growing factor
53745396 // depending on freed global handles.
53755397 // TODO(ulan, hpayer): Take into account mutator utilization.
5398+ // TODO(hpayer): The idle factor could make the handles heuristic obsolete.
5399+ // Look into that.
53765400 double factor;
53775401 if (freed_global_handles <= kMinHandles ) {
53785402 factor = max_factor;
@@ -5391,11 +5415,10 @@ intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size,
53915415 factor = min_factor;
53925416 }
53935417
5394- intptr_t limit = static_cast <intptr_t >(old_gen_size * factor);
5395- limit = Max (limit, kMinimumOldGenerationAllocationLimit );
5396- limit += new_space_.Capacity ();
5397- intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2 ;
5398- return Min (limit, halfway_to_the_max);
5418+ old_generation_allocation_limit_ =
5419+ CalculateOldGenerationAllocationLimit (factor, old_gen_size);
5420+ idle_old_generation_allocation_limit_ = CalculateOldGenerationAllocationLimit (
5421+ Min (factor, idle_max_factor), old_gen_size);
53995422}
54005423
54015424
0 commit comments