OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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/log.h" | 5 #include "src/log.h" |
6 | 6 |
7 #include <cstdarg> | 7 #include <cstdarg> |
8 #include <memory> | 8 #include <memory> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 public: | 552 public: |
553 explicit Profiler(Isolate* isolate); | 553 explicit Profiler(Isolate* isolate); |
554 void Engage(); | 554 void Engage(); |
555 void Disengage(); | 555 void Disengage(); |
556 | 556 |
557 // Inserts collected profiling data into buffer. | 557 // Inserts collected profiling data into buffer. |
558 void Insert(v8::TickSample* sample) { | 558 void Insert(v8::TickSample* sample) { |
559 if (paused_) | 559 if (paused_) |
560 return; | 560 return; |
561 | 561 |
562 if (Succ(head_) == static_cast<int>(base::NoBarrier_Load(&tail_))) { | 562 if (Succ(head_) == static_cast<int>(base::Relaxed_Load(&tail_))) { |
563 overflow_ = true; | 563 overflow_ = true; |
564 } else { | 564 } else { |
565 buffer_[head_] = *sample; | 565 buffer_[head_] = *sample; |
566 head_ = Succ(head_); | 566 head_ = Succ(head_); |
567 buffer_semaphore_.Signal(); // Tell we have an element. | 567 buffer_semaphore_.Signal(); // Tell we have an element. |
568 } | 568 } |
569 } | 569 } |
570 | 570 |
571 virtual void Run(); | 571 virtual void Run(); |
572 | 572 |
573 // Pause and Resume TickSample data collection. | 573 // Pause and Resume TickSample data collection. |
574 void pause() { paused_ = true; } | 574 void pause() { paused_ = true; } |
575 void resume() { paused_ = false; } | 575 void resume() { paused_ = false; } |
576 | 576 |
577 private: | 577 private: |
578 // Waits for a signal and removes profiling data. | 578 // Waits for a signal and removes profiling data. |
579 bool Remove(v8::TickSample* sample) { | 579 bool Remove(v8::TickSample* sample) { |
580 buffer_semaphore_.Wait(); // Wait for an element. | 580 buffer_semaphore_.Wait(); // Wait for an element. |
581 *sample = buffer_[base::NoBarrier_Load(&tail_)]; | 581 *sample = buffer_[base::Relaxed_Load(&tail_)]; |
582 bool result = overflow_; | 582 bool result = overflow_; |
583 base::NoBarrier_Store(&tail_, static_cast<base::Atomic32>( | 583 base::Relaxed_Store( |
584 Succ(base::NoBarrier_Load(&tail_)))); | 584 &tail_, static_cast<base::Atomic32>(Succ(base::Relaxed_Load(&tail_)))); |
585 overflow_ = false; | 585 overflow_ = false; |
586 return result; | 586 return result; |
587 } | 587 } |
588 | 588 |
589 // Returns the next index in the cyclic buffer. | 589 // Returns the next index in the cyclic buffer. |
590 int Succ(int index) { return (index + 1) % kBufferSize; } | 590 int Succ(int index) { return (index + 1) % kBufferSize; } |
591 | 591 |
592 Isolate* isolate_; | 592 Isolate* isolate_; |
593 // Cyclic buffer for communicating profiling samples | 593 // Cyclic buffer for communicating profiling samples |
594 // between the signal handler and the worker thread. | 594 // between the signal handler and the worker thread. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 // Profiler implementation. | 660 // Profiler implementation. |
661 // | 661 // |
662 Profiler::Profiler(Isolate* isolate) | 662 Profiler::Profiler(Isolate* isolate) |
663 : base::Thread(Options("v8:Profiler")), | 663 : base::Thread(Options("v8:Profiler")), |
664 isolate_(isolate), | 664 isolate_(isolate), |
665 head_(0), | 665 head_(0), |
666 overflow_(false), | 666 overflow_(false), |
667 buffer_semaphore_(0), | 667 buffer_semaphore_(0), |
668 engaged_(false), | 668 engaged_(false), |
669 paused_(false) { | 669 paused_(false) { |
670 base::NoBarrier_Store(&tail_, 0); | 670 base::Relaxed_Store(&tail_, 0); |
671 base::NoBarrier_Store(&running_, 0); | 671 base::Relaxed_Store(&running_, 0); |
672 } | 672 } |
673 | 673 |
674 | 674 |
675 void Profiler::Engage() { | 675 void Profiler::Engage() { |
676 if (engaged_) return; | 676 if (engaged_) return; |
677 engaged_ = true; | 677 engaged_ = true; |
678 | 678 |
679 std::vector<base::OS::SharedLibraryAddress> addresses = | 679 std::vector<base::OS::SharedLibraryAddress> addresses = |
680 base::OS::GetSharedLibraryAddresses(); | 680 base::OS::GetSharedLibraryAddresses(); |
681 for (size_t i = 0; i < addresses.size(); ++i) { | 681 for (size_t i = 0; i < addresses.size(); ++i) { |
682 LOG(isolate_, | 682 LOG(isolate_, |
683 SharedLibraryEvent(addresses[i].library_path, addresses[i].start, | 683 SharedLibraryEvent(addresses[i].library_path, addresses[i].start, |
684 addresses[i].end, addresses[i].aslr_slide)); | 684 addresses[i].end, addresses[i].aslr_slide)); |
685 } | 685 } |
686 | 686 |
687 // Start thread processing the profiler buffer. | 687 // Start thread processing the profiler buffer. |
688 base::NoBarrier_Store(&running_, 1); | 688 base::Relaxed_Store(&running_, 1); |
689 Start(); | 689 Start(); |
690 | 690 |
691 // Register to get ticks. | 691 // Register to get ticks. |
692 Logger* logger = isolate_->logger(); | 692 Logger* logger = isolate_->logger(); |
693 logger->ticker_->SetProfiler(this); | 693 logger->ticker_->SetProfiler(this); |
694 | 694 |
695 logger->ProfilerBeginEvent(); | 695 logger->ProfilerBeginEvent(); |
696 } | 696 } |
697 | 697 |
698 | 698 |
699 void Profiler::Disengage() { | 699 void Profiler::Disengage() { |
700 if (!engaged_) return; | 700 if (!engaged_) return; |
701 | 701 |
702 // Stop receiving ticks. | 702 // Stop receiving ticks. |
703 isolate_->logger()->ticker_->ClearProfiler(); | 703 isolate_->logger()->ticker_->ClearProfiler(); |
704 | 704 |
705 // Terminate the worker thread by setting running_ to false, | 705 // Terminate the worker thread by setting running_ to false, |
706 // inserting a fake element in the queue and then wait for | 706 // inserting a fake element in the queue and then wait for |
707 // the thread to terminate. | 707 // the thread to terminate. |
708 base::NoBarrier_Store(&running_, 0); | 708 base::Relaxed_Store(&running_, 0); |
709 v8::TickSample sample; | 709 v8::TickSample sample; |
710 // Reset 'paused_' flag, otherwise semaphore may not be signalled. | 710 // Reset 'paused_' flag, otherwise semaphore may not be signalled. |
711 resume(); | 711 resume(); |
712 Insert(&sample); | 712 Insert(&sample); |
713 Join(); | 713 Join(); |
714 | 714 |
715 LOG(isolate_, UncheckedStringEvent("profiler", "end")); | 715 LOG(isolate_, UncheckedStringEvent("profiler", "end")); |
716 } | 716 } |
717 | 717 |
718 | 718 |
719 void Profiler::Run() { | 719 void Profiler::Run() { |
720 v8::TickSample sample; | 720 v8::TickSample sample; |
721 bool overflow = Remove(&sample); | 721 bool overflow = Remove(&sample); |
722 while (base::NoBarrier_Load(&running_)) { | 722 while (base::Relaxed_Load(&running_)) { |
723 LOG(isolate_, TickEvent(&sample, overflow)); | 723 LOG(isolate_, TickEvent(&sample, overflow)); |
724 overflow = Remove(&sample); | 724 overflow = Remove(&sample); |
725 } | 725 } |
726 } | 726 } |
727 | 727 |
728 | 728 |
729 // | 729 // |
730 // Logger class implementation. | 730 // Logger class implementation. |
731 // | 731 // |
732 | 732 |
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 | 1901 |
1902 if (profiler_listener_.get() != nullptr) { | 1902 if (profiler_listener_.get() != nullptr) { |
1903 removeCodeEventListener(profiler_listener_.get()); | 1903 removeCodeEventListener(profiler_listener_.get()); |
1904 } | 1904 } |
1905 | 1905 |
1906 return log_->Close(); | 1906 return log_->Close(); |
1907 } | 1907 } |
1908 | 1908 |
1909 } // namespace internal | 1909 } // namespace internal |
1910 } // namespace v8 | 1910 } // namespace v8 |
OLD | NEW |