Reviewers: Yang,

Description:
Debug: support breakpoints set in the middle of statement

Please review this at https://codereview.chromium.org/16093040/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/debug-debugger.js
  M src/debug.h
  M src/debug.cc
  M src/runtime.h
  M src/runtime.cc
  M test/cctest/test-debug.cc


Index: src/debug-debugger.js
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index 7787312ddc68ead51e24738a512d6affda2f4501..180717ecf2dda9cf9108399cf89cb36385a87b7d 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -251,7 +251,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_statement_aligned) {
   this.type_ = type;
   if (type == Debug.ScriptBreakPointType.ScriptId) {
     this.script_id_ = script_id_or_name;
@@ -265,6 +265,7 @@ 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.statement_aligned_ = opt_statement_aligned !== false;
   this.hit_count_ = 0;
   this.active_ = true;
   this.condition_ = null;
@@ -276,7 +277,7 @@ 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.statement_aligned_);
   copy.number_ = next_break_point_number++;
   script_break_points.push(copy);

@@ -443,7 +444,7 @@ 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.statement_aligned_, break_point);
   if (IS_UNDEFINED(actual_position)) {
     actual_position = position;
   }
@@ -685,7 +686,7 @@ Debug.setBreakPointByScriptIdAndPosition = function(script_id, position,
   for (var i = 0; i < scripts.length; i++) {
     if (script_id == scripts[i].id) {
break_point.actual_position = %SetScriptBreakPoint(scripts[i], position,
-                                                         break_point);
+ true, break_point);
       break;
     }
   }
@@ -780,11 +781,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_statement_aligned) {
   // 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_statement_aligned);

   // Assign number to the new script break point and add it.
   script_break_point.number_ = next_break_point_number++;
@@ -806,10 +807,10 @@ 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_statement_aligned) {
   return this.setScriptBreakPoint(Debug.ScriptBreakPointType.ScriptId,
                                   script_id, opt_line, opt_column,
-                                  opt_condition, opt_groupId);
+ opt_condition, opt_groupId, opt_statement_aligned);
 };


Index: src/debug.cc
diff --git a/src/debug.cc b/src/debug.cc
index 5d26ba2b139e36fc8704678c4b2c1919b74447a8..de44ff5e3ec6f84004d8a52d29dc3634c72b3aa4 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -235,17 +235,24 @@ 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,
+    bool statement_alighned) {
   // 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;
+    if (statement_alighned) {
+      next_position = this->statement_position();
+    } else {
+      next_position = this->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;
     }
@@ -1176,7 +1183,7 @@ void Debug::SetBreakPoint(Handle<JSFunction> function,

   // Find the break point and change it.
   BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
-  it.FindBreakLocationFromPosition(*source_position);
+  it.FindBreakLocationFromPosition(*source_position, true);
   it.SetBreakPoint(break_point_object);

   *source_position = it.position();
@@ -1188,7 +1195,8 @@ void Debug::SetBreakPoint(Handle<JSFunction> function,

 bool Debug::SetBreakPointForScript(Handle<Script> script,
                                    Handle<Object> break_point_object,
-                                   int* source_position) {
+                                   int* source_position,
+                                   bool statement_alighned) {
   HandleScope scope(isolate_);

   PrepareForBreakPoints();
@@ -1219,7 +1227,7 @@ bool Debug::SetBreakPointForScript(Handle<Script> script,

   // Find the break point and change it.
   BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS);
-  it.FindBreakLocationFromPosition(position);
+  it.FindBreakLocationFromPosition(position, statement_alighned);
   it.SetBreakPoint(break_point_object);

   *source_position = it.position() + shared->start_position();
Index: src/debug.h
diff --git a/src/debug.h b/src/debug.h
index 467acb93e81eb130372a36eb2c4a873e00302a96..f7e94f57095c655dd07477f5d019bad9c751bb3b 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -90,7 +90,7 @@ class BreakLocationIterator {
   void Next();
   void Next(int count);
   void FindBreakLocationFromAddress(Address pc);
-  void FindBreakLocationFromPosition(int position);
+ void FindBreakLocationFromPosition(int position, bool statement_alighned);
   void Reset();
   bool Done() const;
   void SetBreakPoint(Handle<Object> break_point_object);
@@ -240,7 +240,8 @@ class Debug {
                      int* source_position);
   bool SetBreakPointForScript(Handle<Script> script,
                               Handle<Object> break_point_object,
-                              int* source_position);
+                              int* source_position,
+                              bool statement_alighned);
   void ClearBreakPoint(Handle<Object> break_point_object);
   void ClearAllBreakPoints();
   void FloodWithOneShot(Handle<JSFunction> function);
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index ff55fab8c95f51359464eb2e80f05ab24c63b792..ed196fc230369feae516039ce7cb2ceaff5fd313 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -11878,11 +11878,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFunctionBreakPoint) {
 // args[2]: number: break point object
 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 3);
+  ASSERT(args.length() == 4);
   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
   RUNTIME_ASSERT(source_position >= 0);
-  Handle<Object> break_point_object_arg = args.at<Object>(2);
+  CONVERT_BOOLEAN_ARG_CHECKED(statement_alighned, 2);
+  Handle<Object> break_point_object_arg = args.at<Object>(3);

   // Get the script from the script wrapper.
   RUNTIME_ASSERT(wrapper->value()->IsScript());
@@ -11890,7 +11891,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetScriptBreakPoint) {

   // Set break point.
if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
-                                                &source_position)) {
+                                                &source_position,
+                                                statement_alighned)) {
     return  isolate->heap()->undefined_value();
   }

Index: src/runtime.h
diff --git a/src/runtime.h b/src/runtime.h
index 8ef4c813fcaf452650156059a8d1fa0e32eef8cf..d8d00909bcdcb4ebd933c919d268a934f43e4dc7 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -477,7 +477,7 @@ namespace internal {
   F(SetDisableBreak, 1, 1) \
   F(GetBreakLocations, 1, 1) \
   F(SetFunctionBreakPoint, 3, 1) \
-  F(SetScriptBreakPoint, 3, 1) \
+  F(SetScriptBreakPoint, 4, 1) \
   F(ClearBreakPoint, 1, 1) \
   F(ChangeBreakOnException, 2, 1) \
   F(IsBreakOnException, 1, 1) \
Index: test/cctest/test-debug.cc
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index b22092a2632b9fa7635ba9f57fef327650c72db7..f1a66f9b93109e3dfb6b783292c6c0d88f574491 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -508,7 +508,7 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
   Handle<v8::internal::SharedFunctionInfo> shared(fun->shared());
   CHECK(Debug::HasDebugInfo(shared));
   TestBreakLocationIterator it1(Debug::GetDebugInfo(shared));
-  it1.FindBreakLocationFromPosition(position);
+  it1.FindBreakLocationFromPosition(position, true);
   v8::internal::RelocInfo::Mode actual_mode = it1.it()->rinfo()->rmode();
   if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
     actual_mode = v8::internal::RelocInfo::CODE_TARGET;
@@ -527,7 +527,7 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
   CHECK(!debug->HasDebugInfo(shared));
   CHECK(debug->EnsureDebugInfo(shared, fun));
   TestBreakLocationIterator it2(Debug::GetDebugInfo(shared));
-  it2.FindBreakLocationFromPosition(position);
+  it2.FindBreakLocationFromPosition(position, true);
   actual_mode = it2.it()->rinfo()->rmode();
   if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
     actual_mode = v8::internal::RelocInfo::CODE_TARGET;


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to