Index: src/counters.h |
diff --git a/src/counters.h b/src/counters.h |
index da8deb35eb54d8b9c8f5141dad077b494698a502..80839b96d8a40f26415631c174b5feb63c8a7dd9 100644 |
--- a/src/counters.h |
+++ b/src/counters.h |
@@ -358,6 +358,124 @@ class AggregatedHistogramTimerScope { |
}; |
+// AggretatedMemoryHistogram collects (time, value) sample pairs and turns |
+// them into time-uniform samples for the backing historgram, such that the |
+// backing histogram receives one sample every T ms, where the T is controlled |
+// by the FLAG_histogram_interval. |
+// |
+// More formally: let F be a real-valued function that maps time to sample |
+// values. We define F as a linear interpolation between adjacent samples. For |
+// each time interval [x; x + T) the backing histogram gets one sample value |
+// that is the average of F(t) in the interval. |
+template <typename Histogram> |
+class AggregatedMemoryHistogram { |
+ public: |
+ AggregatedMemoryHistogram() |
+ : is_initialized_(false), |
+ start_ms_(0.0), |
+ last_ms_(0.0), |
+ aggregate_value_(0.0), |
+ last_value_(0.0), |
+ backing_histogram_(NULL) {} |
+ |
+ explicit AggregatedMemoryHistogram(Histogram* backing_histogram) |
+ : AggregatedMemoryHistogram() { |
+ backing_histogram_ = backing_histogram; |
+ } |
+ |
+ // Invariants that hold before and after AddSample if |
+ // is_initialized_ is true: |
+ // |
+ // 1) For we processed samples that came in before start_ms_ and sent the |
+ // corresponding aggregated samples to backing histogram. |
+ // 2) (last_ms_, last_value_) is the last received sample. |
+ // 3) last_ms_ < start_ms_ + FLAG_histogram_interval. |
+ // 4) aggregate_value_ is the average of the function that is constructed by |
+ // linearly interpolating samples received between start_ms_ and last_ms_. |
+ void AddSample(double current_ms, double current_value); |
+ |
+ private: |
+ double Aggregate(double current_ms, double current_value); |
+ bool is_initialized_; |
+ double start_ms_; |
+ double last_ms_; |
+ double aggregate_value_; |
+ double last_value_; |
+ Histogram* backing_histogram_; |
+}; |
+ |
+ |
+template <typename Histogram> |
+void AggregatedMemoryHistogram<Histogram>::AddSample(double current_ms, |
+ double current_value) { |
+ if (!is_initialized_) { |
+ aggregate_value_ = current_value; |
+ start_ms_ = current_ms; |
+ last_value_ = current_value; |
+ last_ms_ = current_ms; |
+ is_initialized_ = true; |
+ } else { |
+ const double kEpsilon = 1e-6; |
+ const int kMaxSamples = 1000; |
+ if (current_ms < last_ms_ + kEpsilon) { |
+ // Two samples have the same time, remember the last one. |
+ last_value_ = current_value; |
+ } else { |
+ double sample_interval_ms = FLAG_histogram_interval; |
+ double end_ms = start_ms_ + sample_interval_ms; |
+ if (end_ms <= current_ms + kEpsilon) { |
+ // Linearly interpolate between the last_ms_ and the current_ms. |
+ double slope = (current_value - last_value_) / (current_ms - last_ms_); |
+ int i; |
+ // Send aggregated samples to the backing histogram from the start_ms |
+ // to the current_ms. |
+ for (i = 0; i < kMaxSamples && end_ms <= current_ms + kEpsilon; i++) { |
+ double end_value = last_value_ + (end_ms - last_ms_) * slope; |
+ double sample_value; |
+ if (i == 0) { |
+ // Take aggregate_value_ into account. |
+ sample_value = Aggregate(end_ms, end_value); |
+ } else { |
+ // There is no aggregate_value_ for i > 0. |
+ sample_value = (last_value_ + end_value) / 2; |
+ } |
+ backing_histogram_->AddSample(static_cast<int>(sample_value + 0.5)); |
+ last_value_ = end_value; |
+ last_ms_ = end_ms; |
+ end_ms += sample_interval_ms; |
+ } |
+ if (i == kMaxSamples) { |
+ // We hit the sample limit, ignore the remaining samples. |
+ aggregate_value_ = current_value; |
+ start_ms_ = current_ms; |
+ } else { |
+ aggregate_value_ = last_value_; |
+ start_ms_ = last_ms_; |
+ } |
+ } |
+ aggregate_value_ = current_ms > start_ms_ + kEpsilon |
+ ? Aggregate(current_ms, current_value) |
+ : aggregate_value_; |
+ last_value_ = current_value; |
+ last_ms_ = current_ms; |
+ } |
+ } |
+} |
+ |
+ |
+template <typename Histogram> |
+double AggregatedMemoryHistogram<Histogram>::Aggregate(double current_ms, |
+ double current_value) { |
+ double interval_ms = current_ms - start_ms_; |
+ double value = (current_value + last_value_) / 2; |
+ // The aggregate_value_ is the average for [start_ms_; last_ms_]. |
+ // The value is the average for [last_ms_; current_ms]. |
+ // Return the weighted average of the aggregate_value_ and the value. |
+ return aggregate_value_ * ((last_ms_ - start_ms_) / interval_ms) + |
+ value * ((current_ms - last_ms_) / interval_ms); |
+} |
+ |
+ |
#define HISTOGRAM_RANGE_LIST(HR) \ |
/* Generic range histograms */ \ |
HR(detached_context_age_in_gc, V8.DetachedContextAgeInGC, 0, 20, 21) \ |
@@ -414,15 +532,16 @@ class AggregatedHistogramTimerScope { |
HP(codegen_fraction_crankshaft, V8.CodegenFractionCrankshaft) |
-#define HISTOGRAM_MEMORY_LIST(HM) \ |
- HM(heap_sample_total_committed, V8.MemoryHeapSampleTotalCommitted) \ |
- HM(heap_sample_total_used, V8.MemoryHeapSampleTotalUsed) \ |
- HM(heap_sample_map_space_committed, \ |
- V8.MemoryHeapSampleMapSpaceCommitted) \ |
- HM(heap_sample_code_space_committed, \ |
- V8.MemoryHeapSampleCodeSpaceCommitted) \ |
- HM(heap_sample_maximum_committed, \ |
- V8.MemoryHeapSampleMaximumCommitted) \ |
+#define HISTOGRAM_LEGACY_MEMORY_LIST(HM) \ |
+ HM(heap_sample_total_committed, V8.MemoryHeapSampleTotalCommitted) \ |
+ HM(heap_sample_total_used, V8.MemoryHeapSampleTotalUsed) \ |
+ HM(heap_sample_map_space_committed, V8.MemoryHeapSampleMapSpaceCommitted) \ |
+ HM(heap_sample_code_space_committed, V8.MemoryHeapSampleCodeSpaceCommitted) \ |
+ HM(heap_sample_maximum_committed, V8.MemoryHeapSampleMaximumCommitted) |
Alexei Svitkine (slow)
2016/06/28 16:54:39
Hi, this histogram doesn't appear to be in histogr
|
+ |
+#define HISTOGRAM_MEMORY_LIST(HM) \ |
+ HM(memory_heap_committed, V8.MemoryHeapCommitted) \ |
+ HM(memory_heap_used, V8.MemoryHeapUsed) |
// WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC |
@@ -620,6 +739,14 @@ class Counters { |
#define HM(name, caption) \ |
Histogram* name() { return &name##_; } |
+ HISTOGRAM_LEGACY_MEMORY_LIST(HM) |
+ HISTOGRAM_MEMORY_LIST(HM) |
+#undef HM |
+ |
+#define HM(name, caption) \ |
+ AggregatedMemoryHistogram<Histogram>* aggregated_##name() { \ |
+ return &aggregated_##name##_; \ |
+ } |
HISTOGRAM_MEMORY_LIST(HM) |
#undef HM |
@@ -670,6 +797,7 @@ class Counters { |
HISTOGRAM_PERCENTAGE_LIST(PERCENTAGE_ID) |
#undef PERCENTAGE_ID |
#define MEMORY_ID(name, caption) k_##name, |
+ HISTOGRAM_LEGACY_MEMORY_LIST(MEMORY_ID) |
HISTOGRAM_MEMORY_LIST(MEMORY_ID) |
#undef MEMORY_ID |
#define COUNTER_ID(name, caption) k_##name, |
@@ -718,6 +846,12 @@ class Counters { |
#define HM(name, caption) \ |
Histogram name##_; |
+ HISTOGRAM_LEGACY_MEMORY_LIST(HM) |
+ HISTOGRAM_MEMORY_LIST(HM) |
+#undef HM |
+ |
+#define HM(name, caption) \ |
+ AggregatedMemoryHistogram<Histogram> aggregated_##name##_; |
HISTOGRAM_MEMORY_LIST(HM) |
#undef HM |