Commit 5c3d1cbf authored by Hannes Payer's avatar Hannes Payer

Re-land: Distinguish beween final incremental mark-compact and full...

Re-land: Distinguish beween final incremental mark-compact and full mark-compact event in IdleNotification.

BUG=
R=ulan@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#25545}
parent b1527e1d
...@@ -11,6 +11,7 @@ namespace internal { ...@@ -11,6 +11,7 @@ namespace internal {
const double GCIdleTimeHandler::kConservativeTimeRatio = 0.9; const double GCIdleTimeHandler::kConservativeTimeRatio = 0.9;
const size_t GCIdleTimeHandler::kMaxMarkCompactTimeInMs = 1000; const size_t GCIdleTimeHandler::kMaxMarkCompactTimeInMs = 1000;
const size_t GCIdleTimeHandler::kMaxFinalIncrementalMarkCompactTimeInMs = 1000;
const size_t GCIdleTimeHandler::kMinTimeForFinalizeSweeping = 100; const size_t GCIdleTimeHandler::kMinTimeForFinalizeSweeping = 100;
const int GCIdleTimeHandler::kMaxMarkCompactsInIdleRound = 7; const int GCIdleTimeHandler::kMaxMarkCompactsInIdleRound = 7;
const int GCIdleTimeHandler::kIdleScavengeThreshold = 5; const int GCIdleTimeHandler::kIdleScavengeThreshold = 5;
...@@ -84,8 +85,7 @@ size_t GCIdleTimeHandler::EstimateMarkingStepSize( ...@@ -84,8 +85,7 @@ size_t GCIdleTimeHandler::EstimateMarkingStepSize(
size_t GCIdleTimeHandler::EstimateMarkCompactTime( size_t GCIdleTimeHandler::EstimateMarkCompactTime(
size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms) { size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms) {
// TODO(hpayer): Be more precise about the type of mark-compact event. It // TODO(hpayer): Be more precise about the type of mark-compact event. It
// makes a huge difference if it is incremental or non-incremental and if // makes a huge difference if compaction is happening.
// compaction is happening.
if (mark_compact_speed_in_bytes_per_ms == 0) { if (mark_compact_speed_in_bytes_per_ms == 0) {
mark_compact_speed_in_bytes_per_ms = kInitialConservativeMarkCompactSpeed; mark_compact_speed_in_bytes_per_ms = kInitialConservativeMarkCompactSpeed;
} }
...@@ -94,6 +94,19 @@ size_t GCIdleTimeHandler::EstimateMarkCompactTime( ...@@ -94,6 +94,19 @@ size_t GCIdleTimeHandler::EstimateMarkCompactTime(
} }
size_t GCIdleTimeHandler::EstimateFinalIncrementalMarkCompactTime(
size_t size_of_objects,
size_t final_incremental_mark_compact_speed_in_bytes_per_ms) {
if (final_incremental_mark_compact_speed_in_bytes_per_ms == 0) {
final_incremental_mark_compact_speed_in_bytes_per_ms =
kInitialConservativeFinalIncrementalMarkCompactSpeed;
}
size_t result =
size_of_objects / final_incremental_mark_compact_speed_in_bytes_per_ms;
return Min(result, kMaxFinalIncrementalMarkCompactTimeInMs);
}
bool GCIdleTimeHandler::ShouldDoScavenge( bool GCIdleTimeHandler::ShouldDoScavenge(
size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size, size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
size_t scavenge_speed_in_bytes_per_ms, size_t scavenge_speed_in_bytes_per_ms,
...@@ -149,6 +162,16 @@ bool GCIdleTimeHandler::ShouldDoContextDisposalMarkCompact( ...@@ -149,6 +162,16 @@ bool GCIdleTimeHandler::ShouldDoContextDisposalMarkCompact(
} }
bool GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
size_t idle_time_in_ms, size_t size_of_objects,
size_t final_incremental_mark_compact_speed_in_bytes_per_ms) {
return idle_time_in_ms >=
EstimateFinalIncrementalMarkCompactTime(
size_of_objects,
final_incremental_mark_compact_speed_in_bytes_per_ms);
}
// The following logic is implemented by the controller: // The following logic is implemented by the controller:
// (1) If we don't have any idle time, do nothing, unless a context was // (1) If we don't have any idle time, do nothing, unless a context was
// disposed, incremental marking is stopped, and the heap is small. Then do // disposed, incremental marking is stopped, and the heap is small. Then do
......
...@@ -92,9 +92,18 @@ class GCIdleTimeHandler { ...@@ -92,9 +92,18 @@ class GCIdleTimeHandler {
// conservative lower bound for the mark-compact speed. // conservative lower bound for the mark-compact speed.
static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB; static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
// If we haven't recorded any final incremental mark-compact events yet, we
// use conservative lower bound for the mark-compact speed.
static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
2 * MB;
// Maximum mark-compact time returned by EstimateMarkCompactTime. // Maximum mark-compact time returned by EstimateMarkCompactTime.
static const size_t kMaxMarkCompactTimeInMs; static const size_t kMaxMarkCompactTimeInMs;
// Maximum final incremental mark-compact time returned by
// EstimateFinalIncrementalMarkCompactTime.
static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
// Minimum time to finalize sweeping phase. The main thread may wait for // Minimum time to finalize sweeping phase. The main thread may wait for
// sweeper threads. // sweeper threads.
static const size_t kMinTimeForFinalizeSweeping; static const size_t kMinTimeForFinalizeSweeping;
...@@ -128,6 +137,7 @@ class GCIdleTimeHandler { ...@@ -128,6 +137,7 @@ class GCIdleTimeHandler {
bool sweeping_in_progress; bool sweeping_in_progress;
size_t mark_compact_speed_in_bytes_per_ms; size_t mark_compact_speed_in_bytes_per_ms;
size_t incremental_marking_speed_in_bytes_per_ms; size_t incremental_marking_speed_in_bytes_per_ms;
size_t final_incremental_mark_compact_speed_in_bytes_per_ms;
size_t scavenge_speed_in_bytes_per_ms; size_t scavenge_speed_in_bytes_per_ms;
size_t used_new_space_size; size_t used_new_space_size;
size_t new_space_capacity; size_t new_space_capacity;
...@@ -158,6 +168,9 @@ class GCIdleTimeHandler { ...@@ -158,6 +168,9 @@ class GCIdleTimeHandler {
static size_t EstimateMarkCompactTime( static size_t EstimateMarkCompactTime(
size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms); size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
static size_t EstimateFinalIncrementalMarkCompactTime(
size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
static bool ShouldDoMarkCompact(size_t idle_time_in_ms, static bool ShouldDoMarkCompact(size_t idle_time_in_ms,
size_t size_of_objects, size_t size_of_objects,
size_t mark_compact_speed_in_bytes_per_ms); size_t mark_compact_speed_in_bytes_per_ms);
...@@ -165,6 +178,10 @@ class GCIdleTimeHandler { ...@@ -165,6 +178,10 @@ class GCIdleTimeHandler {
static bool ShouldDoContextDisposalMarkCompact(bool context_disposed, static bool ShouldDoContextDisposalMarkCompact(bool context_disposed,
double contexts_disposal_rate); double contexts_disposal_rate);
static bool ShouldDoFinalIncrementalMarkCompact(
size_t idle_time_in_ms, size_t size_of_objects,
size_t final_incremental_mark_compact_speed_in_bytes_per_ms);
static bool ShouldDoScavenge( static bool ShouldDoScavenge(
size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size, size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
size_t scavenger_speed_in_bytes_per_ms, size_t scavenger_speed_in_bytes_per_ms,
......
...@@ -68,6 +68,7 @@ const char* GCTracer::Event::TypeName(bool short_name) const { ...@@ -68,6 +68,7 @@ const char* GCTracer::Event::TypeName(bool short_name) const {
return "Scavenge"; return "Scavenge";
} }
case MARK_COMPACTOR: case MARK_COMPACTOR:
case INCREMENTAL_MARK_COMPACTOR:
if (short_name) { if (short_name) {
return "ms"; return "ms";
} else { } else {
...@@ -97,7 +98,7 @@ GCTracer::GCTracer(Heap* heap) ...@@ -97,7 +98,7 @@ GCTracer::GCTracer(Heap* heap)
start_counter_(0) { start_counter_(0) {
current_ = Event(Event::START, NULL, NULL); current_ = Event(Event::START, NULL, NULL);
current_.end_time = base::OS::TimeCurrentMillis(); current_.end_time = base::OS::TimeCurrentMillis();
previous_ = previous_mark_compactor_event_ = current_; previous_ = previous_incremental_mark_compactor_event_ = current_;
} }
...@@ -114,13 +115,18 @@ void GCTracer::Start(GarbageCollector collector, const char* gc_reason, ...@@ -114,13 +115,18 @@ void GCTracer::Start(GarbageCollector collector, const char* gc_reason,
reinterpret_cast<intptr_t>((heap_->new_space()->top()) - reinterpret_cast<intptr_t>((heap_->new_space()->top()) -
new_space_top_after_gc_)); new_space_top_after_gc_));
} }
if (current_.type == Event::MARK_COMPACTOR) if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR)
previous_mark_compactor_event_ = current_; previous_incremental_mark_compactor_event_ = current_;
if (collector == SCAVENGER) { if (collector == SCAVENGER) {
current_ = Event(Event::SCAVENGER, gc_reason, collector_reason); current_ = Event(Event::SCAVENGER, gc_reason, collector_reason);
} else { } else if (collector == MARK_COMPACTOR) {
current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason); if (heap_->incremental_marking()->IsMarking()) {
current_ =
Event(Event::INCREMENTAL_MARK_COMPACTOR, gc_reason, collector_reason);
} else {
current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason);
}
} }
current_.start_time = start_time; current_.start_time = start_time;
...@@ -158,9 +164,10 @@ void GCTracer::Stop(GarbageCollector collector) { ...@@ -158,9 +164,10 @@ void GCTracer::Stop(GarbageCollector collector) {
} }
DCHECK(start_counter_ >= 0); DCHECK(start_counter_ >= 0);
DCHECK( DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) ||
(collector == SCAVENGER && current_.type == Event::SCAVENGER) || (collector == MARK_COMPACTOR &&
(collector == MARK_COMPACTOR && current_.type == Event::MARK_COMPACTOR)); (current_.type == Event::MARK_COMPACTOR ||
current_.type == Event::INCREMENTAL_MARK_COMPACTOR)));
current_.end_time = base::OS::TimeCurrentMillis(); current_.end_time = base::OS::TimeCurrentMillis();
current_.end_object_size = heap_->SizeOfObjects(); current_.end_object_size = heap_->SizeOfObjects();
...@@ -183,21 +190,30 @@ void GCTracer::Stop(GarbageCollector collector) { ...@@ -183,21 +190,30 @@ void GCTracer::Stop(GarbageCollector collector) {
current_.cumulative_pure_incremental_marking_duration - current_.cumulative_pure_incremental_marking_duration -
previous_.cumulative_pure_incremental_marking_duration; previous_.cumulative_pure_incremental_marking_duration;
scavenger_events_.push_front(current_); scavenger_events_.push_front(current_);
} else { } else if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) {
current_.incremental_marking_steps = current_.incremental_marking_steps =
current_.cumulative_incremental_marking_steps - current_.cumulative_incremental_marking_steps -
previous_mark_compactor_event_.cumulative_incremental_marking_steps; previous_incremental_mark_compactor_event_
.cumulative_incremental_marking_steps;
current_.incremental_marking_bytes = current_.incremental_marking_bytes =
current_.cumulative_incremental_marking_bytes - current_.cumulative_incremental_marking_bytes -
previous_mark_compactor_event_.cumulative_incremental_marking_bytes; previous_incremental_mark_compactor_event_
.cumulative_incremental_marking_bytes;
current_.incremental_marking_duration = current_.incremental_marking_duration =
current_.cumulative_incremental_marking_duration - current_.cumulative_incremental_marking_duration -
previous_mark_compactor_event_.cumulative_incremental_marking_duration; previous_incremental_mark_compactor_event_
.cumulative_incremental_marking_duration;
current_.pure_incremental_marking_duration = current_.pure_incremental_marking_duration =
current_.cumulative_pure_incremental_marking_duration - current_.cumulative_pure_incremental_marking_duration -
previous_mark_compactor_event_ previous_incremental_mark_compactor_event_
.cumulative_pure_incremental_marking_duration; .cumulative_pure_incremental_marking_duration;
longest_incremental_marking_step_ = 0.0; longest_incremental_marking_step_ = 0.0;
incremental_mark_compactor_events_.push_front(current_);
} else {
DCHECK(current_.incremental_marking_bytes == 0);
DCHECK(current_.incremental_marking_duration == 0);
DCHECK(current_.pure_incremental_marking_duration == 0);
DCHECK(longest_incremental_marking_step_ == 0.0);
mark_compactor_events_.push_front(current_); mark_compactor_events_.push_front(current_);
} }
...@@ -400,15 +416,15 @@ double GCTracer::MeanIncrementalMarkingDuration() const { ...@@ -400,15 +416,15 @@ double GCTracer::MeanIncrementalMarkingDuration() const {
// We haven't completed an entire round of incremental marking, yet. // We haven't completed an entire round of incremental marking, yet.
// Use data from GCTracer instead of data from event buffers. // Use data from GCTracer instead of data from event buffers.
if (mark_compactor_events_.empty()) { if (incremental_mark_compactor_events_.empty()) {
return cumulative_incremental_marking_duration_ / return cumulative_incremental_marking_duration_ /
cumulative_incremental_marking_steps_; cumulative_incremental_marking_steps_;
} }
int steps = 0; int steps = 0;
double durations = 0.0; double durations = 0.0;
EventBuffer::const_iterator iter = mark_compactor_events_.begin(); EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin();
while (iter != mark_compactor_events_.end()) { while (iter != incremental_mark_compactor_events_.end()) {
steps += iter->incremental_marking_steps; steps += iter->incremental_marking_steps;
durations += iter->incremental_marking_duration; durations += iter->incremental_marking_duration;
++iter; ++iter;
...@@ -423,11 +439,12 @@ double GCTracer::MeanIncrementalMarkingDuration() const { ...@@ -423,11 +439,12 @@ double GCTracer::MeanIncrementalMarkingDuration() const {
double GCTracer::MaxIncrementalMarkingDuration() const { double GCTracer::MaxIncrementalMarkingDuration() const {
// We haven't completed an entire round of incremental marking, yet. // We haven't completed an entire round of incremental marking, yet.
// Use data from GCTracer instead of data from event buffers. // Use data from GCTracer instead of data from event buffers.
if (mark_compactor_events_.empty()) return longest_incremental_marking_step_; if (incremental_mark_compactor_events_.empty())
return longest_incremental_marking_step_;
double max_duration = 0.0; double max_duration = 0.0;
EventBuffer::const_iterator iter = mark_compactor_events_.begin(); EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin();
while (iter != mark_compactor_events_.end()) while (iter != incremental_mark_compactor_events_.end())
max_duration = Max(iter->longest_incremental_marking_step, max_duration); max_duration = Max(iter->longest_incremental_marking_step, max_duration);
return max_duration; return max_duration;
...@@ -439,15 +456,15 @@ intptr_t GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const { ...@@ -439,15 +456,15 @@ intptr_t GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const {
// We haven't completed an entire round of incremental marking, yet. // We haven't completed an entire round of incremental marking, yet.
// Use data from GCTracer instead of data from event buffers. // Use data from GCTracer instead of data from event buffers.
if (mark_compactor_events_.empty()) { if (incremental_mark_compactor_events_.empty()) {
return static_cast<intptr_t>(cumulative_incremental_marking_bytes_ / return static_cast<intptr_t>(cumulative_incremental_marking_bytes_ /
cumulative_pure_incremental_marking_duration_); cumulative_pure_incremental_marking_duration_);
} }
intptr_t bytes = 0; intptr_t bytes = 0;
double durations = 0.0; double durations = 0.0;
EventBuffer::const_iterator iter = mark_compactor_events_.begin(); EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin();
while (iter != mark_compactor_events_.end()) { while (iter != incremental_mark_compactor_events_.end()) {
bytes += iter->incremental_marking_bytes; bytes += iter->incremental_marking_bytes;
durations += iter->pure_incremental_marking_duration; durations += iter->pure_incremental_marking_duration;
++iter; ++iter;
...@@ -481,8 +498,24 @@ intptr_t GCTracer::MarkCompactSpeedInBytesPerMillisecond() const { ...@@ -481,8 +498,24 @@ intptr_t GCTracer::MarkCompactSpeedInBytesPerMillisecond() const {
EventBuffer::const_iterator iter = mark_compactor_events_.begin(); EventBuffer::const_iterator iter = mark_compactor_events_.begin();
while (iter != mark_compactor_events_.end()) { while (iter != mark_compactor_events_.end()) {
bytes += iter->start_object_size; bytes += iter->start_object_size;
durations += iter->end_time - iter->start_time + durations += iter->end_time - iter->start_time;
iter->pure_incremental_marking_duration; ++iter;
}
if (durations == 0.0) return 0;
return static_cast<intptr_t>(bytes / durations);
}
intptr_t GCTracer::FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()
const {
intptr_t bytes = 0;
double durations = 0.0;
EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin();
while (iter != incremental_mark_compactor_events_.end()) {
bytes += iter->start_object_size;
durations += iter->end_time - iter->start_time;
++iter; ++iter;
} }
......
...@@ -160,7 +160,12 @@ class GCTracer { ...@@ -160,7 +160,12 @@ class GCTracer {
class Event { class Event {
public: public:
enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 }; enum Type {
SCAVENGER = 0,
MARK_COMPACTOR = 1,
INCREMENTAL_MARK_COMPACTOR = 2,
START = 3
};
// Default constructor leaves the event uninitialized. // Default constructor leaves the event uninitialized.
Event() {} Event() {}
...@@ -211,7 +216,8 @@ class GCTracer { ...@@ -211,7 +216,8 @@ class GCTracer {
// Incremental marking steps since // Incremental marking steps since
// - last event for SCAVENGER events // - last event for SCAVENGER events
// - last MARK_COMPACTOR event for MARK_COMPACTOR events // - last INCREMENTAL_MARK_COMPACTOR event for INCREMENTAL_MARK_COMPACTOR
// events
int incremental_marking_steps; int incremental_marking_steps;
// Bytes marked since creation of tracer (value at start of event). // Bytes marked since creation of tracer (value at start of event).
...@@ -219,7 +225,8 @@ class GCTracer { ...@@ -219,7 +225,8 @@ class GCTracer {
// Bytes marked since // Bytes marked since
// - last event for SCAVENGER events // - last event for SCAVENGER events
// - last MARK_COMPACTOR event for MARK_COMPACTOR events // - last INCREMENTAL_MARK_COMPACTOR event for INCREMENTAL_MARK_COMPACTOR
// events
intptr_t incremental_marking_bytes; intptr_t incremental_marking_bytes;
// Cumulative duration of incremental marking steps since creation of // Cumulative duration of incremental marking steps since creation of
...@@ -228,7 +235,8 @@ class GCTracer { ...@@ -228,7 +235,8 @@ class GCTracer {
// Duration of incremental marking steps since // Duration of incremental marking steps since
// - last event for SCAVENGER events // - last event for SCAVENGER events
// - last MARK_COMPACTOR event for MARK_COMPACTOR events // - last INCREMENTAL_MARK_COMPACTOR event for INCREMENTAL_MARK_COMPACTOR
// events
double incremental_marking_duration; double incremental_marking_duration;
// Cumulative pure duration of incremental marking steps since creation of // Cumulative pure duration of incremental marking steps since creation of
...@@ -237,7 +245,8 @@ class GCTracer { ...@@ -237,7 +245,8 @@ class GCTracer {
// Duration of pure incremental marking steps since // Duration of pure incremental marking steps since
// - last event for SCAVENGER events // - last event for SCAVENGER events
// - last MARK_COMPACTOR event for MARK_COMPACTOR events // - last INCREMENTAL_MARK_COMPACTOR event for INCREMENTAL_MARK_COMPACTOR
// events
double pure_incremental_marking_duration; double pure_incremental_marking_duration;
// Longest incremental marking step since start of marking. // Longest incremental marking step since start of marking.
...@@ -316,6 +325,12 @@ class GCTracer { ...@@ -316,6 +325,12 @@ class GCTracer {
return MaxDuration(mark_compactor_events_); return MaxDuration(mark_compactor_events_);
} }
// Compute the mean duration of the last incremental mark compactor
// events. Returns 0 if no events have been recorded.
double MeanIncrementalMarkCompactorDuration() const {
return MeanDuration(incremental_mark_compactor_events_);
}
// Compute the mean step duration of the last incremental marking round. // Compute the mean step duration of the last incremental marking round.
// Returns 0 if no incremental marking round has been completed. // Returns 0 if no incremental marking round has been completed.
double MeanIncrementalMarkingDuration() const; double MeanIncrementalMarkingDuration() const;
...@@ -332,10 +347,15 @@ class GCTracer { ...@@ -332,10 +347,15 @@ class GCTracer {
// Returns 0 if no events have been recorded. // Returns 0 if no events have been recorded.
intptr_t ScavengeSpeedInBytesPerMillisecond() const; intptr_t ScavengeSpeedInBytesPerMillisecond() const;
// Compute the max mark-sweep speed in bytes/millisecond. // Compute the average mark-sweep speed in bytes/millisecond.
// Returns 0 if no events have been recorded. // Returns 0 if no events have been recorded.
intptr_t MarkCompactSpeedInBytesPerMillisecond() const; intptr_t MarkCompactSpeedInBytesPerMillisecond() const;
// Compute the average incremental mark-sweep finalize speed in
// bytes/millisecond.
// Returns 0 if no events have been recorded.
intptr_t FinalIncrementalMarkCompactSpeedInBytesPerMillisecond() const;
// Allocation throughput in the new space in bytes/millisecond. // Allocation throughput in the new space in bytes/millisecond.
// Returns 0 if no events have been recorded. // Returns 0 if no events have been recorded.
intptr_t NewSpaceAllocationThroughputInBytesPerMillisecond() const; intptr_t NewSpaceAllocationThroughputInBytesPerMillisecond() const;
...@@ -361,6 +381,16 @@ class GCTracer { ...@@ -361,6 +381,16 @@ class GCTracer {
// Compute the max duration of the events in the given ring buffer. // Compute the max duration of the events in the given ring buffer.
double MaxDuration(const EventBuffer& events) const; double MaxDuration(const EventBuffer& events) const;
void ClearMarkCompactStatistics() {
cumulative_incremental_marking_steps_ = 0;
cumulative_incremental_marking_bytes_ = 0;
cumulative_incremental_marking_duration_ = 0;
cumulative_pure_incremental_marking_duration_ = 0;
longest_incremental_marking_step_ = 0;
cumulative_marking_duration_ = 0;
cumulative_sweeping_duration_ = 0;
}
// Pointer to the heap that owns this tracer. // Pointer to the heap that owns this tracer.
Heap* heap_; Heap* heap_;
...@@ -371,8 +401,8 @@ class GCTracer { ...@@ -371,8 +401,8 @@ class GCTracer {
// Previous tracer event. // Previous tracer event.
Event previous_; Event previous_;
// Previous MARK_COMPACTOR event. // Previous INCREMENTAL_MARK_COMPACTOR event.
Event previous_mark_compactor_event_; Event previous_incremental_mark_compactor_event_;
// RingBuffers for SCAVENGER events. // RingBuffers for SCAVENGER events.
EventBuffer scavenger_events_; EventBuffer scavenger_events_;
...@@ -380,6 +410,9 @@ class GCTracer { ...@@ -380,6 +410,9 @@ class GCTracer {
// RingBuffers for MARK_COMPACTOR events. // RingBuffers for MARK_COMPACTOR events.
EventBuffer mark_compactor_events_; EventBuffer mark_compactor_events_;
// RingBuffers for INCREMENTAL_MARK_COMPACTOR events.
EventBuffer incremental_mark_compactor_events_;
// RingBuffer for allocation events. // RingBuffer for allocation events.
AllocationEventBuffer allocation_events_; AllocationEventBuffer allocation_events_;
......
...@@ -4387,12 +4387,12 @@ void Heap::IdleMarkCompact(const char* message) { ...@@ -4387,12 +4387,12 @@ void Heap::IdleMarkCompact(const char* message) {
void Heap::TryFinalizeIdleIncrementalMarking( void Heap::TryFinalizeIdleIncrementalMarking(
size_t idle_time_in_ms, size_t size_of_objects, size_t idle_time_in_ms, size_t size_of_objects,
size_t mark_compact_speed_in_bytes_per_ms) { size_t final_incremental_mark_compact_speed_in_bytes_per_ms) {
if (incremental_marking()->IsComplete() || if (incremental_marking()->IsComplete() ||
(mark_compact_collector()->IsMarkingDequeEmpty() && (mark_compact_collector()->IsMarkingDequeEmpty() &&
gc_idle_time_handler_.ShouldDoMarkCompact( gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact(
idle_time_in_ms, size_of_objects, idle_time_in_ms, size_of_objects,
mark_compact_speed_in_bytes_per_ms))) { final_incremental_mark_compact_speed_in_bytes_per_ms))) {
CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
} }
} }
...@@ -4427,6 +4427,9 @@ bool Heap::IdleNotification(int idle_time_in_ms) { ...@@ -4427,6 +4427,9 @@ bool Heap::IdleNotification(int idle_time_in_ms) {
static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond());
heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>( heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>(
tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); tracer()->IncrementalMarkingSpeedInBytesPerMillisecond());
heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms =
static_cast<size_t>(
tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond());
heap_state.scavenge_speed_in_bytes_per_ms = heap_state.scavenge_speed_in_bytes_per_ms =
static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond());
heap_state.used_new_space_size = new_space_.Size(); heap_state.used_new_space_size = new_space_.Size();
...@@ -4457,7 +4460,7 @@ bool Heap::IdleNotification(int idle_time_in_ms) { ...@@ -4457,7 +4460,7 @@ bool Heap::IdleNotification(int idle_time_in_ms) {
if (remaining_idle_time_in_ms > 0) { if (remaining_idle_time_in_ms > 0) {
TryFinalizeIdleIncrementalMarking( TryFinalizeIdleIncrementalMarking(
remaining_idle_time_in_ms, heap_state.size_of_objects, remaining_idle_time_in_ms, heap_state.size_of_objects,
heap_state.mark_compact_speed_in_bytes_per_ms); heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms);
} }
break; break;
} }
......
...@@ -180,6 +180,20 @@ TEST_F(GCIdleTimeHandlerTest, DontDoMarkCompact) { ...@@ -180,6 +180,20 @@ TEST_F(GCIdleTimeHandlerTest, DontDoMarkCompact) {
} }
TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) {
size_t idle_time_in_ms = 16;
EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
idle_time_in_ms, 0, 0));
}
TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) {
size_t idle_time_in_ms = 1;
EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
idle_time_in_ms, kSizeOfObjects, kMarkingSpeed));
}
TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) { TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
heap_state.contexts_disposed = 1; heap_state.contexts_disposed = 1;
......
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