@@ -104,6 +104,8 @@ Heap::Heap()
104
104
allocation_timeout_ (0 ),
105
105
#endif // DEBUG
106
106
old_generation_allocation_limit_ (initial_old_generation_size_),
107
+ idle_old_generation_allocation_limit_(
108
+ kMinimumOldGenerationAllocationLimit ),
107
109
old_gen_exhausted_(false ),
108
110
inline_allocation_disabled_(false ),
109
111
store_buffer_rebuilder_(store_buffer()),
@@ -1159,8 +1161,7 @@ bool Heap::PerformGarbageCollection(
1159
1161
// Temporarily set the limit for case when PostGarbageCollectionProcessing
1160
1162
// allocates and triggers GC. The real limit is set at after
1161
1163
// PostGarbageCollectionProcessing.
1162
- old_generation_allocation_limit_ =
1163
- OldGenerationAllocationLimit (PromotedSpaceSizeOfObjects (), 0 );
1164
+ SetOldGenerationAllocationLimit (PromotedSpaceSizeOfObjects (), 0 );
1164
1165
old_gen_exhausted_ = false ;
1165
1166
old_generation_size_configured_ = true ;
1166
1167
} else {
@@ -1194,8 +1195,8 @@ bool Heap::PerformGarbageCollection(
1194
1195
// Register the amount of external allocated memory.
1195
1196
amount_of_external_allocated_memory_at_last_global_gc_ =
1196
1197
amount_of_external_allocated_memory_;
1197
- old_generation_allocation_limit_ = OldGenerationAllocationLimit (
1198
- PromotedSpaceSizeOfObjects (), freed_global_handles);
1198
+ SetOldGenerationAllocationLimit ( PromotedSpaceSizeOfObjects (),
1199
+ freed_global_handles);
1199
1200
// We finished a marking cycle. We can uncommit the marking deque until
1200
1201
// we start marking again.
1201
1202
mark_compact_collector_.UncommitMarkingDeque ();
@@ -4558,7 +4559,7 @@ bool Heap::TryFinalizeIdleIncrementalMarking(
4558
4559
4559
4560
bool Heap::WorthActivatingIncrementalMarking () {
4560
4561
return incremental_marking ()->IsStopped () &&
4561
- incremental_marking ()->WorthActivating () && NextGCIsLikelyToBeFull ();
4562
+ incremental_marking ()->ShouldActivate ();
4562
4563
}
4563
4564
4564
4565
@@ -4583,6 +4584,7 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
4583
4584
static_cast <double >(base::Time::kMillisecondsPerSecond );
4584
4585
HistogramTimerScope idle_notification_scope (
4585
4586
isolate_->counters ()->gc_idle_notification ());
4587
+ double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs ();
4586
4588
4587
4589
GCIdleTimeHandler::HeapState heap_state;
4588
4590
heap_state.contexts_disposed = contexts_disposed_;
@@ -4591,8 +4593,15 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
4591
4593
heap_state.size_of_objects = static_cast <size_t >(SizeOfObjects ());
4592
4594
heap_state.incremental_marking_stopped = incremental_marking ()->IsStopped ();
4593
4595
// 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
+
4594
4602
heap_state.can_start_incremental_marking =
4595
- incremental_marking ()->ShouldActivate () && FLAG_incremental_marking;
4603
+ incremental_marking ()->WorthActivating () &&
4604
+ NextGCIsLikelyToBeFull (limit) && FLAG_incremental_marking;
4596
4605
heap_state.sweeping_in_progress =
4597
4606
mark_compact_collector ()->sweeping_in_progress ();
4598
4607
heap_state.mark_compact_speed_in_bytes_per_ms =
@@ -4610,7 +4619,6 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
4610
4619
static_cast <size_t >(
4611
4620
tracer ()->NewSpaceAllocationThroughputInBytesPerMillisecond ());
4612
4621
4613
- double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs ();
4614
4622
GCIdleTimeAction action =
4615
4623
gc_idle_time_handler_.Compute (idle_time_in_ms, heap_state);
4616
4624
isolate ()->counters ()->gc_idle_time_allotted_in_ms ()->AddSample (
@@ -5358,21 +5366,37 @@ int64_t Heap::PromotedExternalMemorySize() {
5358
5366
}
5359
5367
5360
5368
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) {
5363
5383
const int kMaxHandles = 1000 ;
5364
5384
const int kMinHandles = 100 ;
5365
- double min_factor = 1.1 ;
5385
+ const double min_factor = 1.1 ;
5366
5386
double max_factor = 4 ;
5387
+ const double idle_max_factor = 1.5 ;
5367
5388
// We set the old generation growing factor to 2 to grow the heap slower on
5368
5389
// memory-constrained devices.
5369
5390
if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice ) {
5370
5391
max_factor = 2 ;
5371
5392
}
5393
+
5372
5394
// If there are many freed global handles, then the next full GC will
5373
5395
// likely collect a lot of garbage. Choose the heap growing factor
5374
5396
// depending on freed global handles.
5375
5397
// TODO(ulan, hpayer): Take into account mutator utilization.
5398
+ // TODO(hpayer): The idle factor could make the handles heuristic obsolete.
5399
+ // Look into that.
5376
5400
double factor;
5377
5401
if (freed_global_handles <= kMinHandles ) {
5378
5402
factor = max_factor;
@@ -5391,11 +5415,10 @@ intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size,
5391
5415
factor = min_factor;
5392
5416
}
5393
5417
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);
5399
5422
}
5400
5423
5401
5424
0 commit comments