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

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

Issue 13852005: Move *BSD and Solaris Sampler implementations into sampler.cc (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Removed class TickSample forward declaration Created 7 years, 8 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/platform-linux.cc ('k') | src/platform-solaris.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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include <strings.h> // index 46 #include <strings.h> // index
47 #include <errno.h> 47 #include <errno.h>
48 #include <stdarg.h> 48 #include <stdarg.h>
49 49
50 #undef MAP_TYPE 50 #undef MAP_TYPE
51 51
52 #include "v8.h" 52 #include "v8.h"
53 53
54 #include "platform-posix.h" 54 #include "platform-posix.h"
55 #include "platform.h" 55 #include "platform.h"
56 #include "simulator.h"
57 #include "v8threads.h" 56 #include "v8threads.h"
58 #include "vm-state-inl.h" 57 #include "vm-state-inl.h"
59 58
60 59
61 namespace v8 { 60 namespace v8 {
62 namespace internal { 61 namespace internal {
63 62
64 // 0 is never a valid thread id on Linux and OpenBSD since tids and pids share a 63 // 0 is never a valid thread id on Linux and OpenBSD since tids and pids share a
65 // name space and pid 0 is reserved (see man 2 kill). 64 // name space and pid 0 is reserved (see man 2 kill).
66 static const pthread_t kNoThread = (pthread_t) 0; 65 static const pthread_t kNoThread = (pthread_t) 0;
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 usleep(ts.tv_nsec / 1000); 721 usleep(ts.tv_nsec / 1000);
723 to--; 722 to--;
724 } 723 }
725 } 724 }
726 725
727 Semaphore* OS::CreateSemaphore(int count) { 726 Semaphore* OS::CreateSemaphore(int count) {
728 return new OpenBSDSemaphore(count); 727 return new OpenBSDSemaphore(count);
729 } 728 }
730 729
731 730
732 static pthread_t GetThreadID() {
733 return pthread_self();
734 }
735
736
737 class Sampler::PlatformData : public Malloced {
738 public:
739 PlatformData()
740 : vm_tid_(GetThreadID()),
741 profiled_thread_id_(ThreadId::Current()) {}
742
743 pthread_t vm_tid() const { return vm_tid_; }
744 ThreadId profiled_thread_id() { return profiled_thread_id_; }
745
746 private:
747 pthread_t vm_tid_;
748 ThreadId profiled_thread_id_;
749 };
750
751
752 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
753 USE(info);
754 if (signal != SIGPROF) return;
755 Isolate* isolate = Isolate::UncheckedCurrent();
756 if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) {
757 // We require a fully initialized and entered isolate.
758 return;
759 }
760 if (v8::Locker::IsActive() &&
761 !isolate->thread_manager()->IsLockedByCurrentThread()) {
762 return;
763 }
764
765 Sampler* sampler = isolate->logger()->sampler();
766 if (sampler == NULL || !sampler->IsActive()) return;
767
768 #if defined(USE_SIMULATOR)
769 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
770 ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
771 Isolate::PerIsolateThreadData* per_thread_data = isolate->
772 FindPerThreadDataForThread(thread_id);
773 if (!per_thread_data) return;
774 Simulator* sim = per_thread_data->simulator();
775 // Check if there is active simulator before allocating TickSample.
776 if (!sim) return;
777 #endif
778 #endif // USE_SIMULATOR
779
780 TickSample sample_obj;
781 TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
782 if (sample == NULL) sample = &sample_obj;
783
784 // Extracting the sample from the context is extremely machine dependent.
785 sample->state = isolate->current_vm_state();
786 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
787 #if defined(USE_SIMULATOR)
788 #if V8_TARGET_ARCH_ARM
789 sample->pc = reinterpret_cast<Address>(sim->get_register(Simulator::pc));
790 sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp));
791 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11));
792 #elif V8_TARGET_ARCH_MIPS
793 sample->pc = reinterpret_cast<Address>(sim->get_register(Simulator::pc));
794 sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp));
795 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp));
796 #endif
797 #else
798 #ifdef __NetBSD__
799 mcontext_t& mcontext = ucontext->uc_mcontext;
800 #if V8_HOST_ARCH_IA32
801 sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]);
802 sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]);
803 sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]);
804 #elif V8_HOST_ARCH_X64
805 sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]);
806 sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]);
807 sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]);
808 #endif // V8_HOST_ARCH
809 #else // OpenBSD
810 #if V8_HOST_ARCH_IA32
811 sample->pc = reinterpret_cast<Address>(ucontext->sc_eip);
812 sample->sp = reinterpret_cast<Address>(ucontext->sc_esp);
813 sample->fp = reinterpret_cast<Address>(ucontext->sc_ebp);
814 #elif V8_HOST_ARCH_X64
815 sample->pc = reinterpret_cast<Address>(ucontext->sc_rip);
816 sample->sp = reinterpret_cast<Address>(ucontext->sc_rsp);
817 sample->fp = reinterpret_cast<Address>(ucontext->sc_rbp);
818 #endif // V8_HOST_ARCH
819 #endif // __NetBSD__
820 #endif // USE_SIMULATOR
821 sampler->SampleStack(sample);
822 sampler->Tick(sample);
823 }
824
825
826 class SignalSender : public Thread {
827 public:
828 static const int kSignalSenderStackSize = 64 * KB;
829
830 explicit SignalSender(int interval)
831 : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
832 vm_tgid_(getpid()),
833 interval_(interval) {}
834
835 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); }
836 static void TearDown() { delete mutex_; }
837
838 static void InstallSignalHandler() {
839 struct sigaction sa;
840 sa.sa_sigaction = ProfilerSignalHandler;
841 sigemptyset(&sa.sa_mask);
842 sa.sa_flags = SA_RESTART | SA_SIGINFO;
843 signal_handler_installed_ =
844 (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
845 }
846
847 static void RestoreSignalHandler() {
848 if (signal_handler_installed_) {
849 sigaction(SIGPROF, &old_signal_handler_, 0);
850 signal_handler_installed_ = false;
851 }
852 }
853
854 static void AddActiveSampler(Sampler* sampler) {
855 ScopedLock lock(mutex_);
856 SamplerRegistry::AddActiveSampler(sampler);
857 if (instance_ == NULL) {
858 // Start a thread that will send SIGPROF signal to VM threads,
859 // when CPU profiling will be enabled.
860 instance_ = new SignalSender(sampler->interval());
861 instance_->StartSynchronously();
862 } else {
863 ASSERT(instance_->interval_ == sampler->interval());
864 }
865 }
866
867 static void RemoveActiveSampler(Sampler* sampler) {
868 ScopedLock lock(mutex_);
869 SamplerRegistry::RemoveActiveSampler(sampler);
870 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
871 instance_->Join();
872 delete instance_;
873 instance_ = NULL;
874 RestoreSignalHandler();
875 }
876 }
877
878 // Implement Thread::Run().
879 virtual void Run() {
880 SamplerRegistry::State state;
881 while ((state = SamplerRegistry::GetState()) !=
882 SamplerRegistry::HAS_NO_SAMPLERS) {
883 // When CPU profiling is enabled both JavaScript and C++ code is
884 // profiled. We must not suspend.
885 if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) {
886 if (!signal_handler_installed_) InstallSignalHandler();
887 SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this);
888 } else if (signal_handler_installed_) {
889 RestoreSignalHandler();
890 }
891 Sleep(); // TODO(svenpanne) Figure out if OS:Sleep(interval_) is enough.
892 }
893 }
894
895 static void DoCpuProfile(Sampler* sampler, void* raw_sender) {
896 if (!sampler->IsProfiling()) return;
897 SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender);
898 sender->SendProfilingSignal(sampler->platform_data()->vm_tid());
899 }
900
901 void SendProfilingSignal(pthread_t tid) {
902 if (!signal_handler_installed_) return;
903 pthread_kill(tid, SIGPROF);
904 }
905
906 void Sleep() {
907 // Convert ms to us and subtract 100 us to compensate delays
908 // occuring during signal delivery.
909 useconds_t interval = interval_ * 1000 - 100;
910 int result = usleep(interval);
911 #ifdef DEBUG
912 if (result != 0 && errno != EINTR) {
913 fprintf(stderr,
914 "SignalSender usleep error; interval = %u, errno = %d\n",
915 interval,
916 errno);
917 ASSERT(result == 0 || errno == EINTR);
918 }
919 #endif
920 USE(result);
921 }
922
923 const int vm_tgid_;
924 const int interval_;
925
926 // Protects the process wide state below.
927 static Mutex* mutex_;
928 static SignalSender* instance_;
929 static bool signal_handler_installed_;
930 static struct sigaction old_signal_handler_;
931
932 private:
933 DISALLOW_COPY_AND_ASSIGN(SignalSender);
934 };
935
936
937 Mutex* SignalSender::mutex_ = NULL;
938 SignalSender* SignalSender::instance_ = NULL;
939 struct sigaction SignalSender::old_signal_handler_;
940 bool SignalSender::signal_handler_installed_ = false;
941
942
943 void OS::SetUp() { 731 void OS::SetUp() {
944 // Seed the random number generator. We preserve microsecond resolution. 732 // Seed the random number generator. We preserve microsecond resolution.
945 uint64_t seed = Ticks() ^ (getpid() << 16); 733 uint64_t seed = Ticks() ^ (getpid() << 16);
946 srandom(static_cast<unsigned int>(seed)); 734 srandom(static_cast<unsigned int>(seed));
947 limit_mutex = CreateMutex(); 735 limit_mutex = CreateMutex();
948 SignalSender::SetUp();
949 } 736 }
950 737
951 738
952 void OS::TearDown() { 739 void OS::TearDown() {
953 SignalSender::TearDown();
954 delete limit_mutex; 740 delete limit_mutex;
955 } 741 }
956 742
957 743
958 Sampler::Sampler(Isolate* isolate, int interval)
959 : isolate_(isolate),
960 interval_(interval),
961 profiling_(false),
962 active_(false),
963 samples_taken_(0) {
964 data_ = new PlatformData;
965 }
966
967
968 Sampler::~Sampler() {
969 ASSERT(!IsActive());
970 delete data_;
971 }
972
973
974 void Sampler::Start() {
975 ASSERT(!IsActive());
976 SetActive(true);
977 SignalSender::AddActiveSampler(this);
978 }
979
980
981 void Sampler::Stop() {
982 ASSERT(IsActive());
983 SignalSender::RemoveActiveSampler(this);
984 SetActive(false);
985 }
986
987
988 } } // namespace v8::internal 744 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform-linux.cc ('k') | src/platform-solaris.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698