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 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 #else | 1013 #else |
1014 // Glibc doesn't provide a wrapper for gettid(2). | 1014 // Glibc doesn't provide a wrapper for gettid(2). |
1015 return syscall(SYS_gettid); | 1015 return syscall(SYS_gettid); |
1016 #endif | 1016 #endif |
1017 } | 1017 } |
1018 | 1018 |
1019 | 1019 |
1020 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { | 1020 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { |
1021 USE(info); | 1021 USE(info); |
1022 if (signal != SIGPROF) return; | 1022 if (signal != SIGPROF) return; |
| 1023 |
1023 Isolate* isolate = Isolate::UncheckedCurrent(); | 1024 Isolate* isolate = Isolate::UncheckedCurrent(); |
1024 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { | 1025 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { |
1025 // We require a fully initialized and entered isolate. | 1026 // We require a fully initialized and entered isolate. |
1026 return; | 1027 return; |
1027 } | 1028 } |
1028 if (v8::Locker::IsActive() && | 1029 if (v8::Locker::IsActive() && |
1029 !isolate->thread_manager()->IsLockedByCurrentThread()) { | 1030 !isolate->thread_manager()->IsLockedByCurrentThread()) { |
1030 return; | 1031 return; |
1031 } | 1032 } |
1032 | 1033 |
1033 Sampler* sampler = isolate->logger()->sampler(); | 1034 Sampler* sampler = isolate->logger()->sampler(); |
1034 if (sampler == NULL || !sampler->IsActive()) return; | 1035 if (sampler == NULL || !sampler->IsActive()) return; |
1035 | 1036 |
| 1037 TickSample sample_obj; |
1036 TickSample* sample = CpuProfiler::StartTickSampleEvent(isolate); | 1038 TickSample* sample = CpuProfiler::StartTickSampleEvent(isolate); |
1037 if (sample == NULL) return; | 1039 if (sample == NULL) sample = &sample_obj; |
1038 | 1040 |
1039 // Extracting the sample from the context is extremely machine dependent. | 1041 // Extracting the sample from the context is extremely machine dependent. |
1040 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); | 1042 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
1041 mcontext_t& mcontext = ucontext->uc_mcontext; | 1043 mcontext_t& mcontext = ucontext->uc_mcontext; |
1042 sample->state = isolate->current_vm_state(); | 1044 sample->state = isolate->current_vm_state(); |
1043 #if V8_HOST_ARCH_IA32 | 1045 #if V8_HOST_ARCH_IA32 |
1044 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); | 1046 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); |
1045 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); | 1047 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); |
1046 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); | 1048 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); |
1047 #elif V8_HOST_ARCH_X64 | 1049 #elif V8_HOST_ARCH_X64 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 delete instance_; | 1180 delete instance_; |
1179 instance_ = NULL; | 1181 instance_ = NULL; |
1180 } | 1182 } |
1181 } | 1183 } |
1182 | 1184 |
1183 // Implement Thread::Run(). | 1185 // Implement Thread::Run(). |
1184 virtual void Run() { | 1186 virtual void Run() { |
1185 SamplerRegistry::State state; | 1187 SamplerRegistry::State state; |
1186 while ((state = SamplerRegistry::GetState()) != | 1188 while ((state = SamplerRegistry::GetState()) != |
1187 SamplerRegistry::HAS_NO_SAMPLERS) { | 1189 SamplerRegistry::HAS_NO_SAMPLERS) { |
1188 if (rate_limiter_.SuspendIfNecessary()) continue; | 1190 bool cpu_profiling_enabled = |
1189 if (RuntimeProfiler::IsEnabled()) { | 1191 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS); |
| 1192 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled(); |
| 1193 // When CPU profiling is enabled both JavaScript and C++ code is |
| 1194 // profiled. We must not suspend. |
| 1195 if (!cpu_profiling_enabled) { |
| 1196 if (rate_limiter_.SuspendIfNecessary()) continue; |
| 1197 } |
| 1198 if (cpu_profiling_enabled && runtime_profiler_enabled) { |
| 1199 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, NULL)) { |
| 1200 return; |
| 1201 } |
| 1202 Sleep(HALF_INTERVAL); |
1190 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) { | 1203 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) { |
1191 return; | 1204 return; |
1192 } | 1205 } |
| 1206 Sleep(HALF_INTERVAL); |
| 1207 } else { |
| 1208 if (cpu_profiling_enabled) { |
| 1209 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, NULL)) { |
| 1210 return; |
| 1211 } |
| 1212 } |
| 1213 if (runtime_profiler_enabled) { |
| 1214 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, |
| 1215 NULL)) { |
| 1216 return; |
| 1217 } |
| 1218 } |
| 1219 Sleep(FULL_INTERVAL); |
1193 } | 1220 } |
1194 Sleep(FULL_INTERVAL); | |
1195 } | 1221 } |
1196 } | 1222 } |
1197 | 1223 |
| 1224 static void DoCpuProfile(Sampler* sampler, void*) { |
| 1225 if (!sampler->IsProfiling()) return; |
| 1226 sampler->platform_data()->SendProfilingSignal(); |
| 1227 } |
| 1228 |
1198 static void DoRuntimeProfile(Sampler* sampler, void* ignored) { | 1229 static void DoRuntimeProfile(Sampler* sampler, void* ignored) { |
1199 if (!sampler->isolate()->IsInitialized()) return; | 1230 if (!sampler->isolate()->IsInitialized()) return; |
1200 sampler->isolate()->runtime_profiler()->NotifyTick(); | 1231 sampler->isolate()->runtime_profiler()->NotifyTick(); |
1201 } | 1232 } |
1202 | 1233 |
1203 void Sleep(SleepInterval full_or_half) { | 1234 void Sleep(SleepInterval full_or_half) { |
1204 // Convert ms to us and subtract 100 us to compensate delays | 1235 // Convert ms to us and subtract 100 us to compensate delays |
1205 // occuring during signal delivery. | 1236 // occuring during signal delivery. |
1206 useconds_t interval = interval_ * 1000 - 100; | 1237 useconds_t interval = interval_ * 1000 - 100; |
1207 if (full_or_half == HALF_INTERVAL) interval /= 2; | 1238 if (full_or_half == HALF_INTERVAL) interval /= 2; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 CpuProfilerSignalHandler::TearDown(); | 1303 CpuProfilerSignalHandler::TearDown(); |
1273 delete limit_mutex; | 1304 delete limit_mutex; |
1274 } | 1305 } |
1275 | 1306 |
1276 | 1307 |
1277 Sampler::Sampler(Isolate* isolate, int interval) | 1308 Sampler::Sampler(Isolate* isolate, int interval) |
1278 : isolate_(isolate), | 1309 : isolate_(isolate), |
1279 interval_(interval), | 1310 interval_(interval), |
1280 profiling_(false), | 1311 profiling_(false), |
1281 active_(false), | 1312 active_(false), |
| 1313 has_processing_thread_(false), |
1282 samples_taken_(0) { | 1314 samples_taken_(0) { |
1283 data_ = new PlatformData; | 1315 data_ = new PlatformData; |
1284 } | 1316 } |
1285 | 1317 |
1286 | 1318 |
1287 Sampler::~Sampler() { | 1319 Sampler::~Sampler() { |
1288 ASSERT(!IsActive()); | 1320 ASSERT(!IsActive()); |
1289 delete data_; | 1321 delete data_; |
1290 } | 1322 } |
1291 | 1323 |
1292 | 1324 |
1293 void Sampler::DoSample() { | 1325 void Sampler::DoSample() { |
1294 platform_data()->SendProfilingSignal(); | 1326 platform_data()->SendProfilingSignal(); |
1295 } | 1327 } |
1296 | 1328 |
1297 | 1329 |
1298 void Sampler::Start() { | 1330 void Sampler::Start() { |
1299 ASSERT(!IsActive()); | 1331 ASSERT(!IsActive()); |
1300 CpuProfilerSignalHandler::InstallSignalHandler(); | |
1301 SetActive(true); | 1332 SetActive(true); |
1302 SignalSender::AddActiveSampler(this); | 1333 SignalSender::AddActiveSampler(this); |
1303 } | 1334 } |
1304 | 1335 |
1305 | 1336 |
1306 void Sampler::Stop() { | 1337 void Sampler::Stop() { |
1307 ASSERT(IsActive()); | 1338 ASSERT(IsActive()); |
1308 CpuProfilerSignalHandler::RestoreSignalHandler(); | |
1309 SignalSender::RemoveActiveSampler(this); | 1339 SignalSender::RemoveActiveSampler(this); |
1310 SetActive(false); | 1340 SetActive(false); |
1311 } | 1341 } |
1312 | 1342 |
1313 | 1343 |
| 1344 void Sampler::StartSampling() { |
| 1345 CpuProfilerSignalHandler::InstallSignalHandler(); |
| 1346 } |
| 1347 |
| 1348 |
| 1349 void Sampler::StopSampling() { |
| 1350 CpuProfilerSignalHandler::RestoreSignalHandler(); |
| 1351 } |
| 1352 |
| 1353 |
1314 } } // namespace v8::internal | 1354 } } // namespace v8::internal |
OLD | NEW |