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

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

Issue 6685052: Version 3.2.2. Fixed a number of crash and correctness bugs. Improved Cranksh... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 9 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/objects-inl.h ('k') | src/profile-generator.h » ('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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 27 matching lines...) Expand all
38 #include <ucontext.h> // walkstack(), getcontext() 38 #include <ucontext.h> // walkstack(), getcontext()
39 #include <dlfcn.h> // dladdr 39 #include <dlfcn.h> // dladdr
40 #include <pthread.h> 40 #include <pthread.h>
41 #include <sched.h> // for sched_yield 41 #include <sched.h> // for sched_yield
42 #include <semaphore.h> 42 #include <semaphore.h>
43 #include <time.h> 43 #include <time.h>
44 #include <sys/time.h> // gettimeofday(), timeradd() 44 #include <sys/time.h> // gettimeofday(), timeradd()
45 #include <errno.h> 45 #include <errno.h>
46 #include <ieeefp.h> // finite() 46 #include <ieeefp.h> // finite()
47 #include <signal.h> // sigemptyset(), etc 47 #include <signal.h> // sigemptyset(), etc
48 #include <sys/kdi_regs.h> 48 #include <sys/regset.h>
49 49
50 50
51 #undef MAP_TYPE 51 #undef MAP_TYPE
52 52
53 #include "v8.h" 53 #include "v8.h"
54 54
55 #include "platform.h" 55 #include "platform.h"
56 #include "vm-state-inl.h" 56 #include "vm-state-inl.h"
57 57
58 58
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 return new SolarisSemaphore(count); 605 return new SolarisSemaphore(count);
606 } 606 }
607 607
608 608
609 #ifdef ENABLE_LOGGING_AND_PROFILING 609 #ifdef ENABLE_LOGGING_AND_PROFILING
610 610
611 static Sampler* active_sampler_ = NULL; 611 static Sampler* active_sampler_ = NULL;
612 static pthread_t vm_tid_ = 0; 612 static pthread_t vm_tid_ = 0;
613 613
614 614
615 static pthread_t GetThreadID() {
616 return pthread_self();
617 }
618
619
615 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { 620 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
616 USE(info); 621 USE(info);
617 if (signal != SIGPROF) return; 622 if (signal != SIGPROF) return;
618 if (active_sampler_ == NULL || !active_sampler_->IsActive()) return; 623 if (active_sampler_ == NULL || !active_sampler_->IsActive()) return;
619 if (vm_tid_ != pthread_self()) return; 624 if (vm_tid_ != GetThreadID()) return;
620 625
621 TickSample sample_obj; 626 TickSample sample_obj;
622 TickSample* sample = CpuProfiler::TickSampleEvent(); 627 TickSample* sample = CpuProfiler::TickSampleEvent();
623 if (sample == NULL) sample = &sample_obj; 628 if (sample == NULL) sample = &sample_obj;
624 629
625 // Extracting the sample from the context is extremely machine dependent. 630 // Extracting the sample from the context is extremely machine dependent.
626 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 631 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
627 mcontext_t& mcontext = ucontext->uc_mcontext; 632 mcontext_t& mcontext = ucontext->uc_mcontext;
628 sample->state = Top::current_vm_state(); 633 sample->state = Top::current_vm_state();
629 634
630 #if V8_HOST_ARCH_IA32 635 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]);
631 sample->pc = reinterpret_cast<Address>(mcontext.gregs[KDIREG_EIP]); 636 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]);
632 sample->sp = reinterpret_cast<Address>(mcontext.gregs[KDIREG_ESP]); 637 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]);
633 sample->fp = reinterpret_cast<Address>(mcontext.gregs[KDIREG_EBP]); 638
634 #elif V8_HOST_ARCH_X64
635 sample->pc = reinterpret_cast<Address>(mcontext.gregs[KDIREG_RIP]);
636 sample->sp = reinterpret_cast<Address>(mcontext.gregs[KDIREG_RSP]);
637 sample->fp = reinterpret_cast<Address>(mcontext.gregs[KDIREG_RBP]);
638 #else
639 UNIMPLEMENTED();
640 #endif
641 active_sampler_->SampleStack(sample); 639 active_sampler_->SampleStack(sample);
642 active_sampler_->Tick(sample); 640 active_sampler_->Tick(sample);
643 } 641 }
644 642
645 643
646 class Sampler::PlatformData : public Malloced { 644 class Sampler::PlatformData : public Malloced {
647 public: 645 public:
648 PlatformData() { 646 enum SleepInterval {
649 signal_handler_installed_ = false; 647 FULL_INTERVAL,
648 HALF_INTERVAL
649 };
650
651 explicit PlatformData(Sampler* sampler)
652 : sampler_(sampler),
653 signal_handler_installed_(false),
654 vm_tgid_(getpid()),
655 signal_sender_launched_(false) {
650 } 656 }
651 657
658 void SignalSender() {
659 while (sampler_->IsActive()) {
660 if (rate_limiter_.SuspendIfNecessary()) continue;
661 if (sampler_->IsProfiling() && RuntimeProfiler::IsEnabled()) {
662 SendProfilingSignal();
663 Sleep(HALF_INTERVAL);
664 RuntimeProfiler::NotifyTick();
665 Sleep(HALF_INTERVAL);
666 } else {
667 if (sampler_->IsProfiling()) SendProfilingSignal();
668 if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick();
669 Sleep(FULL_INTERVAL);
670 }
671 }
672 }
673
674 void SendProfilingSignal() {
675 if (!signal_handler_installed_) return;
676 pthread_kill(vm_tid_, SIGPROF);
677 }
678
679 void Sleep(SleepInterval full_or_half) {
680 // Convert ms to us and subtract 100 us to compensate delays
681 // occuring during signal delivery.
682 useconds_t interval = sampler_->interval_ * 1000 - 100;
683 if (full_or_half == HALF_INTERVAL) interval /= 2;
684 int result = usleep(interval);
685 #ifdef DEBUG
686 if (result != 0 && errno != EINTR) {
687 fprintf(stderr,
688 "SignalSender usleep error; interval = %u, errno = %d\n",
689 interval,
690 errno);
691 ASSERT(result == 0 || errno == EINTR);
692 }
693 #endif
694 USE(result);
695 }
696
697 Sampler* sampler_;
652 bool signal_handler_installed_; 698 bool signal_handler_installed_;
653 struct sigaction old_signal_handler_; 699 struct sigaction old_signal_handler_;
654 struct itimerval old_timer_value_; 700 int vm_tgid_;
701 bool signal_sender_launched_;
702 pthread_t signal_sender_thread_;
703 RuntimeProfilerRateLimiter rate_limiter_;
655 }; 704 };
656 705
657 706
707 static void* SenderEntry(void* arg) {
708 Sampler::PlatformData* data =
709 reinterpret_cast<Sampler::PlatformData*>(arg);
710 data->SignalSender();
711 return 0;
712 }
713
714
658 Sampler::Sampler(int interval) 715 Sampler::Sampler(int interval)
659 : interval_(interval), 716 : interval_(interval),
660 profiling_(false), 717 profiling_(false),
661 active_(false), 718 active_(false),
662 samples_taken_(0) { 719 samples_taken_(0) {
663 data_ = new PlatformData(); 720 data_ = new PlatformData(this);
664 } 721 }
665 722
666 723
667 Sampler::~Sampler() { 724 Sampler::~Sampler() {
725 ASSERT(!data_->signal_sender_launched_);
668 delete data_; 726 delete data_;
669 } 727 }
670 728
671 729
672 void Sampler::Start() { 730 void Sampler::Start() {
673 // There can only be one active sampler at the time on POSIX 731 // There can only be one active sampler at the time on POSIX
674 // platforms. 732 // platforms.
675 if (active_sampler_ != NULL) return; 733 ASSERT(!IsActive());
734 vm_tid_ = GetThreadID();
676 735
677 // Request profiling signals. 736 // Request profiling signals.
678 struct sigaction sa; 737 struct sigaction sa;
679 sa.sa_sigaction = ProfilerSignalHandler; 738 sa.sa_sigaction = ProfilerSignalHandler;
680 sigemptyset(&sa.sa_mask); 739 sigemptyset(&sa.sa_mask);
681 sa.sa_flags = SA_SIGINFO; 740 sa.sa_flags = SA_RESTART | SA_SIGINFO;
682 if (sigaction(SIGPROF, &sa, &data_->old_signal_handler_) != 0) return; 741 data_->signal_handler_installed_ =
683 data_->signal_handler_installed_ = true; 742 sigaction(SIGPROF, &sa, &data_->old_signal_handler_) == 0;
684 743
685 // Set the itimer to generate a tick for each interval. 744 // Start a thread that sends SIGPROF signal to VM thread.
686 itimerval itimer; 745 // Sending the signal ourselves instead of relying on itimer provides
687 itimer.it_interval.tv_sec = interval_ / 1000; 746 // much better accuracy.
688 itimer.it_interval.tv_usec = (interval_ % 1000) * 1000; 747 SetActive(true);
689 itimer.it_value.tv_sec = itimer.it_interval.tv_sec; 748 if (pthread_create(
690 itimer.it_value.tv_usec = itimer.it_interval.tv_usec; 749 &data_->signal_sender_thread_, NULL, SenderEntry, data_) == 0) {
691 setitimer(ITIMER_PROF, &itimer, &data_->old_timer_value_); 750 data_->signal_sender_launched_ = true;
751 }
692 752
693 // Set this sampler as the active sampler. 753 // Set this sampler as the active sampler.
694 active_sampler_ = this; 754 active_sampler_ = this;
695 active_ = true;
696 } 755 }
697 756
698 757
699 void Sampler::Stop() { 758 void Sampler::Stop() {
759 SetActive(false);
760
761 // Wait for signal sender termination (it will exit after setting
762 // active_ to false).
763 if (data_->signal_sender_launched_) {
764 Top::WakeUpRuntimeProfilerThreadBeforeShutdown();
765 pthread_join(data_->signal_sender_thread_, NULL);
766 data_->signal_sender_launched_ = false;
767 }
768
700 // Restore old signal handler 769 // Restore old signal handler
701 if (data_->signal_handler_installed_) { 770 if (data_->signal_handler_installed_) {
702 setitimer(ITIMER_PROF, &data_->old_timer_value_, NULL);
703 sigaction(SIGPROF, &data_->old_signal_handler_, 0); 771 sigaction(SIGPROF, &data_->old_signal_handler_, 0);
704 data_->signal_handler_installed_ = false; 772 data_->signal_handler_installed_ = false;
705 } 773 }
706 774
707 // This sampler is no longer the active sampler. 775 // This sampler is no longer the active sampler.
708 active_sampler_ = NULL; 776 active_sampler_ = NULL;
709 active_ = false;
710 } 777 }
711 778
712 #endif // ENABLE_LOGGING_AND_PROFILING 779 #endif // ENABLE_LOGGING_AND_PROFILING
713 780
714 } } // namespace v8::internal 781 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | src/profile-generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698