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