1e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 2e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Redistribution and use in source and binary forms, with or without 3e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// modification, are permitted provided that the following conditions are 4e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// met: 5e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 6e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// * Redistributions of source code must retain the above copyright 7e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// notice, this list of conditions and the following disclaimer. 8e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// * Redistributions in binary form must reproduce the above 9e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// copyright notice, this list of conditions and the following 10e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// disclaimer in the documentation and/or other materials provided 11e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// with the distribution. 12e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// * Neither the name of Google Inc. nor the names of its 13e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// contributors may be used to endorse or promote products derived 14e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// from this software without specific prior written permission. 15e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 16e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 28c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "sampler.h" 29c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 30dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if V8_OS_POSIX && !V8_OS_CYGWIN 31e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 32e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#define USE_SIGNALS 33e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 34e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include <errno.h> 35e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include <pthread.h> 36e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include <signal.h> 37e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include <sys/time.h> 38e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include <sys/syscall.h> 391e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 40dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if V8_OS_MACOSX 411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include <mach/mach.h> 42594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org// OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h> 43594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org// and is a typedef for struct sigcontext. There is no uc_mcontext. 44dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) \ 45dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org && !V8_OS_OPENBSD 46e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include <ucontext.h> 47e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif 48e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include <unistd.h> 49e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 50e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'. 51e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Old versions of the C library <signal.h> didn't define the type. 52dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ 53e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org defined(__arm__) && !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) 54e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include <asm/sigcontext.h> 55e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif 56e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 57dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif V8_OS_WIN || V8_OS_CYGWIN 58e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 59e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "win32-headers.h" 60e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 61e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif 62e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 63e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "v8.h" 64e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 659259716434187c932704601f700375e53d865de8rossberg@chromium.org#include "cpu-profiler-inl.h" 66c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "flags.h" 67e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "frames-inl.h" 68e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "log.h" 69e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "platform.h" 70e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "simulator.h" 71e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "v8threads.h" 72c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#include "vm-state-inl.h" 73e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 74e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 75dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) 76e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 77e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Not all versions of Android's C library provide ucontext_t. 78e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Detect this and provide custom but compatible definitions. Note that these 79e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// follow the GLibc naming convention to access register values from 80e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// mcontext_t. 81e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 82e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// See http://code.google.com/p/android/issues/detail?id=34784 83e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 84e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if defined(__arm__) 85e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 86e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtypedef struct sigcontext mcontext_t; 87e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 88e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtypedef struct ucontext { 89e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t uc_flags; 90e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct ucontext* uc_link; 91e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org stack_t uc_stack; 92e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mcontext_t uc_mcontext; 93e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Other fields are not used by V8, don't define them here. 94e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} ucontext_t; 95e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 96e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif defined(__mips__) 97e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// MIPS version of sigcontext, for Android bionic. 98e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtypedef struct { 99e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t regmask; 100e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t status; 101e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint64_t pc; 102e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint64_t gregs[32]; 103e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint64_t fpregs[32]; 104e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t acx; 105e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t fpc_csr; 106e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t fpc_eir; 107e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t used_math; 108e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t dsp; 109e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint64_t mdhi; 110e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint64_t mdlo; 111e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t hi1; 112e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t lo1; 113e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t hi2; 114e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t lo2; 115e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t hi3; 116e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t lo3; 117e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} mcontext_t; 118e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 119e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtypedef struct ucontext { 120e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t uc_flags; 121e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct ucontext* uc_link; 122e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org stack_t uc_stack; 123e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mcontext_t uc_mcontext; 124e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Other fields are not used by V8, don't define them here. 125e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} ucontext_t; 126e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 127e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif defined(__i386__) 128e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// x86 version for Android. 129e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtypedef struct { 130e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t gregs[19]; 131e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void* fpregs; 132e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t oldmask; 133e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t cr2; 134e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} mcontext_t; 135e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 136e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtypedef uint32_t kernel_sigset_t[2]; // x86 kernel uses 64-bit signal masks 137e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgtypedef struct ucontext { 138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org uint32_t uc_flags; 139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct ucontext* uc_link; 140e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org stack_t uc_stack; 141e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mcontext_t uc_mcontext; 142e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Other fields are not used by V8, don't define them here. 143e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} ucontext_t; 144e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgenum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 }; 145e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif 146e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 147dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif // V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) 148e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 149e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgnamespace v8 { 151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgnamespace internal { 152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 15379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.orgnamespace { 154e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 15579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.orgclass PlatformDataCommon : public Malloced { 156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org public: 15779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org PlatformDataCommon() : profiled_thread_id_(ThreadId::Current()) {} 15879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org ThreadId profiled_thread_id() { return profiled_thread_id_; } 15979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 16079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org protected: 16179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org ~PlatformDataCommon() {} 16279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 16379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org private: 16479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org ThreadId profiled_thread_id_; 16579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org}; 16679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 16779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org} // namespace 168e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 16979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#if defined(USE_SIGNALS) 17079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 17179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.orgclass Sampler::PlatformData : public PlatformDataCommon { 17279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org public: 17379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org PlatformData() : vm_tid_(pthread_self()) {} 174e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org pthread_t vm_tid() const { return vm_tid_; } 175e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 176e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org private: 177e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org pthread_t vm_tid_; 17879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org}; 17979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 180dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif V8_OS_WIN || V8_OS_CYGWIN 18179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 18279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org// ---------------------------------------------------------------------------- 18379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org// Win32 profiler support. On Cygwin we use the same sampler implementation as 18479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org// on Win32. 18579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 18679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.orgclass Sampler::PlatformData : public PlatformDataCommon { 18779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org public: 18879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org // Get a handle to the calling thread. This is the thread that we are 18979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org // going to profile. We need to make a copy of the handle because we are 19079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org // going to use it in the sampler thread. Using GetThreadHandle() will 19179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org // not work in this case. We're using OpenThread because DuplicateHandle 19279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org // for some reason doesn't work in Chrome's sandbox. 19379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org PlatformData() 19479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org : profiled_thread_(OpenThread(THREAD_GET_CONTEXT | 19579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org THREAD_SUSPEND_RESUME | 19679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org THREAD_QUERY_INFORMATION, 19779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org false, 19879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org GetCurrentThreadId())) {} 19979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 20079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org ~PlatformData() { 20179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org if (profiled_thread_ != NULL) { 20279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org CloseHandle(profiled_thread_); 20379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org profiled_thread_ = NULL; 20479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org } 20579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org } 20679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 20779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org HANDLE profiled_thread() { return profiled_thread_; } 20879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 20979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org private: 21079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org HANDLE profiled_thread_; 21179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org}; 21279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#endif 21379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 21479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 21579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#if defined(USE_SIMULATOR) 216c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgclass SimulatorHelper { 217c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org public: 218c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org inline bool Init(Sampler* sampler, Isolate* isolate) { 219fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org simulator_ = isolate->thread_local_top()->simulator_; 220c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // Check if there is active simulator. 221c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org return simulator_ != NULL; 22279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org } 22379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 224c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org inline void FillRegisters(RegisterState* state) { 225c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state->pc = reinterpret_cast<Address>(simulator_->get_pc()); 226c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state->sp = reinterpret_cast<Address>(simulator_->get_register( 22779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org Simulator::sp)); 22879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#if V8_TARGET_ARCH_ARM 229c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state->fp = reinterpret_cast<Address>(simulator_->get_register( 23079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org Simulator::r11)); 23179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#elif V8_TARGET_ARCH_MIPS 232c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state->fp = reinterpret_cast<Address>(simulator_->get_register( 23379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org Simulator::fp)); 23479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#endif 23579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org } 23679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 23779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org private: 23879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org Simulator* simulator_; 239e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}; 240c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#endif // USE_SIMULATOR 241e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 242e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 24379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org#if defined(USE_SIGNALS) 24479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org 245e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgclass SignalHandler : public AllStatic { 246e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org public: 247dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static void SetUp() { if (!mutex_) mutex_ = new Mutex(); } 248dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static void TearDown() { delete mutex_; } 249dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 250dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static void IncreaseSamplerCount() { 251dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(mutex_); 252dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (++client_count_ == 1) Install(); 253dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 254dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 255dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static void DecreaseSamplerCount() { 256dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(mutex_); 257dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (--client_count_ == 0) Restore(); 258dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 259dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 260dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static bool Installed() { 261dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org return signal_handler_installed_; 262dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 263dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 264dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org private: 265dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static void Install() { 266e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org struct sigaction sa; 267e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org sa.sa_sigaction = &HandleProfilerSignal; 268e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org sigemptyset(&sa.sa_mask); 269e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org sa.sa_flags = SA_RESTART | SA_SIGINFO; 270e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org signal_handler_installed_ = 271e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); 272e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 273e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 274dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static void Restore() { 275e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (signal_handler_installed_) { 276e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org sigaction(SIGPROF, &old_signal_handler_, 0); 277e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org signal_handler_installed_ = false; 278e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 279e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 280e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 281e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); 282dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org // Protects the process wide state below. 283dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static Mutex* mutex_; 284dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static int client_count_; 285e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static bool signal_handler_installed_; 286e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static struct sigaction old_signal_handler_; 287e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}; 288e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 289dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 290dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgMutex* SignalHandler::mutex_ = NULL; 291dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgint SignalHandler::client_count_ = 0; 292e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstruct sigaction SignalHandler::old_signal_handler_; 293e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool SignalHandler::signal_handler_installed_ = false; 294e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 295e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 296e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, 297e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void* context) { 298dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if V8_OS_NACL 299e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // As Native Client does not support signal handling, profiling 300e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // is disabled. 301e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return; 302e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#else 303e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org USE(info); 304e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (signal != SIGPROF) return; 305e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Isolate* isolate = Isolate::UncheckedCurrent(); 306e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { 307e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // We require a fully initialized and entered isolate. 308e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return; 309e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 310e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (v8::Locker::IsActive() && 311e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org !isolate->thread_manager()->IsLockedByCurrentThread()) { 312e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return; 313e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 314e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 315e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Sampler* sampler = isolate->logger()->sampler(); 316dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (sampler == NULL) return; 317e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 318c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org RegisterState state; 319e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 320e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if defined(USE_SIMULATOR) 321c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org SimulatorHelper helper; 322c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (!helper.Init(sampler, isolate)) return; 323c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org helper.FillRegisters(&state); 324e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#else 325e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Extracting the sample from the context is extremely machine dependent. 326e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 327dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if !V8_OS_OPENBSD 328e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org mcontext_t& mcontext = ucontext->uc_mcontext; 329594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org#endif 330dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if V8_OS_LINUX 331e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if V8_HOST_ARCH_IA32 332c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); 333c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); 334c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); 335e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif V8_HOST_ARCH_X64 336c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]); 337c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]); 338c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]); 339e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif V8_HOST_ARCH_ARM 340e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if defined(__GLIBC__) && !defined(__UCLIBC__) && \ 341e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) 342e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Old GLibc ARM versions used a gregs[] array to access the register 343e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // values from mcontext_t. 344c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.gregs[R15]); 345c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.gregs[R13]); 346c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.gregs[R11]); 347e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#else 348c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.arm_pc); 349c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.arm_sp); 350c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.arm_fp); 351e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif // defined(__GLIBC__) && !defined(__UCLIBC__) && 352e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) 353e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif V8_HOST_ARCH_MIPS 354c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.pc); 355c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.gregs[29]); 356c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.gregs[30]); 357e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif // V8_HOST_ARCH_* 358dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif V8_OS_MACOSX 3591e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if V8_HOST_ARCH_X64 3601e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if __DARWIN_UNIX03 3611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.pc = reinterpret_cast<Address>(mcontext->__ss.__rip); 3621e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.sp = reinterpret_cast<Address>(mcontext->__ss.__rsp); 3631e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.fp = reinterpret_cast<Address>(mcontext->__ss.__rbp); 3641e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#else // !__DARWIN_UNIX03 3651e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.pc = reinterpret_cast<Address>(mcontext->ss.rip); 3661e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.sp = reinterpret_cast<Address>(mcontext->ss.rsp); 3671e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.fp = reinterpret_cast<Address>(mcontext->ss.rbp); 3681e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif // __DARWIN_UNIX03 3691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#elif V8_HOST_ARCH_IA32 3701e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if __DARWIN_UNIX03 3711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.pc = reinterpret_cast<Address>(mcontext->__ss.__eip); 3721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.sp = reinterpret_cast<Address>(mcontext->__ss.__esp); 3731e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.fp = reinterpret_cast<Address>(mcontext->__ss.__ebp); 3741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#else // !__DARWIN_UNIX03 3751e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.pc = reinterpret_cast<Address>(mcontext->ss.eip); 3761e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.sp = reinterpret_cast<Address>(mcontext->ss.esp); 3771e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.fp = reinterpret_cast<Address>(mcontext->ss.ebp); 3781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif // __DARWIN_UNIX03 3791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif // V8_HOST_ARCH_IA32 380dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif V8_OS_FREEBSD 381e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if V8_HOST_ARCH_IA32 382c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.mc_eip); 383c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.mc_esp); 384c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.mc_ebp); 385e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif V8_HOST_ARCH_X64 386c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.mc_rip); 387c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.mc_rsp); 388c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.mc_rbp); 389e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif V8_HOST_ARCH_ARM 390c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.mc_r15); 391c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.mc_r13); 392c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.mc_r11); 393e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif // V8_HOST_ARCH_* 394dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif V8_OS_NETBSD 395e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if V8_HOST_ARCH_IA32 396c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]); 397c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]); 398c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]); 399e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif V8_HOST_ARCH_X64 400c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]); 401c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]); 402c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]); 403e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif // V8_HOST_ARCH_* 404dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif V8_OS_OPENBSD 405e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if V8_HOST_ARCH_IA32 406c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(ucontext->sc_eip); 407c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(ucontext->sc_esp); 408c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(ucontext->sc_ebp); 409e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif V8_HOST_ARCH_X64 410c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(ucontext->sc_rip); 411c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(ucontext->sc_rsp); 412c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(ucontext->sc_rbp); 413e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif // V8_HOST_ARCH_* 414dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif V8_OS_SOLARIS 415c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]); 416c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]); 417c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]); 418dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif // V8_OS_SOLARIS 419e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif // USE_SIMULATOR 420c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org sampler->SampleStack(state); 421dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif // V8_OS_NACL 422e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 423e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 424e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif 425e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 426e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 427e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgclass SamplerThread : public Thread { 428e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org public: 429e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static const int kSamplerThreadStackSize = 64 * KB; 430e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 431e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org explicit SamplerThread(int interval) 432e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), 433e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org interval_(interval) {} 434e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 435dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static void SetUp() { if (!mutex_) mutex_ = new Mutex(); } 436dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org static void TearDown() { delete mutex_; mutex_ = NULL; } 437e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 438e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static void AddActiveSampler(Sampler* sampler) { 439e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool need_to_start = false; 440dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(mutex_); 441e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (instance_ == NULL) { 442e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Start a thread that will send SIGPROF signal to VM threads, 443e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // when CPU profiling will be enabled. 444e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instance_ = new SamplerThread(sampler->interval()); 445e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org need_to_start = true; 446e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 447e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 448e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(sampler->IsActive()); 449e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!instance_->active_samplers_.Contains(sampler)); 450e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(instance_->interval_ == sampler->interval()); 451e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instance_->active_samplers_.Add(sampler); 452e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 453e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (need_to_start) instance_->StartSynchronously(); 454e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 455e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 456e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static void RemoveActiveSampler(Sampler* sampler) { 457e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org SamplerThread* instance_to_remove = NULL; 458e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org { 459dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(mutex_); 460e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 461e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(sampler->IsActive()); 462e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool removed = instance_->active_samplers_.RemoveElement(sampler); 463e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(removed); 464e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org USE(removed); 465e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 466e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // We cannot delete the instance immediately as we need to Join() the 467e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // thread but we are holding mutex_ and the thread may try to acquire it. 468e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (instance_->active_samplers_.is_empty()) { 469e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instance_to_remove = instance_; 470e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instance_ = NULL; 471e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 473e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!instance_to_remove) return; 475e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org instance_to_remove->Join(); 476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org delete instance_to_remove; 477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Implement Thread::Run(). 480e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org virtual void Run() { 481e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org while (true) { 482e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org { 483dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(mutex_); 484e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (active_samplers_.is_empty()) break; 485e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // When CPU profiling is enabled both JavaScript and C++ code is 486e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // profiled. We must not suspend. 487e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org for (int i = 0; i < active_samplers_.length(); ++i) { 488e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Sampler* sampler = active_samplers_.at(i); 489e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!sampler->isolate()->IsInitialized()) continue; 490e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (!sampler->IsProfiling()) continue; 4911e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org sampler->DoSample(); 492e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 493e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::Sleep(interval_); 495e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 496e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 497e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 498e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org private: 499e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Protects the process wide state below. 500e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static Mutex* mutex_; 501e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org static SamplerThread* instance_; 502e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 503e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org const int interval_; 504e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org List<Sampler*> active_samplers_; 505e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 506e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DISALLOW_COPY_AND_ASSIGN(SamplerThread); 507e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}; 508e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 509e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 510e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgMutex* SamplerThread::mutex_ = NULL; 511e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgSamplerThread* SamplerThread::instance_ = NULL; 512e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 513e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 514e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 515e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// StackTracer implementation 516e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// 517c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgDISABLE_ASAN void TickSample::Init(Isolate* isolate, 518c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org const RegisterState& regs) { 519e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(isolate->IsInitialized()); 520c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org pc = regs.pc; 521c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org state = isolate->current_vm_state(); 522e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 523e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Avoid collecting traces while doing GC. 524e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (state == GC) return; 525e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 526594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Address js_entry_sp = isolate->js_entry_sp(); 527e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (js_entry_sp == 0) { 528e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Not executing JS now. 529e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return; 530e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 532c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org ExternalCallbackScope* scope = isolate->external_callback_scope(); 533c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org Address handler = Isolate::handler(isolate->thread_local_top()); 534c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // If there is a handler on top of the external callback scope then 535c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // we have already entrered JavaScript again and the external callback 536c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org // is not the top function. 537c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org if (scope && scope->scope_address() < handler) { 538c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org external_callback = scope->callback(); 53977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org has_external_callback = true; 54077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } else { 54177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // Sample potential return address value for frameless invocation of 54277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org // stubs (we'll figure out later, if this value makes sense). 543c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org tos = Memory::Address_at(regs.sp); 54477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org has_external_callback = false; 54577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org } 546e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 547c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp); 548c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org top_frame_type = it.top_frame_type(); 549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int i = 0; 550e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org while (!it.done() && i < TickSample::kMaxFramesCount) { 551e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org stack[i++] = it.frame()->pc(); 552e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org it.Advance(); 553e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 554e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org frames_count = i; 555e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 556e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 557e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 558e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Sampler::SetUp() { 559dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if defined(USE_SIGNALS) 560dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org SignalHandler::SetUp(); 561dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif 562e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org SamplerThread::SetUp(); 563e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 564e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 565e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 566e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Sampler::TearDown() { 567e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org SamplerThread::TearDown(); 568dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if defined(USE_SIGNALS) 569dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org SignalHandler::TearDown(); 570dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif 571e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 572e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 573e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 574e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgSampler::Sampler(Isolate* isolate, int interval) 575e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org : isolate_(isolate), 576e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org interval_(interval), 577e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org profiling_(false), 5781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org has_processing_thread_(false), 579e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org active_(false), 580bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org is_counting_samples_(false), 581bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org js_and_external_sample_count_(0) { 582e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org data_ = new PlatformData; 583e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 584e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 585e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 586e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgSampler::~Sampler() { 587e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!IsActive()); 588e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org delete data_; 589e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 590e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 591e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 592e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Sampler::Start() { 593e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(!IsActive()); 594e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org SetActive(true); 595e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org SamplerThread::AddActiveSampler(this); 596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 597e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid Sampler::Stop() { 600e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(IsActive()); 601e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org SamplerThread::RemoveActiveSampler(this); 602e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org SetActive(false); 603e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 604e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 605e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 606dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid Sampler::IncreaseProfilingDepth() { 607dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org NoBarrier_AtomicIncrement(&profiling_, 1); 608dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if defined(USE_SIGNALS) 609dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org SignalHandler::IncreaseSamplerCount(); 610dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif 611dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 612dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 613dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 614dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid Sampler::DecreaseProfilingDepth() { 615dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#if defined(USE_SIGNALS) 616dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org SignalHandler::DecreaseSamplerCount(); 617dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#endif 618dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org NoBarrier_AtomicIncrement(&profiling_, -1); 619dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 620dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 621dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 622c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid Sampler::SampleStack(const RegisterState& state) { 6239259716434187c932704601f700375e53d865de8rossberg@chromium.org TickSample* sample = isolate_->cpu_profiler()->StartTickSample(); 624c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org TickSample sample_obj; 625c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (sample == NULL) sample = &sample_obj; 626c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org sample->Init(isolate_, state); 627bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (is_counting_samples_) { 628bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (sample->state == JS || sample->state == EXTERNAL) { 629bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org ++js_and_external_sample_count_; 630bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 631bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 632c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Tick(sample); 6339259716434187c932704601f700375e53d865de8rossberg@chromium.org if (sample != &sample_obj) { 6349259716434187c932704601f700375e53d865de8rossberg@chromium.org isolate_->cpu_profiler()->FinishTickSample(); 6359259716434187c932704601f700375e53d865de8rossberg@chromium.org } 636e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 637e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 6381e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6391e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if defined(USE_SIGNALS) 6401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgvoid Sampler::DoSample() { 6421e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (!SignalHandler::Installed()) return; 6431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org pthread_kill(platform_data()->vm_tid(), SIGPROF); 6441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org} 6451e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 646dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org#elif V8_OS_WIN || V8_OS_CYGWIN 6471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6481e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgvoid Sampler::DoSample() { 6491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HANDLE profiled_thread = platform_data()->profiled_thread(); 6501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (profiled_thread == NULL) return; 6511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6521e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if defined(USE_SIMULATOR) 6531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org SimulatorHelper helper; 6541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (!helper.Init(this, isolate())) return; 6551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif 6561e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6571e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org const DWORD kSuspendFailed = static_cast<DWORD>(-1); 6581e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (SuspendThread(profiled_thread) == kSuspendFailed) return; 6591e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6601e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Context used for sampling the register state of the profiled thread. 6611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org CONTEXT context; 6621e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org memset(&context, 0, sizeof(context)); 6631e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org context.ContextFlags = CONTEXT_FULL; 6641e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (GetThreadContext(profiled_thread, &context) != 0) { 6651e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org RegisterState state; 6661e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if defined(USE_SIMULATOR) 6671e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org helper.FillRegisters(&state); 6681e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#else 6691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if V8_HOST_ARCH_X64 6701e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.pc = reinterpret_cast<Address>(context.Rip); 6711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.sp = reinterpret_cast<Address>(context.Rsp); 6721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.fp = reinterpret_cast<Address>(context.Rbp); 6731e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#else 6741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.pc = reinterpret_cast<Address>(context.Eip); 6751e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.sp = reinterpret_cast<Address>(context.Esp); 6761e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org state.fp = reinterpret_cast<Address>(context.Ebp); 6771e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif 6781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif // USE_SIMULATOR 6791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org SampleStack(state); 6801e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 6811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org ResumeThread(profiled_thread); 6821e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org} 6831e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6841e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif // USE_SIGNALS 6851e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 6861e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 687e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} } // namespace v8::internal 688