Index: src/debug.cc |
diff --git a/src/debug.cc b/src/debug.cc |
index 2d58ce1f54aefba1e93be618b9a1f76a69f7bcd3..15299e36524e2c68a17d8bdd8ac4349f77bb41f8 100644 |
--- a/src/debug.cc |
+++ b/src/debug.cc |
@@ -542,6 +542,7 @@ void Debug::ThreadInit() { |
thread_local_.last_statement_position_ = RelocInfo::kNoPosition; |
thread_local_.step_count_ = 0; |
thread_local_.last_fp_ = 0; |
+ thread_local_.queued_step_count_ = 0; |
thread_local_.step_into_fp_ = 0; |
thread_local_.step_out_fp_ = 0; |
thread_local_.after_break_target_ = 0; |
@@ -957,14 +958,49 @@ Object* Debug::Break(Arguments args) { |
// Clear all current stepping setup. |
ClearStepping(); |
- // Notify the debug event listeners. |
- isolate_->debugger()->OnDebugBreak(break_points_hit, false); |
+ if (thread_local_.queued_step_count_ > 0) { |
+ // Perform queued steps |
+ int step_count = thread_local_.queued_step_count_; |
+ |
+ // Clear queue |
+ thread_local_.queued_step_count_ = 0; |
+ |
+ PrepareStep(StepNext, step_count); |
+ } else { |
+ // Notify the debug event listeners. |
+ isolate_->debugger()->OnDebugBreak(break_points_hit, false); |
+ } |
} else if (thread_local_.last_step_action_ != StepNone) { |
// Hold on to last step action as it is cleared by the call to |
// ClearStepping. |
StepAction step_action = thread_local_.last_step_action_; |
int step_count = thread_local_.step_count_; |
+ // If StepNext gone deeper in code |
+ // StepOut until original frame |
+ if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) { |
+ // Count frames until target frame |
+ int count = 0; |
+ JavaScriptFrameIterator it(isolate_); |
+ while (!it.done() && it.frame()->fp() != thread_local_.last_fp_) { |
+ count++; |
+ it.Advance(); |
+ } |
+ |
+ // If we found original frame |
+ if (it.frame()->fp() == thread_local_.last_fp_) { |
+ if (step_count > 1) { |
+ // Save old count and action to continue stepping after |
+ // StepOut |
+ thread_local_.queued_step_count_ = step_count - 1; |
+ } |
+ |
+ // Set up for StepOut to reach target frame |
+ step_action = StepOut; |
+ step_count = count; |
+ } |
+ } |
+ |
// Clear all current stepping setup. |
ClearStepping(); |
@@ -1448,6 +1484,13 @@ void Debug::PrepareStep(StepAction step_action, int step_count) { |
// steps before reporting break back to the debugger. |
bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, |
JavaScriptFrame* frame) { |
+ // StepNext and StepOut shouldn't bring us deeper in code |
+ // So last frame shouldn't be a one of parents of current frame |
+ if (thread_local_.last_step_action_ == StepNext || |
+ thread_local_.last_step_action_ == StepOut) { |
+ if (frame->fp() < thread_local_.last_fp_) return true; |
+ } |
+ |
// If the step last action was step next or step in make sure that a new |
// statement is hit. |
if (thread_local_.last_step_action_ == StepNext || |