Reviewers: Søren Thygesen Gjesse,
Message:
Please take a look.
Description:
Find correct source position in inlined functions on debug break.
BUG=110010
TEST=test-debug/DebugBreakInline
Please review this at http://codereview.chromium.org/9295014/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/deoptimizer.h
M src/deoptimizer.cc
M src/runtime.cc
M test/cctest/test-debug.cc
Index: src/deoptimizer.cc
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index
56ff4549da25b5e60f60ab0709172cc1d9aad821..525ccec5bab91ee5be43811162396fd7c322672c
100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -1603,6 +1603,7 @@ DeoptimizedFrameInfo::DeoptimizedFrameInfo(
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));
}
Index: src/deoptimizer.h
diff --git a/src/deoptimizer.h b/src/deoptimizer.h
index
8b1152d52957a7da6e37ecb56c4a07d17767accd..db6a59a259bd4b4fa3d28da6c34d3bf308d459d9
100644
--- a/src/deoptimizer.h
+++ b/src/deoptimizer.h
@@ -749,6 +749,10 @@ class DeoptimizedFrameInfo : public Malloced {
return expression_stack_[index];
}
+ Address GetPc() {
+ return reinterpret_cast<Address>(pc_);
+ }
+
private:
// Set the frame function.
void SetFunction(JSFunction* function) {
@@ -772,6 +776,7 @@ class DeoptimizedFrameInfo : public Malloced {
int expression_count_;
Object** parameters_;
Object** expression_stack_;
+ intptr_t pc_;
friend class Deoptimizer;
};
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
a5cc10cd8ee9d3ca46267bcbbfecd5adf308714c..5e007e2f84f08a4aa54351615c6025d826eb3f5b
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -10747,6 +10747,11 @@ class FrameInspector {
? 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 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_GetFrameDetails) {
// 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());
Index: test/cctest/test-debug.cc
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index
c0ea7072fed35bd782f377a8b2d974bc9d32dc98..1e674dc2bdf89bb7a451838c52b38226238b616b
100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -7286,4 +7286,57 @@ TEST(DebugBreakLoop) {
}
+class DebugBreakSendThread : public v8::internal::Thread {
+ public:
+ DebugBreakSendThread() : Thread("DebugBreakSendThread") { }
+ virtual void Run() {
+ // Wait for crankshaft to inline f() into g();
+ OS::Sleep(2000);
+ v8::Debug::DebugBreak();
+ }
+};
+
+
+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 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();
+ int previous = -1;
+ 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);
+ ASSERT_NE(previous, result->Int32Value());
+ previous = result->Int32Value();
+ }
+
+ v8::V8::TerminateExecution();
+}
+
+
+TEST(DebugBreakInline) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope;
+ DebugLocalContext env;
+ const char* source =
+ "function f() { for(var i=0; i<1000000; i++) { 1+1; } };\n"
+ "function g() { while(true) {f();} };\n"
+ "g();";
+ v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
+ DebugBreakSendThread debugbreak;
+ debugbreak.Start();
+ CompileRun(source);
+ v8::Debug::SetDebugEventListener(NULL);
+}
+
+
#endif // ENABLE_DEBUGGER_SUPPORT
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev