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

Side by Side Diff: src/sampler.cc

Issue 23011029: Do not start sampler thread when CpuProfiler is active (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « src/sampler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 private: 241 private:
242 Simulator* simulator_; 242 Simulator* simulator_;
243 }; 243 };
244 #endif // USE_SIMULATOR 244 #endif // USE_SIMULATOR
245 245
246 246
247 #if defined(USE_SIGNALS) 247 #if defined(USE_SIGNALS)
248 248
249 class SignalHandler : public AllStatic { 249 class SignalHandler : public AllStatic {
250 public: 250 public:
251 static inline void EnsureInstalled() { 251 static void SetUp() { if (!mutex_) mutex_ = new Mutex(); }
252 if (signal_handler_installed_) return; 252 static void TearDown() { delete mutex_; }
253
254 static void IncreaseSamplerCount() {
255 LockGuard<Mutex> lock_guard(mutex_);
256 if (++client_count_ == 1) Install();
257 }
258
259 static void DecreaseSamplerCount() {
260 LockGuard<Mutex> lock_guard(mutex_);
261 if (--client_count_ == 0) Restore();
262 }
263
264 static bool Installed() {
265 return signal_handler_installed_;
266 }
267
268 private:
269 static void Install() {
253 struct sigaction sa; 270 struct sigaction sa;
254 sa.sa_sigaction = &HandleProfilerSignal; 271 sa.sa_sigaction = &HandleProfilerSignal;
255 sigemptyset(&sa.sa_mask); 272 sigemptyset(&sa.sa_mask);
256 sa.sa_flags = SA_RESTART | SA_SIGINFO; 273 sa.sa_flags = SA_RESTART | SA_SIGINFO;
257 signal_handler_installed_ = 274 signal_handler_installed_ =
258 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); 275 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
259 } 276 }
260 277
261 static inline void Restore() { 278 static void Restore() {
262 if (signal_handler_installed_) { 279 if (signal_handler_installed_) {
263 sigaction(SIGPROF, &old_signal_handler_, 0); 280 sigaction(SIGPROF, &old_signal_handler_, 0);
264 signal_handler_installed_ = false; 281 signal_handler_installed_ = false;
265 } 282 }
266 } 283 }
267 284
268 static inline bool Installed() {
269 return signal_handler_installed_;
270 }
271
272 private:
273 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); 285 static void HandleProfilerSignal(int signal, siginfo_t* info, void* context);
286 // Protects the process wide state below.
287 static Mutex* mutex_;
288 static int client_count_;
274 static bool signal_handler_installed_; 289 static bool signal_handler_installed_;
275 static struct sigaction old_signal_handler_; 290 static struct sigaction old_signal_handler_;
276 }; 291 };
277 292
293
294 Mutex* SignalHandler::mutex_ = NULL;
295 int SignalHandler::client_count_ = 0;
278 struct sigaction SignalHandler::old_signal_handler_; 296 struct sigaction SignalHandler::old_signal_handler_;
279 bool SignalHandler::signal_handler_installed_ = false; 297 bool SignalHandler::signal_handler_installed_ = false;
280 298
281 299
282 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, 300 void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
283 void* context) { 301 void* context) {
284 #if V8_OS_NACL 302 #if V8_OS_NACL
285 // As Native Client does not support signal handling, profiling 303 // As Native Client does not support signal handling, profiling
286 // is disabled. 304 // is disabled.
287 return; 305 return;
288 #else 306 #else
289 USE(info); 307 USE(info);
290 if (signal != SIGPROF) return; 308 if (signal != SIGPROF) return;
291 Isolate* isolate = Isolate::UncheckedCurrent(); 309 Isolate* isolate = Isolate::UncheckedCurrent();
292 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { 310 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) {
293 // We require a fully initialized and entered isolate. 311 // We require a fully initialized and entered isolate.
294 return; 312 return;
295 } 313 }
296 if (v8::Locker::IsActive() && 314 if (v8::Locker::IsActive() &&
297 !isolate->thread_manager()->IsLockedByCurrentThread()) { 315 !isolate->thread_manager()->IsLockedByCurrentThread()) {
298 return; 316 return;
299 } 317 }
300 318
301 Sampler* sampler = isolate->logger()->sampler(); 319 Sampler* sampler = isolate->logger()->sampler();
302 if (sampler == NULL || !sampler->IsActive()) return; 320 if (sampler == NULL) return;
303 321
304 RegisterState state; 322 RegisterState state;
305 323
306 #if defined(USE_SIMULATOR) 324 #if defined(USE_SIMULATOR)
307 SimulatorHelper helper; 325 SimulatorHelper helper;
308 if (!helper.Init(sampler, isolate)) return; 326 if (!helper.Init(sampler, isolate)) return;
309 helper.FillRegisters(&state); 327 helper.FillRegisters(&state);
310 #else 328 #else
311 // Extracting the sample from the context is extremely machine dependent. 329 // Extracting the sample from the context is extremely machine dependent.
312 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 330 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 // when CPU profiling will be enabled. 447 // when CPU profiling will be enabled.
430 instance_ = new SamplerThread(sampler->interval()); 448 instance_ = new SamplerThread(sampler->interval());
431 need_to_start = true; 449 need_to_start = true;
432 } 450 }
433 451
434 ASSERT(sampler->IsActive()); 452 ASSERT(sampler->IsActive());
435 ASSERT(!instance_->active_samplers_.Contains(sampler)); 453 ASSERT(!instance_->active_samplers_.Contains(sampler));
436 ASSERT(instance_->interval_ == sampler->interval()); 454 ASSERT(instance_->interval_ == sampler->interval());
437 instance_->active_samplers_.Add(sampler); 455 instance_->active_samplers_.Add(sampler);
438 456
439 #if defined(USE_SIGNALS)
440 SignalHandler::EnsureInstalled();
441 #endif
442 if (need_to_start) instance_->StartSynchronously(); 457 if (need_to_start) instance_->StartSynchronously();
443 } 458 }
444 459
445 static void RemoveActiveSampler(Sampler* sampler) { 460 static void RemoveActiveSampler(Sampler* sampler) {
446 SamplerThread* instance_to_remove = NULL; 461 SamplerThread* instance_to_remove = NULL;
447 { 462 {
448 LockGuard<Mutex> lock_guard(mutex_); 463 LockGuard<Mutex> lock_guard(mutex_);
449 464
450 ASSERT(sampler->IsActive()); 465 ASSERT(sampler->IsActive());
451 bool removed = instance_->active_samplers_.RemoveElement(sampler); 466 bool removed = instance_->active_samplers_.RemoveElement(sampler);
452 ASSERT(removed); 467 ASSERT(removed);
453 USE(removed); 468 USE(removed);
454 469
455 // We cannot delete the instance immediately as we need to Join() the 470 // We cannot delete the instance immediately as we need to Join() the
456 // thread but we are holding mutex_ and the thread may try to acquire it. 471 // thread but we are holding mutex_ and the thread may try to acquire it.
457 if (instance_->active_samplers_.is_empty()) { 472 if (instance_->active_samplers_.is_empty()) {
458 instance_to_remove = instance_; 473 instance_to_remove = instance_;
459 instance_ = NULL; 474 instance_ = NULL;
460 #if defined(USE_SIGNALS)
461 SignalHandler::Restore();
462 #endif
463 } 475 }
464 } 476 }
465 477
466 if (!instance_to_remove) return; 478 if (!instance_to_remove) return;
467 instance_to_remove->Join(); 479 instance_to_remove->Join();
468 delete instance_to_remove; 480 delete instance_to_remove;
469 } 481 }
470 482
471 // Implement Thread::Run(). 483 // Implement Thread::Run().
472 virtual void Run() { 484 virtual void Run() {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 int i = 0; 553 int i = 0;
542 while (!it.done() && i < TickSample::kMaxFramesCount) { 554 while (!it.done() && i < TickSample::kMaxFramesCount) {
543 stack[i++] = it.frame()->pc(); 555 stack[i++] = it.frame()->pc();
544 it.Advance(); 556 it.Advance();
545 } 557 }
546 frames_count = i; 558 frames_count = i;
547 } 559 }
548 560
549 561
550 void Sampler::SetUp() { 562 void Sampler::SetUp() {
563 #if defined(USE_SIGNALS)
564 SignalHandler::SetUp();
565 #endif
551 SamplerThread::SetUp(); 566 SamplerThread::SetUp();
552 } 567 }
553 568
554 569
555 void Sampler::TearDown() { 570 void Sampler::TearDown() {
556 SamplerThread::TearDown(); 571 SamplerThread::TearDown();
572 #if defined(USE_SIGNALS)
573 SignalHandler::TearDown();
574 #endif
557 } 575 }
558 576
559 577
560 Sampler::Sampler(Isolate* isolate, int interval) 578 Sampler::Sampler(Isolate* isolate, int interval)
561 : isolate_(isolate), 579 : isolate_(isolate),
562 interval_(interval), 580 interval_(interval),
563 profiling_(false), 581 profiling_(false),
564 has_processing_thread_(false), 582 has_processing_thread_(false),
565 active_(false), 583 active_(false),
566 is_counting_samples_(false), 584 is_counting_samples_(false),
(...skipping 15 matching lines...) Expand all
582 } 600 }
583 601
584 602
585 void Sampler::Stop() { 603 void Sampler::Stop() {
586 ASSERT(IsActive()); 604 ASSERT(IsActive());
587 SamplerThread::RemoveActiveSampler(this); 605 SamplerThread::RemoveActiveSampler(this);
588 SetActive(false); 606 SetActive(false);
589 } 607 }
590 608
591 609
610 void Sampler::IncreaseProfilingDepth() {
611 NoBarrier_AtomicIncrement(&profiling_, 1);
612 #if defined(USE_SIGNALS)
613 SignalHandler::IncreaseSamplerCount();
614 #endif
615 }
616
617
618 void Sampler::DecreaseProfilingDepth() {
619 #if defined(USE_SIGNALS)
620 SignalHandler::DecreaseSamplerCount();
621 #endif
622 NoBarrier_AtomicIncrement(&profiling_, -1);
623 }
624
625
592 void Sampler::SampleStack(const RegisterState& state) { 626 void Sampler::SampleStack(const RegisterState& state) {
593 TickSample* sample = isolate_->cpu_profiler()->StartTickSample(); 627 TickSample* sample = isolate_->cpu_profiler()->StartTickSample();
594 TickSample sample_obj; 628 TickSample sample_obj;
595 if (sample == NULL) sample = &sample_obj; 629 if (sample == NULL) sample = &sample_obj;
596 sample->Init(isolate_, state); 630 sample->Init(isolate_, state);
597 if (is_counting_samples_) { 631 if (is_counting_samples_) {
598 if (sample->state == JS || sample->state == EXTERNAL) { 632 if (sample->state == JS || sample->state == EXTERNAL) {
599 ++js_and_external_sample_count_; 633 ++js_and_external_sample_count_;
600 } 634 }
601 } 635 }
602 Tick(sample); 636 Tick(sample);
603 if (sample != &sample_obj) { 637 if (sample != &sample_obj) {
604 isolate_->cpu_profiler()->FinishTickSample(); 638 isolate_->cpu_profiler()->FinishTickSample();
605 } 639 }
606 } 640 }
607 641
608 642
609 bool Sampler::CanSampleOnProfilerEventsProcessorThread() {
610 #if defined(USE_SIGNALS)
611 return true;
612 #elif V8_OS_WIN || V8_OS_CYGWIN
613 return true;
614 #else
615 return false;
616 #endif
617 }
618
619
620 #if defined(USE_SIGNALS) 643 #if defined(USE_SIGNALS)
621 644
622 void Sampler::DoSample() { 645 void Sampler::DoSample() {
623 if (!SignalHandler::Installed()) return; 646 if (!SignalHandler::Installed()) return;
624 pthread_kill(platform_data()->vm_tid(), SIGPROF); 647 pthread_kill(platform_data()->vm_tid(), SIGPROF);
625 } 648 }
626 649
627 #elif V8_OS_WIN || V8_OS_CYGWIN 650 #elif V8_OS_WIN || V8_OS_CYGWIN
628 651
629 void Sampler::DoSample() { 652 void Sampler::DoSample() {
(...skipping 29 matching lines...) Expand all
659 #endif // USE_SIMULATOR 682 #endif // USE_SIMULATOR
660 SampleStack(state); 683 SampleStack(state);
661 } 684 }
662 ResumeThread(profiled_thread); 685 ResumeThread(profiled_thread);
663 } 686 }
664 687
665 #endif // USE_SIGNALS 688 #endif // USE_SIGNALS
666 689
667 690
668 } } // namespace v8::internal 691 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/sampler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698