Do not store fp and sp values in TickSample
Their values are not used neither by the tick processor nor by CpuProfiler so it is just a waste of space. TickSample used to be a transport for grabbed register values to TickSample::Trace, now they are passed in a special structure RegisterState which is allocated on the stack for the sampling period. Some common pieces were moved from platform-dependent code into Sampler::SampleStack and TickSample::Init. BUG=None R=jkummerow@chromium.org, loislo@chromium.org Review URL: https://codereview.chromium.org/18620002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15484 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
91be57a469
commit
9ef762b683
@ -216,10 +216,11 @@ bool StackTraceFrameIterator::IsValidFrame() {
|
||||
|
||||
SafeStackFrameIterator::SafeStackFrameIterator(
|
||||
Isolate* isolate,
|
||||
Address fp, Address sp, Address low_bound, Address high_bound) :
|
||||
StackFrameIteratorBase(isolate, false),
|
||||
low_bound_(low_bound), high_bound_(high_bound),
|
||||
top_frame_type_(StackFrame::NONE) {
|
||||
Address fp, Address sp, Address js_entry_sp)
|
||||
: StackFrameIteratorBase(isolate, false),
|
||||
low_bound_(sp),
|
||||
high_bound_(js_entry_sp),
|
||||
top_frame_type_(StackFrame::NONE) {
|
||||
StackFrame::State state;
|
||||
StackFrame::Type type;
|
||||
ThreadLocalTop* top = isolate->thread_local_top();
|
||||
|
@ -881,7 +881,7 @@ class SafeStackFrameIterator: public StackFrameIteratorBase {
|
||||
public:
|
||||
SafeStackFrameIterator(Isolate* isolate,
|
||||
Address fp, Address sp,
|
||||
Address low_bound, Address high_bound);
|
||||
Address js_entry_sp);
|
||||
|
||||
inline JavaScriptFrame* frame() const;
|
||||
void Advance();
|
||||
|
@ -1364,8 +1364,6 @@ void Logger::TickEvent(TickSample* sample, bool overflow) {
|
||||
LogMessageBuilder msg(this);
|
||||
msg.Append("%s,", kLogEventsNames[TICK_EVENT]);
|
||||
msg.AppendAddress(sample->pc);
|
||||
msg.Append(',');
|
||||
msg.AppendAddress(sample->sp);
|
||||
msg.Append(",%ld", static_cast<int>(OS::Ticks() - epoch_));
|
||||
if (sample->has_external_callback) {
|
||||
msg.Append(",1,");
|
||||
|
186
src/sampler.cc
186
src/sampler.cc
@ -231,44 +231,36 @@ class Sampler::PlatformData : public PlatformDataCommon {
|
||||
#endif
|
||||
|
||||
|
||||
class SampleHelper {
|
||||
public:
|
||||
inline TickSample* Init(Sampler* sampler, Isolate* isolate) {
|
||||
#if defined(USE_SIMULATOR)
|
||||
class SimulatorHelper {
|
||||
public:
|
||||
inline bool Init(Sampler* sampler, Isolate* isolate) {
|
||||
ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
|
||||
Isolate::PerIsolateThreadData* per_thread_data = isolate->
|
||||
FindPerThreadDataForThread(thread_id);
|
||||
if (!per_thread_data) return NULL;
|
||||
if (!per_thread_data) return false;
|
||||
simulator_ = per_thread_data->simulator();
|
||||
// Check if there is active simulator before allocating TickSample.
|
||||
if (!simulator_) return NULL;
|
||||
#endif // USE_SIMULATOR
|
||||
TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
|
||||
if (sample == NULL) sample = &sample_obj;
|
||||
return sample;
|
||||
// Check if there is active simulator.
|
||||
return simulator_ != NULL;
|
||||
}
|
||||
|
||||
#if defined(USE_SIMULATOR)
|
||||
inline void FillRegisters(TickSample* sample) {
|
||||
sample->pc = reinterpret_cast<Address>(simulator_->get_pc());
|
||||
sample->sp = reinterpret_cast<Address>(simulator_->get_register(
|
||||
inline void FillRegisters(RegisterState* state) {
|
||||
state->pc = reinterpret_cast<Address>(simulator_->get_pc());
|
||||
state->sp = reinterpret_cast<Address>(simulator_->get_register(
|
||||
Simulator::sp));
|
||||
#if V8_TARGET_ARCH_ARM
|
||||
sample->fp = reinterpret_cast<Address>(simulator_->get_register(
|
||||
state->fp = reinterpret_cast<Address>(simulator_->get_register(
|
||||
Simulator::r11));
|
||||
#elif V8_TARGET_ARCH_MIPS
|
||||
sample->fp = reinterpret_cast<Address>(simulator_->get_register(
|
||||
state->fp = reinterpret_cast<Address>(simulator_->get_register(
|
||||
Simulator::fp));
|
||||
#endif
|
||||
}
|
||||
#endif // USE_SIMULATOR
|
||||
|
||||
private:
|
||||
#if defined(USE_SIMULATOR)
|
||||
Simulator* simulator_;
|
||||
#endif
|
||||
TickSample sample_obj;
|
||||
};
|
||||
#endif // USE_SIMULATOR
|
||||
|
||||
|
||||
#if defined(USE_SIGNALS)
|
||||
@ -328,89 +320,86 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
|
||||
Sampler* sampler = isolate->logger()->sampler();
|
||||
if (sampler == NULL || !sampler->IsActive()) return;
|
||||
|
||||
SampleHelper helper;
|
||||
TickSample* sample = helper.Init(sampler, isolate);
|
||||
if (sample == NULL) return;
|
||||
RegisterState state;
|
||||
|
||||
#if defined(USE_SIMULATOR)
|
||||
helper.FillRegisters(sample);
|
||||
SimulatorHelper helper;
|
||||
if (!helper.Init(sampler, isolate)) return;
|
||||
helper.FillRegisters(&state);
|
||||
#else
|
||||
// Extracting the sample from the context is extremely machine dependent.
|
||||
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
|
||||
mcontext_t& mcontext = ucontext->uc_mcontext;
|
||||
sample->state = isolate->current_vm_state();
|
||||
#if defined(__linux__) || defined(__ANDROID__)
|
||||
#if V8_HOST_ARCH_IA32
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
|
||||
#elif V8_HOST_ARCH_X64
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
|
||||
#elif V8_HOST_ARCH_ARM
|
||||
#if defined(__GLIBC__) && !defined(__UCLIBC__) && \
|
||||
(__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
|
||||
// Old GLibc ARM versions used a gregs[] array to access the register
|
||||
// values from mcontext_t.
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
|
||||
#else
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.arm_pc);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.arm_sp);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.arm_fp);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.arm_pc);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.arm_sp);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.arm_fp);
|
||||
#endif // defined(__GLIBC__) && !defined(__UCLIBC__) &&
|
||||
// (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
|
||||
#elif V8_HOST_ARCH_MIPS
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.pc);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.pc);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.gregs[29]);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.gregs[30]);
|
||||
#endif // V8_HOST_ARCH_*
|
||||
#elif defined(__FreeBSD__)
|
||||
#if V8_HOST_ARCH_IA32
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.mc_eip);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.mc_esp);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.mc_ebp);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.mc_eip);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.mc_esp);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.mc_ebp);
|
||||
#elif V8_HOST_ARCH_X64
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.mc_rip);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.mc_rsp);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.mc_rbp);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.mc_rip);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.mc_rsp);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.mc_rbp);
|
||||
#elif V8_HOST_ARCH_ARM
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.mc_r15);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.mc_r13);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.mc_r11);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.mc_r15);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.mc_r13);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.mc_r11);
|
||||
#endif // V8_HOST_ARCH_*
|
||||
#elif defined(__NetBSD__)
|
||||
#if V8_HOST_ARCH_IA32
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]);
|
||||
#elif V8_HOST_ARCH_X64
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]);
|
||||
#endif // V8_HOST_ARCH_*
|
||||
#elif defined(__OpenBSD__)
|
||||
USE(mcontext);
|
||||
#if V8_HOST_ARCH_IA32
|
||||
sample->pc = reinterpret_cast<Address>(ucontext->sc_eip);
|
||||
sample->sp = reinterpret_cast<Address>(ucontext->sc_esp);
|
||||
sample->fp = reinterpret_cast<Address>(ucontext->sc_ebp);
|
||||
state.pc = reinterpret_cast<Address>(ucontext->sc_eip);
|
||||
state.sp = reinterpret_cast<Address>(ucontext->sc_esp);
|
||||
state.fp = reinterpret_cast<Address>(ucontext->sc_ebp);
|
||||
#elif V8_HOST_ARCH_X64
|
||||
sample->pc = reinterpret_cast<Address>(ucontext->sc_rip);
|
||||
sample->sp = reinterpret_cast<Address>(ucontext->sc_rsp);
|
||||
sample->fp = reinterpret_cast<Address>(ucontext->sc_rbp);
|
||||
state.pc = reinterpret_cast<Address>(ucontext->sc_rip);
|
||||
state.sp = reinterpret_cast<Address>(ucontext->sc_rsp);
|
||||
state.fp = reinterpret_cast<Address>(ucontext->sc_rbp);
|
||||
#endif // V8_HOST_ARCH_*
|
||||
#elif defined(__sun)
|
||||
sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]);
|
||||
state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]);
|
||||
state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]);
|
||||
state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]);
|
||||
#endif // __sun
|
||||
#endif // USE_SIMULATOR
|
||||
|
||||
sampler->SampleStack(sample);
|
||||
sampler->Tick(sample);
|
||||
sampler->SampleStack(state);
|
||||
#endif // __native_client__
|
||||
}
|
||||
|
||||
@ -509,9 +498,10 @@ class SamplerThread : public Thread {
|
||||
thread_act_t profiled_thread = sampler->platform_data()->profiled_thread();
|
||||
Isolate* isolate = sampler->isolate();
|
||||
|
||||
SampleHelper helper;
|
||||
TickSample* sample = helper.Init(sampler, isolate);
|
||||
if (sample == NULL) return;
|
||||
#if defined(USE_SIMULATOR)
|
||||
SimulatorHelper helper;
|
||||
if (!helper.Init(sampler, isolate)) return;
|
||||
#endif
|
||||
|
||||
if (KERN_SUCCESS != thread_suspend(profiled_thread)) return;
|
||||
|
||||
@ -541,17 +531,16 @@ class SamplerThread : public Thread {
|
||||
flavor,
|
||||
reinterpret_cast<natural_t*>(&state),
|
||||
&count) == KERN_SUCCESS) {
|
||||
sample->state = isolate->current_vm_state();
|
||||
RegisterState state;
|
||||
#if defined(USE_SIMULATOR)
|
||||
helper.FillRegisters(sample);
|
||||
helper.FillRegisters(&state);
|
||||
#else
|
||||
sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
|
||||
sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
|
||||
sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
|
||||
state.pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
|
||||
state.sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
|
||||
state.fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
|
||||
#endif // USE_SIMULATOR
|
||||
#undef REGISTER_FIELD
|
||||
sampler->SampleStack(sample);
|
||||
sampler->Tick(sample);
|
||||
sampler->SampleStack(state);
|
||||
}
|
||||
thread_resume(profiled_thread);
|
||||
}
|
||||
@ -563,34 +552,34 @@ class SamplerThread : public Thread {
|
||||
if (profiled_thread == NULL) return;
|
||||
|
||||
Isolate* isolate = sampler->isolate();
|
||||
SampleHelper helper;
|
||||
TickSample* sample = helper.Init(sampler, isolate);
|
||||
if (sample == NULL) return;
|
||||
#if defined(USE_SIMULATOR)
|
||||
SimulatorHelper helper;
|
||||
if (!helper.Init(sampler, isolate)) return;
|
||||
#endif
|
||||
|
||||
const DWORD kSuspendFailed = static_cast<DWORD>(-1);
|
||||
if (SuspendThread(profiled_thread) == kSuspendFailed) return;
|
||||
sample->state = isolate->current_vm_state();
|
||||
|
||||
// Context used for sampling the register state of the profiled thread.
|
||||
CONTEXT context;
|
||||
memset(&context, 0, sizeof(context));
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
if (GetThreadContext(profiled_thread, &context) != 0) {
|
||||
RegisterState state;
|
||||
#if defined(USE_SIMULATOR)
|
||||
helper.FillRegisters(sample);
|
||||
helper.FillRegisters(&state);
|
||||
#else
|
||||
#if V8_HOST_ARCH_X64
|
||||
sample->pc = reinterpret_cast<Address>(context.Rip);
|
||||
sample->sp = reinterpret_cast<Address>(context.Rsp);
|
||||
sample->fp = reinterpret_cast<Address>(context.Rbp);
|
||||
state.pc = reinterpret_cast<Address>(context.Rip);
|
||||
state.sp = reinterpret_cast<Address>(context.Rsp);
|
||||
state.fp = reinterpret_cast<Address>(context.Rbp);
|
||||
#else
|
||||
sample->pc = reinterpret_cast<Address>(context.Eip);
|
||||
sample->sp = reinterpret_cast<Address>(context.Esp);
|
||||
sample->fp = reinterpret_cast<Address>(context.Ebp);
|
||||
state.pc = reinterpret_cast<Address>(context.Eip);
|
||||
state.sp = reinterpret_cast<Address>(context.Esp);
|
||||
state.fp = reinterpret_cast<Address>(context.Ebp);
|
||||
#endif
|
||||
#endif // USE_SIMULATOR
|
||||
sampler->SampleStack(sample);
|
||||
sampler->Tick(sample);
|
||||
sampler->SampleStack(state);
|
||||
}
|
||||
ResumeThread(profiled_thread);
|
||||
}
|
||||
@ -616,8 +605,11 @@ SamplerThread* SamplerThread::instance_ = NULL;
|
||||
//
|
||||
// StackTracer implementation
|
||||
//
|
||||
DISABLE_ASAN void TickSample::Trace(Isolate* isolate) {
|
||||
DISABLE_ASAN void TickSample::Init(Isolate* isolate,
|
||||
const RegisterState& regs) {
|
||||
ASSERT(isolate->IsInitialized());
|
||||
pc = regs.pc;
|
||||
state = isolate->current_vm_state();
|
||||
|
||||
// Avoid collecting traces while doing GC.
|
||||
if (state == GC) return;
|
||||
@ -636,11 +628,11 @@ DISABLE_ASAN void TickSample::Trace(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(sp);
|
||||
tos = Memory::Address_at(regs.sp);
|
||||
has_external_callback = false;
|
||||
}
|
||||
|
||||
SafeStackFrameIterator it(isolate, fp, sp, sp, js_entry_sp);
|
||||
SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp);
|
||||
top_frame_type = it.top_frame_type();
|
||||
int i = 0;
|
||||
while (!it.done() && i < TickSample::kMaxFramesCount) {
|
||||
@ -689,9 +681,13 @@ void Sampler::Stop() {
|
||||
SetActive(false);
|
||||
}
|
||||
|
||||
void Sampler::SampleStack(TickSample* sample) {
|
||||
sample->Trace(isolate_);
|
||||
void Sampler::SampleStack(const RegisterState& state) {
|
||||
TickSample* sample = isolate_->cpu_profiler()->TickSampleEvent();
|
||||
TickSample sample_obj;
|
||||
if (sample == NULL) sample = &sample_obj;
|
||||
sample->Init(isolate_, state);
|
||||
if (++samples_taken_ < 0) samples_taken_ = 0;
|
||||
Tick(sample);
|
||||
}
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -44,22 +44,25 @@ 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()
|
||||
: state(OTHER),
|
||||
pc(NULL),
|
||||
sp(NULL),
|
||||
fp(NULL),
|
||||
external_callback(NULL),
|
||||
frames_count(0),
|
||||
has_external_callback(false),
|
||||
top_frame_type(StackFrame::NONE) {}
|
||||
void Trace(Isolate* isolate);
|
||||
void Init(Isolate* isolate, const RegisterState& state);
|
||||
StateTag state; // The state of the VM.
|
||||
Address pc; // Instruction pointer.
|
||||
Address sp; // Stack pointer.
|
||||
Address fp; // Frame pointer.
|
||||
union {
|
||||
Address tos; // Top stack value (*sp).
|
||||
Address external_callback;
|
||||
@ -85,11 +88,7 @@ class Sampler {
|
||||
int interval() const { return interval_; }
|
||||
|
||||
// Performs stack sampling.
|
||||
void SampleStack(TickSample* sample);
|
||||
|
||||
// This method is called for each sampling period with the current
|
||||
// program counter.
|
||||
virtual void Tick(TickSample* sample) = 0;
|
||||
void SampleStack(const RegisterState& regs);
|
||||
|
||||
// Start and stop sampler.
|
||||
void Start();
|
||||
@ -110,6 +109,11 @@ class Sampler {
|
||||
class PlatformData;
|
||||
PlatformData* platform_data() const { return data_; }
|
||||
|
||||
protected:
|
||||
// This method is called for each sampling period with the current
|
||||
// program counter.
|
||||
virtual void Tick(TickSample* sample) = 0;
|
||||
|
||||
private:
|
||||
void SetActive(bool value) { NoBarrier_Store(&active_, value); }
|
||||
|
||||
|
@ -52,6 +52,7 @@ using v8::internal::Address;
|
||||
using v8::internal::Handle;
|
||||
using v8::internal::Isolate;
|
||||
using v8::internal::JSFunction;
|
||||
using v8::internal::RegisterState;
|
||||
using v8::internal::TickSample;
|
||||
|
||||
|
||||
@ -66,11 +67,12 @@ static void InitTraceEnv(TickSample* sample) {
|
||||
|
||||
|
||||
static void DoTrace(Address fp) {
|
||||
trace_env.sample->fp = fp;
|
||||
RegisterState regs;
|
||||
regs.fp = fp;
|
||||
// sp is only used to define stack high bound
|
||||
trace_env.sample->sp =
|
||||
regs.sp =
|
||||
reinterpret_cast<Address>(trace_env.sample) - 10240;
|
||||
trace_env.sample->Trace(Isolate::Current());
|
||||
trace_env.sample->Init(Isolate::Current(), regs);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@ profiler,"begin",1
|
||||
code-creation,Stub,0,0x424260,348,"CompareStub_GE"
|
||||
code-creation,LazyCompile,0,0x2a8100,18535,"DrawQube 3d-cube.js:188",0xf43abcac,
|
||||
code-creation,LazyCompile,0,0x480100,3908,"DrawLine 3d-cube.js:17",0xf43abc50,
|
||||
tick,0x424284,0xbfffeea0,0,0,0x480600,0,0x2aaaa5
|
||||
tick,0x42429f,0xbfffed88,0,0,0x480600,0,0x2aacb4
|
||||
tick,0x48063d,0xbfffec7c,0,0,0x2d0f7c,0,0x2aaec6
|
||||
tick,0x424284,0,0,0x480600,0,0x2aaaa5
|
||||
tick,0x42429f,0,0,0x480600,0,0x2aacb4
|
||||
tick,0x48063d,0,0,0x2d0f7c,0,0x2aaec6
|
||||
profiler,"end"
|
||||
|
@ -9,17 +9,17 @@ code-creation,LazyCompile,0,0xf541d120,145,"exp native math.js:41"
|
||||
function-creation,0xf441d280,0xf541d120
|
||||
code-creation,LoadIC,0,0xf541d280,117,"j"
|
||||
code-creation,LoadIC,0,0xf541d360,63,"i"
|
||||
tick,0x80f82d1,0xffdfe880,0,0,0,0,0xf541ce5c
|
||||
tick,0x80f89a1,0xffdfecf0,0,0,0,0,0xf541ce5c
|
||||
tick,0x8123b5c,0xffdff1a0,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0x8123b65,0xffdff1a0,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf541d2be,0xffdff1e4,0,0,0,0
|
||||
tick,0xf541d320,0xffdff1dc,0,0,0,0
|
||||
tick,0xf541d384,0xffdff1d8,0,0,0,0
|
||||
tick,0xf7db94da,0xffdff0ec,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf7db951c,0xffdff0f0,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf7dbc508,0xffdff14c,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf7dbff21,0xffdff198,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf7edec90,0xffdff0ec,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xffffe402,0xffdff488,0,0,0,0
|
||||
tick,0x80f82d1,0,0,0,0,0xf541ce5c
|
||||
tick,0x80f89a1,0,0,0,0,0xf541ce5c
|
||||
tick,0x8123b5c,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0x8123b65,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf541d2be,0,0,0,0
|
||||
tick,0xf541d320,0,0,0,0
|
||||
tick,0xf541d384,0,0,0,0
|
||||
tick,0xf7db94da,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf7db951c,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf7dbc508,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf7dbff21,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xf7edec90,0,0,0,0,0xf541d1a1,0xf541ceea
|
||||
tick,0xffffe402,0,0,0,0
|
||||
profiler,"end"
|
||||
|
@ -169,7 +169,7 @@ function TickProcessor(
|
||||
'snapshot-pos': { parsers: [parseInt, parseInt],
|
||||
processor: this.processSnapshotPosition },
|
||||
'tick': {
|
||||
parsers: [parseInt, parseInt, parseInt, parseInt,
|
||||
parsers: [parseInt, parseInt, parseInt,
|
||||
parseInt, parseInt, 'var-args'],
|
||||
processor: this.processTick },
|
||||
'heap-sample-begin': { parsers: [null, null, parseInt],
|
||||
@ -365,7 +365,6 @@ TickProcessor.prototype.includeTick = function(vmState) {
|
||||
};
|
||||
|
||||
TickProcessor.prototype.processTick = function(pc,
|
||||
sp,
|
||||
ns_since_start,
|
||||
is_external_callback,
|
||||
tos_or_external_callback,
|
||||
|
Loading…
Reference in New Issue
Block a user