Index: src/sampler.cc |
diff --git a/src/sampler.cc b/src/sampler.cc |
index 394efeb7640764870b6f768a9d11a1b879955416..890dd79d082275f9c04bbf1df82df2554fcfab64 100644 |
--- a/src/sampler.cc |
+++ b/src/sampler.cc |
@@ -4,44 +4,6 @@ |
#include "src/sampler.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 |
- |
#include "src/v8.h" |
#include "src/base/platform/platform.h" |
@@ -53,111 +15,6 @@ |
#include "src/v8threads.h" |
#include "src/vm-state-inl.h" |
- |
-#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 { |
@@ -232,7 +89,7 @@ class SimulatorHelper { |
return simulator_ != NULL; |
} |
- inline void FillRegisters(RegisterState* state) { |
+ inline void FillRegisters(v8::RegisterState* state) { |
#if V8_TARGET_ARCH_ARM |
state->pc = reinterpret_cast<Address>(simulator_->get_pc()); |
state->sp = reinterpret_cast<Address>(simulator_->get_register( |
@@ -353,7 +210,7 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, |
Sampler* sampler = isolate->logger()->sampler(); |
if (sampler == NULL) return; |
- RegisterState state; |
+ v8::RegisterState state; |
#if defined(USE_SIMULATOR) |
SimulatorHelper helper; |
@@ -577,10 +434,10 @@ SamplerThread* SamplerThread::instance_ = NULL; |
// StackTracer implementation |
// |
DISABLE_ASAN void TickSample::Init(Isolate* isolate, |
- const RegisterState& regs) { |
+ const v8::RegisterState& regs) { |
DCHECK(isolate->IsInitialized()); |
timestamp = base::TimeTicks::HighResolutionNow(); |
- pc = regs.pc; |
+ pc = reinterpret_cast<Address>(regs.pc); |
state = isolate->current_vm_state(); |
// Avoid collecting traces while doing GC. |
@@ -603,11 +460,14 @@ DISABLE_ASAN void TickSample::Init(Isolate* isolate, |
} else { |
// Sample potential return address value for frameless invocation of |
// stubs (we'll figure out later, if this value makes sense). |
- tos = Memory::Address_at(regs.sp); |
+ tos = Memory::Address_at(reinterpret_cast<Address>(regs.sp)); |
has_external_callback = false; |
} |
- SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp); |
+ SafeStackFrameIterator it(isolate, |
+ reinterpret_cast<Address>(regs.fp), |
+ reinterpret_cast<Address>(regs.sp), |
+ js_entry_sp); |
top_frame_type = it.top_frame_type(); |
unsigned i = 0; |
while (!it.done() && i < TickSample::kMaxFramesCount) { |
@@ -682,7 +542,7 @@ void Sampler::DecreaseProfilingDepth() { |
} |
-void Sampler::SampleStack(const RegisterState& state) { |
+void Sampler::SampleStack(const v8::RegisterState& state) { |
TickSample* sample = isolate_->cpu_profiler()->StartTickSample(); |
TickSample sample_obj; |
if (sample == NULL) sample = &sample_obj; |
@@ -699,6 +559,41 @@ void Sampler::SampleStack(const RegisterState& state) { |
} |
+int Sampler::GetSample(Isolate* isolate, |
+ const v8::RegisterState& state, |
+ void** buffer, |
+ unsigned int depth) { |
+ DCHECK(isolate->IsInitialized()); |
+ |
+ // Avoid collecting traces while doing GC. |
+ if (isolate->current_vm_state() == GC) return -1; |
+ |
+ fprintf(stderr, "sp:%p\nfp:%p\npc:%p\ndepth:%d\n", |
+ state.sp, |
+ state.fp, |
+ state.pc, |
+ depth); |
+ Address js_entry_sp = isolate->js_entry_sp(); |
+ if (js_entry_sp == 0) { |
+ fprintf(stderr, "js_entry_sp is zero.\n"); |
+ return 0; // Not executing JS now. |
+ } |
+ |
+ |
+ SafeStackFrameIterator it(isolate, |
+ reinterpret_cast<Address>(state.fp), |
+ reinterpret_cast<Address>(state.sp), |
+ js_entry_sp); |
+ unsigned i = 0; |
+ while (!it.done() && i < depth) { |
+ buffer[i++] = it.frame()->pc(); |
+ it.Advance(); |
+ } |
+ fprintf(stderr, "GetSample returning %d\n", i); |
+ return i; |
+} |
+ |
+ |
#if defined(USE_SIGNALS) |
void Sampler::DoSample() { |
@@ -725,7 +620,7 @@ void Sampler::DoSample() { |
memset(&context, 0, sizeof(context)); |
context.ContextFlags = CONTEXT_FULL; |
if (GetThreadContext(profiled_thread, &context) != 0) { |
- RegisterState state; |
+ v8::RegisterState state; |
#if defined(USE_SIMULATOR) |
helper.FillRegisters(&state); |
#else |