| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 enum SleepInterval { | 915 enum SleepInterval { |
| 916 HALF_INTERVAL, | 916 HALF_INTERVAL, |
| 917 FULL_INTERVAL | 917 FULL_INTERVAL |
| 918 }; | 918 }; |
| 919 | 919 |
| 920 explicit SignalSender(int interval) | 920 explicit SignalSender(int interval) |
| 921 : Thread(NULL, "SignalSender"), | 921 : Thread(NULL, "SignalSender"), |
| 922 vm_tgid_(getpid()), | 922 vm_tgid_(getpid()), |
| 923 interval_(interval) {} | 923 interval_(interval) {} |
| 924 | 924 |
| 925 static void InstallSignalHandler() { |
| 926 struct sigaction sa; |
| 927 sa.sa_sigaction = ProfilerSignalHandler; |
| 928 sigemptyset(&sa.sa_mask); |
| 929 sa.sa_flags = SA_RESTART | SA_SIGINFO; |
| 930 signal_handler_installed_ = |
| 931 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
| 932 } |
| 933 |
| 934 static void RestoreSignalHandler() { |
| 935 if (signal_handler_installed_) { |
| 936 sigaction(SIGPROF, &old_signal_handler_, 0); |
| 937 signal_handler_installed_ = false; |
| 938 } |
| 939 } |
| 940 |
| 925 static void AddActiveSampler(Sampler* sampler) { | 941 static void AddActiveSampler(Sampler* sampler) { |
| 926 ScopedLock lock(mutex_); | 942 ScopedLock lock(mutex_); |
| 927 SamplerRegistry::AddActiveSampler(sampler); | 943 SamplerRegistry::AddActiveSampler(sampler); |
| 928 if (instance_ == NULL) { | 944 if (instance_ == NULL) { |
| 929 // Install a signal handler. | 945 // Start a thread that will send SIGPROF signal to VM threads, |
| 930 struct sigaction sa; | 946 // when CPU profiling will be enabled. |
| 931 sa.sa_sigaction = ProfilerSignalHandler; | |
| 932 sigemptyset(&sa.sa_mask); | |
| 933 sa.sa_flags = SA_RESTART | SA_SIGINFO; | |
| 934 signal_handler_installed_ = | |
| 935 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); | |
| 936 | |
| 937 // Start a thread that sends SIGPROF signal to VM threads. | |
| 938 instance_ = new SignalSender(sampler->interval()); | 947 instance_ = new SignalSender(sampler->interval()); |
| 939 instance_->Start(); | 948 instance_->Start(); |
| 940 } else { | 949 } else { |
| 941 ASSERT(instance_->interval_ == sampler->interval()); | 950 ASSERT(instance_->interval_ == sampler->interval()); |
| 942 } | 951 } |
| 943 } | 952 } |
| 944 | 953 |
| 945 static void RemoveActiveSampler(Sampler* sampler) { | 954 static void RemoveActiveSampler(Sampler* sampler) { |
| 946 ScopedLock lock(mutex_); | 955 ScopedLock lock(mutex_); |
| 947 SamplerRegistry::RemoveActiveSampler(sampler); | 956 SamplerRegistry::RemoveActiveSampler(sampler); |
| 948 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { | 957 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { |
| 949 RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown(); | 958 RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown(); |
| 950 instance_->Join(); | 959 instance_->Join(); |
| 951 delete instance_; | 960 delete instance_; |
| 952 instance_ = NULL; | 961 instance_ = NULL; |
| 953 | 962 RestoreSignalHandler(); |
| 954 // Restore the old signal handler. | |
| 955 if (signal_handler_installed_) { | |
| 956 sigaction(SIGPROF, &old_signal_handler_, 0); | |
| 957 signal_handler_installed_ = false; | |
| 958 } | |
| 959 } | 963 } |
| 960 } | 964 } |
| 961 | 965 |
| 962 // Implement Thread::Run(). | 966 // Implement Thread::Run(). |
| 963 virtual void Run() { | 967 virtual void Run() { |
| 964 SamplerRegistry::State state; | 968 SamplerRegistry::State state; |
| 965 while ((state = SamplerRegistry::GetState()) != | 969 while ((state = SamplerRegistry::GetState()) != |
| 966 SamplerRegistry::HAS_NO_SAMPLERS) { | 970 SamplerRegistry::HAS_NO_SAMPLERS) { |
| 967 bool cpu_profiling_enabled = | 971 bool cpu_profiling_enabled = |
| 968 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); | 972 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); |
| 969 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); | 973 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); |
| 974 if (cpu_profiling_enabled && !signal_handler_installed_) |
| 975 InstallSignalHandler(); |
| 976 else if (!cpu_profiling_enabled && signal_handler_installed_) |
| 977 RestoreSignalHandler(); |
| 970 // When CPU profiling is enabled both JavaScript and C++ code is | 978 // When CPU profiling is enabled both JavaScript and C++ code is |
| 971 // profiled. We must not suspend. | 979 // profiled. We must not suspend. |
| 972 if (!cpu_profiling_enabled) { | 980 if (!cpu_profiling_enabled) { |
| 973 if (rate_limiter_.SuspendIfNecessary()) continue; | 981 if (rate_limiter_.SuspendIfNecessary()) continue; |
| 974 } | 982 } |
| 975 if (cpu_profiling_enabled && runtime_profiler_enabled) { | 983 if (cpu_profiling_enabled && runtime_profiler_enabled) { |
| 976 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) { | 984 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) { |
| 977 return; | 985 return; |
| 978 } | 986 } |
| 979 Sleep(HALF_INTERVAL); | 987 Sleep(HALF_INTERVAL); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 | 1091 |
| 1084 void Sampler::Stop() { | 1092 void Sampler::Stop() { |
| 1085 ASSERT(IsActive()); | 1093 ASSERT(IsActive()); |
| 1086 SignalSender::RemoveActiveSampler(this); | 1094 SignalSender::RemoveActiveSampler(this); |
| 1087 SetActive(false); | 1095 SetActive(false); |
| 1088 } | 1096 } |
| 1089 | 1097 |
| 1090 #endif // ENABLE_LOGGING_AND_PROFILING | 1098 #endif // ENABLE_LOGGING_AND_PROFILING |
| 1091 | 1099 |
| 1092 } } // namespace v8::internal | 1100 } } // namespace v8::internal |
| OLD | NEW |