From fe626586da465423194d377b03711896a7b22bba Mon Sep 17 00:00:00 2001 From: "hpayer@chromium.org" Date: Wed, 17 Sep 2014 08:50:57 +0000 Subject: [PATCH] Measure new space allocation throughput. BUG= R=ulan@chromium.org Review URL: https://codereview.chromium.org/578453003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23994 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/heap/gc-tracer.cc | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/heap/gc-tracer.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/heap/gc-tracer.cc b/src/heap/gc-tracer.cc index 035e3ee..85ee8aa 100644 --- a/src/heap/gc-tracer.cc +++ b/src/heap/gc-tracer.cc @@ -19,6 +19,13 @@ static intptr_t CountTotalHolesSize(Heap* heap) { } +GCTracer::AllocationEvent::AllocationEvent(double duration, + intptr_t allocation_in_bytes) { + duration_ = duration; + allocation_in_bytes_ = allocation_in_bytes; +} + + GCTracer::Event::Event(Type type, const char* gc_reason, const char* collector_reason) : type(type), @@ -80,7 +87,8 @@ GCTracer::GCTracer(Heap* heap) cumulative_pure_incremental_marking_duration_(0.0), longest_incremental_marking_step_(0.0), cumulative_marking_duration_(0.0), - cumulative_sweeping_duration_(0.0) { + cumulative_sweeping_duration_(0.0), + new_space_top_after_gc_(0) { current_ = Event(Event::START, NULL, NULL); current_.end_time = base::OS::TimeCurrentMillis(); previous_ = previous_mark_compactor_event_ = current_; @@ -90,6 +98,13 @@ GCTracer::GCTracer(Heap* heap) void GCTracer::Start(GarbageCollector collector, const char* gc_reason, const char* collector_reason) { previous_ = current_; + double start_time = base::OS::TimeCurrentMillis(); + if (new_space_top_after_gc_ != 0) { + AddNewSpaceAllocationTime( + start_time - previous_.end_time, + reinterpret_cast((heap_->new_space()->top()) - + new_space_top_after_gc_)); + } if (current_.type == Event::MARK_COMPACTOR) previous_mark_compactor_event_ = current_; @@ -99,7 +114,7 @@ void GCTracer::Start(GarbageCollector collector, const char* gc_reason, current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason); } - current_.start_time = base::OS::TimeCurrentMillis(); + current_.start_time = start_time; current_.start_object_size = heap_->SizeOfObjects(); current_.start_memory_size = heap_->isolate()->memory_allocator()->Size(); current_.start_holes_size = CountTotalHolesSize(heap_); @@ -127,6 +142,8 @@ void GCTracer::Stop() { current_.end_object_size = heap_->SizeOfObjects(); current_.end_memory_size = heap_->isolate()->memory_allocator()->Size(); current_.end_holes_size = CountTotalHolesSize(heap_); + new_space_top_after_gc_ = + reinterpret_cast(heap_->new_space()->top()); if (current_.type == Event::SCAVENGER) { current_.incremental_marking_steps = @@ -184,6 +201,12 @@ void GCTracer::Stop() { } +void GCTracer::AddNewSpaceAllocationTime(double duration, + intptr_t allocation_in_bytes) { + allocation_events_.push_front(AllocationEvent(duration, allocation_in_bytes)); +} + + void GCTracer::AddIncrementalMarkingStep(double duration, intptr_t bytes) { cumulative_incremental_marking_steps_++; cumulative_incremental_marking_bytes_ += bytes; @@ -294,6 +317,8 @@ void GCTracer::PrintNVP() const { PrintF("nodes_promoted=%d ", heap_->nodes_promoted_); PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_); PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_); + PrintF("new_space_allocation_throughput=%d ", + NewSpaceAllocationThroughputInBytesPerMillisecond()); if (current_.type == Event::SCAVENGER) { PrintF("steps_count=%d ", current_.incremental_marking_steps); @@ -435,5 +460,21 @@ intptr_t GCTracer::MarkCompactSpeedInBytesPerMillisecond() const { return static_cast(bytes / durations); } + + +intptr_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond() const { + intptr_t bytes = 0; + double durations = 0.0; + AllocationEventBuffer::const_iterator iter = allocation_events_.begin(); + while (iter != allocation_events_.end()) { + bytes += iter->allocation_in_bytes_; + durations += iter->duration_; + ++iter; + } + + if (durations == 0.0) return 0; + + return static_cast(bytes / durations); +} } } // namespace v8::internal diff --git a/src/heap/gc-tracer.h b/src/heap/gc-tracer.h index 0524f25..4e70f07 100644 --- a/src/heap/gc-tracer.h +++ b/src/heap/gc-tracer.h @@ -129,6 +129,22 @@ class GCTracer { }; + class AllocationEvent { + public: + // Default constructor leaves the event uninitialized. + AllocationEvent() {} + + AllocationEvent(double duration, intptr_t allocation_in_bytes); + + // Time spent in the mutator during the end of the last garbage collection + // to the beginning of the next garbage collection. + double duration_; + + // Memory allocated in the new space during the end of the last garbage + // collection to the beginning of the next garbage collection. + intptr_t allocation_in_bytes_; + }; + class Event { public: enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 }; @@ -223,6 +239,8 @@ class GCTracer { typedef RingBuffer EventBuffer; + typedef RingBuffer AllocationEventBuffer; + explicit GCTracer(Heap* heap); // Start collecting data. @@ -232,6 +250,9 @@ class GCTracer { // Stop collecting data and print results. void Stop(); + // Log an allocation throughput event. + void AddNewSpaceAllocationTime(double duration, intptr_t allocation_in_bytes); + // Log an incremental marking step. void AddIncrementalMarkingStep(double duration, intptr_t bytes); @@ -297,6 +318,10 @@ class GCTracer { // Returns 0 if no events have been recorded. intptr_t MarkCompactSpeedInBytesPerMillisecond() const; + // Allocation throughput in the new space in bytes/millisecond. + // Returns 0 if no events have been recorded. + intptr_t NewSpaceAllocationThroughputInBytesPerMillisecond() const; + private: // Print one detailed trace line in name=value format. // TODO(ernstm): Move to Heap. @@ -331,6 +356,9 @@ class GCTracer { // RingBuffers for MARK_COMPACTOR events. EventBuffer mark_compactor_events_; + // RingBuffer for allocation events. + AllocationEventBuffer allocation_events_; + // Cumulative number of incremental marking steps since creation of tracer. int cumulative_incremental_marking_steps_; @@ -361,6 +389,10 @@ class GCTracer { // all sweeping operations performed on the main thread. double cumulative_sweeping_duration_; + // Holds the new space top pointer recorded at the end of the last garbage + // collection. + intptr_t new_space_top_after_gc_; + DISALLOW_COPY_AND_ASSIGN(GCTracer); }; } -- 2.7.4