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

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

Powered by Google App Engine
This is Rietveld 408576698