| Index: src/log.cc
|
| diff --git a/src/log.cc b/src/log.cc
|
| index ed8f4752503293b82a4ad5a37a1de5591b406319..21167ddeda3eaa3e55d58d59d62c1f71b78cc155 100644
|
| --- a/src/log.cc
|
| +++ b/src/log.cc
|
| @@ -137,14 +137,38 @@ bool Profiler::paused_ = false;
|
| // StackTracer implementation
|
| //
|
| void StackTracer::Trace(TickSample* sample) {
|
| - // Assuming that stack grows from lower addresses
|
| - if (sample->state != GC
|
| - && (sample->sp < sample->fp && sample->fp < low_stack_bound_)) {
|
| + if (sample->state == GC) {
|
| + sample->InitStack(0);
|
| + return;
|
| + }
|
| +
|
| + // If c_entry_fp is available, this means that we are inside a C++
|
| + // function and sample->fp value isn't reliable due to FPO
|
| + if (Top::c_entry_fp(Top::GetCurrentThread()) != NULL) {
|
| + SafeStackTraceFrameIterator it(
|
| + reinterpret_cast<Address>(sample->sp),
|
| + reinterpret_cast<Address>(low_stack_bound_));
|
| + // Pass 1: Calculate depth
|
| + int depth = 0;
|
| + while (!it.done() && depth <= kMaxStackFrames) {
|
| + ++depth;
|
| + it.Advance();
|
| + }
|
| + // Pass 2: Save stack
|
| + sample->InitStack(depth);
|
| + if (depth > 0) {
|
| + it.Reset();
|
| + for (int i = 0; i < depth && !it.done(); ++i, it.Advance()) {
|
| + sample->stack[i] = it.frame()->pc();
|
| + }
|
| + }
|
| + } else if (sample->sp < sample->fp && sample->fp < low_stack_bound_) {
|
| + // The check assumes that stack grows from lower addresses
|
| sample->InitStack(1);
|
| sample->stack[0] = Memory::Address_at(
|
| (Address)(sample->fp + StandardFrameConstants::kCallerPCOffset));
|
| } else {
|
| - // GC runs or FP seems to be in some intermediate state,
|
| + // FP seems to be in some intermediate state,
|
| // better discard this sample
|
| sample->InitStack(0);
|
| }
|
|
|