113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Copyright 2016 the V8 project authors. All rights reserved. 213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Use of this source code is governed by a BSD-style license that can be 313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// found in the LICENSE file. 413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/libsampler/sampler.h" 613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_OS_POSIX && !V8_OS_CYGWIN 813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define USE_SIGNALS 1013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 1113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <errno.h> 1213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <pthread.h> 1313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <signal.h> 1413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <sys/time.h> 1513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#if !V8_OS_QNX && !V8_OS_AIX 1713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <sys/syscall.h> // NOLINT 1813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 1913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_OS_MACOSX 2113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <mach/mach.h> 2213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h> 2313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// and is a typedef for struct sigcontext. There is no uc_mcontext. 24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) && !V8_OS_OPENBSD 2513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <ucontext.h> 2613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 2713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <unistd.h> 2913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 3013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'. 3113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Old versions of the C library <signal.h> didn't define the type. 3213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ 3313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch (defined(__arm__) || defined(__aarch64__)) && \ 3413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) 3513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <asm/sigcontext.h> // NOLINT 3613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 3713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 3813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_WIN || V8_OS_CYGWIN 3913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 4013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/base/win32-headers.h" 4113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 4213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 4313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 4413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <algorithm> 4513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <vector> 4613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include <map> 4713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 4813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/base/atomic-utils.h" 4913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/base/hashmap.h" 5013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/base/platform/platform.h" 5113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 5213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) 5313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Not all versions of Android's C library provide ucontext_t. 5513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Detect this and provide custom but compatible definitions. Note that these 5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// follow the GLibc naming convention to access register values from 5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// mcontext_t. 5813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// 5913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// See http://code.google.com/p/android/issues/detail?id=34784 6013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 6113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(__arm__) 6213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 6313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct sigcontext mcontext_t; 6413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 6513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct ucontext { 6613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t uc_flags; 6713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct ucontext* uc_link; 6813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stack_t uc_stack; 6913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch mcontext_t uc_mcontext; 7013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Other fields are not used by V8, don't define them here. 7113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} ucontext_t; 7213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 7313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif defined(__aarch64__) 7413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 7513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct sigcontext mcontext_t; 7613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 7713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct ucontext { 7813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t uc_flags; 7913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct ucontext *uc_link; 8013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stack_t uc_stack; 8113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch mcontext_t uc_mcontext; 8213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Other fields are not used by V8, don't define them here. 8313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} ucontext_t; 8413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 8513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif defined(__mips__) 8613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// MIPS version of sigcontext, for Android bionic. 8713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct { 8813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t regmask; 8913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t status; 9013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t pc; 9113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t gregs[32]; 9213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t fpregs[32]; 9313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t acx; 9413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t fpc_csr; 9513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t fpc_eir; 9613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t used_math; 9713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t dsp; 9813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t mdhi; 9913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t mdlo; 10013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t hi1; 10113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t lo1; 10213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t hi2; 10313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t lo2; 10413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t hi3; 10513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t lo3; 10613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} mcontext_t; 10713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 10813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct ucontext { 10913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t uc_flags; 11013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct ucontext* uc_link; 11113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stack_t uc_stack; 11213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch mcontext_t uc_mcontext; 11313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Other fields are not used by V8, don't define them here. 11413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} ucontext_t; 11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif defined(__i386__) 11713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// x86 version for Android. 11813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct { 11913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t gregs[19]; 12013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void* fpregs; 12113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t oldmask; 12213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t cr2; 12313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} mcontext_t; 12413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 12513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef uint32_t kernel_sigset_t[2]; // x86 kernel uses 64-bit signal masks 12613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct ucontext { 12713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t uc_flags; 12813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct ucontext* uc_link; 12913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stack_t uc_stack; 13013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch mcontext_t uc_mcontext; 13113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Other fields are not used by V8, don't define them here. 13213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} ucontext_t; 13313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochenum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 }; 13413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif defined(__x86_64__) 13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// x64 version for Android. 13713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct { 13813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t gregs[23]; 13913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void* fpregs; 14013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t __reserved1[8]; 14113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} mcontext_t; 14213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 14313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef struct ucontext { 14413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint64_t uc_flags; 14513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct ucontext *uc_link; 14613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stack_t uc_stack; 14713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch mcontext_t uc_mcontext; 14813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Other fields are not used by V8, don't define them here. 14913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} ucontext_t; 15013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochenum { REG_RBP = 10, REG_RSP = 15, REG_RIP = 16 }; 15113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 15213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 15313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) 15413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 15513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 15613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochnamespace v8 { 15713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochnamespace sampler { 15813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 15913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochnamespace { 16013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 16113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 16213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef std::vector<Sampler*> SamplerList; 16313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef SamplerList::iterator SamplerListIterator; 16413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtypedef base::AtomicValue<bool> AtomicMutex; 16513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass AtomicGuard { 16713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch public: 16813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch explicit AtomicGuard(AtomicMutex* atomic, bool is_blocking = true) 16913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch : atomic_(atomic), is_success_(false) { 17013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch do { 17113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Use Acquire_Load to gain mutual exclusion. 17213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch USE(atomic_->Value()); 17313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch is_success_ = atomic_->TrySetValue(false, true); 17413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } while (is_blocking && !is_success_); 17513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 17613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 17713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool is_success() const { return is_success_; } 17813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 17913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ~AtomicGuard() { 18013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!is_success_) return; 18113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch atomic_->SetValue(false); 18213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 18313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 18413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch private: 18513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AtomicMutex* const atomic_; 18613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool is_success_; 18713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}; 18813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 18913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Returns key for hash map. 19013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid* ThreadKey(pthread_t thread_id) { 19113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return reinterpret_cast<void*>(thread_id); 19213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 19313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 19413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Returns hash value for hash map. 19513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochuint32_t ThreadHash(pthread_t thread_id) { 196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#if V8_OS_BSD 19713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return static_cast<uint32_t>(reinterpret_cast<intptr_t>(thread_id)); 19813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#else 19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return static_cast<uint32_t>(thread_id); 20013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 20113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 20213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 20313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // USE_SIGNALS 20413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} // namespace 20613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 20713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 20813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 20913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass Sampler::PlatformData { 21013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch public: 21113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PlatformData() : vm_tid_(pthread_self()) {} 21213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch pthread_t vm_tid() const { return vm_tid_; } 21313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 21413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch private: 21513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch pthread_t vm_tid_; 21613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}; 21713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 21813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass SamplerManager { 21913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch public: 220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch SamplerManager() : sampler_map_() {} 22113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 22213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void AddSampler(Sampler* sampler) { 22313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AtomicGuard atomic_guard(&samplers_access_counter_); 22413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(sampler->IsActive() || !sampler->IsRegistered()); 22513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Add sampler into map if needed. 22613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch pthread_t thread_id = sampler->platform_data()->vm_tid(); 22713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap::Entry* entry = 22813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sampler_map_.LookupOrInsert(ThreadKey(thread_id), 22913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ThreadHash(thread_id)); 23013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(entry != nullptr); 23113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (entry->value == nullptr) { 23213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerList* samplers = new SamplerList(); 23313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch samplers->push_back(sampler); 23413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch entry->value = samplers; 23513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 23613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); 23713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool exists = false; 23813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (SamplerListIterator iter = samplers->begin(); 23913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch iter != samplers->end(); ++iter) { 24013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (*iter == sampler) { 24113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch exists = true; 24213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 24313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 24413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 24513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!exists) { 24613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch samplers->push_back(sampler); 24713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 24813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 24913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 25013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 25113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void RemoveSampler(Sampler* sampler) { 25213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AtomicGuard atomic_guard(&samplers_access_counter_); 25313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(sampler->IsActive() || sampler->IsRegistered()); 25413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Remove sampler from map. 25513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch pthread_t thread_id = sampler->platform_data()->vm_tid(); 25613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void* thread_key = ThreadKey(thread_id); 25713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t thread_hash = ThreadHash(thread_id); 25813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap::Entry* entry = sampler_map_.Lookup(thread_key, thread_hash); 25913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(entry != nullptr); 26013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerList* samplers = reinterpret_cast<SamplerList*>(entry->value); 26113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (SamplerListIterator iter = samplers->begin(); iter != samplers->end(); 26213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ++iter) { 26313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (*iter == sampler) { 26413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch samplers->erase(iter); 26513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 26613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 26713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 26813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (samplers->empty()) { 26913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sampler_map_.Remove(thread_key, thread_hash); 27013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch delete samplers; 27113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 27213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 27313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 27413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 27513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void DoSample(const v8::RegisterState& state) { 27613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AtomicGuard atomic_guard(&SamplerManager::samplers_access_counter_, false); 27713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!atomic_guard.is_success()) return; 27813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch pthread_t thread_id = pthread_self(); 27913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap::Entry* entry = 28013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sampler_map_.Lookup(ThreadKey(thread_id), ThreadHash(thread_id)); 28113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!entry) return; 28213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerList& samplers = *static_cast<SamplerList*>(entry->value); 28313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 284c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (size_t i = 0; i < samplers.size(); ++i) { 28513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Sampler* sampler = samplers[i]; 28613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Isolate* isolate = sampler->isolate(); 28713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // We require a fully initialized and entered isolate. 28813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (isolate == nullptr || !isolate->IsInUse()) continue; 28913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (v8::Locker::IsActive() && !Locker::IsLocked(isolate)) continue; 29013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sampler->SampleStack(state); 29113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 29213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 29313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 29413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static SamplerManager* instance() { return instance_.Pointer(); } 29613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 29713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch private: 29813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap sampler_map_; 29913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static AtomicMutex samplers_access_counter_; 30013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static base::LazyInstance<SamplerManager>::type instance_; 30113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}; 30213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 30313e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochAtomicMutex SamplerManager::samplers_access_counter_; 30413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbase::LazyInstance<SamplerManager>::type SamplerManager::instance_ = 30513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch LAZY_INSTANCE_INITIALIZER; 30613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 30713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_WIN || V8_OS_CYGWIN 30813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 30913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// ---------------------------------------------------------------------------- 31013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// Win32 profiler support. On Cygwin we use the same sampler implementation as 31113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// on Win32. 31213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 31313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass Sampler::PlatformData { 31413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch public: 31513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Get a handle to the calling thread. This is the thread that we are 31613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // going to profile. We need to make a copy of the handle because we are 31713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // going to use it in the sampler thread. Using GetThreadHandle() will 31813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // not work in this case. We're using OpenThread because DuplicateHandle 31913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // for some reason doesn't work in Chrome's sandbox. 32013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PlatformData() 32113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch : profiled_thread_(OpenThread(THREAD_GET_CONTEXT | 32213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch THREAD_SUSPEND_RESUME | 32313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch THREAD_QUERY_INFORMATION, 32413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch false, 32513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GetCurrentThreadId())) {} 32613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 32713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ~PlatformData() { 32813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (profiled_thread_ != nullptr) { 32913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CloseHandle(profiled_thread_); 33013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch profiled_thread_ = nullptr; 33113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 33213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 33313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 33413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HANDLE profiled_thread() { return profiled_thread_; } 33513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 33613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch private: 33713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HANDLE profiled_thread_; 33813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}; 33913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // USE_SIGNALS 34013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 34113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 34213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 34313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass SignalHandler { 34413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch public: 34513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); } 34613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static void TearDown() { 34713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch delete mutex_; 34813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch mutex_ = nullptr; 34913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 35013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 35113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static void IncreaseSamplerCount() { 35213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::LockGuard<base::Mutex> lock_guard(mutex_); 35313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (++client_count_ == 1) Install(); 35413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 35513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 35613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static void DecreaseSamplerCount() { 35713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::LockGuard<base::Mutex> lock_guard(mutex_); 35813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (--client_count_ == 0) Restore(); 35913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 36013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 36113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static bool Installed() { 36213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::LockGuard<base::Mutex> lock_guard(mutex_); 36313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return signal_handler_installed_; 36413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 36513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 36613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch private: 36713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static void Install() { 36813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct sigaction sa; 36913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sa.sa_sigaction = &HandleProfilerSignal; 37013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sigemptyset(&sa.sa_mask); 37113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_OS_QNX 37213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sa.sa_flags = SA_SIGINFO; 37313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#else 37413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sa.sa_flags = SA_RESTART | SA_SIGINFO; 37513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 37613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch signal_handler_installed_ = 37713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); 37813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 37913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 38013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static void Restore() { 38113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (signal_handler_installed_) { 38213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch sigaction(SIGPROF, &old_signal_handler_, 0); 38313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch signal_handler_installed_ = false; 38413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 38713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static void FillRegisterState(void* context, RegisterState* regs); 38813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); 389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 39013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Protects the process wide state below. 39113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static base::Mutex* mutex_; 39213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static int client_count_; 39313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static bool signal_handler_installed_; 39413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static struct sigaction old_signal_handler_; 39513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}; 39613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 39713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbase::Mutex* SignalHandler::mutex_ = nullptr; 39813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochint SignalHandler::client_count_ = 0; 39913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstruct sigaction SignalHandler::old_signal_handler_; 40013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbool SignalHandler::signal_handler_installed_ = false; 40113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 40213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 40313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, 40413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void* context) { 40513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch USE(info); 40613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (signal != SIGPROF) return; 40713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch v8::RegisterState state; 40813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FillRegisterState(context, &state); 40913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerManager::instance()->DoSample(state); 41013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 41113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 41213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid SignalHandler::FillRegisterState(void* context, RegisterState* state) { 41313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Extracting the sample from the context is extremely machine dependent. 41413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 41513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if !(V8_OS_OPENBSD || (V8_OS_LINUX && (V8_HOST_ARCH_PPC || V8_HOST_ARCH_S390))) 41613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch mcontext_t& mcontext = ucontext->uc_mcontext; 41713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 41813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_OS_LINUX 41913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_HOST_ARCH_IA32 42013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.gregs[REG_EIP]); 42113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.gregs[REG_ESP]); 42213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.gregs[REG_EBP]); 42313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_X64 42413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.gregs[REG_RIP]); 42513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.gregs[REG_RSP]); 42613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.gregs[REG_RBP]); 42713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_ARM 42813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_LIBC_GLIBC && !V8_GLIBC_PREREQ(2, 4) 42913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Old GLibc ARM versions used a gregs[] array to access the register 43013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // values from mcontext_t. 43113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.gregs[R15]); 43213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.gregs[R13]); 43313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.gregs[R11]); 43413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#else 43513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.arm_pc); 43613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.arm_sp); 43713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.arm_fp); 43813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_LIBC_GLIBC && !V8_GLIBC_PREREQ(2, 4) 43913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_ARM64 44013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.pc); 44113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.sp); 44213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // FP is an alias for x29. 44313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.regs[29]); 44413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_MIPS 44513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.pc); 44613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.gregs[29]); 44713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.gregs[30]); 44813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_MIPS64 44913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.pc); 45013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.gregs[29]); 45113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.gregs[30]); 45213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_PPC 45313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(ucontext->uc_mcontext.regs->nip); 45413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = 45513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch reinterpret_cast<void*>(ucontext->uc_mcontext.regs->gpr[PT_R1]); 45613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = 45713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch reinterpret_cast<void*>(ucontext->uc_mcontext.regs->gpr[PT_R31]); 45813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_S390 45913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_TARGET_ARCH_32_BIT 46013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // 31-bit target will have bit 0 (MSB) of the PSW set to denote addressing 46113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // mode. This bit needs to be masked out to resolve actual address. 46213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = 46313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch reinterpret_cast<void*>(ucontext->uc_mcontext.psw.addr & 0x7FFFFFFF); 46413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#else 46513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(ucontext->uc_mcontext.psw.addr); 46613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_TARGET_ARCH_32_BIT 46713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(ucontext->uc_mcontext.gregs[15]); 46813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(ucontext->uc_mcontext.gregs[11]); 46913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_HOST_ARCH_* 47013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_MACOSX 47113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_HOST_ARCH_X64 47213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if __DARWIN_UNIX03 47313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext->__ss.__rip); 47413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext->__ss.__rsp); 47513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext->__ss.__rbp); 47613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#else // !__DARWIN_UNIX03 47713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext->ss.rip); 47813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext->ss.rsp); 47913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext->ss.rbp); 48013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // __DARWIN_UNIX03 48113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_IA32 48213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if __DARWIN_UNIX03 48313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext->__ss.__eip); 48413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext->__ss.__esp); 48513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext->__ss.__ebp); 48613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#else // !__DARWIN_UNIX03 48713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext->ss.eip); 48813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext->ss.esp); 48913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext->ss.ebp); 49013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // __DARWIN_UNIX03 49113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_HOST_ARCH_IA32 49213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_FREEBSD 49313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_HOST_ARCH_IA32 49413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.mc_eip); 49513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.mc_esp); 49613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.mc_ebp); 49713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_X64 49813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.mc_rip); 49913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.mc_rsp); 50013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.mc_rbp); 50113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_ARM 50213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.mc_r15); 50313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.mc_r13); 50413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.mc_r11); 50513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_HOST_ARCH_* 50613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_NETBSD 50713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_HOST_ARCH_IA32 50813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.__gregs[_REG_EIP]); 50913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.__gregs[_REG_ESP]); 51013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.__gregs[_REG_EBP]); 51113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_X64 51213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.__gregs[_REG_RIP]); 51313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.__gregs[_REG_RSP]); 51413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.__gregs[_REG_RBP]); 51513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_HOST_ARCH_* 51613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_OPENBSD 51713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_HOST_ARCH_IA32 51813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(ucontext->sc_eip); 51913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(ucontext->sc_esp); 52013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(ucontext->sc_ebp); 52113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_X64 52213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(ucontext->sc_rip); 52313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(ucontext->sc_rsp); 52413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(ucontext->sc_rbp); 52513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_HOST_ARCH_* 52613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_SOLARIS 52713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.gregs[REG_PC]); 52813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.gregs[REG_SP]); 52913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.gregs[REG_FP]); 53013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_QNX 53113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_HOST_ARCH_IA32 53213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.cpu.eip); 53313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.cpu.esp); 53413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.cpu.ebp); 53513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_HOST_ARCH_ARM 53613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.cpu.gpr[ARM_REG_PC]); 53713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.cpu.gpr[ARM_REG_SP]); 53813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.cpu.gpr[ARM_REG_FP]); 53913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_HOST_ARCH_* 54013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_AIX 54113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->pc = reinterpret_cast<void*>(mcontext.jmp_context.iar); 54213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->sp = reinterpret_cast<void*>(mcontext.jmp_context.gpr[1]); 54313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state->fp = reinterpret_cast<void*>(mcontext.jmp_context.gpr[31]); 54413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // V8_OS_AIX 54513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 54613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 54713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // USE_SIGNALS 54813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 54913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 55013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Sampler::SetUp() { 55113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 55213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SignalHandler::SetUp(); 55313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 55413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 55513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 55613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 55713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Sampler::TearDown() { 55813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 55913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SignalHandler::TearDown(); 56013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 56113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 56213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 56313e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochSampler::Sampler(Isolate* isolate) 56413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch : is_counting_samples_(false), 56513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch js_sample_count_(0), 56613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch external_sample_count_(0), 56713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch isolate_(isolate), 56813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch profiling_(false), 56913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch has_processing_thread_(false), 57013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch active_(false), 57113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch registered_(false) { 57213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch data_ = new PlatformData; 57313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 57413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 57513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochSampler::~Sampler() { 57613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!IsActive()); 57713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 57813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (IsRegistered()) { 57913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerManager::instance()->RemoveSampler(this); 58013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 58113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 58213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch delete data_; 58313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 58413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 58513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Sampler::Start() { 58613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!IsActive()); 58713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SetActive(true); 58813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 58913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerManager::instance()->AddSampler(this); 59013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 59113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 59213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 59313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 59413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Sampler::Stop() { 59513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 59613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerManager::instance()->RemoveSampler(this); 59713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 59813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(IsActive()); 59913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SetActive(false); 60013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SetRegistered(false); 60113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 60213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 60313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 60413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Sampler::IncreaseProfilingDepth() { 60513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::NoBarrier_AtomicIncrement(&profiling_, 1); 60613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 60713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SignalHandler::IncreaseSamplerCount(); 60813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 60913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 61013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 61113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 61213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Sampler::DecreaseProfilingDepth() { 61313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 61413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SignalHandler::DecreaseSamplerCount(); 61513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 61613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::NoBarrier_AtomicIncrement(&profiling_, -1); 61713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 61813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 61913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 62013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if defined(USE_SIGNALS) 62113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 62213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Sampler::DoSample() { 62313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!SignalHandler::Installed()) return; 62413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!IsActive() && !IsRegistered()) { 62513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SamplerManager::instance()->AddSampler(this); 62613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SetRegistered(true); 62713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 62813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch pthread_kill(platform_data()->vm_tid(), SIGPROF); 62913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 63013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 63113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#elif V8_OS_WIN || V8_OS_CYGWIN 63213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 63313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Sampler::DoSample() { 63413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HANDLE profiled_thread = platform_data()->profiled_thread(); 63513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (profiled_thread == nullptr) return; 63613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 63713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const DWORD kSuspendFailed = static_cast<DWORD>(-1); 63813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (SuspendThread(profiled_thread) == kSuspendFailed) return; 63913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 64013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Context used for sampling the register state of the profiled thread. 64113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CONTEXT context; 64213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch memset(&context, 0, sizeof(context)); 64313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch context.ContextFlags = CONTEXT_FULL; 64413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (GetThreadContext(profiled_thread, &context) != 0) { 64513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch v8::RegisterState state; 64613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#if V8_HOST_ARCH_X64 64713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state.pc = reinterpret_cast<void*>(context.Rip); 64813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state.sp = reinterpret_cast<void*>(context.Rsp); 64913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state.fp = reinterpret_cast<void*>(context.Rbp); 65013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#else 65113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state.pc = reinterpret_cast<void*>(context.Eip); 65213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state.sp = reinterpret_cast<void*>(context.Esp); 65313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch state.fp = reinterpret_cast<void*>(context.Ebp); 65413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif 65513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SampleStack(state); 65613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 65713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ResumeThread(profiled_thread); 65813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 65913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 66013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif // USE_SIGNALS 66113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 66213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} // namespace sampler 66313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} // namespace v8 664