Revision: 10551
Author:   [email protected]
Date:     Mon Jan 30 05:07:01 2012
Log:      Find correct source position in inlined functions on debug break.

BUG=110010
TEST=test-debug/DebugBreakInline

Review URL: https://chromiumcodereview.appspot.com/9295014
http://code.google.com/p/v8/source/detail?r=10551

Modified:
 /branches/bleeding_edge/src/deoptimizer.cc
 /branches/bleeding_edge/src/deoptimizer.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/test/cctest/test-debug.cc

=======================================
--- /branches/bleeding_edge/src/deoptimizer.cc  Mon Jan 30 02:20:13 2012
+++ /branches/bleeding_edge/src/deoptimizer.cc  Mon Jan 30 05:07:01 2012
@@ -1603,6 +1603,7 @@
   SetFunction(output_frame->GetFunction());
   expression_count_ = output_frame->GetExpressionCount();
   expression_stack_ = new Object*[expression_count_];
+  pc_ = output_frame->GetPc();
   for (int i = 0; i < expression_count_; i++) {
     SetExpression(i, output_frame->GetExpression(i));
   }
=======================================
--- /branches/bleeding_edge/src/deoptimizer.h   Thu Jan 26 07:53:21 2012
+++ /branches/bleeding_edge/src/deoptimizer.h   Mon Jan 30 05:07:01 2012
@@ -748,6 +748,10 @@
     ASSERT(0 <= index && index < expression_count());
     return expression_stack_[index];
   }
+
+  Address GetPc() {
+    return reinterpret_cast<Address>(pc_);
+  }

  private:
   // Set the frame function.
@@ -772,6 +776,7 @@
   int expression_count_;
   Object** parameters_;
   Object** expression_stack_;
+  intptr_t pc_;

   friend class Deoptimizer;
 };
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Thu Jan 26 13:47:57 2012
+++ /branches/bleeding_edge/src/runtime.cc      Mon Jan 30 05:07:01 2012
@@ -10747,6 +10747,11 @@
         ? deoptimized_frame_->GetExpression(index)
         : frame_->GetExpression(index);
   }
+  Address GetPc() {
+    return is_optimized_
+        ? deoptimized_frame_->GetPc()
+        : frame_->pc();
+  }

   // To inspect all the provided arguments the frame might need to be
   // replaced with the arguments frame.
@@ -10852,17 +10857,16 @@
   // Get the frame id.
   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);

-  // Find source position.
-  int position =
-      it.frame()->LookupCode()->SourcePosition(it.frame()->pc());
+  // Find source position in unoptimized code.
+ Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
+  Handle<SharedFunctionInfo> shared(function->shared());
+  int position = shared->code()->SourcePosition(frame_inspector.GetPc());

   // Check for constructor frame. Inlined frames cannot be construct calls.
   bool inlined_frame = is_optimized && inlined_jsframe_index != 0;
   bool constructor = !inlined_frame && it.frame()->IsConstructor();

   // Get scope info and read from it for local variable information.
- Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
-  Handle<SharedFunctionInfo> shared(function->shared());
   Handle<ScopeInfo> scope_info(shared->scope_info());
   ASSERT(*scope_info != ScopeInfo::Empty());

=======================================
--- /branches/bleeding_edge/test/cctest/test-debug.cc Tue Jan 24 08:36:55 2012 +++ /branches/bleeding_edge/test/cctest/test-debug.cc Mon Jan 30 05:07:01 2012
@@ -7284,6 +7284,67 @@
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
 }
+
+
+v8::Local<v8::Script> inline_script;
+
+static void DebugBreakInlineListener(v8::DebugEvent event,
+                                     v8::Handle<v8::Object> exec_state,
+                                     v8::Handle<v8::Object> event_data,
+                                     v8::Handle<v8::Value> data) {
+  if (event != v8::Break) return;
+
+  int expected_frame_count = 4;
+  int expected_line_number[] = {1, 4, 7, 12};
+
+ i::Handle<i::Object> compiled_script = v8::Utils::OpenHandle(*inline_script); + i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast(
+      i::JSFunction::cast(*compiled_script)->shared()->script()));
+
+  int break_id = v8::internal::Isolate::Current()->debug()->break_id();
+  char script[128];
+  i::Vector<char> script_vector(script, sizeof(script));
+  OS::SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id);
+  v8::Local<v8::Value> result = CompileRun(script);
+
+  int frame_count = result->Int32Value();
+  CHECK_EQ(expected_frame_count, frame_count);
+
+  for (int i = 0; i < frame_count; i++) {
+    // The 5. element in the returned array of GetFrameDetails contains the
+    // source position of that frame.
+ OS::SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i);
+    v8::Local<v8::Value> result = CompileRun(script);
+    CHECK_EQ(expected_line_number[i],
+             i::GetScriptLineNumber(source_script, result->Int32Value()));
+  }
+  v8::Debug::SetDebugEventListener(NULL);
+  v8::V8::TerminateExecution();
+}
+
+
+TEST(DebugBreakInline) {
+  i::FLAG_allow_natives_syntax = true;
+  v8::HandleScope scope;
+  DebugLocalContext env;
+  const char* source =
+      "function debug(b) {             \n"
+      "  if (b) debugger;              \n"
+      "}                               \n"
+      "function f(b) {                 \n"
+      "  debug(b)                      \n"
+      "};                              \n"
+      "function g(b) {                 \n"
+      "  f(b);                         \n"
+      "};                              \n"
+      "g(false);                       \n"
+      "g(false);                       \n"
+      "%OptimizeFunctionOnNextCall(g); \n"
+      "g(true);";
+  v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
+  inline_script = v8::Script::Compile(v8::String::New(source));
+  inline_script->Run();
+}


 #endif  // ENABLE_DEBUGGER_SUPPORT

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to