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 |