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" |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 public: | 494 public: |
495 RuntimeCallTimer() {} | 495 RuntimeCallTimer() {} |
496 | 496 |
497 private: | 497 private: |
498 friend class RuntimeCallStats; | 498 friend class RuntimeCallStats; |
499 | 499 |
500 inline void Start(RuntimeCallCounter* counter, RuntimeCallTimer* parent) { | 500 inline void Start(RuntimeCallCounter* counter, RuntimeCallTimer* parent) { |
501 counter_ = counter; | 501 counter_ = counter; |
502 parent_ = parent; | 502 parent_ = parent; |
503 timer_.Start(); | 503 timer_.Start(); |
504 counter_->count++; | |
505 } | 504 } |
506 | 505 |
507 inline RuntimeCallTimer* Stop() { | 506 inline RuntimeCallTimer* Stop() { |
508 base::TimeDelta delta = timer_.Elapsed(); | 507 base::TimeDelta delta = timer_.Elapsed(); |
509 timer_.Stop(); | 508 timer_.Stop(); |
| 509 counter_->count++; |
510 counter_->time += delta; | 510 counter_->time += delta; |
511 if (parent_ != NULL) { | 511 if (parent_ != NULL) { |
512 // Adjust parent timer so that it does not include sub timer's time. | 512 // Adjust parent timer so that it does not include sub timer's time. |
513 parent_->counter_->time -= delta; | 513 parent_->counter_->time -= delta; |
514 } | 514 } |
515 return parent_; | 515 return parent_; |
516 } | 516 } |
517 | 517 |
518 RuntimeCallCounter* counter_ = nullptr; | 518 RuntimeCallCounter* counter_ = nullptr; |
519 RuntimeCallTimer* parent_ = nullptr; | 519 RuntimeCallTimer* parent_ = nullptr; |
520 base::ElapsedTimer timer_; | 520 base::ElapsedTimer timer_; |
521 }; | 521 }; |
522 | 522 |
| 523 #define FOR_EACH_HANDLER_COUNTER(V) \ |
| 524 V(IC_HandlerCacheHit) \ |
| 525 V(KeyedLoadIC_LoadIndexedStringStub) \ |
| 526 V(KeyedLoadIC_LoadIndexedInterceptorStub) \ |
| 527 V(KeyedLoadIC_KeyedLoadSloppyArgumentsStub) \ |
| 528 V(KeyedLoadIC_LoadFastElementStub) \ |
| 529 V(KeyedLoadIC_LoadDictionaryElementStub) \ |
| 530 V(KeyedLoadIC_PolymorphicElement) \ |
| 531 V(KeyedStoreIC_KeyedStoreSloppyArgumentsStub) \ |
| 532 V(KeyedStoreIC_StoreFastElementStub) \ |
| 533 V(KeyedStoreIC_StoreElementStub) \ |
| 534 V(KeyedStoreIC_Polymorphic) \ |
| 535 V(LoadIC_FunctionPrototypeStub) \ |
| 536 V(LoadIC_ArrayBufferViewLoadFieldStub) \ |
| 537 V(LoadIC_LoadApiGetterStub) \ |
| 538 V(LoadIC_LoadCallback) \ |
| 539 V(LoadIC_LoadConstant) \ |
| 540 V(LoadIC_LoadConstantStub) \ |
| 541 V(LoadIC_LoadField) \ |
| 542 V(LoadIC_LoadFieldStub) \ |
| 543 V(LoadIC_LoadGlobal) \ |
| 544 V(LoadIC_LoadInterceptor) \ |
| 545 V(LoadIC_LoadNonexistent) \ |
| 546 V(LoadIC_LoadNormal) \ |
| 547 V(LoadIC_LoadScriptContextFieldStub) \ |
| 548 V(LoadIC_LoadViaGetter) \ |
| 549 V(LoadIC_SlowStub) \ |
| 550 V(LoadIC_StringLengthStub) \ |
| 551 V(StoreIC_SlowStub) \ |
| 552 V(StoreIC_StoreCallback) \ |
| 553 V(StoreIC_StoreField) \ |
| 554 V(StoreIC_StoreFieldStub) \ |
| 555 V(StoreIC_StoreGlobal) \ |
| 556 V(StoreIC_StoreGlobalTransition) \ |
| 557 V(StoreIC_StoreInterceptorStub) \ |
| 558 V(StoreIC_StoreNormal) \ |
| 559 V(StoreIC_StoreScriptContextFieldStub) \ |
| 560 V(StoreIC_StoreTransition) \ |
| 561 V(StoreIC_StoreViaSetter) |
| 562 |
523 class RuntimeCallStats { | 563 class RuntimeCallStats { |
524 public: | 564 public: |
525 typedef RuntimeCallCounter RuntimeCallStats::*CounterId; | 565 typedef RuntimeCallCounter RuntimeCallStats::*CounterId; |
526 | 566 |
527 // Dummy counter for the unexpected stub miss. | 567 // Dummy counter for the unexpected stub miss. |
528 RuntimeCallCounter UnexpectedStubMiss = | 568 RuntimeCallCounter UnexpectedStubMiss = |
529 RuntimeCallCounter("UnexpectedStubMiss"); | 569 RuntimeCallCounter("UnexpectedStubMiss"); |
530 // Counter for runtime callbacks into JavaScript. | 570 // Counter for runtime callbacks into JavaScript. |
531 RuntimeCallCounter ExternalCallback = RuntimeCallCounter("ExternalCallback"); | 571 RuntimeCallCounter ExternalCallback = RuntimeCallCounter("ExternalCallback"); |
532 RuntimeCallCounter GC = RuntimeCallCounter("GC"); | 572 RuntimeCallCounter GC = RuntimeCallCounter("GC"); |
533 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ | 573 #define CALL_RUNTIME_COUNTER(name, nargs, ressize) \ |
534 RuntimeCallCounter Runtime_##name = RuntimeCallCounter(#name); | 574 RuntimeCallCounter Runtime_##name = RuntimeCallCounter(#name); |
535 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) | 575 FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) |
536 #undef CALL_RUNTIME_COUNTER | 576 #undef CALL_RUNTIME_COUNTER |
537 #define CALL_BUILTIN_COUNTER(name, type) \ | 577 #define CALL_BUILTIN_COUNTER(name, type) \ |
538 RuntimeCallCounter Builtin_##name = RuntimeCallCounter(#name); | 578 RuntimeCallCounter Builtin_##name = RuntimeCallCounter(#name); |
539 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) | 579 BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) |
540 #undef CALL_BUILTIN_COUNTER | 580 #undef CALL_BUILTIN_COUNTER |
| 581 #define CALL_BUILTIN_COUNTER(name) \ |
| 582 RuntimeCallCounter Handler_##name = RuntimeCallCounter(#name); |
| 583 FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER) |
| 584 #undef CALL_BUILTIN_COUNTER |
541 | 585 |
542 // Starting measuring the time for a function. This will establish the | 586 // Starting measuring the time for a function. This will establish the |
543 // connection to the parent counter for properly calculating the own times. | 587 // connection to the parent counter for properly calculating the own times. |
544 static void Enter(Isolate* isolate, RuntimeCallTimer* timer, | 588 static void Enter(Isolate* isolate, RuntimeCallTimer* timer, |
545 CounterId counter_id); | 589 CounterId counter_id); |
546 | 590 |
547 // Leave a scope for a measured runtime function. This will properly add | 591 // Leave a scope for a measured runtime function. This will properly add |
548 // the time delta to the current_counter and subtract the delta from its | 592 // the time delta to the current_counter and subtract the delta from its |
549 // parent. | 593 // parent. |
550 static void Leave(Isolate* isolate, RuntimeCallTimer* timer); | 594 static void Leave(Isolate* isolate, RuntimeCallTimer* timer); |
551 | 595 |
| 596 // Set counter id for the innermost measurement. It can be used to refine |
| 597 // event kind when a runtime entry counter is too generic. |
| 598 static void CorrectCurrentCounterId(Isolate* isolate, CounterId counter_id); |
| 599 |
552 void Reset(); | 600 void Reset(); |
553 void Print(std::ostream& os); | 601 void Print(std::ostream& os); |
554 | 602 |
555 RuntimeCallStats() { Reset(); } | 603 RuntimeCallStats() { Reset(); } |
556 | 604 |
557 private: | 605 private: |
558 // Counter to track recursive time events. | 606 // Counter to track recursive time events. |
559 RuntimeCallTimer* current_timer_ = NULL; | 607 RuntimeCallTimer* current_timer_ = NULL; |
560 }; | 608 }; |
561 | 609 |
| 610 #define TRACE_RUNTIME_CALL_STATS(isolate, counter_name) \ |
| 611 do { \ |
| 612 if (FLAG_runtime_call_stats) { \ |
| 613 RuntimeCallStats::CorrectCurrentCounterId( \ |
| 614 isolate, &RuntimeCallStats::counter_name); \ |
| 615 } \ |
| 616 } while (false) |
| 617 |
| 618 #define TRACE_HANDLER_STATS(isolate, counter_name) \ |
| 619 TRACE_RUNTIME_CALL_STATS(isolate, Handler_##counter_name) |
| 620 |
562 // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the | 621 // A RuntimeCallTimerScopes wraps around a RuntimeCallTimer to measure the |
563 // the time of C++ scope. | 622 // the time of C++ scope. |
564 class RuntimeCallTimerScope { | 623 class RuntimeCallTimerScope { |
565 public: | 624 public: |
566 inline explicit RuntimeCallTimerScope( | 625 inline explicit RuntimeCallTimerScope( |
567 Isolate* isolate, RuntimeCallStats::CounterId counter_id) { | 626 Isolate* isolate, RuntimeCallStats::CounterId counter_id) { |
568 if (V8_UNLIKELY(FLAG_runtime_call_stats)) { | 627 if (V8_UNLIKELY(FLAG_runtime_call_stats)) { |
569 isolate_ = isolate; | 628 isolate_ = isolate; |
570 RuntimeCallStats::Enter(isolate_, &timer_, counter_id); | 629 RuntimeCallStats::Enter(isolate_, &timer_, counter_id); |
571 } | 630 } |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 | 1050 |
992 explicit Counters(Isolate* isolate); | 1051 explicit Counters(Isolate* isolate); |
993 | 1052 |
994 DISALLOW_IMPLICIT_CONSTRUCTORS(Counters); | 1053 DISALLOW_IMPLICIT_CONSTRUCTORS(Counters); |
995 }; | 1054 }; |
996 | 1055 |
997 } // namespace internal | 1056 } // namespace internal |
998 } // namespace v8 | 1057 } // namespace v8 |
999 | 1058 |
1000 #endif // V8_COUNTERS_H_ | 1059 #endif // V8_COUNTERS_H_ |
OLD | NEW |