Chromium Code Reviews| 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 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 481 // The value is the average for [last_ms_; current_ms]. | 481 // The value is the average for [last_ms_; current_ms]. |
| 482 // Return the weighted average of the aggregate_value_ and the value. | 482 // Return the weighted average of the aggregate_value_ and the value. |
| 483 return aggregate_value_ * ((last_ms_ - start_ms_) / interval_ms) + | 483 return aggregate_value_ * ((last_ms_ - start_ms_) / interval_ms) + |
| 484 value * ((current_ms - last_ms_) / interval_ms); | 484 value * ((current_ms - last_ms_) / interval_ms); |
| 485 } | 485 } |
| 486 | 486 |
| 487 struct RuntimeCallCounter { | 487 struct RuntimeCallCounter { |
| 488 explicit RuntimeCallCounter(const char* name) : name(name) {} | 488 explicit RuntimeCallCounter(const char* name) : name(name) {} |
| 489 V8_NOINLINE void Reset(); | 489 V8_NOINLINE void Reset(); |
| 490 V8_NOINLINE void Dump(v8::tracing::TracedValue* value); | 490 V8_NOINLINE void Dump(v8::tracing::TracedValue* value); |
| 491 void Add(RuntimeCallCounter* other); | |
| 491 | 492 |
| 492 const char* name; | 493 const char* name; |
| 493 int64_t count = 0; | 494 int64_t count = 0; |
| 494 base::TimeDelta time; | 495 base::TimeDelta time; |
| 495 }; | 496 }; |
| 496 | 497 |
| 497 // RuntimeCallTimer is used to keep track of the stack of currently active | 498 // RuntimeCallTimer is used to keep track of the stack of currently active |
| 498 // timers used for properly measuring the own time of a RuntimeCallCounter. | 499 // timers used for properly measuring the own time of a RuntimeCallCounter. |
| 499 class RuntimeCallTimer { | 500 class RuntimeCallTimer { |
| 500 public: | 501 public: |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 530 inline void Elapsed() { | 531 inline void Elapsed() { |
| 531 base::TimeDelta delta = timer_.Elapsed(); | 532 base::TimeDelta delta = timer_.Elapsed(); |
| 532 counter_->time += delta; | 533 counter_->time += delta; |
| 533 if (parent()) { | 534 if (parent()) { |
| 534 parent()->counter_->time -= delta; | 535 parent()->counter_->time -= delta; |
| 535 parent()->Elapsed(); | 536 parent()->Elapsed(); |
| 536 } | 537 } |
| 537 timer_.Restart(); | 538 timer_.Restart(); |
| 538 } | 539 } |
| 539 | 540 |
| 541 const char* name() { return counter_->name; } | |
| 542 | |
| 540 RuntimeCallCounter* counter_ = nullptr; | 543 RuntimeCallCounter* counter_ = nullptr; |
| 541 base::AtomicValue<RuntimeCallTimer*> parent_; | 544 base::AtomicValue<RuntimeCallTimer*> parent_; |
| 542 base::ElapsedTimer timer_; | 545 base::ElapsedTimer timer_; |
| 543 }; | 546 }; |
| 544 | 547 |
| 545 #define FOR_EACH_API_COUNTER(V) \ | 548 #define FOR_EACH_API_COUNTER(V) \ |
| 546 V(ArrayBuffer_Cast) \ | 549 V(ArrayBuffer_Cast) \ |
| 547 V(ArrayBuffer_Neuter) \ | 550 V(ArrayBuffer_Neuter) \ |
| 548 V(ArrayBuffer_New) \ | 551 V(ArrayBuffer_New) \ |
| 549 V(Array_CloneElementAt) \ | 552 V(Array_CloneElementAt) \ |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 718 V(IndexedPropertySetterCallback) \ | 721 V(IndexedPropertySetterCallback) \ |
| 719 V(InvokeApiInterruptCallbacks) \ | 722 V(InvokeApiInterruptCallbacks) \ |
| 720 V(InvokeFunctionCallback) \ | 723 V(InvokeFunctionCallback) \ |
| 721 V(JS_Execution) \ | 724 V(JS_Execution) \ |
| 722 V(Map_SetPrototype) \ | 725 V(Map_SetPrototype) \ |
| 723 V(Map_TransitionToAccessorProperty) \ | 726 V(Map_TransitionToAccessorProperty) \ |
| 724 V(Map_TransitionToDataProperty) \ | 727 V(Map_TransitionToDataProperty) \ |
| 725 V(Object_DeleteProperty) \ | 728 V(Object_DeleteProperty) \ |
| 726 V(OptimizeCode) \ | 729 V(OptimizeCode) \ |
| 727 V(ParseProgram) \ | 730 V(ParseProgram) \ |
| 731 V(ParseEval) \ | |
| 728 V(ParseFunction) \ | 732 V(ParseFunction) \ |
| 733 V(ParseFunctionLiteral) \ | |
| 734 V(PreParseWithVariableResolution) \ | |
| 735 V(PreParseNoVariableResolution) \ | |
| 736 V(ParseArrowFunctionLiteral) \ | |
| 737 V(PreParseArrowFunctionLiteral) \ | |
|
vogelheim
2016/11/14 13:05:05
nitpick: The list was (mostly) alphabetically orde
Camillo Bruni
2016/11/15 18:10:29
argh, thought that I did sort them, thx!
| |
| 729 V(PropertyCallback) \ | 738 V(PropertyCallback) \ |
| 730 V(PrototypeMap_TransitionToAccessorProperty) \ | 739 V(PrototypeMap_TransitionToAccessorProperty) \ |
| 731 V(PrototypeMap_TransitionToDataProperty) \ | 740 V(PrototypeMap_TransitionToDataProperty) \ |
| 732 V(PrototypeObject_DeleteProperty) \ | 741 V(PrototypeObject_DeleteProperty) \ |
| 733 V(RecompileConcurrent) \ | 742 V(RecompileConcurrent) \ |
| 734 V(RecompileSynchronous) \ | 743 V(RecompileSynchronous) \ |
| 735 /* Dummy counter for the unexpected stub miss. */ \ | 744 /* Dummy counter for the unexpected stub miss. */ \ |
| 736 V(UnexpectedStubMiss) | 745 V(UnexpectedStubMiss) |
| 737 | 746 |
| 738 #define FOR_EACH_HANDLER_COUNTER(V) \ | 747 #define FOR_EACH_HANDLER_COUNTER(V) \ |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 795 V(StoreIC_StoreFieldDH) \ | 804 V(StoreIC_StoreFieldDH) \ |
| 796 V(StoreIC_StoreFieldStub) \ | 805 V(StoreIC_StoreFieldStub) \ |
| 797 V(StoreIC_StoreGlobal) \ | 806 V(StoreIC_StoreGlobal) \ |
| 798 V(StoreIC_StoreGlobalTransition) \ | 807 V(StoreIC_StoreGlobalTransition) \ |
| 799 V(StoreIC_StoreInterceptorStub) \ | 808 V(StoreIC_StoreInterceptorStub) \ |
| 800 V(StoreIC_StoreNormal) \ | 809 V(StoreIC_StoreNormal) \ |
| 801 V(StoreIC_StoreScriptContextFieldStub) \ | 810 V(StoreIC_StoreScriptContextFieldStub) \ |
| 802 V(StoreIC_StoreTransition) \ | 811 V(StoreIC_StoreTransition) \ |
| 803 V(StoreIC_StoreViaSetter) | 812 V(StoreIC_StoreViaSetter) |
| 804 | 813 |
| 805 class RuntimeCallStats { | 814 class RuntimeCallStats : public ZoneObject { |
| 806 public: | 815 public: |
| 807 typedef RuntimeCallCounter RuntimeCallStats::*CounterId; | 816 typedef RuntimeCallCounter RuntimeCallStats::*CounterId; |
| 808 | 817 |
| 809 #define CALL_RUNTIME_COUNTER(name) \ | 818 #define CALL_RUNTIME_COUNTER(name) \ |
| 810 RuntimeCallCounter name = RuntimeCallCounter(#name); | 819 RuntimeCallCounter name = RuntimeCallCounter(#name); |
| 811 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) | 820 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) |
| 812 #undef CALL_RUNTIME_COUNTER | 821 #undef CALL_RUNTIME_COUNTER |
| 813 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ | 822 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ |
| 814 RuntimeCallCounter Runtime_##name = RuntimeCallCounter(#name); | 823 RuntimeCallCounter Runtime_##name = RuntimeCallCounter(#name); |
| 815 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) | 824 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) |
| 816 #undef CALL_RUNTIME_COUNTER | 825 #undef CALL_RUNTIME_COUNTER |
| 817 #define CALL_BUILTIN_COUNTER(name) \ | 826 #define CALL_BUILTIN_COUNTER(name) \ |
| 818 RuntimeCallCounter Builtin_##name = RuntimeCallCounter(#name); | 827 RuntimeCallCounter Builtin_##name = RuntimeCallCounter(#name); |
| 819 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) | 828 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) |
| 820 #undef CALL_BUILTIN_COUNTER | 829 #undef CALL_BUILTIN_COUNTER |
| 821 #define CALL_BUILTIN_COUNTER(name) \ | 830 #define CALL_BUILTIN_COUNTER(name) \ |
| 822 RuntimeCallCounter API_##name = RuntimeCallCounter("API_" #name); | 831 RuntimeCallCounter API_##name = RuntimeCallCounter("API_" #name); |
| 823 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) | 832 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) |
| 824 #undef CALL_BUILTIN_COUNTER | 833 #undef CALL_BUILTIN_COUNTER |
| 825 #define CALL_BUILTIN_COUNTER(name) \ | 834 #define CALL_BUILTIN_COUNTER(name) \ |
| 826 RuntimeCallCounter Handler_##name = RuntimeCallCounter(#name); | 835 RuntimeCallCounter Handler_##name = RuntimeCallCounter(#name); |
| 827 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) | 836 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) |
| 828 #undef CALL_BUILTIN_COUNTER | 837 #undef CALL_BUILTIN_COUNTER |
| 829 | 838 |
| 839 static constexpr RuntimeCallStats::CounterId counters[] = { | |
| 840 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name, | |
| 841 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) | |
| 842 #undef CALL_RUNTIME_COUNTER | |
| 843 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ | |
| 844 &RuntimeCallStats::Runtime_##name, | |
| 845 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) | |
| 846 #undef CALL_RUNTIME_COUNTER | |
| 847 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name, | |
| 848 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) | |
| 849 #undef CALL_BUILTIN_COUNTER | |
| 850 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::API_##name, | |
| 851 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) | |
| 852 #undef CALL_BUILTIN_COUNTER | |
| 853 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Handler_##name, | |
| 854 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) | |
|
vogelheim
2016/11/14 13:05:05
nitpick: The formatting is weird, with the ever-in
Camillo Bruni
2016/11/15 18:10:29
I tried a couple of times to force a different lay
| |
| 855 #undef CALL_BUILTIN_COUNTER | |
| 856 }; | |
| 857 | |
| 830 // Starting measuring the time for a function. This will establish the | 858 // Starting measuring the time for a function. This will establish the |
| 831 // connection to the parent counter for properly calculating the own times. | 859 // connection to the parent counter for properly calculating the own times. |
| 832 static void Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer, | 860 static void Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer, |
| 833 CounterId counter_id); | 861 CounterId counter_id); |
| 834 | 862 |
| 835 // Leave a scope for a measured runtime function. This will properly add | 863 // Leave a scope for a measured runtime function. This will properly add |
| 836 // the time delta to the current_counter and subtract the delta from its | 864 // the time delta to the current_counter and subtract the delta from its |
| 837 // parent. | 865 // parent. |
| 838 static void Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer); | 866 static void Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer); |
| 839 | 867 |
| 840 // Set counter id for the innermost measurement. It can be used to refine | 868 // Set counter id for the innermost measurement. It can be used to refine |
| 841 // event kind when a runtime entry counter is too generic. | 869 // event kind when a runtime entry counter is too generic. |
| 842 static void CorrectCurrentCounterId(RuntimeCallStats* stats, | 870 static void CorrectCurrentCounterId(RuntimeCallStats* stats, |
| 843 CounterId counter_id); | 871 CounterId counter_id); |
| 844 | 872 |
| 845 void Reset(); | 873 void Reset(); |
| 874 // Add all entries from another stats object. | |
| 875 void Add(RuntimeCallStats* other); | |
| 846 void Print(std::ostream& os); | 876 void Print(std::ostream& os); |
| 847 V8_NOINLINE void Dump(v8::tracing::TracedValue* value); | 877 V8_NOINLINE void Dump(v8::tracing::TracedValue* value); |
| 848 | 878 |
| 849 RuntimeCallStats() { | 879 RuntimeCallStats() { |
| 850 Reset(); | 880 Reset(); |
| 851 in_use_ = false; | 881 in_use_ = false; |
| 852 } | 882 } |
| 853 | 883 |
| 854 RuntimeCallTimer* current_timer() { return current_timer_.Value(); } | 884 RuntimeCallTimer* current_timer() { return current_timer_.Value(); } |
| 855 bool InUse() { return in_use_; } | 885 bool InUse() { return in_use_; } |
| 856 | 886 |
| 857 private: | 887 private: |
| 858 // Counter to track recursive time events. | 888 // Counter to track recursive time events. |
| 859 base::AtomicValue<RuntimeCallTimer*> current_timer_; | 889 base::AtomicValue<RuntimeCallTimer*> current_timer_; |
| 860 // Used to track nested tracing scopes. | 890 // Used to track nested tracing scopes. |
| 861 bool in_use_; | 891 bool in_use_; |
| 862 }; | 892 }; |
| 863 | 893 |
| 864 #define TRACE_RUNTIME_CALL_STATS(isolate, counter_name) \ | 894 #define CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats, counter_name) \ |
| 865 do { \ | 895 do { \ |
| 866 if (V8_UNLIKELY(FLAG_runtime_stats)) { \ | 896 if (V8_UNLIKELY(FLAG_runtime_stats)) { \ |
| 867 RuntimeCallStats::CorrectCurrentCounterId( \ | 897 RuntimeCallStats::CorrectCurrentCounterId( \ |
| 868 isolate->counters()->runtime_call_stats(), \ | 898 runtime_call_stats, &RuntimeCallStats::counter_name); \ |
| 869 &RuntimeCallStats::counter_name); \ | 899 } \ |
| 870 } \ | |
| 871 } while (false) | 900 } while (false) |
| 872 | 901 |
| 873 #define TRACE_HANDLER_STATS(isolate, counter_name) \ | 902 #define TRACE_HANDLER_STATS(isolate, counter_name) \ |
| 874 TRACE_RUNTIME_CALL_STATS(isolate, Handler_##counter_name) | 903 CHANGE_CURRENT_RUNTIME_COUNTER(isolate->counters()->runtime_call_stats(), \ |
| 904 Handler_##counter_name) | |
| 875 | 905 |
| 876 #define HISTOGRAM_RANGE_LIST(HR) \ | 906 #define HISTOGRAM_RANGE_LIST(HR) \ |
| 877 /* Generic range histograms */ \ | 907 /* Generic range histograms */ \ |
| 878 HR(detached_context_age_in_gc, V8.DetachedContextAgeInGC, 0, 20, 21) \ | 908 HR(detached_context_age_in_gc, V8.DetachedContextAgeInGC, 0, 20, 21) \ |
| 879 HR(gc_idle_time_allotted_in_ms, V8.GCIdleTimeAllottedInMS, 0, 10000, 101) \ | 909 HR(gc_idle_time_allotted_in_ms, V8.GCIdleTimeAllottedInMS, 0, 10000, 101) \ |
| 880 HR(gc_idle_time_limit_overshot, V8.GCIdleTimeLimit.Overshot, 0, 10000, 101) \ | 910 HR(gc_idle_time_limit_overshot, V8.GCIdleTimeLimit.Overshot, 0, 10000, 101) \ |
| 881 HR(gc_idle_time_limit_undershot, V8.GCIdleTimeLimit.Undershot, 0, 10000, \ | 911 HR(gc_idle_time_limit_undershot, V8.GCIdleTimeLimit.Undershot, 0, 10000, \ |
| 882 101) \ | 912 101) \ |
| 883 HR(code_cache_reject_reason, V8.CodeCacheRejectReason, 1, 6, 6) \ | 913 HR(code_cache_reject_reason, V8.CodeCacheRejectReason, 1, 6, 6) \ |
| 884 HR(errors_thrown_per_context, V8.ErrorsThrownPerContext, 0, 200, 20) \ | 914 HR(errors_thrown_per_context, V8.ErrorsThrownPerContext, 0, 200, 20) \ |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1287 // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the | 1317 // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the |
| 1288 // the time of C++ scope. | 1318 // the time of C++ scope. |
| 1289 class RuntimeCallTimerScope { | 1319 class RuntimeCallTimerScope { |
| 1290 public: | 1320 public: |
| 1291 inline RuntimeCallTimerScope(Isolate* isolate, | 1321 inline RuntimeCallTimerScope(Isolate* isolate, |
| 1292 RuntimeCallStats::CounterId counter_id); | 1322 RuntimeCallStats::CounterId counter_id); |
| 1293 // This constructor is here just to avoid calling GetIsolate() when the | 1323 // This constructor is here just to avoid calling GetIsolate() when the |
| 1294 // stats are disabled and the isolate is not directly available. | 1324 // stats are disabled and the isolate is not directly available. |
| 1295 inline RuntimeCallTimerScope(HeapObject* heap_object, | 1325 inline RuntimeCallTimerScope(HeapObject* heap_object, |
| 1296 RuntimeCallStats::CounterId counter_id); | 1326 RuntimeCallStats::CounterId counter_id); |
| 1327 inline RuntimeCallTimerScope(RuntimeCallStats* stats, | |
| 1328 RuntimeCallStats::CounterId counter_id); | |
| 1297 | 1329 |
| 1298 inline ~RuntimeCallTimerScope() { | 1330 inline ~RuntimeCallTimerScope() { |
| 1299 if (V8_UNLIKELY(isolate_ != nullptr)) { | 1331 if (V8_UNLIKELY(stats_ != nullptr)) { |
| 1300 RuntimeCallStats::Leave(isolate_->counters()->runtime_call_stats(), | 1332 RuntimeCallStats::Leave(stats_, &timer_); |
| 1301 &timer_); | |
| 1302 } | 1333 } |
| 1303 } | 1334 } |
| 1304 | 1335 |
| 1305 private: | 1336 private: |
| 1306 V8_INLINE void Initialize(Isolate* isolate, | 1337 V8_INLINE void Initialize(RuntimeCallStats* stats, |
| 1307 RuntimeCallStats::CounterId counter_id) { | 1338 RuntimeCallStats::CounterId counter_id) { |
| 1308 isolate_ = isolate; | 1339 stats_ = stats; |
| 1309 RuntimeCallStats::Enter(isolate_->counters()->runtime_call_stats(), &timer_, | 1340 RuntimeCallStats::Enter(stats_, &timer_, counter_id); |
| 1310 counter_id); | |
| 1311 } | 1341 } |
| 1312 | 1342 |
| 1313 Isolate* isolate_ = nullptr; | 1343 RuntimeCallStats* stats_ = nullptr; |
| 1314 RuntimeCallTimer timer_; | 1344 RuntimeCallTimer timer_; |
| 1315 }; | 1345 }; |
| 1316 | 1346 |
| 1317 } // namespace internal | 1347 } // namespace internal |
| 1318 } // namespace v8 | 1348 } // namespace v8 |
| 1319 | 1349 |
| 1320 #endif // V8_COUNTERS_H_ | 1350 #endif // V8_COUNTERS_H_ |
| OLD | NEW |