From: yangguo@chromium.org Date: Mon, 30 Jan 2012 13:07:01 +0000 (+0000) Subject: Find correct source position in inlined functions on debug break. X-Git-Tag: upstream/4.7.83~17492 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f7c09d99b79c5c35c4665d1116d627011d793ade;p=platform%2Fupstream%2Fv8.git Find correct source position in inlined functions on debug break. BUG=110010 TEST=test-debug/DebugBreakInline Review URL: https://chromiumcodereview.appspot.com/9295014 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10551 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index 56ff454..525ccec 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)); } diff --git a/src/deoptimizer.h b/src/deoptimizer.h index 8b1152d..db6a59a 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
(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; }; diff --git a/src/runtime.cc b/src/runtime.cc index a5cc10c..5e007e2 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 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 function(JSFunction::cast(frame_inspector.GetFunction())); + Handle 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 function(JSFunction::cast(frame_inspector.GetFunction())); - Handle shared(function->shared()); Handle scope_info(shared->scope_info()); ASSERT(*scope_info != ScopeInfo::Empty()); diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc index c0ea707..d66f094 100644 --- a/test/cctest/test-debug.cc +++ b/test/cctest/test-debug.cc @@ -7286,4 +7286,65 @@ TEST(DebugBreakLoop) { } +v8::Local inline_script; + +static void DebugBreakInlineListener(v8::DebugEvent event, + v8::Handle exec_state, + v8::Handle event_data, + v8::Handle data) { + if (event != v8::Break) return; + + int expected_frame_count = 4; + int expected_line_number[] = {1, 4, 7, 12}; + + i::Handle compiled_script = v8::Utils::OpenHandle(*inline_script); + i::Handle source_script = i::Handle(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 script_vector(script, sizeof(script)); + OS::SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id); + v8::Local 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 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