| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 return new SolarisSemaphore(count); | 588 return new SolarisSemaphore(count); |
| 589 } | 589 } |
| 590 | 590 |
| 591 | 591 |
| 592 #ifdef ENABLE_LOGGING_AND_PROFILING | 592 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 593 | 593 |
| 594 static pthread_t GetThreadID() { | 594 static pthread_t GetThreadID() { |
| 595 return pthread_self(); | 595 return pthread_self(); |
| 596 } | 596 } |
| 597 | 597 |
| 598 class Sampler::PlatformData : public Malloced { | |
| 599 public: | |
| 600 PlatformData() : vm_tid_(GetThreadID()) {} | |
| 601 | |
| 602 pthread_t vm_tid() const { return vm_tid_; } | |
| 603 | |
| 604 private: | |
| 605 pthread_t vm_tid_; | |
| 606 }; | |
| 607 | |
| 608 | |
| 609 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { | 598 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { |
| 610 USE(info); | 599 USE(info); |
| 611 if (signal != SIGPROF) return; | 600 if (signal != SIGPROF) return; |
| 612 Isolate* isolate = Isolate::UncheckedCurrent(); | 601 Isolate* isolate = Isolate::UncheckedCurrent(); |
| 613 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { | 602 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { |
| 614 // We require a fully initialized and entered isolate. | 603 // We require a fully initialized and entered isolate. |
| 615 return; | 604 return; |
| 616 } | 605 } |
| 617 if (v8::Locker::IsActive() && | 606 if (v8::Locker::IsActive() && |
| 618 !isolate->thread_manager()->IsLockedByCurrentThread()) { | 607 !isolate->thread_manager()->IsLockedByCurrentThread()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 632 sample->state = isolate->current_vm_state(); | 621 sample->state = isolate->current_vm_state(); |
| 633 | 622 |
| 634 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]); | 623 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]); |
| 635 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]); | 624 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]); |
| 636 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]); | 625 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]); |
| 637 | 626 |
| 638 sampler->SampleStack(sample); | 627 sampler->SampleStack(sample); |
| 639 sampler->Tick(sample); | 628 sampler->Tick(sample); |
| 640 } | 629 } |
| 641 | 630 |
| 631 class Sampler::PlatformData : public Malloced { |
| 632 public: |
| 633 PlatformData() : vm_tid_(GetThreadID()) {} |
| 634 |
| 635 pthread_t vm_tid() const { return vm_tid_; } |
| 636 |
| 637 private: |
| 638 pthread_t vm_tid_; |
| 639 }; |
| 640 |
| 641 |
| 642 class SignalSender : public Thread { | 642 class SignalSender : public Thread { |
| 643 public: | 643 public: |
| 644 enum SleepInterval { | 644 enum SleepInterval { |
| 645 HALF_INTERVAL, | 645 HALF_INTERVAL, |
| 646 FULL_INTERVAL | 646 FULL_INTERVAL |
| 647 }; | 647 }; |
| 648 | 648 |
| 649 explicit SignalSender(int interval) | 649 explicit SignalSender(int interval) |
| 650 : Thread("SignalSender"), | 650 : Thread("SignalSender"), |
| 651 interval_(interval) {} | 651 interval_(interval) {} |
| 652 | 652 |
| 653 static void InstallSignalHandler() { |
| 654 struct sigaction sa; |
| 655 sa.sa_sigaction = ProfilerSignalHandler; |
| 656 sigemptyset(&sa.sa_mask); |
| 657 sa.sa_flags = SA_RESTART | SA_SIGINFO; |
| 658 signal_handler_installed_ = |
| 659 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
| 660 } |
| 661 |
| 662 static void RestoreSignalHandler() { |
| 663 if (signal_handler_installed_) { |
| 664 sigaction(SIGPROF, &old_signal_handler_, 0); |
| 665 signal_handler_installed_ = false; |
| 666 } |
| 667 } |
| 668 |
| 653 static void AddActiveSampler(Sampler* sampler) { | 669 static void AddActiveSampler(Sampler* sampler) { |
| 654 ScopedLock lock(mutex_); | 670 ScopedLock lock(mutex_); |
| 655 SamplerRegistry::AddActiveSampler(sampler); | 671 SamplerRegistry::AddActiveSampler(sampler); |
| 656 if (instance_ == NULL) { | 672 if (instance_ == NULL) { |
| 657 // Install a signal handler. | 673 // Start a thread that will send SIGPROF signal to VM threads, |
| 658 struct sigaction sa; | 674 // when CPU profiling will be enabled. |
| 659 sa.sa_sigaction = ProfilerSignalHandler; | |
| 660 sigemptyset(&sa.sa_mask); | |
| 661 sa.sa_flags = SA_RESTART | SA_SIGINFO; | |
| 662 signal_handler_installed_ = | |
| 663 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); | |
| 664 | |
| 665 // Start a thread that sends SIGPROF signal to VM threads. | |
| 666 instance_ = new SignalSender(sampler->interval()); | 675 instance_ = new SignalSender(sampler->interval()); |
| 667 instance_->Start(); | 676 instance_->Start(); |
| 668 } else { | 677 } else { |
| 669 ASSERT(instance_->interval_ == sampler->interval()); | 678 ASSERT(instance_->interval_ == sampler->interval()); |
| 670 } | 679 } |
| 671 } | 680 } |
| 672 | 681 |
| 673 static void RemoveActiveSampler(Sampler* sampler) { | 682 static void RemoveActiveSampler(Sampler* sampler) { |
| 674 ScopedLock lock(mutex_); | 683 ScopedLock lock(mutex_); |
| 675 SamplerRegistry::RemoveActiveSampler(sampler); | 684 SamplerRegistry::RemoveActiveSampler(sampler); |
| 676 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { | 685 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { |
| 677 RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown(); | 686 RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown(); |
| 678 instance_->Join(); | 687 instance_->Join(); |
| 679 delete instance_; | 688 delete instance_; |
| 680 instance_ = NULL; | 689 instance_ = NULL; |
| 681 | 690 RestoreSignalHandler(); |
| 682 // Restore the old signal handler. | |
| 683 if (signal_handler_installed_) { | |
| 684 sigaction(SIGPROF, &old_signal_handler_, 0); | |
| 685 signal_handler_installed_ = false; | |
| 686 } | |
| 687 } | 691 } |
| 688 } | 692 } |
| 689 | 693 |
| 690 // Implement Thread::Run(). | 694 // Implement Thread::Run(). |
| 691 virtual void Run() { | 695 virtual void Run() { |
| 692 SamplerRegistry::State state; | 696 SamplerRegistry::State state; |
| 693 while ((state = SamplerRegistry::GetState()) != | 697 while ((state = SamplerRegistry::GetState()) != |
| 694 SamplerRegistry::HAS_NO_SAMPLERS) { | 698 SamplerRegistry::HAS_NO_SAMPLERS) { |
| 695 bool cpu_profiling_enabled = | 699 bool cpu_profiling_enabled = |
| 696 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); | 700 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); |
| 697 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); | 701 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); |
| 702 if (cpu_profiling_enabled && !signal_handler_installed_) { |
| 703 InstallSignalHandler(); |
| 704 } else if (!cpu_profiling_enabled && signal_handler_installed_) { |
| 705 RestoreSignalHandler(); |
| 706 } |
| 707 |
| 698 // When CPU profiling is enabled both JavaScript and C++ code is | 708 // When CPU profiling is enabled both JavaScript and C++ code is |
| 699 // profiled. We must not suspend. | 709 // profiled. We must not suspend. |
| 700 if (!cpu_profiling_enabled) { | 710 if (!cpu_profiling_enabled) { |
| 701 if (rate_limiter_.SuspendIfNecessary()) continue; | 711 if (rate_limiter_.SuspendIfNecessary()) continue; |
| 702 } | 712 } |
| 703 if (cpu_profiling_enabled && runtime_profiler_enabled) { | 713 if (cpu_profiling_enabled && runtime_profiler_enabled) { |
| 704 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) { | 714 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) { |
| 705 return; | 715 return; |
| 706 } | 716 } |
| 707 Sleep(HALF_INTERVAL); | 717 Sleep(HALF_INTERVAL); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 | 814 |
| 805 void Sampler::Stop() { | 815 void Sampler::Stop() { |
| 806 ASSERT(IsActive()); | 816 ASSERT(IsActive()); |
| 807 SignalSender::RemoveActiveSampler(this); | 817 SignalSender::RemoveActiveSampler(this); |
| 808 SetActive(false); | 818 SetActive(false); |
| 809 } | 819 } |
| 810 | 820 |
| 811 #endif // ENABLE_LOGGING_AND_PROFILING | 821 #endif // ENABLE_LOGGING_AND_PROFILING |
| 812 | 822 |
| 813 } } // namespace v8::internal | 823 } } // namespace v8::internal |
| OLD | NEW |