[V8] Add flag to avoid breakpoint relocation
authorKai Koehne <kai.koehne@nokia.com>
Thu, 10 Nov 2011 15:00:37 +0000 (16:00 +0100)
committerQt by Nokia <qt-info@nokia.com>
Wed, 13 Jun 2012 07:57:32 +0000 (09:57 +0200)
Add a flag that prevents v8 from relocating breakpoints across
line boundaries.

Change-Id: I29dea335ad362d995326dea09ecf4d3aba3f462d
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
src/3rdparty/v8/src/debug-debugger.js
src/3rdparty/v8/src/flag-definitions.h
src/3rdparty/v8/src/runtime.cc
src/3rdparty/v8/src/runtime.h
src/3rdparty/v8/test/cctest/test-debug.cc

index 91838e8..5cdbf14 100644 (file)
@@ -449,6 +449,11 @@ ScriptBreakPoint.prototype.set = function (script) {
     actual_position = position;
   }
   var actual_location = script.locationFromPosition(actual_position, true);
+  // Check for any relocation and compare it with the breakpoint_relocation flag
+  if (actual_location.line != line && !%AllowBreakPointRelocation()) {
+    %ClearBreakPoint(break_point);
+    return;
+  }
   break_point.actual_location = { line: actual_location.line,
                                   column: actual_location.column,
                                   script_id: script.id };
index ccba511..f59be3c 100644 (file)
@@ -317,6 +317,7 @@ DEFINE_bool(trace_debug_json, false, "trace debugging JSON request/response")
 DEFINE_bool(debugger_auto_break, true,
             "automatically set the debug break flag when debugger commands are "
             "in the queue")
+DEFINE_bool(breakpoint_relocation, true, "relocate breakpoints to the next executable line")
 DEFINE_bool(enable_liveedit, true, "enable liveedit experimental feature")
 DEFINE_bool(break_on_abort, true, "always cause a debug break before aborting")
 
index f9acdb7..919bf7a 100644 (file)
@@ -11605,6 +11605,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetBreakLocations) {
 }
 
 
+// Return the value of breakpoint_relocation flag
+RUNTIME_FUNCTION(MaybeObject*, Runtime_AllowBreakPointRelocation) {
+  return Smi::FromInt(FLAG_breakpoint_relocation);
+}
+
+
 // Set a break point in a function
 // args[0]: function
 // args[1]: number: break source position (within the function source)
index 429102b..cfd8b1e 100644 (file)
@@ -412,6 +412,7 @@ namespace internal {
   F(GetThreadDetails, 2, 1) \
   F(SetDisableBreak, 1, 1) \
   F(GetBreakLocations, 1, 1) \
+  F(AllowBreakPointRelocation, 0, 1) \
   F(SetFunctionBreakPoint, 3, 1) \
   F(SetScriptBreakPoint, 3, 1) \
   F(ClearBreakPoint, 1, 1) \
index e40f406..9c831fb 100644 (file)
@@ -2300,6 +2300,65 @@ TEST(ScriptBreakPointTopLevelCrash) {
   CheckDebuggerUnloaded();
 }
 
+// Test that breakpoint_relocation flag is honored
+TEST(ScriptBreakPointNoRelocation) {
+    i::FLAG_breakpoint_relocation = false;
+
+    v8::HandleScope scope;
+    DebugLocalContext env;
+    env.ExposeDebug();
+
+    // Create a function for checking the function when hitting a break point.
+    frame_function_name = CompileFunction(&env,
+                                          frame_function_name_source,
+                                          "frame_function_name");
+
+    v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
+                                     v8::Undefined());
+
+    v8::Local<v8::String> script1 = v8::String::New(
+      "a = 0                      // line 0\n"
+      "                           // line 1\n"
+      "                           // line 2\n"
+      "                           // line 3\n"
+      "function f() {             // line 4\n"
+      "  return 0;                // line 5\n"
+      "}                          // line 6");
+
+    // Set the script break point on the empty line
+    SetScriptBreakPointByNameFromJS("test.html", 2, -1);
+
+    // Compile the script and call the function.
+    v8::ScriptOrigin origin(v8::String::New("test.html"), v8::Integer::New(0));
+    v8::Script::Compile(script1, &origin)->Run();
+    v8::Local<v8::Function> f
+            = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
+    f->Call(env->Global(), 0, NULL);
+
+    // Check that a break point was not hit
+    CHECK_EQ(0, break_point_hit_count);
+
+    v8::Local<v8::String> script2 = v8::String::New(
+      "a = 0                      // line 0\n"
+      "function g() {             // line 1\n"
+      "  return 0;                // line 2\n"
+      "}                          // line 3\n"
+      "function f() {             // line 4\n"
+      "  return 0;                // line 5\n"
+      "}                          // line 6");
+
+    // Compile the script and call the new function
+    v8::Script::Compile(script2, &origin)->Run();
+    v8::Local<v8::Function> g
+            = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g")));
+    g->Call(env->Global(), 0, NULL);
+
+    // Check that a break point was not hit
+    CHECK_EQ(1, break_point_hit_count);
+
+    v8::Debug::SetDebugEventListener(NULL);
+    CheckDebuggerUnloaded();
+}
 
 // Test that it is possible to remove the last break point for a function
 // inside the break handling of that break point.