Index: src/sampler.h |
diff --git a/src/sampler.h b/src/sampler.h |
index c3dce4ed7c2fec7e353cb06d1641f63e82092a84..2b0a62a56dca04eafe9e27f3c07528be4f472f05 100644 |
--- a/src/sampler.h |
+++ b/src/sampler.h |
@@ -9,6 +9,149 @@ |
#include "src/frames.h" |
#include "src/globals.h" |
+#if V8_OS_POSIX && !V8_OS_CYGWIN |
+ |
+#define USE_SIGNALS |
+ |
+#include <errno.h> |
+#include <pthread.h> |
+#include <signal.h> |
+#include <sys/time.h> |
+ |
+#if !V8_OS_QNX && !V8_OS_NACL |
+#include <sys/syscall.h> // NOLINT |
+#endif |
+ |
+#if V8_OS_MACOSX |
+#include <mach/mach.h> |
+// OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h> |
+// and is a typedef for struct sigcontext. There is no uc_mcontext. |
+#elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) && \ |
+ !V8_OS_OPENBSD && !V8_OS_NACL |
+#include <ucontext.h> |
+#endif |
+ |
+#include <unistd.h> |
+ |
+// GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'. |
+// Old versions of the C library <signal.h> didn't define the type. |
+#if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) && \ |
+ (defined(__arm__) || defined(__aarch64__)) && \ |
+ !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT) |
+#include <asm/sigcontext.h> // NOLINT |
+#endif |
+ |
+#elif V8_OS_WIN || V8_OS_CYGWIN |
+ |
+#include "src/base/win32-headers.h" |
+ |
+#endif |
+ |
+ |
+#if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) |
+ |
+// Not all versions of Android's C library provide ucontext_t. |
+// Detect this and provide custom but compatible definitions. Note that these |
+// follow the GLibc naming convention to access register values from |
+// mcontext_t. |
+// |
+// See http://code.google.com/p/android/issues/detail?id=34784 |
+ |
+#if defined(__arm__) |
+ |
+typedef struct sigcontext mcontext_t; |
+ |
+typedef struct ucontext { |
+ uint32_t uc_flags; |
+ struct ucontext* uc_link; |
+ stack_t uc_stack; |
+ mcontext_t uc_mcontext; |
+ // Other fields are not used by V8, don't define them here. |
+} ucontext_t; |
+ |
+#elif defined(__aarch64__) |
+ |
+typedef struct sigcontext mcontext_t; |
+ |
+typedef struct ucontext { |
+ uint64_t uc_flags; |
+ struct ucontext *uc_link; |
+ stack_t uc_stack; |
+ mcontext_t uc_mcontext; |
+ // Other fields are not used by V8, don't define them here. |
+} ucontext_t; |
+ |
+#elif defined(__mips__) |
+// MIPS version of sigcontext, for Android bionic. |
+typedef struct { |
+ uint32_t regmask; |
+ uint32_t status; |
+ uint64_t pc; |
+ uint64_t gregs[32]; |
+ uint64_t fpregs[32]; |
+ uint32_t acx; |
+ uint32_t fpc_csr; |
+ uint32_t fpc_eir; |
+ uint32_t used_math; |
+ uint32_t dsp; |
+ uint64_t mdhi; |
+ uint64_t mdlo; |
+ uint32_t hi1; |
+ uint32_t lo1; |
+ uint32_t hi2; |
+ uint32_t lo2; |
+ uint32_t hi3; |
+ uint32_t lo3; |
+} mcontext_t; |
+ |
+typedef struct ucontext { |
+ uint32_t uc_flags; |
+ struct ucontext* uc_link; |
+ stack_t uc_stack; |
+ mcontext_t uc_mcontext; |
+ // Other fields are not used by V8, don't define them here. |
+} ucontext_t; |
+ |
+#elif defined(__i386__) |
+// x86 version for Android. |
+typedef struct { |
+ uint32_t gregs[19]; |
+ void* fpregs; |
+ uint32_t oldmask; |
+ uint32_t cr2; |
+} mcontext_t; |
+ |
+typedef uint32_t kernel_sigset_t[2]; // x86 kernel uses 64-bit signal masks |
+typedef struct ucontext { |
+ uint32_t uc_flags; |
+ struct ucontext* uc_link; |
+ stack_t uc_stack; |
+ mcontext_t uc_mcontext; |
+ // Other fields are not used by V8, don't define them here. |
+} ucontext_t; |
+enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 }; |
+ |
+#elif defined(__x86_64__) |
+// x64 version for Android. |
+typedef struct { |
+ uint64_t gregs[23]; |
+ void* fpregs; |
+ uint64_t __reserved1[8]; |
+} mcontext_t; |
+ |
+typedef struct ucontext { |
+ uint64_t uc_flags; |
+ struct ucontext *uc_link; |
+ stack_t uc_stack; |
+ mcontext_t uc_mcontext; |
+ // Other fields are not used by V8, don't define them here. |
+} ucontext_t; |
+enum { REG_RBP = 10, REG_RSP = 15, REG_RIP = 16 }; |
+#endif |
+ |
+#endif // V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) |
+ |
+ |
namespace v8 { |
namespace internal { |
@@ -21,13 +164,6 @@ class Isolate; |
// (if used for profiling) the program counter and stack pointer for |
// the thread that created it. |
-struct RegisterState { |
- RegisterState() : pc(NULL), sp(NULL), fp(NULL) {} |
- Address pc; // Instruction pointer. |
- Address sp; // Stack pointer. |
- Address fp; // Frame pointer. |
-}; |
- |
// TickSample captures the information collected for each sample. |
struct TickSample { |
TickSample() |
@@ -37,7 +173,7 @@ struct TickSample { |
frames_count(0), |
has_external_callback(false), |
top_frame_type(StackFrame::NONE) {} |
- void Init(Isolate* isolate, const RegisterState& state); |
+ void Init(Isolate* isolate, const v8::RegisterState& state); |
StateTag state; // The state of the VM. |
Address pc; // Instruction pointer. |
union { |
@@ -67,7 +203,7 @@ class Sampler { |
int interval() const { return interval_; } |
// Performs stack sampling. |
- void SampleStack(const RegisterState& regs); |
+ void SampleStack(const v8::RegisterState& regs); |
// Start and stop sampler. |
void Start(); |
@@ -85,6 +221,12 @@ class Sampler { |
bool IsActive() const { return base::NoBarrier_Load(&active_); } |
void DoSample(); |
+ |
+ static int GetSample(Isolate* isolate, |
+ const v8::RegisterState& state, |
+ void** buffer, |
+ unsigned int depth); |
+ |
// If true next sample must be initiated on the profiler event processor |
// thread right after latest sample is processed. |
void SetHasProcessingThread(bool value) { |