Commit c96a2d3a authored by hpayer's avatar hpayer Committed by Commit bot

Use smaller heap growing factor in idle notification to start incremental...

Use smaller heap growing factor in idle notification to start incremental marking when there is idle time >16ms.

BUG=chromium:477323
LOG=y

Review URL: https://codereview.chromium.org/1090963002

Cr-Commit-Position: refs/heads/master@{#27897}
parent 8924a9e1
...@@ -119,9 +119,12 @@ class GCIdleTimeHandler { ...@@ -119,9 +119,12 @@ class GCIdleTimeHandler {
static const int kIdleScavengeThreshold; static const int kIdleScavengeThreshold;
// This is the maximum scheduled idle time. Note that it can be more than // This is the maximum scheduled idle time. Note that it can be more than
// 16 ms when there is currently no rendering going on. // 16.66 ms when there is currently no rendering going on.
static const size_t kMaxScheduledIdleTime = 50; static const size_t kMaxScheduledIdleTime = 50;
// The maximum idle time when frames are rendered is 16.66ms.
static const size_t kMaxFrameRenderingIdleTime = 17;
// We conservatively assume that in the next kTimeUntilNextIdleEvent ms // We conservatively assume that in the next kTimeUntilNextIdleEvent ms
// no idle notification happens. // no idle notification happens.
static const size_t kTimeUntilNextIdleEvent = 100; static const size_t kTimeUntilNextIdleEvent = 100;
......
...@@ -1131,8 +1131,7 @@ bool Heap::PerformGarbageCollection( ...@@ -1131,8 +1131,7 @@ bool Heap::PerformGarbageCollection(
// Temporarily set the limit for case when PostGarbageCollectionProcessing // Temporarily set the limit for case when PostGarbageCollectionProcessing
// allocates and triggers GC. The real limit is set at after // allocates and triggers GC. The real limit is set at after
// PostGarbageCollectionProcessing. // PostGarbageCollectionProcessing.
old_generation_allocation_limit_ = SetOldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
old_gen_exhausted_ = false; old_gen_exhausted_ = false;
old_generation_size_configured_ = true; old_generation_size_configured_ = true;
} else { } else {
...@@ -1166,8 +1165,8 @@ bool Heap::PerformGarbageCollection( ...@@ -1166,8 +1165,8 @@ bool Heap::PerformGarbageCollection(
// Register the amount of external allocated memory. // Register the amount of external allocated memory.
amount_of_external_allocated_memory_at_last_global_gc_ = amount_of_external_allocated_memory_at_last_global_gc_ =
amount_of_external_allocated_memory_; amount_of_external_allocated_memory_;
old_generation_allocation_limit_ = OldGenerationAllocationLimit( SetOldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(),
PromotedSpaceSizeOfObjects(), freed_global_handles); freed_global_handles);
// We finished a marking cycle. We can uncommit the marking deque until // We finished a marking cycle. We can uncommit the marking deque until
// we start marking again. // we start marking again.
mark_compact_collector_.UncommitMarkingDeque(); mark_compact_collector_.UncommitMarkingDeque();
...@@ -4548,7 +4547,7 @@ bool Heap::TryFinalizeIdleIncrementalMarking( ...@@ -4548,7 +4547,7 @@ bool Heap::TryFinalizeIdleIncrementalMarking(
bool Heap::WorthActivatingIncrementalMarking() { bool Heap::WorthActivatingIncrementalMarking() {
return incremental_marking()->IsStopped() && return incremental_marking()->IsStopped() &&
incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull(); incremental_marking()->ShouldActivate();
} }
...@@ -4573,6 +4572,7 @@ bool Heap::IdleNotification(double deadline_in_seconds) { ...@@ -4573,6 +4572,7 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
static_cast<double>(base::Time::kMillisecondsPerSecond); static_cast<double>(base::Time::kMillisecondsPerSecond);
HistogramTimerScope idle_notification_scope( HistogramTimerScope idle_notification_scope(
isolate_->counters()->gc_idle_notification()); isolate_->counters()->gc_idle_notification());
double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
GCIdleTimeHandler::HeapState heap_state; GCIdleTimeHandler::HeapState heap_state;
heap_state.contexts_disposed = contexts_disposed_; heap_state.contexts_disposed = contexts_disposed_;
...@@ -4581,8 +4581,15 @@ bool Heap::IdleNotification(double deadline_in_seconds) { ...@@ -4581,8 +4581,15 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
// TODO(ulan): Start incremental marking only for large heaps. // TODO(ulan): Start incremental marking only for large heaps.
intptr_t limit = old_generation_allocation_limit_;
if (static_cast<size_t>(idle_time_in_ms) >
GCIdleTimeHandler::kMaxFrameRenderingIdleTime) {
limit = idle_old_generation_allocation_limit_;
}
heap_state.can_start_incremental_marking = heap_state.can_start_incremental_marking =
incremental_marking()->ShouldActivate() && FLAG_incremental_marking && incremental_marking()->WorthActivating() &&
NextGCIsLikelyToBeFull(limit) && FLAG_incremental_marking &&
!mark_compact_collector()->sweeping_in_progress(); !mark_compact_collector()->sweeping_in_progress();
heap_state.sweeping_in_progress = heap_state.sweeping_in_progress =
mark_compact_collector()->sweeping_in_progress(); mark_compact_collector()->sweeping_in_progress();
...@@ -4603,7 +4610,6 @@ bool Heap::IdleNotification(double deadline_in_seconds) { ...@@ -4603,7 +4610,6 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
static_cast<size_t>( static_cast<size_t>(
tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond());
double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
GCIdleTimeAction action = GCIdleTimeAction action =
gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
...@@ -5192,21 +5198,37 @@ int64_t Heap::PromotedExternalMemorySize() { ...@@ -5192,21 +5198,37 @@ int64_t Heap::PromotedExternalMemorySize() {
} }
intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size, intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor,
int freed_global_handles) { intptr_t old_gen_size) {
CHECK(factor > 1.0);
CHECK(old_gen_size > 0);
intptr_t limit = static_cast<intptr_t>(old_gen_size * factor);
limit = Max(limit, kMinimumOldGenerationAllocationLimit);
limit += new_space_.Capacity();
intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
return Min(limit, halfway_to_the_max);
}
void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
int freed_global_handles) {
const int kMaxHandles = 1000; const int kMaxHandles = 1000;
const int kMinHandles = 100; const int kMinHandles = 100;
double min_factor = 1.1; const double min_factor = 1.1;
double max_factor = 4; double max_factor = 4;
const double idle_max_factor = 1.5;
// We set the old generation growing factor to 2 to grow the heap slower on // We set the old generation growing factor to 2 to grow the heap slower on
// memory-constrained devices. // memory-constrained devices.
if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
max_factor = 2; max_factor = 2;
} }
// If there are many freed global handles, then the next full GC will // If there are many freed global handles, then the next full GC will
// likely collect a lot of garbage. Choose the heap growing factor // likely collect a lot of garbage. Choose the heap growing factor
// depending on freed global handles. // depending on freed global handles.
// TODO(ulan, hpayer): Take into account mutator utilization. // TODO(ulan, hpayer): Take into account mutator utilization.
// TODO(hpayer): The idle factor could make the handles heuristic obsolete.
// Look into that.
double factor; double factor;
if (freed_global_handles <= kMinHandles) { if (freed_global_handles <= kMinHandles) {
factor = max_factor; factor = max_factor;
...@@ -5225,11 +5247,10 @@ intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size, ...@@ -5225,11 +5247,10 @@ intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size,
factor = min_factor; factor = min_factor;
} }
intptr_t limit = static_cast<intptr_t>(old_gen_size * factor); old_generation_allocation_limit_ =
limit = Max(limit, kMinimumOldGenerationAllocationLimit); CalculateOldGenerationAllocationLimit(factor, old_gen_size);
limit += new_space_.Capacity(); idle_old_generation_allocation_limit_ = CalculateOldGenerationAllocationLimit(
intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2; Min(factor, idle_max_factor), old_gen_size);
return Min(limit, halfway_to_the_max);
} }
......
...@@ -634,6 +634,10 @@ class Heap { ...@@ -634,6 +634,10 @@ class Heap {
// Returns of size of all objects residing in the heap. // Returns of size of all objects residing in the heap.
intptr_t SizeOfObjects(); intptr_t SizeOfObjects();
intptr_t old_generation_allocation_limit() const {
return old_generation_allocation_limit_;
}
// Return the starting address and a mask for the new space. And-masking an // Return the starting address and a mask for the new space. And-masking an
// address with the mask will result in the start address of the new space // address with the mask will result in the start address of the new space
// for all addresses in either semispace. // for all addresses in either semispace.
...@@ -1120,8 +1124,14 @@ class Heap { ...@@ -1120,8 +1124,14 @@ class Heap {
static const int kMaxExecutableSizeHugeMemoryDevice = static const int kMaxExecutableSizeHugeMemoryDevice =
256 * kPointerMultiplier; 256 * kPointerMultiplier;
intptr_t OldGenerationAllocationLimit(intptr_t old_gen_size, // Calculates the allocation limit based on a given growing factor and a
int freed_global_handles); // given old generation size.
intptr_t CalculateOldGenerationAllocationLimit(double factor,
intptr_t old_gen_size);
// Sets the allocation limit to trigger the next full garbage collection.
void SetOldGenerationAllocationLimit(intptr_t old_gen_size,
int freed_global_handles);
// Indicates whether inline bump-pointer allocation has been disabled. // Indicates whether inline bump-pointer allocation has been disabled.
bool inline_allocation_disabled() { return inline_allocation_disabled_; } bool inline_allocation_disabled() { return inline_allocation_disabled_; }
...@@ -1231,13 +1241,12 @@ class Heap { ...@@ -1231,13 +1241,12 @@ class Heap {
survived_since_last_expansion_ += survived; survived_since_last_expansion_ += survived;
} }
inline bool NextGCIsLikelyToBeFull() { inline bool NextGCIsLikelyToBeFull(intptr_t limit) {
if (FLAG_gc_global) return true; if (FLAG_gc_global) return true;
if (FLAG_stress_compaction && (gc_count_ & 1) != 0) return true; if (FLAG_stress_compaction && (gc_count_ & 1) != 0) return true;
intptr_t adjusted_allocation_limit = intptr_t adjusted_allocation_limit = limit - new_space_.Capacity();
old_generation_allocation_limit_ - new_space_.Capacity();
if (PromotedTotalSize() >= adjusted_allocation_limit) return true; if (PromotedTotalSize() >= adjusted_allocation_limit) return true;
...@@ -1640,6 +1649,10 @@ class Heap { ...@@ -1640,6 +1649,10 @@ class Heap {
// generation and on every allocation in large object space. // generation and on every allocation in large object space.
intptr_t old_generation_allocation_limit_; intptr_t old_generation_allocation_limit_;
// The allocation limit when there is >16.66ms idle time in the idle time
// handler.
intptr_t idle_old_generation_allocation_limit_;
// Indicates that an allocation has failed in the old generation since the // Indicates that an allocation has failed in the old generation since the
// last GC. // last GC.
bool old_gen_exhausted_; bool old_gen_exhausted_;
......
...@@ -387,7 +387,9 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier() { ...@@ -387,7 +387,9 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier() {
bool IncrementalMarking::ShouldActivate() { bool IncrementalMarking::ShouldActivate() {
return WorthActivating() && heap_->NextGCIsLikelyToBeFull(); return WorthActivating() &&
heap_->NextGCIsLikelyToBeFull(
heap_->old_generation_allocation_limit());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment