| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_COUNTERS_H_ | 5 #ifndef V8_COUNTERS_H_ |
| 6 #define V8_COUNTERS_H_ | 6 #define V8_COUNTERS_H_ |
| 7 | 7 |
| 8 #include "include/v8.h" | 8 #include "include/v8.h" |
| 9 #include "src/allocation.h" | 9 #include "src/allocation.h" |
| 10 #include "src/base/atomic-utils.h" | 10 #include "src/base/atomic-utils.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 namespace internal { | 22 namespace internal { |
| 23 | 23 |
| 24 // StatsCounters is an interface for plugging into external | 24 // StatsCounters is an interface for plugging into external |
| 25 // counters for monitoring. Counters can be looked up and | 25 // counters for monitoring. Counters can be looked up and |
| 26 // manipulated by name. | 26 // manipulated by name. |
| 27 | 27 |
| 28 class Counters; | 28 class Counters; |
| 29 | 29 |
| 30 class StatsTable { | 30 class StatsTable { |
| 31 public: | 31 public: |
| 32 // Register an application-defined function where | 32 // Register an application-defined function for recording |
| 33 // counters can be looked up. Note: Must be called on main thread, | 33 // subsequent counter statistics. |
| 34 // so that threaded stats counters can be created now. | |
| 35 void SetCounterFunction(CounterLookupCallback f); | 34 void SetCounterFunction(CounterLookupCallback f); |
| 36 | 35 |
| 37 // Register an application-defined function to create | 36 // Register an application-defined function to create histograms for |
| 38 // a histogram for passing to the AddHistogramSample function | 37 // recording subsequent histogram samples. |
| 39 void SetCreateHistogramFunction(CreateHistogramCallback f) { | 38 void SetCreateHistogramFunction(CreateHistogramCallback f) { |
| 40 create_histogram_function_ = f; | 39 create_histogram_function_ = f; |
| 41 } | 40 } |
| 42 | 41 |
| 43 // Register an application-defined function to add a sample | 42 // Register an application-defined function to add a sample |
| 44 // to a histogram created with CreateHistogram function | 43 // to a histogram created with CreateHistogram function. |
| 45 void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) { | 44 void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) { |
| 46 add_histogram_sample_function_ = f; | 45 add_histogram_sample_function_ = f; |
| 47 } | 46 } |
| 48 | 47 |
| 49 bool HasCounterFunction() const { | 48 bool HasCounterFunction() const { |
| 50 return lookup_function_ != NULL; | 49 return lookup_function_ != NULL; |
| 51 } | 50 } |
| 52 | 51 |
| 53 // Lookup the location of a counter by name. If the lookup | 52 // Lookup the location of a counter by name. If the lookup |
| 54 // is successful, returns a non-NULL pointer for writing the | 53 // is successful, returns a non-NULL pointer for writing the |
| (...skipping 20 matching lines...) Expand all Loading... |
| 75 } | 74 } |
| 76 | 75 |
| 77 // Add a sample to a histogram created with the CreateHistogram | 76 // Add a sample to a histogram created with the CreateHistogram |
| 78 // function. | 77 // function. |
| 79 void AddHistogramSample(void* histogram, int sample) { | 78 void AddHistogramSample(void* histogram, int sample) { |
| 80 if (!add_histogram_sample_function_) return; | 79 if (!add_histogram_sample_function_) return; |
| 81 return add_histogram_sample_function_(histogram, sample); | 80 return add_histogram_sample_function_(histogram, sample); |
| 82 } | 81 } |
| 83 | 82 |
| 84 private: | 83 private: |
| 84 friend class Counters; |
| 85 |
| 85 explicit StatsTable(Counters* counters); | 86 explicit StatsTable(Counters* counters); |
| 86 | 87 |
| 87 Counters* counters_; | |
| 88 CounterLookupCallback lookup_function_; | 88 CounterLookupCallback lookup_function_; |
| 89 CreateHistogramCallback create_histogram_function_; | 89 CreateHistogramCallback create_histogram_function_; |
| 90 AddHistogramSampleCallback add_histogram_sample_function_; | 90 AddHistogramSampleCallback add_histogram_sample_function_; |
| 91 | 91 |
| 92 friend class Counters; | |
| 93 | |
| 94 DISALLOW_COPY_AND_ASSIGN(StatsTable); | 92 DISALLOW_COPY_AND_ASSIGN(StatsTable); |
| 95 }; | 93 }; |
| 96 | 94 |
| 97 // Base class for stats counters. | 95 // Base class for stats counters. |
| 98 class StatsCounterBase { | 96 class StatsCounterBase { |
| 99 protected: | 97 protected: |
| 100 Counters* counters_; | 98 Counters* counters_; |
| 101 const char* name_; | 99 const char* name_; |
| 102 int* ptr_; | 100 int* ptr_; |
| 103 | 101 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 114 int* FindLocationInStatsTable() const; | 112 int* FindLocationInStatsTable() const; |
| 115 }; | 113 }; |
| 116 | 114 |
| 117 // StatsCounters are dynamically created values which can be tracked in | 115 // StatsCounters are dynamically created values which can be tracked in |
| 118 // the StatsTable. They are designed to be lightweight to create and | 116 // the StatsTable. They are designed to be lightweight to create and |
| 119 // easy to use. | 117 // easy to use. |
| 120 // | 118 // |
| 121 // Internally, a counter represents a value in a row of a StatsTable. | 119 // Internally, a counter represents a value in a row of a StatsTable. |
| 122 // The row has a 32bit value for each process/thread in the table and also | 120 // The row has a 32bit value for each process/thread in the table and also |
| 123 // a name (stored in the table metadata). Since the storage location can be | 121 // a name (stored in the table metadata). Since the storage location can be |
| 124 // thread-specific, this class cannot be shared across threads. | 122 // thread-specific, this class cannot be shared across threads. Note: This |
| 123 // class is not thread safe. |
| 125 class StatsCounter : public StatsCounterBase { | 124 class StatsCounter : public StatsCounterBase { |
| 126 public: | 125 public: |
| 127 StatsCounter() { } | |
| 128 StatsCounter(Counters* counters, const char* name) | |
| 129 : StatsCounterBase(counters, name), lookup_done_(false) {} | |
| 130 | |
| 131 // Sets the counter to a specific value. | 126 // Sets the counter to a specific value. |
| 132 void Set(int value) { | 127 void Set(int value) { |
| 133 if (int* loc = GetPtr()) SetLoc(loc, value); | 128 if (int* loc = GetPtr()) SetLoc(loc, value); |
| 134 } | 129 } |
| 135 | 130 |
| 136 // Increments the counter. | 131 // Increments the counter. |
| 137 void Increment() { | 132 void Increment() { |
| 138 if (int* loc = GetPtr()) IncrementLoc(loc); | 133 if (int* loc = GetPtr()) IncrementLoc(loc); |
| 139 } | 134 } |
| 140 | 135 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 159 | 154 |
| 160 // Get the internal pointer to the counter. This is used | 155 // Get the internal pointer to the counter. This is used |
| 161 // by the code generator to emit code that manipulates a | 156 // by the code generator to emit code that manipulates a |
| 162 // given counter without calling the runtime system. | 157 // given counter without calling the runtime system. |
| 163 int* GetInternalPointer() { | 158 int* GetInternalPointer() { |
| 164 int* loc = GetPtr(); | 159 int* loc = GetPtr(); |
| 165 DCHECK(loc != NULL); | 160 DCHECK(loc != NULL); |
| 166 return loc; | 161 return loc; |
| 167 } | 162 } |
| 168 | 163 |
| 164 private: |
| 165 friend class Counters; |
| 166 |
| 167 StatsCounter() {} |
| 168 StatsCounter(Counters* counters, const char* name) |
| 169 : StatsCounterBase(counters, name), lookup_done_(false) {} |
| 170 |
| 169 // Reset the cached internal pointer. | 171 // Reset the cached internal pointer. |
| 170 void Reset() { lookup_done_ = false; } | 172 void Reset() { lookup_done_ = false; } |
| 171 | 173 |
| 172 private: | |
| 173 // Returns the cached address of this counter location. | 174 // Returns the cached address of this counter location. |
| 174 int* GetPtr() { | 175 int* GetPtr() { |
| 175 if (lookup_done_) return ptr_; | 176 if (lookup_done_) return ptr_; |
| 176 lookup_done_ = true; | 177 lookup_done_ = true; |
| 177 ptr_ = FindLocationInStatsTable(); | 178 ptr_ = FindLocationInStatsTable(); |
| 178 return ptr_; | 179 return ptr_; |
| 179 } | 180 } |
| 180 | 181 |
| 181 bool lookup_done_; | 182 bool lookup_done_; |
| 182 }; | 183 }; |
| 183 | 184 |
| 184 // Thread safe version of StatsCounter. WARNING: Unlike StatsCounter, | 185 // Thread safe version of StatsCounter. |
| 185 // StatsCounterThreadSafe's constructor and method Reset() actually do | |
| 186 // the table lookup, and should be called from the main thread | |
| 187 // (i.e. not workers). | |
| 188 class StatsCounterThreadSafe : public StatsCounterBase { | 186 class StatsCounterThreadSafe : public StatsCounterBase { |
| 189 public: | 187 public: |
| 190 StatsCounterThreadSafe(Counters* counters, const char* name); | |
| 191 | |
| 192 void Set(int Value); | 188 void Set(int Value); |
| 193 void Increment(); | 189 void Increment(); |
| 194 void Increment(int value); | 190 void Increment(int value); |
| 195 void Decrement(); | 191 void Decrement(); |
| 196 void Decrement(int value); | 192 void Decrement(int value); |
| 197 bool Enabled() { return ptr_ != NULL; } | 193 bool Enabled() { return ptr_ != NULL; } |
| 198 int* GetInternalPointer() { | 194 int* GetInternalPointer() { |
| 199 DCHECK(ptr_ != NULL); | 195 DCHECK(ptr_ != NULL); |
| 200 return ptr_; | 196 return ptr_; |
| 201 } | 197 } |
| 202 void Reset() { GetPtr(); } | |
| 203 | 198 |
| 204 private: | 199 private: |
| 205 int* GetPtr(); | 200 friend class Counters; |
| 201 |
| 202 StatsCounterThreadSafe(Counters* counters, const char* name); |
| 203 void Reset() { ptr_ = FindLocationInStatsTable(); } |
| 206 | 204 |
| 207 base::Mutex mutex_; | 205 base::Mutex mutex_; |
| 208 | 206 |
| 209 private: | |
| 210 DISALLOW_IMPLICIT_CONSTRUCTORS(StatsCounterThreadSafe); | 207 DISALLOW_IMPLICIT_CONSTRUCTORS(StatsCounterThreadSafe); |
| 211 }; | 208 }; |
| 212 | 209 |
| 213 // A Histogram represents a dynamically created histogram in the StatsTable. | 210 // A Histogram represents a dynamically created histogram in the |
| 214 // It will be registered with the histogram system on first use. | 211 // StatsTable. Note: This class is thread safe. |
| 215 class Histogram { | 212 class Histogram { |
| 216 public: | 213 public: |
| 217 Histogram() { } | 214 // Add a single sample to this histogram. |
| 215 void AddSample(int sample); |
| 216 |
| 217 // Returns true if this histogram is enabled. |
| 218 bool Enabled() { return histogram_ != nullptr; } |
| 219 |
| 220 const char* name() { return name_; } |
| 221 |
| 222 protected: |
| 223 Histogram() {} |
| 218 Histogram(const char* name, int min, int max, int num_buckets, | 224 Histogram(const char* name, int min, int max, int num_buckets, |
| 219 Counters* counters) | 225 Counters* counters) |
| 220 : name_(name), | 226 : name_(name), |
| 221 min_(min), | 227 min_(min), |
| 222 max_(max), | 228 max_(max), |
| 223 num_buckets_(num_buckets), | 229 num_buckets_(num_buckets), |
| 224 histogram_(NULL), | 230 histogram_(nullptr), |
| 225 lookup_done_(false), | |
| 226 counters_(counters) {} | 231 counters_(counters) {} |
| 227 | 232 |
| 228 // Add a single sample to this histogram. | |
| 229 void AddSample(int sample); | |
| 230 | |
| 231 // Returns true if this histogram is enabled. | |
| 232 bool Enabled() { | |
| 233 return GetHistogram() != NULL; | |
| 234 } | |
| 235 | |
| 236 // Reset the cached internal pointer. | |
| 237 void Reset() { | |
| 238 lookup_done_ = false; | |
| 239 } | |
| 240 | |
| 241 const char* name() { return name_; } | |
| 242 | |
| 243 protected: | |
| 244 // Returns the handle to the histogram. | |
| 245 void* GetHistogram() { | |
| 246 if (!lookup_done_) { | |
| 247 lookup_done_ = true; | |
| 248 histogram_ = CreateHistogram(); | |
| 249 } | |
| 250 return histogram_; | |
| 251 } | |
| 252 | |
| 253 Counters* counters() const { return counters_; } | 233 Counters* counters() const { return counters_; } |
| 254 | 234 |
| 235 // Reset the cached internal pointer. |
| 236 void Reset() { histogram_ = CreateHistogram(); } |
| 237 |
| 255 private: | 238 private: |
| 239 friend class Counters; |
| 240 |
| 256 void* CreateHistogram() const; | 241 void* CreateHistogram() const; |
| 257 | 242 |
| 258 const char* name_; | 243 const char* name_; |
| 259 int min_; | 244 int min_; |
| 260 int max_; | 245 int max_; |
| 261 int num_buckets_; | 246 int num_buckets_; |
| 262 void* histogram_; | 247 void* histogram_; |
| 263 bool lookup_done_; | |
| 264 Counters* counters_; | 248 Counters* counters_; |
| 265 }; | 249 }; |
| 266 | 250 |
| 267 // A HistogramTimer allows distributions of results to be created. | 251 // A HistogramTimer allows distributions of results to be created. |
| 268 class HistogramTimer : public Histogram { | 252 class HistogramTimer : public Histogram { |
| 269 public: | 253 public: |
| 270 enum Resolution { | 254 enum Resolution { |
| 271 MILLISECOND, | 255 MILLISECOND, |
| 272 MICROSECOND | 256 MICROSECOND |
| 273 }; | 257 }; |
| 274 | 258 |
| 275 HistogramTimer() {} | 259 // Note: public for testing purposes only. |
| 276 HistogramTimer(const char* name, int min, int max, Resolution resolution, | 260 HistogramTimer(const char* name, int min, int max, Resolution resolution, |
| 277 int num_buckets, Counters* counters) | 261 int num_buckets, Counters* counters) |
| 278 : Histogram(name, min, max, num_buckets, counters), | 262 : Histogram(name, min, max, num_buckets, counters), |
| 279 resolution_(resolution) {} | 263 resolution_(resolution) {} |
| 280 | 264 |
| 281 // Start the timer. | 265 // Start the timer. |
| 282 void Start(); | 266 void Start(); |
| 283 | 267 |
| 284 // Stop the timer and record the results. | 268 // Stop the timer and record the results. |
| 285 void Stop(); | 269 void Stop(); |
| 286 | 270 |
| 287 // Returns true if the timer is running. | 271 // Returns true if the timer is running. |
| 288 bool Running() { | 272 bool Running() { |
| 289 return Enabled() && timer_.IsStarted(); | 273 return Enabled() && timer_.IsStarted(); |
| 290 } | 274 } |
| 291 | 275 |
| 292 // TODO(bmeurer): Remove this when HistogramTimerScope is fixed. | 276 // TODO(bmeurer): Remove this when HistogramTimerScope is fixed. |
| 293 #ifdef DEBUG | 277 #ifdef DEBUG |
| 294 base::ElapsedTimer* timer() { return &timer_; } | 278 base::ElapsedTimer* timer() { return &timer_; } |
| 295 #endif | 279 #endif |
| 296 | 280 |
| 297 private: | 281 private: |
| 282 friend class Counters; |
| 283 |
| 298 base::ElapsedTimer timer_; | 284 base::ElapsedTimer timer_; |
| 299 Resolution resolution_; | 285 Resolution resolution_; |
| 286 |
| 287 HistogramTimer() {} |
| 300 }; | 288 }; |
| 301 | 289 |
| 302 // Helper class for scoping a HistogramTimer. | 290 // Helper class for scoping a HistogramTimer. |
| 303 // TODO(bmeurer): The ifdeffery is an ugly hack around the fact that the | 291 // TODO(bmeurer): The ifdeffery is an ugly hack around the fact that the |
| 304 // Parser is currently reentrant (when it throws an error, we call back | 292 // Parser is currently reentrant (when it throws an error, we call back |
| 305 // into JavaScript and all bets are off), but ElapsedTimer is not | 293 // into JavaScript and all bets are off), but ElapsedTimer is not |
| 306 // reentry-safe. Fix this properly and remove |allow_nesting|. | 294 // reentry-safe. Fix this properly and remove |allow_nesting|. |
| 307 class HistogramTimerScope BASE_EMBEDDED { | 295 class HistogramTimerScope BASE_EMBEDDED { |
| 308 public: | 296 public: |
| 309 explicit HistogramTimerScope(HistogramTimer* timer, | 297 explicit HistogramTimerScope(HistogramTimer* timer, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 // An example use might be to aggregate the time spent in lazy compilation | 336 // An example use might be to aggregate the time spent in lazy compilation |
| 349 // while running a script. | 337 // while running a script. |
| 350 // | 338 // |
| 351 // Helpers: | 339 // Helpers: |
| 352 // - AggregatingHistogramTimerScope, the "outer" scope within which | 340 // - AggregatingHistogramTimerScope, the "outer" scope within which |
| 353 // times will be summed up. | 341 // times will be summed up. |
| 354 // - AggregatedHistogramTimerScope, the "inner" scope which defines the | 342 // - AggregatedHistogramTimerScope, the "inner" scope which defines the |
| 355 // events to be timed. | 343 // events to be timed. |
| 356 class AggregatableHistogramTimer : public Histogram { | 344 class AggregatableHistogramTimer : public Histogram { |
| 357 public: | 345 public: |
| 358 AggregatableHistogramTimer() {} | |
| 359 AggregatableHistogramTimer(const char* name, int min, int max, | |
| 360 int num_buckets, Counters* counters) | |
| 361 : Histogram(name, min, max, num_buckets, counters) {} | |
| 362 | |
| 363 // Start/stop the "outer" scope. | 346 // Start/stop the "outer" scope. |
| 364 void Start() { time_ = base::TimeDelta(); } | 347 void Start() { time_ = base::TimeDelta(); } |
| 365 void Stop() { AddSample(static_cast<int>(time_.InMicroseconds())); } | 348 void Stop() { AddSample(static_cast<int>(time_.InMicroseconds())); } |
| 366 | 349 |
| 367 // Add a time value ("inner" scope). | 350 // Add a time value ("inner" scope). |
| 368 void Add(base::TimeDelta other) { time_ += other; } | 351 void Add(base::TimeDelta other) { time_ += other; } |
| 369 | 352 |
| 370 private: | 353 private: |
| 354 friend class Counters; |
| 355 |
| 356 AggregatableHistogramTimer() {} |
| 357 AggregatableHistogramTimer(const char* name, int min, int max, |
| 358 int num_buckets, Counters* counters) |
| 359 : Histogram(name, min, max, num_buckets, counters) {} |
| 360 |
| 371 base::TimeDelta time_; | 361 base::TimeDelta time_; |
| 372 }; | 362 }; |
| 373 | 363 |
| 374 // A helper class for use with AggregatableHistogramTimer. This is the | 364 // A helper class for use with AggregatableHistogramTimer. This is the |
| 375 // // outer-most timer scope used with an AggregatableHistogramTimer. It will | 365 // // outer-most timer scope used with an AggregatableHistogramTimer. It will |
| 376 // // aggregate the information from the inner AggregatedHistogramTimerScope. | 366 // // aggregate the information from the inner AggregatedHistogramTimerScope. |
| 377 class AggregatingHistogramTimerScope { | 367 class AggregatingHistogramTimerScope { |
| 378 public: | 368 public: |
| 379 explicit AggregatingHistogramTimerScope(AggregatableHistogramTimer* histogram) | 369 explicit AggregatingHistogramTimerScope(AggregatableHistogramTimer* histogram) |
| 380 : histogram_(histogram) { | 370 : histogram_(histogram) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 407 // backing histogram receives one sample every T ms, where the T is controlled | 397 // backing histogram receives one sample every T ms, where the T is controlled |
| 408 // by the FLAG_histogram_interval. | 398 // by the FLAG_histogram_interval. |
| 409 // | 399 // |
| 410 // More formally: let F be a real-valued function that maps time to sample | 400 // More formally: let F be a real-valued function that maps time to sample |
| 411 // values. We define F as a linear interpolation between adjacent samples. For | 401 // values. We define F as a linear interpolation between adjacent samples. For |
| 412 // each time interval [x; x + T) the backing histogram gets one sample value | 402 // each time interval [x; x + T) the backing histogram gets one sample value |
| 413 // that is the average of F(t) in the interval. | 403 // that is the average of F(t) in the interval. |
| 414 template <typename Histogram> | 404 template <typename Histogram> |
| 415 class AggregatedMemoryHistogram { | 405 class AggregatedMemoryHistogram { |
| 416 public: | 406 public: |
| 417 AggregatedMemoryHistogram() | 407 // Note: public for testing purposes only. |
| 418 : is_initialized_(false), | |
| 419 start_ms_(0.0), | |
| 420 last_ms_(0.0), | |
| 421 aggregate_value_(0.0), | |
| 422 last_value_(0.0), | |
| 423 backing_histogram_(NULL) {} | |
| 424 | |
| 425 explicit AggregatedMemoryHistogram(Histogram* backing_histogram) | 408 explicit AggregatedMemoryHistogram(Histogram* backing_histogram) |
| 426 : AggregatedMemoryHistogram() { | 409 : AggregatedMemoryHistogram() { |
| 427 backing_histogram_ = backing_histogram; | 410 backing_histogram_ = backing_histogram; |
| 428 } | 411 } |
| 429 | 412 |
| 430 // Invariants that hold before and after AddSample if | 413 // Invariants that hold before and after AddSample if |
| 431 // is_initialized_ is true: | 414 // is_initialized_ is true: |
| 432 // | 415 // |
| 433 // 1) For we processed samples that came in before start_ms_ and sent the | 416 // 1) For we processed samples that came in before start_ms_ and sent the |
| 434 // corresponding aggregated samples to backing histogram. | 417 // corresponding aggregated samples to backing histogram. |
| 435 // 2) (last_ms_, last_value_) is the last received sample. | 418 // 2) (last_ms_, last_value_) is the last received sample. |
| 436 // 3) last_ms_ < start_ms_ + FLAG_histogram_interval. | 419 // 3) last_ms_ < start_ms_ + FLAG_histogram_interval. |
| 437 // 4) aggregate_value_ is the average of the function that is constructed by | 420 // 4) aggregate_value_ is the average of the function that is constructed by |
| 438 // linearly interpolating samples received between start_ms_ and last_ms_. | 421 // linearly interpolating samples received between start_ms_ and last_ms_. |
| 439 void AddSample(double current_ms, double current_value); | 422 void AddSample(double current_ms, double current_value); |
| 440 | 423 |
| 441 private: | 424 private: |
| 425 friend class Counters; |
| 426 |
| 427 AggregatedMemoryHistogram() |
| 428 : is_initialized_(false), |
| 429 start_ms_(0.0), |
| 430 last_ms_(0.0), |
| 431 aggregate_value_(0.0), |
| 432 last_value_(0.0), |
| 433 backing_histogram_(NULL) {} |
| 442 double Aggregate(double current_ms, double current_value); | 434 double Aggregate(double current_ms, double current_value); |
| 435 |
| 443 bool is_initialized_; | 436 bool is_initialized_; |
| 444 double start_ms_; | 437 double start_ms_; |
| 445 double last_ms_; | 438 double last_ms_; |
| 446 double aggregate_value_; | 439 double aggregate_value_; |
| 447 double last_value_; | 440 double last_value_; |
| 448 Histogram* backing_histogram_; | 441 Histogram* backing_histogram_; |
| 449 }; | 442 }; |
| 450 | 443 |
| 451 | 444 |
| 452 template <typename Histogram> | 445 template <typename Histogram> |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 522 |
| 530 const char* name() const { return name_; } | 523 const char* name() const { return name_; } |
| 531 int64_t count() const { return count_; } | 524 int64_t count() const { return count_; } |
| 532 base::TimeDelta time() const { | 525 base::TimeDelta time() const { |
| 533 return base::TimeDelta::FromMicroseconds(time_); | 526 return base::TimeDelta::FromMicroseconds(time_); |
| 534 } | 527 } |
| 535 void Increment() { count_++; } | 528 void Increment() { count_++; } |
| 536 void Add(base::TimeDelta delta) { time_ += delta.InMicroseconds(); } | 529 void Add(base::TimeDelta delta) { time_ += delta.InMicroseconds(); } |
| 537 | 530 |
| 538 private: | 531 private: |
| 532 friend class RuntimeCallStats; |
| 533 |
| 539 RuntimeCallCounter() {} | 534 RuntimeCallCounter() {} |
| 540 | 535 |
| 541 const char* name_; | 536 const char* name_; |
| 542 int64_t count_; | 537 int64_t count_; |
| 543 // Stored as int64_t so that its initialization can be deferred. | 538 // Stored as int64_t so that its initialization can be deferred. |
| 544 int64_t time_; | 539 int64_t time_; |
| 545 | |
| 546 friend class RuntimeCallStats; | |
| 547 }; | 540 }; |
| 548 | 541 |
| 549 // RuntimeCallTimer is used to keep track of the stack of currently active | 542 // RuntimeCallTimer is used to keep track of the stack of currently active |
| 550 // timers used for properly measuring the own time of a RuntimeCallCounter. | 543 // timers used for properly measuring the own time of a RuntimeCallCounter. |
| 551 class RuntimeCallTimer final { | 544 class RuntimeCallTimer final { |
| 552 public: | 545 public: |
| 553 RuntimeCallCounter* counter() { return counter_; } | 546 RuntimeCallCounter* counter() { return counter_; } |
| 554 void set_counter(RuntimeCallCounter* counter) { counter_ = counter; } | 547 void set_counter(RuntimeCallCounter* counter) { counter_ = counter; } |
| 555 RuntimeCallTimer* parent() const { return parent_.Value(); } | 548 RuntimeCallTimer* parent() const { return parent_.Value(); } |
| 556 void set_parent(RuntimeCallTimer* timer) { parent_.SetValue(timer); } | 549 void set_parent(RuntimeCallTimer* timer) { parent_.SetValue(timer); } |
| (...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 #define STATS_COUNTER_TS_LIST(SC) \ | 1203 #define STATS_COUNTER_TS_LIST(SC) \ |
| 1211 SC(wasm_generated_code_size, V8.WasmGeneratedCodeBytes) \ | 1204 SC(wasm_generated_code_size, V8.WasmGeneratedCodeBytes) \ |
| 1212 SC(wasm_reloc_size, V8.WasmRelocBytes) \ | 1205 SC(wasm_reloc_size, V8.WasmRelocBytes) \ |
| 1213 SC(wasm_lazily_compiled_functions, V8.WasmLazilyCompiledFunctions) | 1206 SC(wasm_lazily_compiled_functions, V8.WasmLazilyCompiledFunctions) |
| 1214 | 1207 |
| 1215 // This file contains all the v8 counters that are in use. | 1208 // This file contains all the v8 counters that are in use. |
| 1216 class Counters : public std::enable_shared_from_this<Counters> { | 1209 class Counters : public std::enable_shared_from_this<Counters> { |
| 1217 public: | 1210 public: |
| 1218 explicit Counters(Isolate* isolate); | 1211 explicit Counters(Isolate* isolate); |
| 1219 | 1212 |
| 1213 // Register an application-defined function for recording |
| 1214 // subsequent counter statistics. Note: Must be called on the main |
| 1215 // thread. |
| 1216 void ResetCounterFunction(CounterLookupCallback f); |
| 1217 |
| 1218 // Register an application-defined function to create histograms for |
| 1219 // recording subsequent histogram samples. Note: Must be called on |
| 1220 // the main thread. |
| 1221 void ResetCreateHistogramFunction(CreateHistogramCallback f); |
| 1222 |
| 1223 // Register an application-defined function to add a sample |
| 1224 // to a histogram. Will be used in all subsequent sample additions. |
| 1225 // Note: Must be called on the main thread. |
| 1226 void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) { |
| 1227 stats_table_.SetAddHistogramSampleFunction(f); |
| 1228 } |
| 1229 |
| 1220 #define HR(name, caption, min, max, num_buckets) \ | 1230 #define HR(name, caption, min, max, num_buckets) \ |
| 1221 Histogram* name() { return &name##_; } | 1231 Histogram* name() { return &name##_; } |
| 1222 HISTOGRAM_RANGE_LIST(HR) | 1232 HISTOGRAM_RANGE_LIST(HR) |
| 1223 #undef HR | 1233 #undef HR |
| 1224 | 1234 |
| 1225 #define HT(name, caption, max, res) \ | 1235 #define HT(name, caption, max, res) \ |
| 1226 HistogramTimer* name() { return &name##_; } | 1236 HistogramTimer* name() { return &name##_; } |
| 1227 HISTOGRAM_TIMER_LIST(HT) | 1237 HISTOGRAM_TIMER_LIST(HT) |
| 1228 #undef HT | 1238 #undef HT |
| 1229 | 1239 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COUNTER_ID) | 1333 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COUNTER_ID) |
| 1324 #undef COUNTER_ID | 1334 #undef COUNTER_ID |
| 1325 #define COUNTER_ID(name) kCountOfCODE_AGE__##name, \ | 1335 #define COUNTER_ID(name) kCountOfCODE_AGE__##name, \ |
| 1326 kSizeOfCODE_AGE__##name, | 1336 kSizeOfCODE_AGE__##name, |
| 1327 CODE_AGE_LIST_COMPLETE(COUNTER_ID) | 1337 CODE_AGE_LIST_COMPLETE(COUNTER_ID) |
| 1328 #undef COUNTER_ID | 1338 #undef COUNTER_ID |
| 1329 stats_counter_count | 1339 stats_counter_count |
| 1330 }; | 1340 }; |
| 1331 // clang-format on | 1341 // clang-format on |
| 1332 | 1342 |
| 1333 void ResetCounters(); | |
| 1334 void ResetHistograms(); | |
| 1335 void InitializeHistograms(); | |
| 1336 | |
| 1337 RuntimeCallStats* runtime_call_stats() { return &runtime_call_stats_; } | 1343 RuntimeCallStats* runtime_call_stats() { return &runtime_call_stats_; } |
| 1338 | 1344 |
| 1339 StatsTable* stats_table() { return &stats_table_; } | 1345 private: |
| 1346 friend class StatsTable; |
| 1347 friend class StatsCounterBase; |
| 1348 friend class Histogram; |
| 1349 friend class HistogramTimer; |
| 1350 |
| 1351 Isolate* isolate_; |
| 1352 StatsTable stats_table_; |
| 1353 |
| 1354 int* FindLocation(const char* name) { |
| 1355 return stats_table_.FindLocation(name); |
| 1356 } |
| 1357 |
| 1358 void* CreateHistogram(const char* name, int min, int max, size_t buckets) { |
| 1359 return stats_table_.CreateHistogram(name, min, max, buckets); |
| 1360 } |
| 1361 |
| 1362 void AddHistogramSample(void* histogram, int sample) { |
| 1363 stats_table_.AddHistogramSample(histogram, sample); |
| 1364 } |
| 1340 | 1365 |
| 1341 Isolate* isolate() { return isolate_; } | 1366 Isolate* isolate() { return isolate_; } |
| 1342 | 1367 |
| 1343 private: | |
| 1344 Isolate* isolate_; | |
| 1345 StatsTable stats_table_; | |
| 1346 | |
| 1347 #define HR(name, caption, min, max, num_buckets) Histogram name##_; | 1368 #define HR(name, caption, min, max, num_buckets) Histogram name##_; |
| 1348 HISTOGRAM_RANGE_LIST(HR) | 1369 HISTOGRAM_RANGE_LIST(HR) |
| 1349 #undef HR | 1370 #undef HR |
| 1350 | 1371 |
| 1351 #define HT(name, caption, max, res) HistogramTimer name##_; | 1372 #define HT(name, caption, max, res) HistogramTimer name##_; |
| 1352 HISTOGRAM_TIMER_LIST(HT) | 1373 HISTOGRAM_TIMER_LIST(HT) |
| 1353 #undef HT | 1374 #undef HT |
| 1354 | 1375 |
| 1355 #define AHT(name, caption) \ | 1376 #define AHT(name, caption) \ |
| 1356 AggregatableHistogramTimer name##_; | 1377 AggregatableHistogramTimer name##_; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 | 1430 |
| 1410 RuntimeCallStats runtime_call_stats_; | 1431 RuntimeCallStats runtime_call_stats_; |
| 1411 | 1432 |
| 1412 DISALLOW_IMPLICIT_CONSTRUCTORS(Counters); | 1433 DISALLOW_IMPLICIT_CONSTRUCTORS(Counters); |
| 1413 }; | 1434 }; |
| 1414 | 1435 |
| 1415 } // namespace internal | 1436 } // namespace internal |
| 1416 } // namespace v8 | 1437 } // namespace v8 |
| 1417 | 1438 |
| 1418 #endif // V8_COUNTERS_H_ | 1439 #endif // V8_COUNTERS_H_ |
| OLD | NEW |