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

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

Issue 14264009: Merge Windows, Mac OS X and Cygwin sampler implementations with the rest ones (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix Android build 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/isolate.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 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup. 616 CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
617 } 617 }
618 } 618 }
619 619
620 620
621 Semaphore* OS::CreateSemaphore(int count) { 621 Semaphore* OS::CreateSemaphore(int count) {
622 return new CygwinSemaphore(count); 622 return new CygwinSemaphore(count);
623 } 623 }
624 624
625 625
626 // ----------------------------------------------------------------------------
627 // Cygwin profiler support.
628 //
629 // On Cygwin we use the same sampler implementation as on win32.
630
631 class Sampler::PlatformData : public Malloced {
632 public:
633 // Get a handle to the calling thread. This is the thread that we are
634 // going to profile. We need to make a copy of the handle because we are
635 // going to use it in the sampler thread. Using GetThreadHandle() will
636 // not work in this case. We're using OpenThread because DuplicateHandle
637 // for some reason doesn't work in Chrome's sandbox.
638 PlatformData()
639 : profiled_thread_(OpenThread(THREAD_GET_CONTEXT |
640 THREAD_SUSPEND_RESUME |
641 THREAD_QUERY_INFORMATION,
642 false,
643 GetCurrentThreadId())),
644 profiled_thread_id_(ThreadId::Current()) {}
645
646 ~PlatformData() {
647 if (profiled_thread_ != NULL) {
648 CloseHandle(profiled_thread_);
649 profiled_thread_ = NULL;
650 }
651 }
652
653 HANDLE profiled_thread() { return profiled_thread_; }
654 ThreadId profiled_thread_id() { return profiled_thread_id_; }
655
656 private:
657 HANDLE profiled_thread_;
658 ThreadId profiled_thread_id_;
659 };
660
661
662 class SamplerThread : public Thread {
663 public:
664 static const int kSamplerThreadStackSize = 64 * KB;
665
666 explicit SamplerThread(int interval)
667 : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)),
668 interval_(interval) {}
669
670 static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); }
671 static void TearDown() { delete mutex_; }
672
673 static void AddActiveSampler(Sampler* sampler) {
674 ScopedLock lock(mutex_);
675 SamplerRegistry::AddActiveSampler(sampler);
676 if (instance_ == NULL) {
677 instance_ = new SamplerThread(sampler->interval());
678 instance_->StartSynchronously();
679 } else {
680 ASSERT(instance_->interval_ == sampler->interval());
681 }
682 }
683
684 static void RemoveActiveSampler(Sampler* sampler) {
685 ScopedLock lock(mutex_);
686 SamplerRegistry::RemoveActiveSampler(sampler);
687 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
688 instance_->Join();
689 delete instance_;
690 instance_ = NULL;
691 }
692 }
693
694 // Implement Thread::Run().
695 virtual void Run() {
696 SamplerRegistry::State state;
697 while ((state = SamplerRegistry::GetState()) !=
698 SamplerRegistry::HAS_NO_SAMPLERS) {
699 // When CPU profiling is enabled both JavaScript and C++ code is
700 // profiled. We must not suspend.
701 if (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS) {
702 SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this);
703 }
704 OS::Sleep(interval_);
705 }
706 }
707
708 static void DoCpuProfile(Sampler* sampler, void* raw_sampler_thread) {
709 if (!sampler->isolate()->IsInitialized()) return;
710 if (!sampler->IsProfiling()) return;
711 SamplerThread* sampler_thread =
712 reinterpret_cast<SamplerThread*>(raw_sampler_thread);
713 sampler_thread->SampleContext(sampler);
714 }
715
716 void SampleContext(Sampler* sampler) {
717 HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
718 if (profiled_thread == NULL) return;
719
720 // Context used for sampling the register state of the profiled thread.
721 CONTEXT context;
722 memset(&context, 0, sizeof(context));
723
724 Isolate* isolate = sampler->isolate();
725 #if defined(USE_SIMULATOR)
726 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
727 ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
728 Isolate::PerIsolateThreadData* per_thread_data = isolate->
729 FindPerThreadDataForThread(thread_id);
730 if (!per_thread_data) return;
731 Simulator* sim = per_thread_data->simulator();
732 // Check if there is active simulator before allocating TickSample.
733 if (!sim) return;
734 #endif
735 #endif // USE_SIMULATOR
736 TickSample sample_obj;
737 TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
738 if (sample == NULL) sample = &sample_obj;
739
740 static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
741 if (SuspendThread(profiled_thread) == kSuspendFailed) return;
742 sample->state = isolate->current_vm_state();
743
744 context.ContextFlags = CONTEXT_FULL;
745 if (GetThreadContext(profiled_thread, &context) != 0) {
746 #if defined(USE_SIMULATOR)
747 #if V8_TARGET_ARCH_ARM
748 sample->pc = reinterpret_cast<Address>(sim->get_register(Simulator::pc));
749 sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp));
750 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11));
751 #elif V8_TARGET_ARCH_MIPS
752 sample->pc = reinterpret_cast<Address>(sim->get_register(Simulator::pc));
753 sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp));
754 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp));
755 #endif
756 #else
757 #if V8_HOST_ARCH_X64
758 sample->pc = reinterpret_cast<Address>(context.Rip);
759 sample->sp = reinterpret_cast<Address>(context.Rsp);
760 sample->fp = reinterpret_cast<Address>(context.Rbp);
761 #else
762 sample->pc = reinterpret_cast<Address>(context.Eip);
763 sample->sp = reinterpret_cast<Address>(context.Esp);
764 sample->fp = reinterpret_cast<Address>(context.Ebp);
765 #endif
766 #endif // USE_SIMULATOR
767 sampler->SampleStack(sample);
768 sampler->Tick(sample);
769 }
770 ResumeThread(profiled_thread);
771 }
772
773 const int interval_;
774
775 // Protects the process wide state below.
776 static Mutex* mutex_;
777 static SamplerThread* instance_;
778
779 private:
780 DISALLOW_COPY_AND_ASSIGN(SamplerThread);
781 };
782
783
784 Mutex* SamplerThread::mutex_ = NULL;
785 SamplerThread* SamplerThread::instance_ = NULL;
786
787
788 void OS::SetUp() { 626 void OS::SetUp() {
789 // Seed the random number generator. 627 // Seed the random number generator.
790 // Convert the current time to a 64-bit integer first, before converting it 628 // Convert the current time to a 64-bit integer first, before converting it
791 // to an unsigned. Going directly can cause an overflow and the seed to be 629 // to an unsigned. Going directly can cause an overflow and the seed to be
792 // set to all ones. The seed will be identical for different instances that 630 // set to all ones. The seed will be identical for different instances that
793 // call this setup code within the same millisecond. 631 // call this setup code within the same millisecond.
794 uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); 632 uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
795 srandom(static_cast<unsigned int>(seed)); 633 srandom(static_cast<unsigned int>(seed));
796 limit_mutex = CreateMutex(); 634 limit_mutex = CreateMutex();
797 SamplerThread::SetUp();
798 } 635 }
799 636
800 637
801 void OS::TearDown() { 638 void OS::TearDown() {
802 SamplerThread::TearDown();
803 delete limit_mutex; 639 delete limit_mutex;
804 } 640 }
805 641
806 642
807 Sampler::Sampler(Isolate* isolate, int interval)
808 : isolate_(isolate),
809 interval_(interval),
810 profiling_(false),
811 active_(false),
812 samples_taken_(0) {
813 data_ = new PlatformData;
814 }
815
816
817 Sampler::~Sampler() {
818 ASSERT(!IsActive());
819 delete data_;
820 }
821
822
823 void Sampler::Start() {
824 ASSERT(!IsActive());
825 SetActive(true);
826 SamplerThread::AddActiveSampler(this);
827 }
828
829
830 void Sampler::Stop() {
831 ASSERT(IsActive());
832 SamplerThread::RemoveActiveSampler(this);
833 SetActive(false);
834 }
835
836
837 } } // namespace v8::internal 643 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/isolate.cc ('k') | src/platform-macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698