Index: src/heap/gc-tracer.h |
diff --git a/src/heap/gc-tracer.h b/src/heap/gc-tracer.h |
index d3a80619661493ce4e1bf0fd947bc5aad6a6219e..45e4dc61dce6859381bae36ecf1476a9c0491338 100644 |
--- a/src/heap/gc-tracer.h |
+++ b/src/heap/gc-tracer.h |
@@ -12,80 +12,49 @@ |
namespace v8 { |
namespace internal { |
-// A simple ring buffer class with maximum size known at compile time. |
-// The class only implements the functionality required in GCTracer. |
-template <typename T, size_t MAX_SIZE> |
+template <typename T> |
class RingBuffer { |
public: |
- class const_iterator { |
- public: |
- const_iterator() : index_(0), elements_(NULL) {} |
- |
- const_iterator(size_t index, const T* elements) |
- : index_(index), elements_(elements) {} |
- |
- bool operator==(const const_iterator& rhs) const { |
- return elements_ == rhs.elements_ && index_ == rhs.index_; |
- } |
- |
- bool operator!=(const const_iterator& rhs) const { |
- return elements_ != rhs.elements_ || index_ != rhs.index_; |
+ RingBuffer() { Reset(); } |
+ static const int kSize = 10; |
+ void Push(const T& value) { |
+ if (count_ == kSize) { |
+ elements_[start_++] = value; |
+ if (start_ == kSize) start_ = 0; |
+ } else { |
+ DCHECK_EQ(start_, 0); |
+ elements_[count_++] = value; |
} |
+ } |
- operator const T*() const { return elements_ + index_; } |
- |
- const T* operator->() const { return elements_ + index_; } |
- |
- const T& operator*() const { return elements_[index_]; } |
+ int Count() const { return count_; } |
- const_iterator& operator++() { |
- index_ = (index_ + 1) % (MAX_SIZE + 1); |
- return *this; |
+ template <typename Callback> |
+ T Sum(Callback callback, const T& initial) const { |
+ int j = start_ + count_ - 1; |
+ if (j >= kSize) j -= kSize; |
+ T result = initial; |
+ for (int i = 0; i < count_; i++) { |
+ result = callback(result, elements_[j]); |
+ if (--j == -1) j += kSize; |
} |
- |
- const_iterator& operator--() { |
- index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1); |
- return *this; |
- } |
- |
- private: |
- size_t index_; |
- const T* elements_; |
- }; |
- |
- RingBuffer() : begin_(0), end_(0) {} |
- |
- bool empty() const { return begin_ == end_; } |
- size_t size() const { |
- return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1); |
- } |
- const_iterator begin() const { return const_iterator(begin_, elements_); } |
- const_iterator end() const { return const_iterator(end_, elements_); } |
- const_iterator back() const { return --end(); } |
- void push_back(const T& element) { |
- elements_[end_] = element; |
- end_ = (end_ + 1) % (MAX_SIZE + 1); |
- if (end_ == begin_) begin_ = (begin_ + 1) % (MAX_SIZE + 1); |
- } |
- void push_front(const T& element) { |
- begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1); |
- if (begin_ == end_) end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1); |
- elements_[begin_] = element; |
+ return result; |
} |
- void reset() { |
- begin_ = 0; |
- end_ = 0; |
- } |
+ void Reset() { start_ = count_ = 0; } |
private: |
- T elements_[MAX_SIZE + 1]; |
- size_t begin_; |
- size_t end_; |
- |
+ T elements_[kSize]; |
+ int start_; |
+ int count_; |
DISALLOW_COPY_AND_ASSIGN(RingBuffer); |
}; |
+typedef std::pair<uint64_t, double> BytesAndDuration; |
+ |
+inline BytesAndDuration MakeBytesAndDuration(uint64_t bytes, double duration) { |
+ return std::make_pair(bytes, duration); |
+} |
enum ScavengeSpeedMode { kForAllObjects, kForSurvivedObjects }; |
@@ -158,58 +127,6 @@ class GCTracer { |
}; |
- class AllocationEvent { |
- public: |
- // Default constructor leaves the event uninitialized. |
- AllocationEvent() {} |
- |
- AllocationEvent(double duration, size_t allocation_in_bytes); |
- |
- // Time spent in the mutator during the end of the last sample to the |
- // beginning of the next sample. |
- double duration_; |
- |
- // Memory allocated in the new space during the end of the last sample |
- // to the beginning of the next sample |
- size_t allocation_in_bytes_; |
- }; |
- |
- |
- class CompactionEvent { |
- public: |
- CompactionEvent() : duration(0), live_bytes_compacted(0) {} |
- |
- CompactionEvent(double duration, intptr_t live_bytes_compacted) |
- : duration(duration), live_bytes_compacted(live_bytes_compacted) {} |
- |
- double duration; |
- intptr_t live_bytes_compacted; |
- }; |
- |
- |
- class ContextDisposalEvent { |
- public: |
- // Default constructor leaves the event uninitialized. |
- ContextDisposalEvent() {} |
- |
- explicit ContextDisposalEvent(double time); |
- |
- // Time when context disposal event happened. |
- double time_; |
- }; |
- |
- |
- class SurvivalEvent { |
- public: |
- // Default constructor leaves the event uninitialized. |
- SurvivalEvent() {} |
- |
- explicit SurvivalEvent(double survival_ratio); |
- |
- double promotion_ratio_; |
- }; |
- |
- |
class Event { |
public: |
enum Type { |
@@ -314,19 +231,6 @@ class GCTracer { |
double scopes[Scope::NUMBER_OF_SCOPES]; |
}; |
- static const size_t kRingBufferMaxSize = 10; |
- |
- typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer; |
- |
- typedef RingBuffer<AllocationEvent, kRingBufferMaxSize> AllocationEventBuffer; |
- |
- typedef RingBuffer<ContextDisposalEvent, kRingBufferMaxSize> |
- ContextDisposalEventBuffer; |
- |
- typedef RingBuffer<CompactionEvent, kRingBufferMaxSize> CompactionEventBuffer; |
- |
- typedef RingBuffer<SurvivalEvent, kRingBufferMaxSize> SurvivalEventBuffer; |
- |
static const int kThroughputTimeFrameMs = 5000; |
explicit GCTracer(Heap* heap); |
@@ -445,6 +349,13 @@ class GCTracer { |
// Discard all recorded survival events. |
void ResetSurvivalEvents(); |
+ // Returns the average speed of the events in the buffer. |
+ // If the buffer is empty, the result is 0. |
+ // Otherwise, the result is between 1 byte/ms and 1 GB/ms. |
+ static int AverageSpeed(const RingBuffer<BytesAndDuration>& buffer); |
+ static int AverageSpeed(const RingBuffer<BytesAndDuration>& buffer, |
+ const BytesAndDuration& initial, double time_ms); |
+ |
private: |
// Print one detailed trace line in name=value format. |
// TODO(ernstm): Move to Heap. |
@@ -458,12 +369,6 @@ class GCTracer { |
// it can be included in later crash dumps. |
void Output(const char* format, ...) const; |
- // Compute the mean duration of the events in the given ring buffer. |
- double MeanDuration(const EventBuffer& events) const; |
- |
- // Compute the max duration of the events in the given ring buffer. |
- double MaxDuration(const EventBuffer& events) const; |
- |
void ClearMarkCompactStatistics() { |
cumulative_incremental_marking_steps_ = 0; |
cumulative_incremental_marking_bytes_ = 0; |
@@ -500,28 +405,6 @@ class GCTracer { |
// Previous INCREMENTAL_MARK_COMPACTOR event. |
Event previous_incremental_mark_compactor_event_; |
- // RingBuffers for SCAVENGER events. |
- EventBuffer scavenger_events_; |
- |
- // RingBuffers for MARK_COMPACTOR events. |
- EventBuffer mark_compactor_events_; |
- |
- // RingBuffers for INCREMENTAL_MARK_COMPACTOR events. |
- EventBuffer incremental_mark_compactor_events_; |
- |
- // RingBuffer for allocation events. |
- AllocationEventBuffer new_space_allocation_events_; |
- AllocationEventBuffer old_generation_allocation_events_; |
- |
- // RingBuffer for context disposal events. |
- ContextDisposalEventBuffer context_disposal_events_; |
- |
- // RingBuffer for compaction events. |
- CompactionEventBuffer compaction_events_; |
- |
- // RingBuffer for survival events. |
- SurvivalEventBuffer survival_events_; |
- |
// Cumulative number of incremental marking steps since creation of tracer. |
int cumulative_incremental_marking_steps_; |
@@ -581,6 +464,17 @@ class GCTracer { |
// Separate timer used for --runtime_call_stats |
RuntimeCallTimer timer_; |
+ RingBuffer<BytesAndDuration> recorded_incremental_marking_steps_; |
+ RingBuffer<BytesAndDuration> recorded_scavenges_total_; |
+ RingBuffer<BytesAndDuration> recorded_scavenges_survived_; |
+ RingBuffer<BytesAndDuration> recorded_compactions_; |
+ RingBuffer<BytesAndDuration> recorded_mark_compacts_; |
+ RingBuffer<BytesAndDuration> recorded_incremental_mark_compacts_; |
+ RingBuffer<BytesAndDuration> recorded_new_generation_allocations_; |
+ RingBuffer<BytesAndDuration> recorded_old_generation_allocations_; |
+ RingBuffer<double> recorded_context_disposal_times_; |
+ RingBuffer<double> recorded_survival_ratios_; |
+ |
DISALLOW_COPY_AND_ASSIGN(GCTracer); |
}; |
} // namespace internal |