Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(305)

Side by Side Diff: src/platform-linux.cc

Issue 11231002: Perform CPU sampling by CPU sampling thread only iff processing thread is not running. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW
« src/platform-cygwin.cc ('K') | « src/platform-freebsd.cc ('k') | src/platform-macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698