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/platform/elapsed-timer.h" | 10 #include "src/base/platform/elapsed-timer.h" |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 void Stop() { AddSample(static_cast<int>(time_.InMicroseconds())); } | 325 void Stop() { AddSample(static_cast<int>(time_.InMicroseconds())); } |
326 | 326 |
327 // Add a time value ("inner" scope). | 327 // Add a time value ("inner" scope). |
328 void Add(base::TimeDelta other) { time_ += other; } | 328 void Add(base::TimeDelta other) { time_ += other; } |
329 | 329 |
330 private: | 330 private: |
331 base::TimeDelta time_; | 331 base::TimeDelta time_; |
332 }; | 332 }; |
333 | 333 |
334 // A helper class for use with AggregatableHistogramTimer. This is the | 334 // A helper class for use with AggregatableHistogramTimer. This is the |
335 // outer-most timer scope used with an AggregatableHistogramTimer. It will | 335 // // outer-most timer scope used with an AggregatableHistogramTimer. It will |
336 // aggregate the information from the inner AggregatedHistogramTimerScope. | 336 // // aggregate the information from the inner AggregatedHistogramTimerScope. |
337 class AggregatingHistogramTimerScope { | 337 class AggregatingHistogramTimerScope { |
338 public: | 338 public: |
339 explicit AggregatingHistogramTimerScope(AggregatableHistogramTimer* histogram) | 339 explicit AggregatingHistogramTimerScope(AggregatableHistogramTimer* histogram) |
340 : histogram_(histogram) { | 340 : histogram_(histogram) { |
341 histogram_->Start(); | 341 histogram_->Start(); |
342 } | 342 } |
343 ~AggregatingHistogramTimerScope() { histogram_->Stop(); } | 343 ~AggregatingHistogramTimerScope() { histogram_->Stop(); } |
344 | 344 |
345 private: | 345 private: |
346 AggregatableHistogramTimer* histogram_; | 346 AggregatableHistogramTimer* histogram_; |
347 }; | 347 }; |
348 | 348 |
349 // A helper class for use with AggregatableHistogramTimer, the "inner" scope | 349 // A helper class for use with AggregatableHistogramTimer, the "inner" scope |
350 // which defines the events to be timed. | 350 // // which defines the events to be timed. |
351 class AggregatedHistogramTimerScope { | 351 class AggregatedHistogramTimerScope { |
352 public: | 352 public: |
353 explicit AggregatedHistogramTimerScope(AggregatableHistogramTimer* histogram) | 353 explicit AggregatedHistogramTimerScope(AggregatableHistogramTimer* histogram) |
354 : histogram_(histogram) { | 354 : histogram_(histogram) { |
355 timer_.Start(); | 355 timer_.Start(); |
356 } | 356 } |
357 ~AggregatedHistogramTimerScope() { histogram_->Add(timer_.Elapsed()); } | 357 ~AggregatedHistogramTimerScope() { histogram_->Add(timer_.Elapsed()); } |
358 | 358 |
359 private: | 359 private: |
360 base::ElapsedTimer timer_; | 360 base::ElapsedTimer timer_; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 double current_value) { | 472 double current_value) { |
473 double interval_ms = current_ms - start_ms_; | 473 double interval_ms = current_ms - start_ms_; |
474 double value = (current_value + last_value_) / 2; | 474 double value = (current_value + last_value_) / 2; |
475 // The aggregate_value_ is the average for [start_ms_; last_ms_]. | 475 // The aggregate_value_ is the average for [start_ms_; last_ms_]. |
476 // The value is the average for [last_ms_; current_ms]. | 476 // The value is the average for [last_ms_; current_ms]. |
477 // Return the weighted average of the aggregate_value_ and the value. | 477 // Return the weighted average of the aggregate_value_ and the value. |
478 return aggregate_value_ * ((last_ms_ - start_ms_) / interval_ms) + | 478 return aggregate_value_ * ((last_ms_ - start_ms_) / interval_ms) + |
479 value * ((current_ms - last_ms_) / interval_ms); | 479 value * ((current_ms - last_ms_) / interval_ms); |
480 } | 480 } |
481 | 481 |
| 482 struct RuntimeCallCounter { |
| 483 explicit RuntimeCallCounter(const char* name) : name(name) {} |
| 484 void Reset(); |
| 485 |
| 486 const char* name; |
| 487 int64_t count = 0; |
| 488 base::TimeDelta time; |
| 489 }; |
| 490 |
| 491 // RuntimeCallTimer is used to keep track of the stack of currently active |
| 492 // timers used for properly measuring the own time of a RuntimeCallCounter. |
| 493 class RuntimeCallTimer { |
| 494 public: |
| 495 RuntimeCallTimer(RuntimeCallCounter* counter, RuntimeCallTimer* parent) |
| 496 : counter_(counter), parent_(parent) {} |
| 497 |
| 498 inline void Start() { |
| 499 timer_.Start(); |
| 500 counter_->count++; |
| 501 } |
| 502 |
| 503 inline RuntimeCallTimer* Stop() { |
| 504 base::TimeDelta delta = timer_.Elapsed(); |
| 505 counter_->time += delta; |
| 506 if (parent_ != NULL) { |
| 507 parent_->AdjustForSubTimer(delta); |
| 508 } |
| 509 return parent_; |
| 510 } |
| 511 |
| 512 void AdjustForSubTimer(base::TimeDelta delta) { counter_->time -= delta; } |
| 513 |
| 514 private: |
| 515 RuntimeCallCounter* counter_; |
| 516 RuntimeCallTimer* parent_; |
| 517 base::ElapsedTimer timer_; |
| 518 }; |
| 519 |
| 520 struct RuntimeCallStats { |
| 521 // Dummy counter for the unexpected stub miss. |
| 522 RuntimeCallCounter UnexpectedStubMiss = |
| 523 RuntimeCallCounter("UnexpectedStubMiss"); |
| 524 // Counter for runtime callbacks into JavaScript. |
| 525 RuntimeCallCounter ExternalCallback = RuntimeCallCounter("ExternalCallback"); |
| 526 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ |
| 527 RuntimeCallCounter Runtime_##name = RuntimeCallCounter(#name); |
| 528 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) |
| 529 #undef CALL_RUNTIME_COUNTER |
| 530 #define CALL_BUILTIN_COUNTER(name, type) \ |
| 531 RuntimeCallCounter Builtin_##name = RuntimeCallCounter(#name); |
| 532 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) |
| 533 #undef CALL_BUILTIN_COUNTER |
| 534 |
| 535 // Counter to track recursive time events. |
| 536 RuntimeCallTimer* current_timer_ = NULL; |
| 537 |
| 538 // Starting measuring the time for a function. This will establish the |
| 539 // connection to the parent counter for properly calculating the own times. |
| 540 void Enter(RuntimeCallCounter* counter); |
| 541 void Enter(RuntimeCallTimer* timer); |
| 542 // Leave a scope for a measured runtime function. This will properly add |
| 543 // the time delta to the current_counter and subtract the delta from its |
| 544 // parent. |
| 545 void Leave(); |
| 546 void Leave(RuntimeCallTimer* timer); |
| 547 |
| 548 RuntimeCallTimer* current_timer() { return current_timer_; } |
| 549 |
| 550 void Reset(); |
| 551 void Print(std::ostream& os); |
| 552 |
| 553 RuntimeCallStats() { Reset(); } |
| 554 }; |
| 555 |
| 556 // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the |
| 557 // the time of C++ scope. |
| 558 class RuntimeCallTimerScope { |
| 559 public: |
| 560 explicit RuntimeCallTimerScope(Isolate* isolate, RuntimeCallCounter* counter); |
| 561 ~RuntimeCallTimerScope(); |
| 562 |
| 563 private: |
| 564 Isolate* isolate_; |
| 565 RuntimeCallTimer timer_; |
| 566 }; |
482 | 567 |
483 #define HISTOGRAM_RANGE_LIST(HR) \ | 568 #define HISTOGRAM_RANGE_LIST(HR) \ |
484 /* Generic range histograms */ \ | 569 /* Generic range histograms */ \ |
485 HR(detached_context_age_in_gc, V8.DetachedContextAgeInGC, 0, 20, 21) \ | 570 HR(detached_context_age_in_gc, V8.DetachedContextAgeInGC, 0, 20, 21) \ |
486 HR(gc_idle_time_allotted_in_ms, V8.GCIdleTimeAllottedInMS, 0, 10000, 101) \ | 571 HR(gc_idle_time_allotted_in_ms, V8.GCIdleTimeAllottedInMS, 0, 10000, 101) \ |
487 HR(gc_idle_time_limit_overshot, V8.GCIdleTimeLimit.Overshot, 0, 10000, 101) \ | 572 HR(gc_idle_time_limit_overshot, V8.GCIdleTimeLimit.Overshot, 0, 10000, 101) \ |
488 HR(gc_idle_time_limit_undershot, V8.GCIdleTimeLimit.Undershot, 0, 10000, \ | 573 HR(gc_idle_time_limit_undershot, V8.GCIdleTimeLimit.Undershot, 0, 10000, \ |
489 101) \ | 574 101) \ |
490 HR(code_cache_reject_reason, V8.CodeCacheRejectReason, 1, 6, 6) \ | 575 HR(code_cache_reject_reason, V8.CodeCacheRejectReason, 1, 6, 6) \ |
491 HR(errors_thrown_per_context, V8.ErrorsThrownPerContext, 0, 200, 20) \ | 576 HR(errors_thrown_per_context, V8.ErrorsThrownPerContext, 0, 200, 20) \ |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed) \ | 781 SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed) \ |
697 SC(turbo_escape_allocs_replaced, V8.TurboEscapeAllocsReplaced) \ | 782 SC(turbo_escape_allocs_replaced, V8.TurboEscapeAllocsReplaced) \ |
698 SC(crankshaft_escape_allocs_replaced, V8.CrankshaftEscapeAllocsReplaced) \ | 783 SC(crankshaft_escape_allocs_replaced, V8.CrankshaftEscapeAllocsReplaced) \ |
699 SC(turbo_escape_loads_replaced, V8.TurboEscapeLoadsReplaced) \ | 784 SC(turbo_escape_loads_replaced, V8.TurboEscapeLoadsReplaced) \ |
700 SC(crankshaft_escape_loads_replaced, V8.CrankshaftEscapeLoadsReplaced) \ | 785 SC(crankshaft_escape_loads_replaced, V8.CrankshaftEscapeLoadsReplaced) \ |
701 /* Total code size (including metadata) of baseline code or bytecode. */ \ | 786 /* Total code size (including metadata) of baseline code or bytecode. */ \ |
702 SC(total_baseline_code_size, V8.TotalBaselineCodeSize) \ | 787 SC(total_baseline_code_size, V8.TotalBaselineCodeSize) \ |
703 /* Total count of functions compiled using the baseline compiler. */ \ | 788 /* Total count of functions compiled using the baseline compiler. */ \ |
704 SC(total_baseline_compile_count, V8.TotalBaselineCompileCount) | 789 SC(total_baseline_compile_count, V8.TotalBaselineCompileCount) |
705 | 790 |
706 typedef struct RuntimeCallCounter { | |
707 int64_t count = 0; | |
708 base::TimeDelta time; | |
709 RuntimeCallCounter* parent_counter; | |
710 | |
711 void Reset(); | |
712 } RuntimeCallCounter; | |
713 | |
714 struct RuntimeCallStats { | |
715 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ | |
716 RuntimeCallCounter Runtime_##name; | |
717 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) | |
718 #undef CALL_RUNTIME_COUNTER | |
719 #define CALL_BUILTIN_COUNTER(name, type) RuntimeCallCounter Builtin_##name; | |
720 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) | |
721 #undef CALL_BUILTIN_COUNTER | |
722 | |
723 // Dummy counter for the unexpected stub miss. | |
724 RuntimeCallCounter UnexpectedStubMiss; | |
725 // Counter to track recursive time events. | |
726 RuntimeCallCounter* current_counter; | |
727 | |
728 // Starting measuring the time for a function. This will establish the | |
729 // connection to the parent counter for properly calculating the own times. | |
730 void Enter(RuntimeCallCounter* counter); | |
731 // Leave a scope for a measured runtime function. This will properly add | |
732 // the time delta to the current_counter and subtract the delta from its | |
733 // parent. | |
734 void Leave(base::TimeDelta time); | |
735 | |
736 void Reset(); | |
737 void Print(std::ostream& os); | |
738 | |
739 RuntimeCallStats() { Reset(); } | |
740 }; | |
741 | |
742 // This file contains all the v8 counters that are in use. | 791 // This file contains all the v8 counters that are in use. |
743 class Counters { | 792 class Counters { |
744 public: | 793 public: |
745 #define HR(name, caption, min, max, num_buckets) \ | 794 #define HR(name, caption, min, max, num_buckets) \ |
746 Histogram* name() { return &name##_; } | 795 Histogram* name() { return &name##_; } |
747 HISTOGRAM_RANGE_LIST(HR) | 796 HISTOGRAM_RANGE_LIST(HR) |
748 #undef HR | 797 #undef HR |
749 | 798 |
750 #define HT(name, caption, max, res) \ | 799 #define HT(name, caption, max, res) \ |
751 HistogramTimer* name() { return &name##_; } | 800 HistogramTimer* name() { return &name##_; } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 | 966 |
918 explicit Counters(Isolate* isolate); | 967 explicit Counters(Isolate* isolate); |
919 | 968 |
920 DISALLOW_IMPLICIT_CONSTRUCTORS(Counters); | 969 DISALLOW_IMPLICIT_CONSTRUCTORS(Counters); |
921 }; | 970 }; |
922 | 971 |
923 } // namespace internal | 972 } // namespace internal |
924 } // namespace v8 | 973 } // namespace v8 |
925 | 974 |
926 #endif // V8_COUNTERS_H_ | 975 #endif // V8_COUNTERS_H_ |
OLD | NEW |