diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-03-12 09:01:49 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-03-14 18:49:21 +0100 |
commit | 7b48713334469818661fe276cf571de9c7899f2d (patch) | |
tree | 4dbda49ac88db76ce09dc330a0cb587e68e139ba /deps/v8/src/libsampler/sampler.cc | |
parent | 8549ac09b256666cf5275224ec58fab9939ff32e (diff) | |
download | android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.tar.gz android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.tar.bz2 android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.zip |
deps: update V8 to 7.3.492.25
PR-URL: https://github.com/nodejs/node/pull/25852
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/src/libsampler/sampler.cc')
-rw-r--r-- | deps/v8/src/libsampler/sampler.cc | 266 |
1 files changed, 72 insertions, 194 deletions
diff --git a/deps/v8/src/libsampler/sampler.cc b/deps/v8/src/libsampler/sampler.cc index 464b4de32a..eb804a787a 100644 --- a/deps/v8/src/libsampler/sampler.cc +++ b/deps/v8/src/libsampler/sampler.cc @@ -4,14 +4,13 @@ #include "src/libsampler/sampler.h" -#if V8_OS_POSIX && !V8_OS_CYGWIN && !V8_OS_FUCHSIA - -#define USE_SIGNALS +#ifdef USE_SIGNALS #include <errno.h> #include <pthread.h> #include <signal.h> #include <sys/time.h> +#include <atomic> #if !V8_OS_QNX && !V8_OS_AIX #include <sys/syscall.h> // NOLINT @@ -57,10 +56,8 @@ typedef zx_arm64_general_regs_t zx_thread_state_general_regs_t; #include <algorithm> #include <vector> -#include <map> #include "src/base/atomic-utils.h" -#include "src/base/hashmap.h" #include "src/base/platform/platform.h" #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) @@ -170,55 +167,24 @@ enum { REG_RBP = 10, REG_RSP = 15, REG_RIP = 16 }; namespace v8 { namespace sampler { -namespace { - #if defined(USE_SIGNALS) -typedef std::vector<Sampler*> SamplerList; -typedef SamplerList::iterator SamplerListIterator; -typedef base::AtomicValue<bool> AtomicMutex; - -class AtomicGuard { - public: - explicit AtomicGuard(AtomicMutex* atomic, bool is_blocking = true) - : atomic_(atomic), is_success_(false) { - do { - // Use Acquire_Load to gain mutual exclusion. - USE(atomic_->Value()); - is_success_ = atomic_->TrySetValue(false, true); - } while (is_blocking && !is_success_); - } - bool is_success() const { return is_success_; } - - ~AtomicGuard() { - if (!is_success_) return; - atomic_->SetValue(false); - } - - private: - AtomicMutex* const atomic_; - bool is_success_; -}; - -// Returns key for hash map. -void* ThreadKey(pthread_t thread_id) { - return reinterpret_cast<void*>(thread_id); +AtomicGuard::AtomicGuard(AtomicMutex* atomic, bool is_blocking) + : atomic_(atomic), is_success_(false) { + do { + bool expected = false; + // We have to use the strong version here for the case where is_blocking + // is false, and we will only attempt the exchange once. + is_success_ = atomic->compare_exchange_strong(expected, true); + } while (is_blocking && !is_success_); } -// Returns hash value for hash map. -uint32_t ThreadHash(pthread_t thread_id) { -#if V8_OS_BSD - return static_cast<uint32_t>(reinterpret_cast<intptr_t>(thread_id)); -#else - return static_cast<uint32_t>(thread_id); -#endif +AtomicGuard::~AtomicGuard() { + if (!is_success_) return; + atomic_->store(false); } -#endif // USE_SIGNALS - -} // namespace - -#if defined(USE_SIGNALS) +bool AtomicGuard::is_success() const { return is_success_; } class Sampler::PlatformData { public: @@ -229,94 +195,57 @@ class Sampler::PlatformData { pthread_t vm_tid_; }; -class SamplerManager { - public: - SamplerManager() : sampler_map_() {} - - void AddSampler(Sampler* sampler) { - AtomicGuard atomic_guard(&samplers_access_counter_); - DCHECK(sampler->IsActive() || !sampler->IsRegistered()); - // Add sampler into map if needed. - pthread_t thread_id = sampler->platform_data()->vm_tid(); - base::HashMap::Entry* entry = - sampler_map_.LookupOrInsert(ThreadKey(thread_id), - ThreadHash(thread_id)); - DCHECK_NOT_NULL(entry); - if (entry->value == nullptr) { - SamplerList* samplers = new SamplerList(); - samplers->push_back(sampler); - entry->value = samplers; - } else { - SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); - bool exists = false; - for (SamplerListIterator iter = samplers->begin(); - iter != samplers->end(); ++iter) { - if (*iter == sampler) { - exists = true; - break; - } - } - if (!exists) { - samplers->push_back(sampler); - } - } +void SamplerManager::AddSampler(Sampler* sampler) { + AtomicGuard atomic_guard(&samplers_access_counter_); + DCHECK(sampler->IsActive()); + pthread_t thread_id = sampler->platform_data()->vm_tid(); + auto it = sampler_map_.find(thread_id); + if (it == sampler_map_.end()) { + SamplerList samplers; + samplers.push_back(sampler); + sampler_map_.emplace(thread_id, std::move(samplers)); + } else { + SamplerList& samplers = it->second; + auto it = std::find(samplers.begin(), samplers.end(), sampler); + if (it == samplers.end()) samplers.push_back(sampler); } +} - void RemoveSampler(Sampler* sampler) { - AtomicGuard atomic_guard(&samplers_access_counter_); - DCHECK(sampler->IsActive() || sampler->IsRegistered()); - // Remove sampler from map. - pthread_t thread_id = sampler->platform_data()->vm_tid(); - void* thread_key = ThreadKey(thread_id); - uint32_t thread_hash = ThreadHash(thread_id); - base::HashMap::Entry* entry = sampler_map_.Lookup(thread_key, thread_hash); - DCHECK_NOT_NULL(entry); - SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); - for (SamplerListIterator iter = samplers->begin(); iter != samplers->end(); - ++iter) { - if (*iter == sampler) { - samplers->erase(iter); - break; - } - } - if (samplers->empty()) { - sampler_map_.Remove(thread_key, thread_hash); - delete samplers; - } +void SamplerManager::RemoveSampler(Sampler* sampler) { + AtomicGuard atomic_guard(&samplers_access_counter_); + DCHECK(sampler->IsActive()); + pthread_t thread_id = sampler->platform_data()->vm_tid(); + auto it = sampler_map_.find(thread_id); + DCHECK_NE(it, sampler_map_.end()); + SamplerList& samplers = it->second; + samplers.erase(std::remove(samplers.begin(), samplers.end(), sampler), + samplers.end()); + if (samplers.empty()) { + sampler_map_.erase(it); } +} -#if defined(USE_SIGNALS) - void DoSample(const v8::RegisterState& state) { - AtomicGuard atomic_guard(&SamplerManager::samplers_access_counter_, false); - if (!atomic_guard.is_success()) return; - pthread_t thread_id = pthread_self(); - base::HashMap::Entry* entry = - sampler_map_.Lookup(ThreadKey(thread_id), ThreadHash(thread_id)); - if (!entry) return; - SamplerList& samplers = *static_cast<SamplerList*>(entry->value); - - for (size_t i = 0; i < samplers.size(); ++i) { - Sampler* sampler = samplers[i]; - Isolate* isolate = sampler->isolate(); - // We require a fully initialized and entered isolate. - if (isolate == nullptr || !isolate->IsInUse()) continue; - if (v8::Locker::IsActive() && !Locker::IsLocked(isolate)) continue; - sampler->SampleStack(state); - } +void SamplerManager::DoSample(const v8::RegisterState& state) { + AtomicGuard atomic_guard(&samplers_access_counter_, false); + if (!atomic_guard.is_success()) return; + pthread_t thread_id = pthread_self(); + auto it = sampler_map_.find(thread_id); + if (it == sampler_map_.end()) return; + SamplerList& samplers = it->second; + + for (Sampler* sampler : samplers) { + Isolate* isolate = sampler->isolate(); + // We require a fully initialized and entered isolate. + if (isolate == nullptr || !isolate->IsInUse()) continue; + if (v8::Locker::IsActive() && !Locker::IsLocked(isolate)) continue; + sampler->SampleStack(state); } -#endif - - static SamplerManager* instance() { return instance_.Pointer(); } - - private: - base::HashMap sampler_map_; - static AtomicMutex samplers_access_counter_; - static base::LazyInstance<SamplerManager>::type instance_; -}; +} -AtomicMutex SamplerManager::samplers_access_counter_; -base::LazyInstance<SamplerManager>::type SamplerManager::instance_ = - LAZY_INSTANCE_INITIALIZER; +SamplerManager* SamplerManager::instance() { + static base::LeakyObject<SamplerManager> instance; + return instance.get(); +} #elif V8_OS_WIN || V8_OS_CYGWIN @@ -378,24 +307,18 @@ class Sampler::PlatformData { #if defined(USE_SIGNALS) class SignalHandler { public: - static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); } - static void TearDown() { - delete mutex_; - mutex_ = nullptr; - } - static void IncreaseSamplerCount() { - base::LockGuard<base::Mutex> lock_guard(mutex_); + base::MutexGuard lock_guard(mutex_.Pointer()); if (++client_count_ == 1) Install(); } static void DecreaseSamplerCount() { - base::LockGuard<base::Mutex> lock_guard(mutex_); + base::MutexGuard lock_guard(mutex_.Pointer()); if (--client_count_ == 0) Restore(); } static bool Installed() { - base::LockGuard<base::Mutex> lock_guard(mutex_); + base::MutexGuard lock_guard(mutex_.Pointer()); return signal_handler_installed_; } @@ -424,13 +347,13 @@ class SignalHandler { static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); // Protects the process wide state below. - static base::Mutex* mutex_; + static base::LazyMutex mutex_; static int client_count_; static bool signal_handler_installed_; static struct sigaction old_signal_handler_; }; -base::Mutex* SignalHandler::mutex_ = nullptr; +base::LazyMutex SignalHandler::mutex_ = LAZY_MUTEX_INITIALIZER; int SignalHandler::client_count_ = 0; struct sigaction SignalHandler::old_signal_handler_; bool SignalHandler::signal_handler_installed_ = false; @@ -589,85 +512,36 @@ void SignalHandler::FillRegisterState(void* context, RegisterState* state) { #endif // USE_SIGNALS - -void Sampler::SetUp() { -#if defined(USE_SIGNALS) - SignalHandler::SetUp(); -#endif -} - - -void Sampler::TearDown() { -#if defined(USE_SIGNALS) - SignalHandler::TearDown(); -#endif -} - Sampler::Sampler(Isolate* isolate) - : is_counting_samples_(false), - js_sample_count_(0), - external_sample_count_(0), - isolate_(isolate), - profiling_(false), - has_processing_thread_(false), - active_(false), - registered_(false) { - data_ = new PlatformData; -} + : isolate_(isolate), data_(base::make_unique<PlatformData>()) {} Sampler::~Sampler() { DCHECK(!IsActive()); -#if defined(USE_SIGNALS) - if (IsRegistered()) { - SamplerManager::instance()->RemoveSampler(this); - } -#endif - delete data_; } void Sampler::Start() { DCHECK(!IsActive()); SetActive(true); #if defined(USE_SIGNALS) + SignalHandler::IncreaseSamplerCount(); SamplerManager::instance()->AddSampler(this); #endif } - void Sampler::Stop() { #if defined(USE_SIGNALS) SamplerManager::instance()->RemoveSampler(this); + SignalHandler::DecreaseSamplerCount(); #endif DCHECK(IsActive()); SetActive(false); - SetRegistered(false); } - -void Sampler::IncreaseProfilingDepth() { - base::Relaxed_AtomicIncrement(&profiling_, 1); -#if defined(USE_SIGNALS) - SignalHandler::IncreaseSamplerCount(); -#endif -} - - -void Sampler::DecreaseProfilingDepth() { -#if defined(USE_SIGNALS) - SignalHandler::DecreaseSamplerCount(); -#endif - base::Relaxed_AtomicIncrement(&profiling_, -1); -} - - #if defined(USE_SIGNALS) void Sampler::DoSample() { if (!SignalHandler::Installed()) return; - if (!IsActive() && !IsRegistered()) { - SamplerManager::instance()->AddSampler(this); - SetRegistered(true); - } + DCHECK(IsActive()); pthread_kill(platform_data()->vm_tid(), SIGPROF); } @@ -690,6 +564,10 @@ void Sampler::DoSample() { state.pc = reinterpret_cast<void*>(context.Rip); state.sp = reinterpret_cast<void*>(context.Rsp); state.fp = reinterpret_cast<void*>(context.Rbp); +#elif V8_HOST_ARCH_ARM64 + state.pc = reinterpret_cast<void*>(context.Pc); + state.sp = reinterpret_cast<void*>(context.Sp); + state.fp = reinterpret_cast<void*>(context.Fp); #else state.pc = reinterpret_cast<void*>(context.Eip); state.sp = reinterpret_cast<void*>(context.Esp); |