Chromium Code Reviews| Index: runtime/vm/stack_frame.cc |
| =================================================================== |
| --- runtime/vm/stack_frame.cc (revision 22762) |
| +++ runtime/vm/stack_frame.cc (working copy) |
| @@ -215,6 +215,7 @@ |
| uword exit_marker = *reinterpret_cast<uword*>(exit_address); |
| frames_.fp_ = exit_marker; |
| frames_.sp_ = 0; |
| + frames_.pc_ = 0; |
| } |
| @@ -223,16 +224,29 @@ |
| SetupLastExitFrameData(); // Setup data for last exit frame. |
| } |
| + |
| StackFrameIterator::StackFrameIterator(uword last_fp, bool validate) |
| : validate_(validate), entry_(), exit_(), current_frame_(NULL) { |
| frames_.fp_ = last_fp; |
| + frames_.sp_ = 0; |
| + frames_.pc_ = 0; |
| } |
| +StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc, |
| + bool validate) |
| + : validate_(validate), entry_(), exit_(), current_frame_(NULL) { |
| + frames_.fp_ = fp; |
| + frames_.sp_ = sp; |
| + frames_.pc_ = pc; |
| +} |
| + |
| + |
| StackFrame* StackFrameIterator::NextFrame() { |
| // When we are at the start of iteration after having created an |
| // iterator object current_frame_ will be NULL as we haven't seen |
|
zra
2013/05/16 20:52:16
Add a comma after 'object'.
regis
2013/05/21 22:07:40
Done. I added a bunch, while I was at it.
|
| - // any frames yet. At this point if NextFrame is called it tries |
| + // any frames yet (unless we start iterating in the simulator from a given |
| + // triplet of fp, sp, and pc). At this point if NextFrame is called it tries |
| // to set up the next exit frame by reading the top_exit_frame_info |
| // from the isolate. If we do not have any dart invocations yet |
| // top_exit_frame_info will be 0 and so we would return NULL. |
| @@ -245,7 +259,17 @@ |
| if (!HasNextFrame()) { |
| return NULL; |
| } |
| - current_frame_ = NextExitFrame(); |
| + if (frames_.pc_ == 0) { |
| + // Iteration starts from an exit frame given by its fp. |
| + current_frame_ = NextExitFrame(); |
| + } else if (*(reinterpret_cast<uword*>( |
| + frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == 0) { |
| + // Iteration starts from an entry frame given by its fp, sp, and pc. |
| + current_frame_ = NextEntryFrame(); |
| + } else { |
| + // Iteration starts from a Dart or stub frame given by its fp, sp, and pc. |
| + current_frame_ = frames_.NextFrame(validate_); |
| + } |
| return current_frame_; |
| } |
| ASSERT((validate_ == kDontValidateFrames) || current_frame_->IsValid()); |
| @@ -276,8 +300,10 @@ |
| frame = &stack_frame_; |
| frame->sp_ = sp_; |
| frame->fp_ = fp_; |
| + frame->pc_ = pc_; |
| sp_ = frame->GetCallerSp(); |
| fp_ = frame->GetCallerFp(); |
| + pc_ = frame->GetCallerPc(); |
| ASSERT((validate == kDontValidateFrames) || frame->IsValid()); |
| return frame; |
| } |
| @@ -286,8 +312,10 @@ |
| ExitFrame* StackFrameIterator::NextExitFrame() { |
| exit_.sp_ = frames_.sp_; |
| exit_.fp_ = frames_.fp_; |
| + exit_.pc_ = frames_.pc_; |
| frames_.sp_ = exit_.GetCallerSp(); |
| frames_.fp_ = exit_.GetCallerFp(); |
| + frames_.pc_ = exit_.GetCallerPc(); |
| ASSERT(exit_.IsValid()); |
| return &exit_; |
| } |
| @@ -297,6 +325,7 @@ |
| ASSERT(!frames_.HasNext()); |
| entry_.sp_ = frames_.sp_; |
| entry_.fp_ = frames_.fp_; |
| + entry_.pc_ = frames_.pc_; |
| SetupNextExitFrameData(); // Setup data for next exit frame in chain. |
| ASSERT(entry_.IsValid()); |
| return &entry_; |
| @@ -317,7 +346,7 @@ |
| intptr_t deopt_reason = kDeoptUnknown; |
| deopt_info_ = code_.GetDeoptInfoAtPc(frame->pc(), &deopt_reason); |
| if (deopt_info_.IsNull()) { |
| - // This is the case when a call without deopt info in optimzed code |
| + // This is the case when a call without deopt info in optimized code |
| // throws an exception. (e.g. in the parameter copying prologue). |
| // In that case there won't be any inlined frames. |
| function_ = code_.function(); |