Revision: 7200
Author: [email protected]
Date: Wed Mar 16 04:15:43 2011
Log: * Fix build errors on FreeBSD 8.2
* Fix Crankshaft on FreeBSD.
* Partially fix profiling on FreeBSD.
* Remove bash-isms from tick processor script.
Review URL: http://codereview.chromium.org/6673045
http://code.google.com/p/v8/source/detail?r=7200

Added:
 /branches/bleeding_edge/tools/freebsd-tick-processor
Modified:
 /branches/bleeding_edge/SConstruct
 /branches/bleeding_edge/src/d8-posix.cc
 /branches/bleeding_edge/src/platform-freebsd.cc
 /branches/bleeding_edge/src/platform.h
 /branches/bleeding_edge/tools/linux-tick-processor

=======================================
--- /dev/null
+++ /branches/bleeding_edge/tools/freebsd-tick-processor Wed Mar 16 04:15:43 2011
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# A wrapper script to call 'linux-tick-processor'.
+
+# Known issues on FreeBSD:
+#  No ticks from C++ code.
+#  You must have d8 built and in your path before calling this.
+
+tools_path=`cd $(dirname "$0");pwd`
+$tools_path/linux-tick-processor "$@"
=======================================
--- /branches/bleeding_edge/SConstruct  Thu Feb 17 08:33:10 2011
+++ /branches/bleeding_edge/SConstruct  Wed Mar 16 04:15:43 2011
@@ -174,6 +174,7 @@
       'CPPPATH' : ['/usr/local/include'],
       'LIBPATH' : ['/usr/local/lib'],
       'CCFLAGS':      ['-ansi'],
+      'LIBS': ['execinfo']
     },
     'os:openbsd': {
       'CPPPATH' : ['/usr/local/include'],
=======================================
--- /branches/bleeding_edge/src/d8-posix.cc     Tue Dec  7 03:01:02 2010
+++ /branches/bleeding_edge/src/d8-posix.cc     Wed Mar 16 04:15:43 2011
@@ -375,8 +375,10 @@
// a parent process hangs on waiting while a child process is already a zombie.
 // See http://code.google.com/p/v8/issues/detail?id=401.
 #if defined(WNOWAIT) && !defined(ANDROID) && !defined(__APPLE__)
+#if !defined(__FreeBSD__)
 #define HAS_WAITID 1
 #endif
+#endif


 // Get exit status of child.
=======================================
--- /branches/bleeding_edge/src/platform-freebsd.cc     Mon Feb 21 09:17:26 2011
+++ /branches/bleeding_edge/src/platform-freebsd.cc     Wed Mar 16 04:15:43 2011
@@ -42,6 +42,7 @@
 #include <sys/stat.h>   // open
 #include <sys/fcntl.h>  // open
 #include <unistd.h>     // getpagesize
+// If you don't have execinfo.h then you need devel/libexecinfo from ports.
 #include <execinfo.h>   // backtrace, backtrace_symbols
 #include <strings.h>    // index
 #include <errno.h>
@@ -525,6 +526,16 @@
     int result = pthread_mutex_unlock(&mutex_);
     return result;
   }
+
+  virtual bool TryLock() {
+    int result = pthread_mutex_trylock(&mutex_);
+    // Return false if the lock is busy and locking failed.
+    if (result == EBUSY) {
+      return false;
+    }
+    ASSERT(result == 0);  // Verify no other errors.
+    return true;
+  }

  private:
   pthread_mutex_t mutex_;   // Pthread mutex for POSIX platforms.
@@ -595,52 +606,116 @@
 #ifdef ENABLE_LOGGING_AND_PROFILING

 static Sampler* active_sampler_ = NULL;
+static pthread_t vm_tid_ = NULL;
+
+
+static pthread_t GetThreadID() {
+  pthread_t thread_id = pthread_self();
+  return thread_id;
+}
+
+
+class Sampler::PlatformData : public Malloced {
+ public:
+  enum SleepInterval {
+    FULL_INTERVAL,
+    HALF_INTERVAL
+  };
+
+  explicit PlatformData(Sampler* sampler)
+      : sampler_(sampler),
+        signal_handler_installed_(false),
+        signal_sender_launched_(false) {
+  }
+
+  void SignalSender() {
+    while (sampler_->IsActive()) {
+      if (rate_limiter_.SuspendIfNecessary()) continue;
+      if (sampler_->IsProfiling() && RuntimeProfiler::IsEnabled()) {
+        Sleep(FULL_INTERVAL);
+        RuntimeProfiler::NotifyTick();
+      } else {
+        if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick();
+        Sleep(FULL_INTERVAL);
+      }
+    }
+  }
+
+  void Sleep(SleepInterval full_or_half) {
+    // Convert ms to us and subtract 100 us to compensate delays
+    // occuring during signal delivery.
+    useconds_t interval = sampler_->interval_ * 1000 - 100;
+    if (full_or_half == HALF_INTERVAL) interval /= 2;
+    int result = usleep(interval);
+#ifdef DEBUG
+    if (result != 0 && errno != EINTR) {
+      fprintf(stderr,
+              "SignalSender usleep error; interval = %u, errno = %d\n",
+              interval,
+              errno);
+      ASSERT(result == 0 || errno == EINTR);
+    }
+#endif
+    USE(result);
+  }
+
+  Sampler* sampler_;
+  bool signal_handler_installed_;
+  struct sigaction old_signal_handler_;
+  struct itimerval old_timer_value_;
+  bool signal_sender_launched_;
+  pthread_t signal_sender_thread_;
+  RuntimeProfilerRateLimiter rate_limiter_;
+};
+

static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
   USE(info);
   if (signal != SIGPROF) return;
   if (active_sampler_ == NULL) return;
-
-  TickSample sample;
-
-  // We always sample the VM state.
-  sample.state = VMState::current_state();
-
-  // If profiling, we extract the current pc and sp.
-  if (active_sampler_->IsProfiling()) {
- // Extracting the sample from the context is extremely machine dependent.
-    ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
-    mcontext_t& mcontext = ucontext->uc_mcontext;
+  if (!active_sampler_->IsActive()) {
+    // Restore old signal handler
+    Sampler::PlatformData* data = active_sampler_->data();
+    if (data->signal_handler_installed_) {
+      sigaction(SIGPROF, &data->old_signal_handler_, 0);
+      data->signal_handler_installed_ = false;
+    }
+    return;
+  }
+
+  if (vm_tid_ != GetThreadID()) return;
+
+  TickSample sample_obj;
+  TickSample* sample = CpuProfiler::TickSampleEvent();
+  if (sample == NULL) sample = &sample_obj;
+
+  // Extracting the sample from the context is extremely machine dependent.
+  ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
+  mcontext_t& mcontext = ucontext->uc_mcontext;
 #if V8_HOST_ARCH_IA32
-    sample.pc = reinterpret_cast<Address>(mcontext.mc_eip);
-    sample.sp = reinterpret_cast<Address>(mcontext.mc_esp);
-    sample.fp = reinterpret_cast<Address>(mcontext.mc_ebp);
+  sample->pc = reinterpret_cast<Address>(mcontext.mc_eip);
+  sample->sp = reinterpret_cast<Address>(mcontext.mc_esp);
+  sample->fp = reinterpret_cast<Address>(mcontext.mc_ebp);
 #elif V8_HOST_ARCH_X64
-    sample.pc = reinterpret_cast<Address>(mcontext.mc_rip);
-    sample.sp = reinterpret_cast<Address>(mcontext.mc_rsp);
-    sample.fp = reinterpret_cast<Address>(mcontext.mc_rbp);
+  sample->pc = reinterpret_cast<Address>(mcontext.mc_rip);
+  sample->sp = reinterpret_cast<Address>(mcontext.mc_rsp);
+  sample->fp = reinterpret_cast<Address>(mcontext.mc_rbp);
 #elif V8_HOST_ARCH_ARM
-    sample.pc = reinterpret_cast<Address>(mcontext.mc_r15);
-    sample.sp = reinterpret_cast<Address>(mcontext.mc_r13);
-    sample.fp = reinterpret_cast<Address>(mcontext.mc_r11);
+  sample->pc = reinterpret_cast<Address>(mcontext.mc_r15);
+  sample->sp = reinterpret_cast<Address>(mcontext.mc_r13);
+  sample->fp = reinterpret_cast<Address>(mcontext.mc_r11);
 #endif
-    active_sampler_->SampleStack(&sample);
-  }
-
-  active_sampler_->Tick(&sample);
+  active_sampler_->SampleStack(sample);
+  active_sampler_->Tick(sample);
 }


-class Sampler::PlatformData : public Malloced {
- public:
-  PlatformData() {
-    signal_handler_installed_ = false;
-  }
-
-  bool signal_handler_installed_;
-  struct sigaction old_signal_handler_;
-  struct itimerval old_timer_value_;
-};
+static void* SenderEntry(void* arg) {
+  Sampler::PlatformData* data =
+      reinterpret_cast<Sampler::PlatformData*>(arg);
+  data->SignalSender();
+  return 0;
+}


 Sampler::Sampler(int interval)
@@ -648,7 +723,7 @@
       profiling_(false),
       active_(false),
       samples_taken_(0) {
-  data_ = new PlatformData();
+  data_ = new PlatformData(this);
 }


@@ -660,7 +735,8 @@
 void Sampler::Start() {
   // There can only be one active sampler at the time on POSIX
   // platforms.
-  if (active_sampler_ != NULL) return;
+  ASSERT(!IsActive());
+  vm_tid_ = GetThreadID();

   // Request profiling signals.
   struct sigaction sa;
@@ -680,21 +756,29 @@

   // Set this sampler as the active sampler.
   active_sampler_ = this;
-  active_ = true;
+  SetActive(true);
+
+  // There's no way to send a signal to a thread on FreeBSD, but we can
+  // start a thread that uses the stack guard to interrupt the JS thread.
+  if (pthread_create(
+          &data_->signal_sender_thread_, NULL, SenderEntry, data_) == 0) {
+    data_->signal_sender_launched_ = true;
+  }
 }


 void Sampler::Stop() {
-  // Restore old signal handler
-  if (data_->signal_handler_installed_) {
-    setitimer(ITIMER_PROF, &data_->old_timer_value_, NULL);
-    sigaction(SIGPROF, &data_->old_signal_handler_, 0);
-    data_->signal_handler_installed_ = false;
-  }
-
   // This sampler is no longer the active sampler.
   active_sampler_ = NULL;
-  active_ = false;
+  SetActive(false);
+
+  // Wait for signal sender termination (it will exit after setting
+  // active_ to false).
+  if (data_->signal_sender_launched_) {
+    Top::WakeUpRuntimeProfilerThreadBeforeShutdown();
+    pthread_join(data_->signal_sender_thread_, NULL);
+    data_->signal_sender_launched_ = false;
+  }
 }

 #endif  // ENABLE_LOGGING_AND_PROFILING
=======================================
--- /branches/bleeding_edge/src/platform.h      Tue Feb 22 08:31:24 2011
+++ /branches/bleeding_edge/src/platform.h      Wed Mar 16 04:15:43 2011
@@ -613,6 +613,7 @@
   void ResetSamplesTaken() { samples_taken_ = 0; }

   class PlatformData;
+  PlatformData* data() { return data_; }

  protected:
   virtual void DoSampleStack(TickSample* sample) = 0;
=======================================
--- /branches/bleeding_edge/tools/linux-tick-processor Tue Dec 7 03:01:02 2010 +++ /branches/bleeding_edge/tools/linux-tick-processor Wed Mar 16 04:15:43 2011
@@ -3,12 +3,12 @@
 tools_path=`cd $(dirname "$0");pwd`
 if [ ! "$D8_PATH" ]; then
   d8_public=`which d8`
-  if [ $d8_public ]; then D8_PATH=$(dirname "$d8_public"); fi
+  if [ -x $d8_public ]; then D8_PATH=$(dirname "$d8_public"); fi
 fi
 [ "$D8_PATH" ] || D8_PATH=$tools_path/..
 d8_exec=$D8_PATH/d8

-if [ "$1" == "--no-build" ]; then
+if [ "$1" = "--no-build" ]; then
   shift
 else
 # compile d8 if it doesn't exist, assuming this script
@@ -16,15 +16,17 @@
   [ -x $d8_exec ] || scons -j4 -C $D8_PATH -Y $tools_path/.. d8
 fi

+
 # find the name of the log file to process, it must not start with a dash.
 log_file="v8.log"
 for arg in "$@"
 do
-  if [[ "${arg}" != -* ]]; then
+  if ! expr "X${arg}" : "^X-" > /dev/null; then
     log_file=${arg}
   fi
 done

+
 # nm spits out 'no symbols found' messages to stderr.
 cat $log_file | $d8_exec $tools_path/splaytree.js $tools_path/codemap.js \
   $tools_path/csvparser.js $tools_path/consarray.js \

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to