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" |
11 #include "src/base/platform/time.h" | 11 #include "src/base/platform/time.h" |
12 #include "src/builtins/builtins.h" | 12 #include "src/builtins/builtins.h" |
13 #include "src/globals.h" | 13 #include "src/globals.h" |
14 #include "src/isolate.h" | |
14 #include "src/objects.h" | 15 #include "src/objects.h" |
15 #include "src/runtime/runtime.h" | 16 #include "src/runtime/runtime.h" |
17 #include "src/tracing/trace-event.h" | |
16 | 18 |
17 namespace v8 { | 19 namespace v8 { |
18 namespace internal { | 20 namespace internal { |
19 | 21 |
20 // StatsCounters is an interface for plugging into external | 22 // StatsCounters is an interface for plugging into external |
21 // counters for monitoring. Counters can be looked up and | 23 // counters for monitoring. Counters can be looked up and |
22 // manipulated by name. | 24 // manipulated by name. |
23 | 25 |
24 class StatsTable { | 26 class StatsTable { |
25 public: | 27 public: |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
761 RuntimeCallCounter API_##name = RuntimeCallCounter("API_" #name); | 763 RuntimeCallCounter API_##name = RuntimeCallCounter("API_" #name); |
762 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) | 764 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) |
763 #undef CALL_BUILTIN_COUNTER | 765 #undef CALL_BUILTIN_COUNTER |
764 #define CALL_BUILTIN_COUNTER(name) \ | 766 #define CALL_BUILTIN_COUNTER(name) \ |
765 RuntimeCallCounter Handler_##name = RuntimeCallCounter(#name); | 767 RuntimeCallCounter Handler_##name = RuntimeCallCounter(#name); |
766 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) | 768 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) |
767 #undef CALL_BUILTIN_COUNTER | 769 #undef CALL_BUILTIN_COUNTER |
768 | 770 |
769 // Starting measuring the time for a function. This will establish the | 771 // Starting measuring the time for a function. This will establish the |
770 // connection to the parent counter for properly calculating the own times. | 772 // connection to the parent counter for properly calculating the own times. |
771 static void Enter(Isolate* isolate, RuntimeCallTimer* timer, | 773 static void Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer, |
772 CounterId counter_id); | 774 CounterId counter_id); |
773 | 775 |
774 // Leave a scope for a measured runtime function. This will properly add | 776 // Leave a scope for a measured runtime function. This will properly add |
775 // the time delta to the current_counter and subtract the delta from its | 777 // the time delta to the current_counter and subtract the delta from its |
776 // parent. | 778 // parent. |
777 static void Leave(Isolate* isolate, RuntimeCallTimer* timer); | 779 static void Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer); |
778 | 780 |
779 // Set counter id for the innermost measurement. It can be used to refine | 781 // Set counter id for the innermost measurement. It can be used to refine |
780 // event kind when a runtime entry counter is too generic. | 782 // event kind when a runtime entry counter is too generic. |
781 static void CorrectCurrentCounterId(Isolate* isolate, CounterId counter_id); | 783 static void CorrectCurrentCounterId(RuntimeCallStats* stats, |
784 CounterId counter_id); | |
782 | 785 |
783 void Reset(); | 786 void Reset(); |
784 void Print(std::ostream& os); | 787 void Print(std::ostream& os); |
788 const char* Dump(); | |
Camillo Bruni
2016/09/02 00:30:49
nit: Please mark the 2 methods above with V8_NOINL
fmeawad
2016/09/02 18:34:21
Done.
| |
785 | 789 |
786 RuntimeCallStats() { Reset(); } | 790 RuntimeCallStats() { |
791 Reset(); | |
792 in_use_ = false; | |
793 } | |
794 | |
787 RuntimeCallTimer* current_timer() { return current_timer_; } | 795 RuntimeCallTimer* current_timer() { return current_timer_; } |
796 bool InUse() { return in_use_; } | |
788 | 797 |
789 private: | 798 private: |
799 std::stringstream buffer_; | |
800 std::unique_ptr<char[]> buffer_c_str_; | |
801 size_t len_ = 0; | |
790 // Counter to track recursive time events. | 802 // Counter to track recursive time events. |
791 RuntimeCallTimer* current_timer_ = NULL; | 803 RuntimeCallTimer* current_timer_ = NULL; |
804 bool in_use_; | |
792 }; | 805 }; |
793 | 806 |
794 #define TRACE_RUNTIME_CALL_STATS(isolate, counter_name) \ | 807 #define TRACE_RUNTIME_CALL_STATS(isolate, counter_name) \ |
795 do { \ | 808 do { \ |
796 if (FLAG_runtime_call_stats) { \ | 809 if (FLAG_runtime_call_stats) { \ |
797 RuntimeCallStats::CorrectCurrentCounterId( \ | 810 RuntimeCallStats::CorrectCurrentCounterId( \ |
798 isolate, &RuntimeCallStats::counter_name); \ | 811 isolate->counters()->runtime_call_stats(), \ |
799 } \ | 812 &RuntimeCallStats::counter_name); \ |
813 } \ | |
814 if (V8_UNLIKELY(TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_ENABLED())) { \ | |
815 RuntimeCallStats::CorrectCurrentCounterId( \ | |
816 isolate->counters()->tracing_runtime_call_stats(), \ | |
817 &RuntimeCallStats::counter_name); \ | |
818 } \ | |
800 } while (false) | 819 } while (false) |
801 | 820 |
802 #define TRACE_HANDLER_STATS(isolate, counter_name) \ | 821 #define TRACE_HANDLER_STATS(isolate, counter_name) \ |
803 TRACE_RUNTIME_CALL_STATS(isolate, Handler_##counter_name) | 822 TRACE_RUNTIME_CALL_STATS(isolate, Handler_##counter_name) |
804 | 823 |
805 // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the | |
806 // the time of C++ scope. | |
807 class RuntimeCallTimerScope { | |
808 public: | |
809 inline RuntimeCallTimerScope(Isolate* isolate, | |
810 RuntimeCallStats::CounterId counter_id) { | |
811 if (V8_UNLIKELY(FLAG_runtime_call_stats)) { | |
812 isolate_ = isolate; | |
813 RuntimeCallStats::Enter(isolate_, &timer_, counter_id); | |
814 } | |
815 } | |
816 // This constructor is here just to avoid calling GetIsolate() when the | |
817 // stats are disabled and the isolate is not directly available. | |
818 inline RuntimeCallTimerScope(HeapObject* heap_object, | |
819 RuntimeCallStats::CounterId counter_id); | |
820 | |
821 inline ~RuntimeCallTimerScope() { | |
822 if (V8_UNLIKELY(FLAG_runtime_call_stats)) { | |
823 RuntimeCallStats::Leave(isolate_, &timer_); | |
824 } | |
825 } | |
826 | |
827 private: | |
828 Isolate* isolate_; | |
829 RuntimeCallTimer timer_; | |
830 }; | |
831 | |
832 #define HISTOGRAM_RANGE_LIST(HR) \ | 824 #define HISTOGRAM_RANGE_LIST(HR) \ |
833 /* Generic range histograms */ \ | 825 /* Generic range histograms */ \ |
834 HR(detached_context_age_in_gc, V8.DetachedContextAgeInGC, 0, 20, 21) \ | 826 HR(detached_context_age_in_gc, V8.DetachedContextAgeInGC, 0, 20, 21) \ |
835 HR(gc_idle_time_allotted_in_ms, V8.GCIdleTimeAllottedInMS, 0, 10000, 101) \ | 827 HR(gc_idle_time_allotted_in_ms, V8.GCIdleTimeAllottedInMS, 0, 10000, 101) \ |
836 HR(gc_idle_time_limit_overshot, V8.GCIdleTimeLimit.Overshot, 0, 10000, 101) \ | 828 HR(gc_idle_time_limit_overshot, V8.GCIdleTimeLimit.Overshot, 0, 10000, 101) \ |
837 HR(gc_idle_time_limit_undershot, V8.GCIdleTimeLimit.Undershot, 0, 10000, \ | 829 HR(gc_idle_time_limit_undershot, V8.GCIdleTimeLimit.Undershot, 0, 10000, \ |
838 101) \ | 830 101) \ |
839 HR(code_cache_reject_reason, V8.CodeCacheRejectReason, 1, 6, 6) \ | 831 HR(code_cache_reject_reason, V8.CodeCacheRejectReason, 1, 6, 6) \ |
840 HR(errors_thrown_per_context, V8.ErrorsThrownPerContext, 0, 200, 20) \ | 832 HR(errors_thrown_per_context, V8.ErrorsThrownPerContext, 0, 200, 20) \ |
841 HR(debug_feature_usage, V8.DebugFeatureUsage, 1, 7, 7) \ | 833 HR(debug_feature_usage, V8.DebugFeatureUsage, 1, 7, 7) \ |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1164 #define COUNTER_ID(name) kCountOfCODE_AGE__##name, \ | 1156 #define COUNTER_ID(name) kCountOfCODE_AGE__##name, \ |
1165 kSizeOfCODE_AGE__##name, | 1157 kSizeOfCODE_AGE__##name, |
1166 CODE_AGE_LIST_COMPLETE(COUNTER_ID) | 1158 CODE_AGE_LIST_COMPLETE(COUNTER_ID) |
1167 #undef COUNTER_ID | 1159 #undef COUNTER_ID |
1168 stats_counter_count | 1160 stats_counter_count |
1169 }; | 1161 }; |
1170 | 1162 |
1171 void ResetCounters(); | 1163 void ResetCounters(); |
1172 void ResetHistograms(); | 1164 void ResetHistograms(); |
1173 RuntimeCallStats* runtime_call_stats() { return &runtime_call_stats_; } | 1165 RuntimeCallStats* runtime_call_stats() { return &runtime_call_stats_; } |
1166 RuntimeCallStats* tracing_runtime_call_stats() { | |
1167 return &tracing_runtime_call_stats_; | |
1168 } | |
1174 | 1169 |
1175 private: | 1170 private: |
1176 #define HR(name, caption, min, max, num_buckets) Histogram name##_; | 1171 #define HR(name, caption, min, max, num_buckets) Histogram name##_; |
1177 HISTOGRAM_RANGE_LIST(HR) | 1172 HISTOGRAM_RANGE_LIST(HR) |
1178 #undef HR | 1173 #undef HR |
1179 | 1174 |
1180 #define HT(name, caption, max, res) HistogramTimer name##_; | 1175 #define HT(name, caption, max, res) HistogramTimer name##_; |
1181 HISTOGRAM_TIMER_LIST(HT) | 1176 HISTOGRAM_TIMER_LIST(HT) |
1182 #undef HT | 1177 #undef HT |
1183 | 1178 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1226 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC) | 1221 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC) |
1227 #undef SC | 1222 #undef SC |
1228 | 1223 |
1229 #define SC(name) \ | 1224 #define SC(name) \ |
1230 StatsCounter size_of_CODE_AGE_##name##_; \ | 1225 StatsCounter size_of_CODE_AGE_##name##_; \ |
1231 StatsCounter count_of_CODE_AGE_##name##_; | 1226 StatsCounter count_of_CODE_AGE_##name##_; |
1232 CODE_AGE_LIST_COMPLETE(SC) | 1227 CODE_AGE_LIST_COMPLETE(SC) |
1233 #undef SC | 1228 #undef SC |
1234 | 1229 |
1235 RuntimeCallStats runtime_call_stats_; | 1230 RuntimeCallStats runtime_call_stats_; |
1231 RuntimeCallStats tracing_runtime_call_stats_; | |
1236 | 1232 |
1237 friend class Isolate; | 1233 friend class Isolate; |
1238 | 1234 |
1239 explicit Counters(Isolate* isolate); | 1235 explicit Counters(Isolate* isolate); |
1240 | 1236 |
1241 DISALLOW_IMPLICIT_CONSTRUCTORS(Counters); | 1237 DISALLOW_IMPLICIT_CONSTRUCTORS(Counters); |
1242 }; | 1238 }; |
1243 | 1239 |
1240 // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the | |
1241 // the time of C++ scope. | |
1242 class RuntimeCallTimerScope { | |
1243 public: | |
1244 inline RuntimeCallTimerScope(Isolate* isolate, | |
1245 RuntimeCallStats::CounterId counter_id) { | |
1246 if (V8_UNLIKELY(FLAG_runtime_call_stats)) { | |
1247 isolate_ = isolate; | |
1248 RuntimeCallStats::Enter(isolate_->counters()->runtime_call_stats(), | |
1249 &timer_, counter_id); | |
1250 } | |
1251 if (V8_UNLIKELY(TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_ENABLED())) { | |
1252 isolate_for_tracing_ = isolate; | |
1253 RuntimeCallStats::Enter( | |
1254 isolate_for_tracing_->counters()->tracing_runtime_call_stats(), | |
1255 &trace_event_timer_, counter_id); | |
1256 } | |
1257 } | |
1258 // This constructor is here just to avoid calling GetIsolate() when the | |
1259 // stats are disabled and the isolate is not directly available. | |
1260 inline RuntimeCallTimerScope(HeapObject* heap_object, | |
1261 RuntimeCallStats::CounterId counter_id); | |
1262 | |
1263 inline ~RuntimeCallTimerScope() { | |
1264 if (V8_UNLIKELY(FLAG_runtime_call_stats)) { | |
1265 RuntimeCallStats::Leave(isolate_->counters()->runtime_call_stats(), | |
1266 &timer_); | |
1267 } | |
1268 if (V8_UNLIKELY(isolate_for_tracing_ != nullptr)) { | |
1269 RuntimeCallStats::Leave( | |
1270 isolate_for_tracing_->counters()->tracing_runtime_call_stats(), | |
1271 &trace_event_timer_); | |
1272 isolate_for_tracing_ = nullptr; | |
1273 } | |
1274 } | |
1275 | |
1276 private: | |
1277 Isolate* isolate_; | |
1278 Isolate* isolate_for_tracing_ = nullptr; | |
1279 RuntimeCallTimer timer_; | |
1280 RuntimeCallTimer trace_event_timer_; | |
Camillo Bruni
2016/09/02 00:30:50
I think we can make --runtime-call-stats and traci
fmeawad
2016/09/02 18:34:21
Added a comment to make a followup CL
| |
1281 }; | |
1282 | |
1244 } // namespace internal | 1283 } // namespace internal |
1245 } // namespace v8 | 1284 } // namespace v8 |
1246 | 1285 |
1247 #endif // V8_COUNTERS_H_ | 1286 #endif // V8_COUNTERS_H_ |
OLD | NEW |