| 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 |