| 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 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 class SignalSender : public Thread { | 1031 class SignalSender : public Thread { |
| 1032 public: | 1032 public: |
| 1033 enum SleepInterval { | 1033 enum SleepInterval { |
| 1034 HALF_INTERVAL, | 1034 HALF_INTERVAL, |
| 1035 FULL_INTERVAL | 1035 FULL_INTERVAL |
| 1036 }; | 1036 }; |
| 1037 | 1037 |
| 1038 explicit SignalSender(int interval) | 1038 explicit SignalSender(int interval) |
| 1039 : Thread("SignalSender"), | 1039 : Thread("SignalSender"), |
| 1040 vm_tgid_(getpid()), | 1040 vm_tgid_(getpid()), |
| 1041 interval_(interval) {} | 1041 interval_(interval), |
| 1042 tick_count_(0) {} |
| 1042 | 1043 |
| 1043 static void InstallSignalHandler() { | 1044 static void InstallSignalHandler() { |
| 1044 struct sigaction sa; | 1045 struct sigaction sa; |
| 1045 sa.sa_sigaction = ProfilerSignalHandler; | 1046 sa.sa_sigaction = ProfilerSignalHandler; |
| 1046 sigemptyset(&sa.sa_mask); | 1047 sigemptyset(&sa.sa_mask); |
| 1047 sa.sa_flags = SA_RESTART | SA_SIGINFO; | 1048 sa.sa_flags = SA_RESTART | SA_SIGINFO; |
| 1048 signal_handler_installed_ = | 1049 signal_handler_installed_ = |
| 1049 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); | 1050 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); |
| 1050 } | 1051 } |
| 1051 | 1052 |
| 1052 static void RestoreSignalHandler() { | 1053 static void RestoreSignalHandler() { |
| 1053 if (signal_handler_installed_) { | 1054 if (signal_handler_installed_) { |
| 1054 sigaction(SIGPROF, &old_signal_handler_, 0); | 1055 sigaction(SIGPROF, &old_signal_handler_, 0); |
| 1055 signal_handler_installed_ = false; | 1056 signal_handler_installed_ = false; |
| 1056 } | 1057 } |
| 1057 } | 1058 } |
| 1058 | 1059 |
| 1059 static void AddActiveSampler(Sampler* sampler) { | 1060 static void AddActiveSampler(Sampler* sampler) { |
| 1060 ScopedLock lock(mutex_); | 1061 ScopedLock lock(mutex_); |
| 1061 SamplerRegistry::AddActiveSampler(sampler); | 1062 SamplerRegistry::AddActiveSampler(sampler); |
| 1062 if (instance_ == NULL) { | 1063 if (instance_ == NULL) { |
| 1063 // Start a thread that will send SIGPROF signal to VM threads, | 1064 // Start a thread that will send SIGPROF signal to VM threads, |
| 1064 // when CPU profiling will be enabled. | 1065 // when CPU profiling will be enabled. |
| 1065 instance_ = new SignalSender(sampler->interval()); | 1066 instance_ = new SignalSender(sampler->interval()); |
| 1066 instance_->Start(); | 1067 instance_->Start(); |
| 1067 } else { | 1068 } else { |
| 1069 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS) |
| 1070 // Flexible interval, assertion doesn't make sense. |
| 1071 #else |
| 1068 ASSERT(instance_->interval_ == sampler->interval()); | 1072 ASSERT(instance_->interval_ == sampler->interval()); |
| 1073 #endif |
| 1069 } | 1074 } |
| 1070 } | 1075 } |
| 1071 | 1076 |
| 1072 static void RemoveActiveSampler(Sampler* sampler) { | 1077 static void RemoveActiveSampler(Sampler* sampler) { |
| 1073 ScopedLock lock(mutex_); | 1078 ScopedLock lock(mutex_); |
| 1074 SamplerRegistry::RemoveActiveSampler(sampler); | 1079 SamplerRegistry::RemoveActiveSampler(sampler); |
| 1075 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { | 1080 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { |
| 1076 RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); | 1081 RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); |
| 1077 delete instance_; | 1082 delete instance_; |
| 1078 instance_ = NULL; | 1083 instance_ = NULL; |
| 1079 RestoreSignalHandler(); | 1084 RestoreSignalHandler(); |
| 1080 } | 1085 } |
| 1081 } | 1086 } |
| 1082 | 1087 |
| 1088 static void ResetInterval(int interval) { |
| 1089 ScopedLock lock(mutex_); |
| 1090 if (instance_ != NULL) { |
| 1091 instance_->interval_ = interval; |
| 1092 instance_->tick_count_ = 0; |
| 1093 } |
| 1094 } |
| 1095 |
| 1083 // Implement Thread::Run(). | 1096 // Implement Thread::Run(). |
| 1084 virtual void Run() { | 1097 virtual void Run() { |
| 1085 SamplerRegistry::State state; | 1098 SamplerRegistry::State state; |
| 1086 while ((state = SamplerRegistry::GetState()) != | 1099 while ((state = SamplerRegistry::GetState()) != |
| 1087 SamplerRegistry::HAS_NO_SAMPLERS) { | 1100 SamplerRegistry::HAS_NO_SAMPLERS) { |
| 1088 bool cpu_profiling_enabled = | 1101 bool cpu_profiling_enabled = |
| 1089 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); | 1102 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); |
| 1090 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); | 1103 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); |
| 1091 if (cpu_profiling_enabled && !signal_handler_installed_) { | 1104 if (cpu_profiling_enabled && !signal_handler_installed_) { |
| 1092 InstallSignalHandler(); | 1105 InstallSignalHandler(); |
| 1093 } else if (!cpu_profiling_enabled && signal_handler_installed_) { | 1106 } else if (!cpu_profiling_enabled && signal_handler_installed_) { |
| 1094 RestoreSignalHandler(); | 1107 RestoreSignalHandler(); |
| 1095 } | 1108 } |
| 1096 // When CPU profiling is enabled both JavaScript and C++ code is | 1109 // When CPU profiling is enabled both JavaScript and C++ code is |
| 1097 // profiled. We must not suspend. | 1110 // profiled. We must not suspend. |
| 1098 if (!cpu_profiling_enabled) { | 1111 if (!cpu_profiling_enabled) { |
| 1099 if (rate_limiter_.SuspendIfNecessary()) continue; | 1112 if (rate_limiter_.SuspendIfNecessary()) continue; |
| 1100 } | 1113 } |
| 1114 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS) |
| 1115 // ARM and MIPS CPUs are typically slower than IA32/X64, so for them |
| 1116 // the tick interval is increased to let them perform a more significant |
| 1117 // amount of work between subsequent ticks. |
| 1118 |
| 1119 static const int kNumberOfFastTicks = 5; |
| 1120 static const int kSlowTickIntervalMs = 5; |
| 1121 |
| 1122 if (tick_count_ == kNumberOfFastTicks) { |
| 1123 interval_ = kSlowTickIntervalMs; |
| 1124 } |
| 1125 tick_count_++; |
| 1126 #endif |
| 1101 if (cpu_profiling_enabled && runtime_profiler_enabled) { | 1127 if (cpu_profiling_enabled && runtime_profiler_enabled) { |
| 1102 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) { | 1128 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) { |
| 1103 return; | 1129 return; |
| 1104 } | 1130 } |
| 1105 Sleep(HALF_INTERVAL); | 1131 Sleep(HALF_INTERVAL); |
| 1106 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) { | 1132 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) { |
| 1107 return; | 1133 return; |
| 1108 } | 1134 } |
| 1109 Sleep(HALF_INTERVAL); | 1135 Sleep(HALF_INTERVAL); |
| 1110 } else { | 1136 } else { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 "SignalSender usleep error; interval = %u, errno = %d\n", | 1184 "SignalSender usleep error; interval = %u, errno = %d\n", |
| 1159 interval, | 1185 interval, |
| 1160 errno); | 1186 errno); |
| 1161 ASSERT(result == 0 || errno == EINTR); | 1187 ASSERT(result == 0 || errno == EINTR); |
| 1162 } | 1188 } |
| 1163 #endif | 1189 #endif |
| 1164 USE(result); | 1190 USE(result); |
| 1165 } | 1191 } |
| 1166 | 1192 |
| 1167 const int vm_tgid_; | 1193 const int vm_tgid_; |
| 1168 const int interval_; | 1194 int interval_; |
| 1195 int tick_count_; |
| 1169 RuntimeProfilerRateLimiter rate_limiter_; | 1196 RuntimeProfilerRateLimiter rate_limiter_; |
| 1170 | 1197 |
| 1171 // Protects the process wide state below. | 1198 // Protects the process wide state below. |
| 1172 static Mutex* mutex_; | 1199 static Mutex* mutex_; |
| 1173 static SignalSender* instance_; | 1200 static SignalSender* instance_; |
| 1174 static bool signal_handler_installed_; | 1201 static bool signal_handler_installed_; |
| 1175 static struct sigaction old_signal_handler_; | 1202 static struct sigaction old_signal_handler_; |
| 1176 | 1203 |
| 1177 DISALLOW_COPY_AND_ASSIGN(SignalSender); | 1204 DISALLOW_COPY_AND_ASSIGN(SignalSender); |
| 1178 }; | 1205 }; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1207 } | 1234 } |
| 1208 | 1235 |
| 1209 | 1236 |
| 1210 void Sampler::Stop() { | 1237 void Sampler::Stop() { |
| 1211 ASSERT(IsActive()); | 1238 ASSERT(IsActive()); |
| 1212 SignalSender::RemoveActiveSampler(this); | 1239 SignalSender::RemoveActiveSampler(this); |
| 1213 SetActive(false); | 1240 SetActive(false); |
| 1214 } | 1241 } |
| 1215 | 1242 |
| 1216 | 1243 |
| 1244 void Sampler::ResetInterval(int interval) { |
| 1245 SignalSender::ResetInterval(interval); |
| 1246 } |
| 1247 |
| 1248 |
| 1217 } } // namespace v8::internal | 1249 } } // namespace v8::internal |
| OLD | NEW |