diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2010-12-07 13:56:11 -0800 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-12-07 13:56:11 -0800 |
commit | c30f1137121315b0d3641af6dc61e3b047f940e1 (patch) | |
tree | f118eaf670505e6a63f28bc8df845520f67adc55 /deps/v8/src/platform-macos.cc | |
parent | 5b8c62f7d12c1c5a553e765ba05bbd8a7e17ee47 (diff) | |
download | node-c30f1137121315b0d3641af6dc61e3b047f940e1.tar.gz |
Upgrade V8 to 3.0.0
Diffstat (limited to 'deps/v8/src/platform-macos.cc')
-rw-r--r-- | deps/v8/src/platform-macos.cc | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/deps/v8/src/platform-macos.cc b/deps/v8/src/platform-macos.cc index c3f21dc51..85c708824 100644 --- a/deps/v8/src/platform-macos.cc +++ b/deps/v8/src/platform-macos.cc @@ -57,6 +57,7 @@ #include "v8.h" #include "platform.h" +#include "vm-state-inl.h" // Manually define these here as weak imports, rather than including execinfo.h. // This lets us launch on 10.4 which does not have these calls. @@ -483,11 +484,20 @@ class MacOSMutex : public Mutex { pthread_mutex_init(&mutex_, &attr); } - ~MacOSMutex() { pthread_mutex_destroy(&mutex_); } + virtual ~MacOSMutex() { pthread_mutex_destroy(&mutex_); } - int Lock() { return pthread_mutex_lock(&mutex_); } + virtual int Lock() { return pthread_mutex_lock(&mutex_); } + virtual int Unlock() { return pthread_mutex_unlock(&mutex_); } - int Unlock() { return pthread_mutex_unlock(&mutex_); } + 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_; @@ -554,40 +564,38 @@ class Sampler::PlatformData : public Malloced { mach_port_t task_self_; thread_act_t profiled_thread_; pthread_t sampler_thread_; + RuntimeProfilerRateLimiter rate_limiter_; // Sampler thread handler. void Runner() { - // Loop until the sampler is disengaged, keeping the specified - // sampling frequency. - for ( ; sampler_->IsActive(); OS::Sleep(sampler_->interval_)) { + while (sampler_->IsActive()) { + if (rate_limiter_.SuspendIfNecessary()) continue; + Sample(); + OS::Sleep(sampler_->interval_); + } + } + + void Sample() { + if (sampler_->IsProfiling()) { TickSample sample_obj; TickSample* sample = CpuProfiler::TickSampleEvent(); if (sample == NULL) sample = &sample_obj; - // If the sampler runs in sync with the JS thread, we try to - // suspend it. If we fail, we skip the current sample. - if (sampler_->IsSynchronous()) { - if (KERN_SUCCESS != thread_suspend(profiled_thread_)) continue; - } + if (KERN_SUCCESS != thread_suspend(profiled_thread_)) return; - // We always sample the VM state. - sample->state = VMState::current_state(); - - // If profiling, we record the pc and sp of the profiled thread. - if (sampler_->IsProfiling()) { #if V8_HOST_ARCH_X64 - thread_state_flavor_t flavor = x86_THREAD_STATE64; - x86_thread_state64_t state; - mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; + thread_state_flavor_t flavor = x86_THREAD_STATE64; + x86_thread_state64_t state; + mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; #if __DARWIN_UNIX03 #define REGISTER_FIELD(name) __r ## name #else #define REGISTER_FIELD(name) r ## name #endif // __DARWIN_UNIX03 #elif V8_HOST_ARCH_IA32 - thread_state_flavor_t flavor = i386_THREAD_STATE; - i386_thread_state_t state; - mach_msg_type_number_t count = i386_THREAD_STATE_COUNT; + thread_state_flavor_t flavor = i386_THREAD_STATE; + i386_thread_state_t state; + mach_msg_type_number_t count = i386_THREAD_STATE_COUNT; #if __DARWIN_UNIX03 #define REGISTER_FIELD(name) __e ## name #else @@ -597,24 +605,20 @@ class Sampler::PlatformData : public Malloced { #error Unsupported Mac OS X host architecture. #endif // V8_HOST_ARCH - if (thread_get_state(profiled_thread_, - flavor, - reinterpret_cast<natural_t*>(&state), - &count) == KERN_SUCCESS) { - sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip)); - sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp)); - sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp)); - sampler_->SampleStack(sample); - } + if (thread_get_state(profiled_thread_, + flavor, + reinterpret_cast<natural_t*>(&state), + &count) == KERN_SUCCESS) { + sample->state = Top::current_vm_state(); + sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip)); + sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp)); + sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp)); + sampler_->SampleStack(sample); + sampler_->Tick(sample); } - - // Invoke tick handler with program counter and stack pointer. - sampler_->Tick(sample); - - // If the sampler runs in sync with the JS thread, we have to - // remember to resume it. - if (sampler_->IsSynchronous()) thread_resume(profiled_thread_); + thread_resume(profiled_thread_); } + if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick(); } }; @@ -630,10 +634,9 @@ static void* SamplerEntry(void* arg) { } -Sampler::Sampler(int interval, bool profiling) +Sampler::Sampler(int interval) : interval_(interval), - profiling_(profiling), - synchronous_(profiling), + profiling_(false), active_(false), samples_taken_(0) { data_ = new PlatformData(this); @@ -646,11 +649,9 @@ Sampler::~Sampler() { void Sampler::Start() { - // If we are starting a synchronous sampler, we need to be able to - // access the calling thread. - if (IsSynchronous()) { - data_->profiled_thread_ = mach_thread_self(); - } + // Do not start multiple threads for the same sampler. + ASSERT(!IsActive()); + data_->profiled_thread_ = mach_thread_self(); // Create sampler thread with high priority. // According to POSIX spec, when SCHED_FIFO policy is used, a thread @@ -663,7 +664,7 @@ void Sampler::Start() { fifo_param.sched_priority = sched_get_priority_max(SCHED_FIFO); pthread_attr_setschedparam(&sched_attr, &fifo_param); - active_ = true; + SetActive(true); pthread_create(&data_->sampler_thread_, &sched_attr, SamplerEntry, data_); } @@ -671,15 +672,14 @@ void Sampler::Start() { void Sampler::Stop() { // Seting active to false triggers termination of the sampler // thread. - active_ = false; + SetActive(false); // Wait for sampler thread to terminate. + Top::WakeUpRuntimeProfilerThreadBeforeShutdown(); pthread_join(data_->sampler_thread_, NULL); // Deallocate Mach port for thread. - if (IsSynchronous()) { - mach_port_deallocate(data_->task_self_, data_->profiled_thread_); - } + mach_port_deallocate(data_->task_self_, data_->profiled_thread_); } #endif // ENABLE_LOGGING_AND_PROFILING |