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

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

Issue 6673045: * Fix build errors on FreeBSD 8.2... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
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/platform.h ('k') | tools/freebsd-tick-processor » ('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-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 24 matching lines...) Expand all
35 #include <sys/resource.h> 35 #include <sys/resource.h>
36 #include <sys/types.h> 36 #include <sys/types.h>
37 #include <sys/ucontext.h> 37 #include <sys/ucontext.h>
38 #include <stdlib.h> 38 #include <stdlib.h>
39 39
40 #include <sys/types.h> // mmap & munmap 40 #include <sys/types.h> // mmap & munmap
41 #include <sys/mman.h> // mmap & munmap 41 #include <sys/mman.h> // mmap & munmap
42 #include <sys/stat.h> // open 42 #include <sys/stat.h> // open
43 #include <sys/fcntl.h> // open 43 #include <sys/fcntl.h> // open
44 #include <unistd.h> // getpagesize 44 #include <unistd.h> // getpagesize
45 // If you don't have execinfo.h then you need devel/libexecinfo from ports.
45 #include <execinfo.h> // backtrace, backtrace_symbols 46 #include <execinfo.h> // backtrace, backtrace_symbols
46 #include <strings.h> // index 47 #include <strings.h> // index
47 #include <errno.h> 48 #include <errno.h>
48 #include <stdarg.h> 49 #include <stdarg.h>
49 #include <limits.h> 50 #include <limits.h>
50 51
51 #undef MAP_TYPE 52 #undef MAP_TYPE
52 53
53 #include "v8.h" 54 #include "v8.h"
54 55
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 virtual int Lock() { 520 virtual int Lock() {
520 int result = pthread_mutex_lock(&mutex_); 521 int result = pthread_mutex_lock(&mutex_);
521 return result; 522 return result;
522 } 523 }
523 524
524 virtual int Unlock() { 525 virtual int Unlock() {
525 int result = pthread_mutex_unlock(&mutex_); 526 int result = pthread_mutex_unlock(&mutex_);
526 return result; 527 return result;
527 } 528 }
528 529
530 virtual bool TryLock() {
531 int result = pthread_mutex_trylock(&mutex_);
532 // Return false if the lock is busy and locking failed.
533 if (result == EBUSY) {
534 return false;
535 }
536 ASSERT(result == 0); // Verify no other errors.
537 return true;
538 }
539
529 private: 540 private:
530 pthread_mutex_t mutex_; // Pthread mutex for POSIX platforms. 541 pthread_mutex_t mutex_; // Pthread mutex for POSIX platforms.
531 }; 542 };
532 543
533 544
534 Mutex* OS::CreateMutex() { 545 Mutex* OS::CreateMutex() {
535 return new FreeBSDMutex(); 546 return new FreeBSDMutex();
536 } 547 }
537 548
538 549
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 599
589 600
590 Semaphore* OS::CreateSemaphore(int count) { 601 Semaphore* OS::CreateSemaphore(int count) {
591 return new FreeBSDSemaphore(count); 602 return new FreeBSDSemaphore(count);
592 } 603 }
593 604
594 605
595 #ifdef ENABLE_LOGGING_AND_PROFILING 606 #ifdef ENABLE_LOGGING_AND_PROFILING
596 607
597 static Sampler* active_sampler_ = NULL; 608 static Sampler* active_sampler_ = NULL;
609 static pthread_t vm_tid_ = NULL;
610
611
612 static pthread_t GetThreadID() {
613 pthread_t thread_id = pthread_self();
614 return thread_id;
615 }
616
617
618 class Sampler::PlatformData : public Malloced {
619 public:
620 enum SleepInterval {
621 FULL_INTERVAL,
622 HALF_INTERVAL
623 };
624
625 PlatformData(Sampler* sampler)
626 : sampler_(sampler),
627 signal_handler_installed_(false),
628 signal_sender_launched_(false) {
629 }
630
631 void SignalSender() {
632 while (sampler_->IsActive()) {
633 if (rate_limiter_.SuspendIfNecessary()) continue;
634 if (sampler_->IsProfiling() && RuntimeProfiler::IsEnabled()) {
635 Sleep(FULL_INTERVAL);
636 RuntimeProfiler::NotifyTick();
637 } else {
638 if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick();
639 Sleep(FULL_INTERVAL);
640 }
641 }
642 }
643
644 void Sleep(SleepInterval full_or_half) {
645 // Convert ms to us and subtract 100 us to compensate delays
646 // occuring during signal delivery.
647 useconds_t interval = sampler_->interval_ * 1000 - 100;
648 if (full_or_half == HALF_INTERVAL) interval /= 2;
649 int result = usleep(interval);
650 #ifdef DEBUG
651 if (result != 0 && errno != EINTR) {
652 fprintf(stderr,
653 "SignalSender usleep error; interval = %u, errno = %d\n",
654 interval,
655 errno);
656 ASSERT(result == 0 || errno == EINTR);
657 }
658 #endif
659 USE(result);
660 }
661
662 Sampler* sampler_;
663 bool signal_handler_installed_;
664 struct sigaction old_signal_handler_;
665 struct itimerval old_timer_value_;
666 bool signal_sender_launched_;
667 pthread_t signal_sender_thread_;
668 RuntimeProfilerRateLimiter rate_limiter_;
669 };
670
598 671
599 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { 672 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
600 USE(info); 673 USE(info);
601 if (signal != SIGPROF) return; 674 if (signal != SIGPROF) return;
602 if (active_sampler_ == NULL) return; 675 if (active_sampler_ == NULL) return;
603 676 if (!active_sampler_->IsActive()) {
604 TickSample sample; 677 // Restore old signal handler
605 678 Sampler::PlatformData* data = active_sampler_->data();
606 // We always sample the VM state. 679 if (data->signal_handler_installed_) {
607 sample.state = VMState::current_state(); 680 sigaction(SIGPROF, &data->old_signal_handler_, 0);
608 681 data->signal_handler_installed_ = false;
609 // If profiling, we extract the current pc and sp. 682 }
610 if (active_sampler_->IsProfiling()) { 683 return;
611 // Extracting the sample from the context is extremely machine dependent.
612 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
613 mcontext_t& mcontext = ucontext->uc_mcontext;
614 #if V8_HOST_ARCH_IA32
615 sample.pc = reinterpret_cast<Address>(mcontext.mc_eip);
616 sample.sp = reinterpret_cast<Address>(mcontext.mc_esp);
617 sample.fp = reinterpret_cast<Address>(mcontext.mc_ebp);
618 #elif V8_HOST_ARCH_X64
619 sample.pc = reinterpret_cast<Address>(mcontext.mc_rip);
620 sample.sp = reinterpret_cast<Address>(mcontext.mc_rsp);
621 sample.fp = reinterpret_cast<Address>(mcontext.mc_rbp);
622 #elif V8_HOST_ARCH_ARM
623 sample.pc = reinterpret_cast<Address>(mcontext.mc_r15);
624 sample.sp = reinterpret_cast<Address>(mcontext.mc_r13);
625 sample.fp = reinterpret_cast<Address>(mcontext.mc_r11);
626 #endif
627 active_sampler_->SampleStack(&sample);
628 } 684 }
629 685
630 active_sampler_->Tick(&sample); 686 if (vm_tid_ != GetThreadID()) return;
687
688 TickSample sample_obj;
689 TickSample* sample = CpuProfiler::TickSampleEvent();
690 if (sample == NULL) sample = &sample_obj;
691
692 // Extracting the sample from the context is extremely machine dependent.
693 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
694 mcontext_t& mcontext = ucontext->uc_mcontext;
695 #if V8_HOST_ARCH_IA32
696 sample->pc = reinterpret_cast<Address>(mcontext.mc_eip);
697 sample->sp = reinterpret_cast<Address>(mcontext.mc_esp);
698 sample->fp = reinterpret_cast<Address>(mcontext.mc_ebp);
699 #elif V8_HOST_ARCH_X64
700 sample->pc = reinterpret_cast<Address>(mcontext.mc_rip);
701 sample->sp = reinterpret_cast<Address>(mcontext.mc_rsp);
702 sample->fp = reinterpret_cast<Address>(mcontext.mc_rbp);
703 #elif V8_HOST_ARCH_ARM
704 sample->pc = reinterpret_cast<Address>(mcontext.mc_r15);
705 sample->sp = reinterpret_cast<Address>(mcontext.mc_r13);
706 sample->fp = reinterpret_cast<Address>(mcontext.mc_r11);
707 #endif
708 active_sampler_->SampleStack(sample);
709 active_sampler_->Tick(sample);
631 } 710 }
632 711
633 712
634 class Sampler::PlatformData : public Malloced { 713 static void* SenderEntry(void* arg) {
635 public: 714 Sampler::PlatformData* data =
636 PlatformData() { 715 reinterpret_cast<Sampler::PlatformData*>(arg);
637 signal_handler_installed_ = false; 716 data->SignalSender();
638 } 717 return 0;
639 718 }
640 bool signal_handler_installed_;
641 struct sigaction old_signal_handler_;
642 struct itimerval old_timer_value_;
643 };
644 719
645 720
646 Sampler::Sampler(int interval) 721 Sampler::Sampler(int interval)
647 : interval_(interval), 722 : interval_(interval),
648 profiling_(false), 723 profiling_(false),
649 active_(false), 724 active_(false),
650 samples_taken_(0) { 725 samples_taken_(0) {
651 data_ = new PlatformData(); 726 data_ = new PlatformData(this);
652 } 727 }
653 728
654 729
655 Sampler::~Sampler() { 730 Sampler::~Sampler() {
656 delete data_; 731 delete data_;
657 } 732 }
658 733
659 734
660 void Sampler::Start() { 735 void Sampler::Start() {
661 // There can only be one active sampler at the time on POSIX 736 // There can only be one active sampler at the time on POSIX
662 // platforms. 737 // platforms.
663 if (active_sampler_ != NULL) return; 738 ASSERT(!IsActive());
739 vm_tid_ = GetThreadID();
664 740
665 // Request profiling signals. 741 // Request profiling signals.
666 struct sigaction sa; 742 struct sigaction sa;
667 sa.sa_sigaction = ProfilerSignalHandler; 743 sa.sa_sigaction = ProfilerSignalHandler;
668 sigemptyset(&sa.sa_mask); 744 sigemptyset(&sa.sa_mask);
669 sa.sa_flags = SA_SIGINFO; 745 sa.sa_flags = SA_SIGINFO;
670 if (sigaction(SIGPROF, &sa, &data_->old_signal_handler_) != 0) return; 746 if (sigaction(SIGPROF, &sa, &data_->old_signal_handler_) != 0) return;
671 data_->signal_handler_installed_ = true; 747 data_->signal_handler_installed_ = true;
672 748
673 // Set the itimer to generate a tick for each interval. 749 // Set the itimer to generate a tick for each interval.
674 itimerval itimer; 750 itimerval itimer;
675 itimer.it_interval.tv_sec = interval_ / 1000; 751 itimer.it_interval.tv_sec = interval_ / 1000;
676 itimer.it_interval.tv_usec = (interval_ % 1000) * 1000; 752 itimer.it_interval.tv_usec = (interval_ % 1000) * 1000;
677 itimer.it_value.tv_sec = itimer.it_interval.tv_sec; 753 itimer.it_value.tv_sec = itimer.it_interval.tv_sec;
678 itimer.it_value.tv_usec = itimer.it_interval.tv_usec; 754 itimer.it_value.tv_usec = itimer.it_interval.tv_usec;
679 setitimer(ITIMER_PROF, &itimer, &data_->old_timer_value_); 755 setitimer(ITIMER_PROF, &itimer, &data_->old_timer_value_);
680 756
681 // Set this sampler as the active sampler. 757 // Set this sampler as the active sampler.
682 active_sampler_ = this; 758 active_sampler_ = this;
683 active_ = true; 759 SetActive(true);
760
761 // There's no way to send a signal to a thread on FreeBSD, but we can
762 // start a thread that uses the stack guard to interrupt the JS thread.
763 if (pthread_create(
764 &data_->signal_sender_thread_, NULL, SenderEntry, data_) == 0) {
765 data_->signal_sender_launched_ = true;
766 }
684 } 767 }
685 768
686 769
687 void Sampler::Stop() { 770 void Sampler::Stop() {
688 // Restore old signal handler 771 // This sampler is no longer the active sampler.
689 if (data_->signal_handler_installed_) { 772 active_sampler_ = NULL;
690 setitimer(ITIMER_PROF, &data_->old_timer_value_, NULL); 773 SetActive(false);
691 sigaction(SIGPROF, &data_->old_signal_handler_, 0); 774
692 data_->signal_handler_installed_ = false; 775 // Wait for signal sender termination (it will exit after setting
776 // active_ to false).
777 if (data_->signal_sender_launched_) {
778 Top::WakeUpRuntimeProfilerThreadBeforeShutdown();
779 pthread_join(data_->signal_sender_thread_, NULL);
780 data_->signal_sender_launched_ = false;
693 } 781 }
694 782
695 // This sampler is no longer the active sampler.
696 active_sampler_ = NULL;
697 active_ = false;
698 } 783 }
699 784
700 #endif // ENABLE_LOGGING_AND_PROFILING 785 #endif // ENABLE_LOGGING_AND_PROFILING
701 786
702 } } // namespace v8::internal 787 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform.h ('k') | tools/freebsd-tick-processor » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698