From f997bacb16040e461870fa546f8e9d6c5d6eb05f Mon Sep 17 00:00:00 2001 From: "prybin@chromium.org" Date: Mon, 1 Jul 2013 12:54:13 +0000 Subject: [PATCH] Debug: support breakpoints set in the middle of statement R=yangguo@chromium.org Review URL: https://codereview.chromium.org/16093040 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15416 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/debug-debugger.js | 45 +++++++++++++++++++++++++++----------- src/debug.cc | 46 +++++++++++++++++++++++++++++++-------- src/debug.h | 17 ++++++++++++--- src/runtime.cc | 35 ++++++++++++++++++++++++----- src/runtime.h | 4 ++-- test/cctest/test-debug.cc | 4 ++-- test/mjsunit/debug-breakpoints.js | 25 ++++++++++++++++++--- 7 files changed, 138 insertions(+), 38 deletions(-) diff --git a/src/debug-debugger.js b/src/debug-debugger.js index 7787312..88efbe2 100644 --- a/src/debug-debugger.js +++ b/src/debug-debugger.js @@ -71,6 +71,13 @@ Debug.ScriptBreakPointType = { ScriptId: 0, ScriptName: 1, ScriptRegExp: 2 }; +// The different types of breakpoint position alignments. +// Must match BreakPositionAlignment in debug.h. +Debug.BreakPositionAlignment = { + Statement: 0, + BreakPosition: 1 +}; + function ScriptTypeFlag(type) { return (1 << type); } @@ -251,7 +258,7 @@ function IsBreakPointTriggered(break_id, break_point) { // script name or script id and the break point is represented as line and // column. function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column, - opt_groupId) { + opt_groupId, opt_position_alignment) { this.type_ = type; if (type == Debug.ScriptBreakPointType.ScriptId) { this.script_id_ = script_id_or_name; @@ -265,6 +272,8 @@ function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column, this.line_ = opt_line || 0; this.column_ = opt_column; this.groupId_ = opt_groupId; + this.position_alignment_ = IS_UNDEFINED(opt_position_alignment) + ? Debug.BreakPositionAlignment.Statement : opt_position_alignment; this.hit_count_ = 0; this.active_ = true; this.condition_ = null; @@ -276,7 +285,8 @@ function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column, //Creates a clone of script breakpoint that is linked to another script. ScriptBreakPoint.prototype.cloneForOtherScript = function (other_script) { var copy = new ScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId, - other_script.id, this.line_, this.column_, this.groupId_); + other_script.id, this.line_, this.column_, this.groupId_, + this.position_alignment_); copy.number_ = next_break_point_number++; script_break_points.push(copy); @@ -443,7 +453,9 @@ ScriptBreakPoint.prototype.set = function (script) { // Create a break point object and set the break point. break_point = MakeBreakPoint(position, this); break_point.setIgnoreCount(this.ignoreCount()); - var actual_position = %SetScriptBreakPoint(script, position, break_point); + var actual_position = %SetScriptBreakPoint(script, position, + this.position_alignment_, + break_point); if (IS_UNDEFINED(actual_position)) { actual_position = position; } @@ -509,9 +521,11 @@ Debug.breakExecution = function(f) { %Break(); }; -Debug.breakLocations = function(f) { +Debug.breakLocations = function(f, opt_position_aligment) { if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.'); - return %GetBreakLocations(f); + var position_aligment = IS_UNDEFINED(opt_position_aligment) + ? Debug.BreakPositionAlignment.Statement : opt_position_aligment; + return %GetBreakLocations(f, position_aligment); }; // Returns a Script object. If the parameter is a function the return value @@ -674,7 +688,8 @@ Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) { Debug.setBreakPointByScriptIdAndPosition = function(script_id, position, - condition, enabled) + condition, enabled, + opt_position_alignment) { break_point = MakeBreakPoint(position); break_point.setCondition(condition); @@ -682,10 +697,12 @@ Debug.setBreakPointByScriptIdAndPosition = function(script_id, position, break_point.disable(); } var scripts = this.scripts(); + var position_alignment = IS_UNDEFINED(opt_position_alignment) + ? Debug.BreakPositionAlignment.Statement : opt_position_alignment; for (var i = 0; i < scripts.length; i++) { if (script_id == scripts[i].id) { break_point.actual_position = %SetScriptBreakPoint(scripts[i], position, - break_point); + position_alignment, break_point); break; } } @@ -780,11 +797,11 @@ Debug.findScriptBreakPoint = function(break_point_number, remove) { // specified source line and column within that line. Debug.setScriptBreakPoint = function(type, script_id_or_name, opt_line, opt_column, opt_condition, - opt_groupId) { + opt_groupId, opt_position_alignment) { // Create script break point object. var script_break_point = new ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column, - opt_groupId); + opt_groupId, opt_position_alignment); // Assign number to the new script break point and add it. script_break_point.number_ = next_break_point_number++; @@ -806,10 +823,12 @@ Debug.setScriptBreakPoint = function(type, script_id_or_name, Debug.setScriptBreakPointById = function(script_id, opt_line, opt_column, - opt_condition, opt_groupId) { + opt_condition, opt_groupId, + opt_position_alignment) { return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId, script_id, opt_line, opt_column, - opt_condition, opt_groupId); + opt_condition, opt_groupId, + opt_position_alignment); }; @@ -893,11 +912,11 @@ Debug.isBreakOnUncaughtException = function() { return !!%IsBreakOnException(Debug.ExceptionBreak.Uncaught); }; -Debug.showBreakPoints = function(f, full) { +Debug.showBreakPoints = function(f, full, opt_position_alignment) { if (!IS_FUNCTION(f)) throw new Error('Parameters have wrong types.'); var source = full ? this.scriptSource(f) : this.source(f); var offset = full ? this.sourcePosition(f) : 0; - var locations = this.breakLocations(f); + var locations = this.breakLocations(f, opt_position_alignment); if (!locations) return source; locations.sort(function(x, y) { return x - y; }); var result = ""; diff --git a/src/debug.cc b/src/debug.cc index efb95a0..07c1a0c 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -235,17 +235,30 @@ void BreakLocationIterator::FindBreakLocationFromAddress(Address pc) { // Find the break point closest to the supplied source position. -void BreakLocationIterator::FindBreakLocationFromPosition(int position) { +void BreakLocationIterator::FindBreakLocationFromPosition(int position, + BreakPositionAlignment alignment) { // Run through all break points to locate the one closest to the source // position. int closest_break_point = 0; int distance = kMaxInt; + while (!Done()) { + int next_position; + switch (alignment) { + case STATEMENT_ALIGNED: + next_position = this->statement_position(); + break; + case BREAK_POSITION_ALIGNED: + next_position = this->position(); + break; + default: + UNREACHABLE(); + next_position = this->statement_position(); + } // Check if this break point is closer that what was previously found. - if (position <= statement_position() && - statement_position() - position < distance) { + if (position <= next_position && next_position - position < distance) { closest_break_point = break_point(); - distance = statement_position() - position; + distance = next_position - position; // Check whether we can't get any closer. if (distance == 0) break; } @@ -1190,7 +1203,7 @@ void Debug::SetBreakPoint(Handle function, // Find the break point and change it. BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); - it.FindBreakLocationFromPosition(*source_position); + it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED); it.SetBreakPoint(break_point_object); *source_position = it.position(); @@ -1202,7 +1215,8 @@ void Debug::SetBreakPoint(Handle function, bool Debug::SetBreakPointForScript(Handle