OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 | 1084 |
1085 int vm_tid() const { return vm_tid_; } | 1085 int vm_tid() const { return vm_tid_; } |
1086 | 1086 |
1087 private: | 1087 private: |
1088 const int vm_tid_; | 1088 const int vm_tid_; |
1089 }; | 1089 }; |
1090 | 1090 |
1091 | 1091 |
1092 class SignalSender : public Thread { | 1092 class SignalSender : public Thread { |
1093 public: | 1093 public: |
1094 enum SleepInterval { | |
1095 HALF_INTERVAL, | |
1096 FULL_INTERVAL | |
1097 }; | |
1098 | |
1099 static const int kSignalSenderStackSize = 64 * KB; | 1094 static const int kSignalSenderStackSize = 64 * KB; |
1100 | 1095 |
1101 explicit SignalSender(int interval) | 1096 explicit SignalSender(int interval) |
1102 : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)), | 1097 : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)), |
1103 vm_tgid_(getpid()), | 1098 vm_tgid_(getpid()), |
1104 interval_(interval) {} | 1099 interval_(interval) {} |
1105 | 1100 |
1106 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } | 1101 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } |
1107 static void TearDown() { delete mutex_; } | 1102 static void TearDown() { delete mutex_; } |
1108 | 1103 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 instance_ = NULL; | 1139 instance_ = NULL; |
1145 RestoreSignalHandler(); | 1140 RestoreSignalHandler(); |
1146 } | 1141 } |
1147 } | 1142 } |
1148 | 1143 |
1149 // Implement Thread::Run(). | 1144 // Implement Thread::Run(). |
1150 virtual void Run() { | 1145 virtual void Run() { |
1151 SamplerRegistry::State state; | 1146 SamplerRegistry::State state; |
1152 while ((state = SamplerRegistry::GetState()) != | 1147 while ((state = SamplerRegistry::GetState()) != |
1153 SamplerRegistry::HAS_NO_SAMPLERS) { | 1148 SamplerRegistry::HAS_NO_SAMPLERS) { |
1154 bool cpu_profiling_enabled = | |
1155 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); | |
1156 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); | |
1157 if (cpu_profiling_enabled && !signal_handler_installed_) { | |
1158 InstallSignalHandler(); | |
1159 } else if (!cpu_profiling_enabled && signal_handler_installed_) { | |
1160 RestoreSignalHandler(); | |
1161 } | |
1162 // When CPU profiling is enabled both JavaScript and C++ code is | 1149 // When CPU profiling is enabled both JavaScript and C++ code is |
1163 // profiled. We must not suspend. | 1150 // profiled. We must not suspend. |
1164 if (!cpu_profiling_enabled) { | 1151 if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) { |
| 1152 if (!signal_handler_installed_) InstallSignalHandler(); |
| 1153 SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this); |
| 1154 } else { |
| 1155 if (signal_handler_installed_) RestoreSignalHandler(); |
1165 if (rate_limiter_.SuspendIfNecessary()) continue; | 1156 if (rate_limiter_.SuspendIfNecessary()) continue; |
1166 } | 1157 } |
1167 if (cpu_profiling_enabled && runtime_profiler_enabled) { | 1158 Sleep(); // TODO(svenpanne) Figure out if OS:Sleep(interval_) is enough. |
1168 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) { | |
1169 return; | |
1170 } | |
1171 Sleep(HALF_INTERVAL); | |
1172 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) { | |
1173 return; | |
1174 } | |
1175 Sleep(HALF_INTERVAL); | |
1176 } else { | |
1177 if (cpu_profiling_enabled) { | |
1178 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, | |
1179 this)) { | |
1180 return; | |
1181 } | |
1182 } | |
1183 if (runtime_profiler_enabled) { | |
1184 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, | |
1185 NULL)) { | |
1186 return; | |
1187 } | |
1188 } | |
1189 Sleep(FULL_INTERVAL); | |
1190 } | |
1191 } | 1159 } |
1192 } | 1160 } |
1193 | 1161 |
1194 static void DoCpuProfile(Sampler* sampler, void* raw_sender) { | 1162 static void DoCpuProfile(Sampler* sampler, void* raw_sender) { |
1195 if (!sampler->IsProfiling()) return; | 1163 if (!sampler->IsProfiling()) return; |
1196 SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender); | 1164 SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender); |
1197 sender->SendProfilingSignal(sampler->platform_data()->vm_tid()); | 1165 sender->SendProfilingSignal(sampler->platform_data()->vm_tid()); |
1198 } | 1166 } |
1199 | 1167 |
1200 static void DoRuntimeProfile(Sampler* sampler, void* ignored) { | |
1201 if (!sampler->isolate()->IsInitialized()) return; | |
1202 sampler->isolate()->runtime_profiler()->NotifyTick(); | |
1203 } | |
1204 | |
1205 void SendProfilingSignal(int tid) { | 1168 void SendProfilingSignal(int tid) { |
1206 if (!signal_handler_installed_) return; | 1169 if (!signal_handler_installed_) return; |
1207 // Glibc doesn't provide a wrapper for tgkill(2). | 1170 // Glibc doesn't provide a wrapper for tgkill(2). |
1208 #if defined(ANDROID) | 1171 #if defined(ANDROID) |
1209 syscall(__NR_tgkill, vm_tgid_, tid, SIGPROF); | 1172 syscall(__NR_tgkill, vm_tgid_, tid, SIGPROF); |
1210 #else | 1173 #else |
1211 syscall(SYS_tgkill, vm_tgid_, tid, SIGPROF); | 1174 syscall(SYS_tgkill, vm_tgid_, tid, SIGPROF); |
1212 #endif | 1175 #endif |
1213 } | 1176 } |
1214 | 1177 |
1215 void Sleep(SleepInterval full_or_half) { | 1178 void Sleep() { |
1216 // Convert ms to us and subtract 100 us to compensate delays | 1179 // Convert ms to us and subtract 100 us to compensate delays |
1217 // occuring during signal delivery. | 1180 // occuring during signal delivery. |
1218 useconds_t interval = interval_ * 1000 - 100; | 1181 useconds_t interval = interval_ * 1000 - 100; |
1219 if (full_or_half == HALF_INTERVAL) interval /= 2; | |
1220 #if defined(ANDROID) | 1182 #if defined(ANDROID) |
1221 usleep(interval); | 1183 usleep(interval); |
1222 #else | 1184 #else |
1223 int result = usleep(interval); | 1185 int result = usleep(interval); |
1224 #ifdef DEBUG | 1186 #ifdef DEBUG |
1225 if (result != 0 && errno != EINTR) { | 1187 if (result != 0 && errno != EINTR) { |
1226 fprintf(stderr, | 1188 fprintf(stderr, |
1227 "SignalSender usleep error; interval = %u, errno = %d\n", | 1189 "SignalSender usleep error; interval = %u, errno = %d\n", |
1228 interval, | 1190 interval, |
1229 errno); | 1191 errno); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 | 1275 |
1314 | 1276 |
1315 void Sampler::Stop() { | 1277 void Sampler::Stop() { |
1316 ASSERT(IsActive()); | 1278 ASSERT(IsActive()); |
1317 SignalSender::RemoveActiveSampler(this); | 1279 SignalSender::RemoveActiveSampler(this); |
1318 SetActive(false); | 1280 SetActive(false); |
1319 } | 1281 } |
1320 | 1282 |
1321 | 1283 |
1322 } } // namespace v8::internal | 1284 } } // namespace v8::internal |
OLD | NEW |