From: yangguo Date: Fri, 29 May 2015 12:56:26 +0000 (-0700) Subject: Debugger: PreservePositionScope should clear positions inside the scope. X-Git-Tag: upstream/4.7.83~2339 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3f223ee69bdf66c31a1f0b340a8124834b82f93d;p=platform%2Fupstream%2Fv8.git Debugger: PreservePositionScope should clear positions inside the scope. The point of this change is so that when emitting code for a call in FullCodegen::VisitCall, the statement position is not associated to any code that loads the function, but to the actual CallIC. R=mvstanton@chromium.org BUG=chromium:481896 LOG=N Review URL: https://codereview.chromium.org/1157543004 Cr-Commit-Position: refs/heads/master@{#28701} --- diff --git a/src/assembler.h b/src/assembler.h index fd66e0b..d582239 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -1112,7 +1112,11 @@ class PreservePositionScope BASE_EMBEDDED { public: explicit PreservePositionScope(PositionsRecorder* positions_recorder) : positions_recorder_(positions_recorder), - saved_state_(positions_recorder->state_) {} + saved_state_(positions_recorder->state_) { + // Reset positions so that previous ones do not accidentally get + // recorded within this scope. + positions_recorder->state_ = PositionState(); + } ~PreservePositionScope() { positions_recorder_->state_ = saved_state_; diff --git a/src/debug.cc b/src/debug.cc index d1a8a50..934f200 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -69,7 +69,8 @@ BreakLocation::Iterator::Iterator(Handle debug_info, ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)), break_index_(-1), position_(1), - statement_position_(1) { + statement_position_(1), + has_immediate_position_(false) { Next(); } @@ -99,6 +100,8 @@ void BreakLocation::Iterator::Next() { debug_info_->shared()->start_position()); DCHECK(position_ >= 0); DCHECK(statement_position_ >= 0); + has_immediate_position_ = true; + continue; } // Check for break at return. @@ -112,7 +115,7 @@ void BreakLocation::Iterator::Next() { } statement_position_ = position_; break_index_++; - return; + break; } if (RelocInfo::IsCodeTarget(rmode())) { @@ -124,24 +127,26 @@ void BreakLocation::Iterator::Next() { if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) { break_index_++; - return; + break; } // Skip below if we only want locations for calls and returns. if (type_ == CALLS_AND_RETURNS) continue; - if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() && + // Only break at an inline cache if it has an immediate position attached. + if (has_immediate_position_ && + (code->is_inline_cache_stub() && !code->is_binary_op_stub() && !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) { break_index_++; - return; + break; } if (code->kind() == Code::STUB) { if (RelocInfo::IsDebuggerStatement(rmode())) { break_index_++; - return; + break; } else if (CodeStub::GetMajorKey(code) == CodeStub::CallFunction) { break_index_++; - return; + break; } } } @@ -149,9 +154,10 @@ void BreakLocation::Iterator::Next() { if (RelocInfo::IsDebugBreakSlot(rmode()) && type_ != CALLS_AND_RETURNS) { // There is always a possible break point at a debug break slot. break_index_++; - return; + break; } } + has_immediate_position_ = false; } diff --git a/src/debug.h b/src/debug.h index fcea2bd..6a267a8 100644 --- a/src/debug.h +++ b/src/debug.h @@ -186,6 +186,7 @@ class BreakLocation { int break_index_; int position_; int statement_position_; + bool has_immediate_position_; DisallowHeapAllocation no_gc_; diff --git a/test/mjsunit/regress/regress-crbug-481896.js b/test/mjsunit/regress/regress-crbug-481896.js new file mode 100644 index 0000000..0d5c650 --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-481896.js @@ -0,0 +1,56 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug + +function static() { + print("> static"); // Break +} + +var Debug = debug.Debug; +var exception = null; +var break_count = 0; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + print("breakpoint hit at " + exec_state.frame(0).sourceLineText()); + assertTrue(exec_state.frame(0).sourceLineText().indexOf("// Break") > 0); + break_count++; + } catch (e) { + exception = e; + } +} + +Debug.setListener(listener); + +function install() { + eval("this.dynamic = function dynamic() { \n" + + " print(\"> dynamic\"); // Break\n" + + "}\n" + + "//@ sourceURL=dynamicScript"); +} + +install(); + +var scripts = Debug.scripts(); +var dynamic_script; +var static_script; +for (var script of scripts) { + if (script.source_url == "dynamicScript") dynamic_script = script; + if (script.source_url == "staticScript") static_script = script; +} + +Debug.setScriptBreakPointById(dynamic_script.id, 1); +Debug.setScriptBreakPointById(static_script.id, 7); + +dynamic(); +static(); + +Debug.setListener(null); + +assertNull(exception); +assertEquals(2, break_count); + +//@ sourceURL=staticScript