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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 entry.Print(os); | 209 entry.Print(os); |
210 } | 210 } |
211 os << std::string(88, '-') << std::endl; | 211 os << std::string(88, '-') << std::endl; |
212 Entry("Total", total_time, total_call_count).Print(os); | 212 Entry("Total", total_time, total_call_count).Print(os); |
213 } | 213 } |
214 | 214 |
215 // By default, the compiler will usually inline this, which results in a large | 215 // By default, the compiler will usually inline this, which results in a large |
216 // binary size increase: std::vector::push_back expands to a large amount of | 216 // binary size increase: std::vector::push_back expands to a large amount of |
217 // instructions, and this function is invoked repeatedly by macros. | 217 // instructions, and this function is invoked repeatedly by macros. |
218 V8_NOINLINE void Add(RuntimeCallCounter* counter) { | 218 V8_NOINLINE void Add(RuntimeCallCounter* counter) { |
219 if (counter->count == 0) return; | 219 if (counter->count() == 0) return; |
220 entries.push_back(Entry(counter->name, counter->time, counter->count)); | 220 entries.push_back( |
221 total_time += counter->time; | 221 Entry(counter->name(), counter->time(), counter->count())); |
222 total_call_count += counter->count; | 222 total_time += counter->time(); |
| 223 total_call_count += counter->count(); |
223 } | 224 } |
224 | 225 |
225 private: | 226 private: |
226 class Entry { | 227 class Entry { |
227 public: | 228 public: |
228 Entry(const char* name, base::TimeDelta time, uint64_t count) | 229 Entry(const char* name, base::TimeDelta time, uint64_t count) |
229 : name_(name), | 230 : name_(name), |
230 time_(time.InMicroseconds()), | 231 time_(time.InMicroseconds()), |
231 count_(count), | 232 count_(count), |
232 time_percent_(100), | 233 time_percent_(100), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 double time_percent_; | 267 double time_percent_; |
267 double count_percent_; | 268 double count_percent_; |
268 }; | 269 }; |
269 | 270 |
270 uint64_t total_call_count = 0; | 271 uint64_t total_call_count = 0; |
271 base::TimeDelta total_time; | 272 base::TimeDelta total_time; |
272 std::vector<Entry> entries; | 273 std::vector<Entry> entries; |
273 }; | 274 }; |
274 | 275 |
275 void RuntimeCallCounter::Reset() { | 276 void RuntimeCallCounter::Reset() { |
276 count = 0; | 277 count_ = 0; |
277 time = base::TimeDelta(); | 278 time_ = base::TimeDelta(); |
278 } | 279 } |
279 | 280 |
280 void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) { | 281 void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) { |
281 value->BeginArray(name); | 282 value->BeginArray(name_); |
282 value->AppendLongInteger(count); | 283 value->AppendLongInteger(count_); |
283 value->AppendLongInteger(time.InMicroseconds()); | 284 value->AppendLongInteger(time_.InMicroseconds()); |
284 value->EndArray(); | 285 value->EndArray(); |
285 } | 286 } |
286 | 287 |
287 void RuntimeCallCounter::Add(RuntimeCallCounter* other) { | 288 void RuntimeCallCounter::Add(RuntimeCallCounter* other) { |
288 count += other->count; | 289 count_ += other->count(); |
289 time += other->time; | 290 time_ += other->time(); |
| 291 } |
| 292 |
| 293 void RuntimeCallTimer::Snapshot() { |
| 294 base::TimeTicks now = Now(); |
| 295 // Pause only / topmost timer in the timer stack. |
| 296 Pause(now); |
| 297 // Commit all the timer's elapsed time to the counters. |
| 298 RuntimeCallTimer* timer = this; |
| 299 while (timer != nullptr) { |
| 300 timer->CommitTimeToCounter(); |
| 301 timer = timer->parent(); |
| 302 } |
| 303 Resume(now); |
290 } | 304 } |
291 | 305 |
292 // static | 306 // static |
293 const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = { | 307 const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = { |
294 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name, | 308 #define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name, |
295 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) // | 309 FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) // |
296 #undef CALL_RUNTIME_COUNTER | 310 #undef CALL_RUNTIME_COUNTER |
297 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ | 311 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ |
298 &RuntimeCallStats::Runtime_##name, // | 312 &RuntimeCallStats::Runtime_##name, // |
299 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) // | 313 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) // |
300 #undef CALL_RUNTIME_COUNTER | 314 #undef CALL_RUNTIME_COUNTER |
301 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name, | 315 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name, |
302 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) // | 316 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) // |
303 #undef CALL_BUILTIN_COUNTER | 317 #undef CALL_BUILTIN_COUNTER |
304 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::API_##name, | 318 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::API_##name, |
305 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) // | 319 FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) // |
306 #undef CALL_BUILTIN_COUNTER | 320 #undef CALL_BUILTIN_COUNTER |
307 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Handler_##name, | 321 #define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Handler_##name, |
308 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) | 322 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) |
309 #undef CALL_BUILTIN_COUNTER | 323 #undef CALL_BUILTIN_COUNTER |
310 }; | 324 }; |
311 | 325 |
312 // static | 326 // static |
313 void RuntimeCallStats::Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer, | 327 void RuntimeCallStats::Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer, |
314 CounterId counter_id) { | 328 CounterId counter_id) { |
315 RuntimeCallCounter* counter = &(stats->*counter_id); | 329 RuntimeCallCounter* counter = &(stats->*counter_id); |
316 DCHECK(counter->name != nullptr); | 330 DCHECK(counter->name() != nullptr); |
317 timer->Start(counter, stats->current_timer_.Value()); | 331 timer->Start(counter, stats->current_timer_.Value()); |
318 stats->current_timer_.SetValue(timer); | 332 stats->current_timer_.SetValue(timer); |
319 } | 333 } |
320 | 334 |
321 // static | 335 // static |
322 void RuntimeCallStats::Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer) { | 336 void RuntimeCallStats::Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer) { |
323 if (stats->current_timer_.Value() == timer) { | 337 if (stats->current_timer_.Value() == timer) { |
324 stats->current_timer_.SetValue(timer->Stop()); | 338 stats->current_timer_.SetValue(timer->Stop()); |
325 } else { | 339 } else { |
326 // Must be a Threading cctest. Walk the chain of Timers to find the | 340 // Must be a Threading cctest. Walk the chain of Timers to find the |
327 // buried one that's leaving. We don't care about keeping nested timings | 341 // buried one that's leaving. We don't care about keeping nested timings |
328 // accurate, just avoid crashing by keeping the chain intact. | 342 // accurate, just avoid crashing by keeping the chain intact. |
329 RuntimeCallTimer* next = stats->current_timer_.Value(); | 343 RuntimeCallTimer* next = stats->current_timer_.Value(); |
330 while (next && next->parent() != timer) next = next->parent(); | 344 while (next && next->parent() != timer) next = next->parent(); |
331 if (next == nullptr) return; | 345 if (next == nullptr) return; |
332 next->parent_.SetValue(timer->Stop()); | 346 next->set_parent(timer->Stop()); |
333 } | 347 } |
334 } | 348 } |
335 | 349 |
336 void RuntimeCallStats::Add(RuntimeCallStats* other) { | 350 void RuntimeCallStats::Add(RuntimeCallStats* other) { |
337 for (const RuntimeCallStats::CounterId counter_id : | 351 for (const RuntimeCallStats::CounterId counter_id : |
338 RuntimeCallStats::counters) { | 352 RuntimeCallStats::counters) { |
339 RuntimeCallCounter* counter = &(this->*counter_id); | 353 RuntimeCallCounter* counter = &(this->*counter_id); |
340 RuntimeCallCounter* other_counter = &(other->*counter_id); | 354 RuntimeCallCounter* other_counter = &(other->*counter_id); |
341 counter->Add(other_counter); | 355 counter->Add(other_counter); |
342 } | 356 } |
343 } | 357 } |
344 | 358 |
345 // static | 359 // static |
346 void RuntimeCallStats::CorrectCurrentCounterId(RuntimeCallStats* stats, | 360 void RuntimeCallStats::CorrectCurrentCounterId(RuntimeCallStats* stats, |
347 CounterId counter_id) { | 361 CounterId counter_id) { |
348 RuntimeCallTimer* timer = stats->current_timer_.Value(); | 362 RuntimeCallTimer* timer = stats->current_timer_.Value(); |
349 // When RCS are enabled dynamically there might be no current timer set up. | 363 // When RCS are enabled dynamically there might be no current timer set up. |
350 if (timer == nullptr) return; | 364 if (timer == nullptr) return; |
351 timer->counter_ = &(stats->*counter_id); | 365 timer->set_counter(&(stats->*counter_id)); |
352 } | 366 } |
353 | 367 |
354 void RuntimeCallStats::Print(std::ostream& os) { | 368 void RuntimeCallStats::Print(std::ostream& os) { |
355 RuntimeCallStatEntries entries; | 369 RuntimeCallStatEntries entries; |
356 if (current_timer_.Value() != nullptr) { | 370 if (current_timer_.Value() != nullptr) { |
357 current_timer_.Value()->Elapsed(); | 371 current_timer_.Value()->Snapshot(); |
358 } | 372 } |
359 for (const RuntimeCallStats::CounterId counter_id : | 373 for (const RuntimeCallStats::CounterId counter_id : |
360 RuntimeCallStats::counters) { | 374 RuntimeCallStats::counters) { |
361 RuntimeCallCounter* counter = &(this->*counter_id); | 375 RuntimeCallCounter* counter = &(this->*counter_id); |
362 entries.Add(counter); | 376 entries.Add(counter); |
363 } | 377 } |
364 entries.Print(os); | 378 entries.Print(os); |
365 } | 379 } |
366 | 380 |
367 void RuntimeCallStats::Reset() { | 381 void RuntimeCallStats::Reset() { |
(...skipping 13 matching lines...) Expand all Loading... |
381 counter->Reset(); | 395 counter->Reset(); |
382 } | 396 } |
383 | 397 |
384 in_use_ = true; | 398 in_use_ = true; |
385 } | 399 } |
386 | 400 |
387 void RuntimeCallStats::Dump(v8::tracing::TracedValue* value) { | 401 void RuntimeCallStats::Dump(v8::tracing::TracedValue* value) { |
388 for (const RuntimeCallStats::CounterId counter_id : | 402 for (const RuntimeCallStats::CounterId counter_id : |
389 RuntimeCallStats::counters) { | 403 RuntimeCallStats::counters) { |
390 RuntimeCallCounter* counter = &(this->*counter_id); | 404 RuntimeCallCounter* counter = &(this->*counter_id); |
391 if (counter->count > 0) counter->Dump(value); | 405 if (counter->count() > 0) counter->Dump(value); |
392 } | 406 } |
393 | 407 |
394 in_use_ = false; | 408 in_use_ = false; |
395 } | 409 } |
396 | 410 |
397 } // namespace internal | 411 } // namespace internal |
398 } // namespace v8 | 412 } // namespace v8 |
OLD | NEW |