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 #include "src/counters.h" | 5 #include "src/counters.h" |
6 | 6 |
7 #include <iomanip> | 7 #include <iomanip> |
8 | 8 |
9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
10 #include "src/isolate.h" | 10 #include "src/isolate.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 : timer_.Elapsed().InMilliseconds(); | 54 : timer_.Elapsed().InMilliseconds(); |
55 // Compute the delta between start and stop, in microseconds. | 55 // Compute the delta between start and stop, in microseconds. |
56 AddSample(static_cast<int>(sample)); | 56 AddSample(static_cast<int>(sample)); |
57 timer_.Stop(); | 57 timer_.Stop(); |
58 } | 58 } |
59 Logger::CallEventLogger(isolate(), name(), Logger::END, true); | 59 Logger::CallEventLogger(isolate(), name(), Logger::END, true); |
60 } | 60 } |
61 | 61 |
62 | 62 |
63 Counters::Counters(Isolate* isolate) { | 63 Counters::Counters(Isolate* isolate) { |
| 64 static const struct { |
| 65 Histogram Counters::*member; |
| 66 const char* caption; |
| 67 int min; |
| 68 int max; |
| 69 int num_buckets; |
| 70 } kHistograms[] = { |
64 #define HR(name, caption, min, max, num_buckets) \ | 71 #define HR(name, caption, min, max, num_buckets) \ |
65 name##_ = Histogram(#caption, min, max, num_buckets, isolate); | 72 {&Counters::name##_, #caption, min, max, num_buckets}, |
66 HISTOGRAM_RANGE_LIST(HR) | 73 HISTOGRAM_RANGE_LIST(HR) |
67 #undef HR | 74 #undef HR |
| 75 }; |
| 76 for (const auto& histogram : kHistograms) { |
| 77 this->*histogram.member = |
| 78 Histogram(histogram.caption, histogram.min, histogram.max, |
| 79 histogram.num_buckets, isolate); |
| 80 } |
68 | 81 |
| 82 static const struct { |
| 83 HistogramTimer Counters::*member; |
| 84 const char* caption; |
| 85 int max; |
| 86 HistogramTimer::Resolution res; |
| 87 } kHistogramTimers[] = { |
69 #define HT(name, caption, max, res) \ | 88 #define HT(name, caption, max, res) \ |
70 name##_ = HistogramTimer(#caption, 0, max, HistogramTimer::res, 50, isolate); | 89 {&Counters::name##_, #caption, max, HistogramTimer::res}, |
71 HISTOGRAM_TIMER_LIST(HT) | 90 HISTOGRAM_TIMER_LIST(HT) |
72 #undef HT | 91 #undef HT |
| 92 }; |
| 93 for (const auto& timer : kHistogramTimers) { |
| 94 this->*timer.member = |
| 95 HistogramTimer(timer.caption, 0, timer.max, timer.res, 50, isolate); |
| 96 } |
73 | 97 |
74 #define AHT(name, caption) \ | 98 static const struct { |
75 name##_ = AggregatableHistogramTimer(#caption, 0, 10000000, 50, isolate); | 99 AggregatableHistogramTimer Counters::*member; |
76 AGGREGATABLE_HISTOGRAM_TIMER_LIST(AHT) | 100 const char* caption; |
| 101 } kAggregatableHistogramTimers[] = { |
| 102 #define AHT(name, caption) {&Counters::name##_, #caption}, |
| 103 AGGREGATABLE_HISTOGRAM_TIMER_LIST(AHT) |
77 #undef AHT | 104 #undef AHT |
| 105 }; |
| 106 for (const auto& aht : kAggregatableHistogramTimers) { |
| 107 this->*aht.member = |
| 108 AggregatableHistogramTimer(aht.caption, 0, 10000000, 50, isolate); |
| 109 } |
78 | 110 |
79 #define HP(name, caption) \ | 111 static const struct { |
80 name##_ = Histogram(#caption, 0, 101, 100, isolate); | 112 Histogram Counters::*member; |
81 HISTOGRAM_PERCENTAGE_LIST(HP) | 113 const char* caption; |
| 114 } kHistogramPercentages[] = { |
| 115 #define HP(name, caption) {&Counters::name##_, #caption}, |
| 116 HISTOGRAM_PERCENTAGE_LIST(HP) |
82 #undef HP | 117 #undef HP |
| 118 }; |
| 119 for (const auto& percentage : kHistogramPercentages) { |
| 120 this->*percentage.member = |
| 121 Histogram(percentage.caption, 0, 101, 100, isolate); |
| 122 } |
83 | 123 |
| 124 // Exponential histogram assigns bucket limits to points |
| 125 // p[1], p[2], ... p[n] such that p[i+1] / p[i] = constant. |
| 126 // The constant factor is equal to the n-th root of (high / low), |
| 127 // where the n is the number of buckets, the low is the lower limit, |
| 128 // the high is the upper limit. |
| 129 // For n = 50, low = 1000, high = 500000: the factor = 1.13. |
| 130 static const struct { |
| 131 Histogram Counters::*member; |
| 132 const char* caption; |
| 133 } kLegacyMemoryHistograms[] = { |
| 134 #define HM(name, caption) {&Counters::name##_, #caption}, |
| 135 HISTOGRAM_LEGACY_MEMORY_LIST(HM) |
| 136 #undef HM |
| 137 }; |
| 138 for (const auto& histogram : kLegacyMemoryHistograms) { |
| 139 this->*histogram.member = |
| 140 Histogram(histogram.caption, 1000, 500000, 50, isolate); |
| 141 } |
84 | 142 |
85 // Exponential histogram assigns bucket limits to points | 143 // For n = 100, low = 4000, high = 2000000: the factor = 1.06. |
86 // p[1], p[2], ... p[n] such that p[i+1] / p[i] = constant. | 144 static const struct { |
87 // The constant factor is equal to the n-th root of (high / low), | 145 Histogram Counters::*member; |
88 // where the n is the number of buckets, the low is the lower limit, | 146 AggregatedMemoryHistogram<Histogram> Counters::*aggregated; |
89 // the high is the upper limit. | 147 const char* caption; |
90 // For n = 50, low = 1000, high = 500000: the factor = 1.13. | 148 } kMemoryHistograms[] = { |
91 #define HM(name, caption) \ | 149 #define HM(name, caption) \ |
92 name##_ = Histogram(#caption, 1000, 500000, 50, isolate); | 150 {&Counters::name##_, &Counters::aggregated_##name##_, #caption}, |
93 HISTOGRAM_LEGACY_MEMORY_LIST(HM) | 151 HISTOGRAM_MEMORY_LIST(HM) |
94 #undef HM | 152 #undef HM |
95 // For n = 100, low = 4000, high = 2000000: the factor = 1.06. | 153 }; |
96 #define HM(name, caption) \ | 154 for (const auto& histogram : kMemoryHistograms) { |
97 name##_ = Histogram(#caption, 4000, 2000000, 100, isolate); | 155 this->*histogram.member = |
98 HISTOGRAM_MEMORY_LIST(HM) | 156 Histogram(histogram.caption, 4000, 2000000, 100, isolate); |
99 #undef HM | 157 this->*histogram.aggregated = |
| 158 AggregatedMemoryHistogram<Histogram>(&(this->*histogram.member)); |
| 159 } |
100 | 160 |
101 #define HM(name, caption) \ | 161 // clang-format off |
102 aggregated_##name##_ = AggregatedMemoryHistogram<Histogram>(&name##_); | 162 static const struct { |
103 HISTOGRAM_MEMORY_LIST(HM) | 163 StatsCounter Counters::*member; |
104 #undef HM | 164 const char* caption; |
105 | 165 } kStatsCounters[] = { |
106 #define SC(name, caption) \ | 166 #define SC(name, caption) {&Counters::name##_, "c:" #caption}, |
107 name##_ = StatsCounter(isolate, "c:" #caption); | 167 STATS_COUNTER_LIST_1(SC) STATS_COUNTER_LIST_2(SC) |
108 | |
109 STATS_COUNTER_LIST_1(SC) | |
110 STATS_COUNTER_LIST_2(SC) | |
111 #undef SC | 168 #undef SC |
112 | 169 #define SC(name) \ |
113 #define SC(name) \ | 170 {&Counters::count_of_##name##_, "c:" "V8.CountOf_" #name}, \ |
114 count_of_##name##_ = StatsCounter(isolate, "c:" "V8.CountOf_" #name); \ | 171 {&Counters::size_of_##name##_, "c:" "V8.SizeOf_" #name}, |
115 size_of_##name##_ = StatsCounter(isolate, "c:" "V8.SizeOf_" #name); | 172 INSTANCE_TYPE_LIST(SC) |
116 INSTANCE_TYPE_LIST(SC) | |
117 #undef SC | 173 #undef SC |
118 | 174 #define SC(name) \ |
119 #define SC(name) \ | 175 {&Counters::count_of_CODE_TYPE_##name##_, \ |
120 count_of_CODE_TYPE_##name##_ = \ | 176 "c:" "V8.CountOf_CODE_TYPE-" #name}, \ |
121 StatsCounter(isolate, "c:" "V8.CountOf_CODE_TYPE-" #name); \ | 177 {&Counters::size_of_CODE_TYPE_##name##_, \ |
122 size_of_CODE_TYPE_##name##_ = \ | 178 "c:" "V8.SizeOf_CODE_TYPE-" #name}, |
123 StatsCounter(isolate, "c:" "V8.SizeOf_CODE_TYPE-" #name); | 179 CODE_KIND_LIST(SC) |
124 CODE_KIND_LIST(SC) | |
125 #undef SC | 180 #undef SC |
126 | 181 #define SC(name) \ |
127 #define SC(name) \ | 182 {&Counters::count_of_FIXED_ARRAY_##name##_, \ |
128 count_of_FIXED_ARRAY_##name##_ = \ | 183 "c:" "V8.CountOf_FIXED_ARRAY-" #name}, \ |
129 StatsCounter(isolate, "c:" "V8.CountOf_FIXED_ARRAY-" #name); \ | 184 {&Counters::size_of_FIXED_ARRAY_##name##_, \ |
130 size_of_FIXED_ARRAY_##name##_ = \ | 185 "c:" "V8.SizeOf_FIXED_ARRAY-" #name}, |
131 StatsCounter(isolate, "c:" "V8.SizeOf_FIXED_ARRAY-" #name); | 186 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC) |
132 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC) | |
133 #undef SC | 187 #undef SC |
134 | 188 #define SC(name) \ |
135 #define SC(name) \ | 189 {&Counters::count_of_CODE_AGE_##name##_, \ |
136 count_of_CODE_AGE_##name##_ = \ | 190 "c:" "V8.CountOf_CODE_AGE-" #name}, \ |
137 StatsCounter(isolate, "c:" "V8.CountOf_CODE_AGE-" #name); \ | 191 {&Counters::size_of_CODE_AGE_##name##_, \ |
138 size_of_CODE_AGE_##name##_ = \ | 192 "c:" "V8.SizeOf_CODE_AGE-" #name}, |
139 StatsCounter(isolate, "c:" "V8.SizeOf_CODE_AGE-" #name); | 193 CODE_AGE_LIST_COMPLETE(SC) |
140 CODE_AGE_LIST_COMPLETE(SC) | |
141 #undef SC | 194 #undef SC |
| 195 }; |
| 196 // clang-format on |
| 197 for (const auto& counter : kStatsCounters) { |
| 198 this->*counter.member = StatsCounter(isolate, counter.caption); |
| 199 } |
142 } | 200 } |
143 | 201 |
144 | 202 |
145 void Counters::ResetCounters() { | 203 void Counters::ResetCounters() { |
146 #define SC(name, caption) name##_.Reset(); | 204 #define SC(name, caption) name##_.Reset(); |
147 STATS_COUNTER_LIST_1(SC) | 205 STATS_COUNTER_LIST_1(SC) |
148 STATS_COUNTER_LIST_2(SC) | 206 STATS_COUNTER_LIST_2(SC) |
149 #undef SC | 207 #undef SC |
150 | 208 |
151 #define SC(name) \ | 209 #define SC(name) \ |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 double count_percent_; | 326 double count_percent_; |
269 }; | 327 }; |
270 | 328 |
271 uint64_t total_call_count = 0; | 329 uint64_t total_call_count = 0; |
272 base::TimeDelta total_time; | 330 base::TimeDelta total_time; |
273 std::vector<Entry> entries; | 331 std::vector<Entry> entries; |
274 }; | 332 }; |
275 | 333 |
276 void RuntimeCallCounter::Reset() { | 334 void RuntimeCallCounter::Reset() { |
277 count_ = 0; | 335 count_ = 0; |
278 time_ = base::TimeDelta(); | 336 time_ = 0; |
279 } | 337 } |
280 | 338 |
281 void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) { | 339 void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) { |
282 value->BeginArray(name_); | 340 value->BeginArray(name_); |
283 value->AppendDouble(count_); | 341 value->AppendDouble(count_); |
284 value->AppendDouble(time_.InMicroseconds()); | 342 value->AppendDouble(time_); |
285 value->EndArray(); | 343 value->EndArray(); |
286 } | 344 } |
287 | 345 |
288 void RuntimeCallCounter::Add(RuntimeCallCounter* other) { | 346 void RuntimeCallCounter::Add(RuntimeCallCounter* other) { |
289 count_ += other->count(); | 347 count_ += other->count(); |
290 time_ += other->time(); | 348 time_ += other->time().InMicroseconds(); |
291 } | 349 } |
292 | 350 |
293 void RuntimeCallTimer::Snapshot() { | 351 void RuntimeCallTimer::Snapshot() { |
294 base::TimeTicks now = Now(); | 352 base::TimeTicks now = Now(); |
295 // Pause only / topmost timer in the timer stack. | 353 // Pause only / topmost timer in the timer stack. |
296 Pause(now); | 354 Pause(now); |
297 // Commit all the timer's elapsed time to the counters. | 355 // Commit all the timer's elapsed time to the counters. |
298 RuntimeCallTimer* timer = this; | 356 RuntimeCallTimer* timer = this; |
299 while (timer != nullptr) { | 357 while (timer != nullptr) { |
300 timer->CommitTimeToCounter(); | 358 timer->CommitTimeToCounter(); |
301 timer = timer->parent(); | 359 timer = timer->parent(); |
302 } | 360 } |
303 Resume(now); | 361 Resume(now); |
304 } | 362 } |
305 | 363 |
| 364 RuntimeCallStats::RuntimeCallStats() : in_use_(false) { |
| 365 static const char* const kNames[] = { |
| 366 #define CALL_RUNTIME_COUNTER(name) #name, |
| 367 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) // |
| 368 #undef CALL_RUNTIME_COUNTER |
| 369 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) #name, |
| 370 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) // |
| 371 #undef CALL_RUNTIME_COUNTER |
| 372 #define CALL_BUILTIN_COUNTER(name) #name, |
| 373 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) // |
| 374 #undef CALL_BUILTIN_COUNTER |
| 375 #define CALL_BUILTIN_COUNTER(name) "API_" #name, |
| 376 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) // |
| 377 #undef CALL_BUILTIN_COUNTER |
| 378 #define CALL_BUILTIN_COUNTER(name) #name, |
| 379 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) |
| 380 #undef CALL_BUILTIN_COUNTER |
| 381 }; |
| 382 for (int i = 0; i < counters_count; i++) { |
| 383 this->*(counters[i]) = RuntimeCallCounter(kNames[i]); |
| 384 } |
| 385 } |
| 386 |
306 // static | 387 // static |
307 const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = { | 388 const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = { |
308 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name, | 389 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name, |
309 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) // | 390 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) // |
310 #undef CALL_RUNTIME_COUNTER | 391 #undef CALL_RUNTIME_COUNTER |
311 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ | 392 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ |
312 &RuntimeCallStats::Runtime_##name, // | 393 &RuntimeCallStats::Runtime_##name, // |
313 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) // | 394 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) // |
314 #undef CALL_RUNTIME_COUNTER | 395 #undef CALL_RUNTIME_COUNTER |
315 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name, | 396 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 RuntimeCallStats::counters) { | 488 RuntimeCallStats::counters) { |
408 RuntimeCallCounter* counter = &(this->*counter_id); | 489 RuntimeCallCounter* counter = &(this->*counter_id); |
409 if (counter->count() > 0) counter->Dump(value); | 490 if (counter->count() > 0) counter->Dump(value); |
410 } | 491 } |
411 | 492 |
412 in_use_ = false; | 493 in_use_ = false; |
413 } | 494 } |
414 | 495 |
415 } // namespace internal | 496 } // namespace internal |
416 } // namespace v8 | 497 } // namespace v8 |
OLD | NEW |