| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 | 242 |
| 243 // Find the break point at the supplied address, or the closest one before | 243 // Find the break point at the supplied address, or the closest one before |
| 244 // the address. | 244 // the address. |
| 245 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info, | 245 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info, |
| 246 int offset) { | 246 int offset) { |
| 247 base::SmartPointer<Iterator> it(GetIterator(debug_info)); | 247 base::SmartPointer<Iterator> it(GetIterator(debug_info)); |
| 248 it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset)); | 248 it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset)); |
| 249 return it->GetBreakLocation(); | 249 return it->GetBreakLocation(); |
| 250 } | 250 } |
| 251 | 251 |
| 252 FrameSummary GetFirstFrameSummary(JavaScriptFrame* frame) { | |
| 253 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | |
| 254 frame->Summarize(&frames); | |
| 255 return frames.first(); | |
| 256 } | |
| 257 | |
| 258 int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) { | 252 int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) { |
| 259 // Code offset points to the instruction after the call. Subtract 1 to | 253 // Code offset points to the instruction after the call. Subtract 1 to |
| 260 // exclude that instruction from the search. For bytecode, the code offset | 254 // exclude that instruction from the search. For bytecode, the code offset |
| 261 // still points to the call. | 255 // still points to the call. |
| 262 return is_interpreted ? code_offset : code_offset - 1; | 256 return is_interpreted ? code_offset : code_offset - 1; |
| 263 } | 257 } |
| 264 | 258 |
| 265 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info, | 259 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info, |
| 266 JavaScriptFrame* frame) { | 260 JavaScriptFrame* frame) { |
| 267 FrameSummary summary = GetFirstFrameSummary(frame); | 261 FrameSummary summary = FrameSummary::GetFirst(frame); |
| 268 int call_offset = | 262 int call_offset = |
| 269 CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted()); | 263 CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted()); |
| 270 return FromCodeOffset(debug_info, call_offset); | 264 return FromCodeOffset(debug_info, call_offset); |
| 271 } | 265 } |
| 272 | 266 |
| 273 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info, | 267 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info, |
| 274 int statement_position, | 268 int statement_position, |
| 275 List<BreakLocation>* result_out) { | 269 List<BreakLocation>* result_out) { |
| 276 for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done(); | 270 for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done(); |
| 277 it->Next()) { | 271 it->Next()) { |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 return; | 604 return; |
| 611 case StepOut: | 605 case StepOut: |
| 612 // Step out has not reached the target frame yet. | 606 // Step out has not reached the target frame yet. |
| 613 if (current_fp < target_fp) return; | 607 if (current_fp < target_fp) return; |
| 614 break; | 608 break; |
| 615 case StepNext: | 609 case StepNext: |
| 616 // Step next should not break in a deeper frame. | 610 // Step next should not break in a deeper frame. |
| 617 if (current_fp < target_fp) return; | 611 if (current_fp < target_fp) return; |
| 618 // Fall through. | 612 // Fall through. |
| 619 case StepIn: { | 613 case StepIn: { |
| 620 FrameSummary summary = GetFirstFrameSummary(frame); | 614 FrameSummary summary = FrameSummary::GetFirst(frame); |
| 621 int offset = summary.code_offset(); | 615 int offset = summary.code_offset(); |
| 622 step_break = location.IsReturn() || (current_fp != last_fp) || | 616 step_break = location.IsReturn() || (current_fp != last_fp) || |
| 623 (thread_local_.last_statement_position_ != | 617 (thread_local_.last_statement_position_ != |
| 624 location.abstract_code()->SourceStatementPosition(offset)); | 618 location.abstract_code()->SourceStatementPosition(offset)); |
| 625 break; | 619 break; |
| 626 } | 620 } |
| 627 case StepFrame: | 621 case StepFrame: |
| 628 step_break = current_fp != last_fp; | 622 step_break = current_fp != last_fp; |
| 629 break; | 623 break; |
| 630 } | 624 } |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 // Step out: Find the calling JavaScript frame and flood it with | 983 // Step out: Find the calling JavaScript frame and flood it with |
| 990 // breakpoints. | 984 // breakpoints. |
| 991 frames_it.Advance(); | 985 frames_it.Advance(); |
| 992 // Fill the function to return to with one-shot break points. | 986 // Fill the function to return to with one-shot break points. |
| 993 JSFunction* function = frames_it.frame()->function(); | 987 JSFunction* function = frames_it.frame()->function(); |
| 994 FloodWithOneShot(Handle<JSFunction>(function)); | 988 FloodWithOneShot(Handle<JSFunction>(function)); |
| 995 return; | 989 return; |
| 996 } | 990 } |
| 997 | 991 |
| 998 // Get the debug info (create it if it does not exist). | 992 // Get the debug info (create it if it does not exist). |
| 999 FrameSummary summary = GetFirstFrameSummary(frame); | 993 FrameSummary summary = FrameSummary::GetFirst(frame); |
| 1000 Handle<JSFunction> function(summary.function()); | 994 Handle<JSFunction> function(summary.function()); |
| 1001 Handle<SharedFunctionInfo> shared(function->shared()); | 995 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1002 if (!EnsureDebugInfo(shared, function)) { | 996 if (!EnsureDebugInfo(shared, function)) { |
| 1003 // Return if ensuring debug info failed. | 997 // Return if ensuring debug info failed. |
| 1004 return; | 998 return; |
| 1005 } | 999 } |
| 1006 | 1000 |
| 1007 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 1001 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
| 1008 // Refresh frame summary if the code has been recompiled for debugging. | 1002 // Refresh frame summary if the code has been recompiled for debugging. |
| 1009 if (AbstractCode::cast(shared->code()) != *summary.abstract_code()) { | 1003 if (AbstractCode::cast(shared->code()) != *summary.abstract_code()) { |
| 1010 summary = GetFirstFrameSummary(frame); | 1004 summary = FrameSummary::GetFirst(frame); |
| 1011 } | 1005 } |
| 1012 | 1006 |
| 1013 int call_offset = | 1007 int call_offset = |
| 1014 CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted()); | 1008 CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted()); |
| 1015 BreakLocation location = | 1009 BreakLocation location = |
| 1016 BreakLocation::FromCodeOffset(debug_info, call_offset); | 1010 BreakLocation::FromCodeOffset(debug_info, call_offset); |
| 1017 | 1011 |
| 1018 // At a return statement we will step out either way. | 1012 // At a return statement we will step out either way. |
| 1019 if (location.IsReturn()) step_action = StepOut; | 1013 if (location.IsReturn()) step_action = StepOut; |
| 1020 | 1014 |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1580 HandleScope scope(isolate_); | 1574 HandleScope scope(isolate_); |
| 1581 | 1575 |
| 1582 // Get the executing function in which the debug break occurred. | 1576 // Get the executing function in which the debug break occurred. |
| 1583 Handle<JSFunction> function(JSFunction::cast(frame->function())); | 1577 Handle<JSFunction> function(JSFunction::cast(frame->function())); |
| 1584 Handle<SharedFunctionInfo> shared(function->shared()); | 1578 Handle<SharedFunctionInfo> shared(function->shared()); |
| 1585 | 1579 |
| 1586 // With no debug info there are no break points, so we can't be at a return. | 1580 // With no debug info there are no break points, so we can't be at a return. |
| 1587 if (!shared->HasDebugInfo()) return false; | 1581 if (!shared->HasDebugInfo()) return false; |
| 1588 | 1582 |
| 1589 DCHECK(!frame->is_optimized()); | 1583 DCHECK(!frame->is_optimized()); |
| 1590 FrameSummary summary = GetFirstFrameSummary(frame); | 1584 FrameSummary summary = FrameSummary::GetFirst(frame); |
| 1591 | 1585 |
| 1592 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 1586 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
| 1593 BreakLocation location = | 1587 BreakLocation location = |
| 1594 BreakLocation::FromCodeOffset(debug_info, summary.code_offset()); | 1588 BreakLocation::FromCodeOffset(debug_info, summary.code_offset()); |
| 1595 return location.IsReturn(); | 1589 return location.IsReturn(); |
| 1596 } | 1590 } |
| 1597 | 1591 |
| 1598 | 1592 |
| 1599 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, | 1593 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, |
| 1600 LiveEdit::FrameDropMode mode) { | 1594 LiveEdit::FrameDropMode mode) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1632 Script* script; | 1626 Script* script; |
| 1633 while ((script = iterator.Next())) { | 1627 while ((script = iterator.Next())) { |
| 1634 if (script->HasValidSource()) results->set(length++, script); | 1628 if (script->HasValidSource()) results->set(length++, script); |
| 1635 } | 1629 } |
| 1636 } | 1630 } |
| 1637 results->Shrink(length); | 1631 results->Shrink(length); |
| 1638 return results; | 1632 return results; |
| 1639 } | 1633 } |
| 1640 | 1634 |
| 1641 | 1635 |
| 1642 void Debug::RecordEvalCaller(Handle<Script> script) { | |
| 1643 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL); | |
| 1644 // For eval scripts add information on the function from which eval was | |
| 1645 // called. | |
| 1646 StackTraceFrameIterator it(script->GetIsolate()); | |
| 1647 if (!it.done()) { | |
| 1648 script->set_eval_from_shared(it.frame()->function()->shared()); | |
| 1649 Code* code = it.frame()->LookupCode(); | |
| 1650 int offset = static_cast<int>( | |
| 1651 it.frame()->pc() - code->instruction_start()); | |
| 1652 script->set_eval_from_instructions_offset(offset); | |
| 1653 } | |
| 1654 } | |
| 1655 | |
| 1656 | |
| 1657 MaybeHandle<Object> Debug::MakeExecutionState() { | 1636 MaybeHandle<Object> Debug::MakeExecutionState() { |
| 1658 // Create the execution state object. | 1637 // Create the execution state object. |
| 1659 Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) }; | 1638 Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) }; |
| 1660 return CallFunction("MakeExecutionState", arraysize(argv), argv); | 1639 return CallFunction("MakeExecutionState", arraysize(argv), argv); |
| 1661 } | 1640 } |
| 1662 | 1641 |
| 1663 | 1642 |
| 1664 MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) { | 1643 MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) { |
| 1665 // Create the new break event object. | 1644 // Create the new break event object. |
| 1666 Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()), | 1645 Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()), |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2263 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only); | 2242 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only); |
| 2264 } | 2243 } |
| 2265 | 2244 |
| 2266 #ifdef DEBUG | 2245 #ifdef DEBUG |
| 2267 void Debug::PrintBreakLocation() { | 2246 void Debug::PrintBreakLocation() { |
| 2268 if (!FLAG_print_break_location) return; | 2247 if (!FLAG_print_break_location) return; |
| 2269 HandleScope scope(isolate_); | 2248 HandleScope scope(isolate_); |
| 2270 JavaScriptFrameIterator iterator(isolate_); | 2249 JavaScriptFrameIterator iterator(isolate_); |
| 2271 if (iterator.done()) return; | 2250 if (iterator.done()) return; |
| 2272 JavaScriptFrame* frame = iterator.frame(); | 2251 JavaScriptFrame* frame = iterator.frame(); |
| 2273 FrameSummary summary = GetFirstFrameSummary(frame); | 2252 FrameSummary summary = FrameSummary::GetFirst(frame); |
| 2274 int source_position = | 2253 int source_position = |
| 2275 summary.abstract_code()->SourcePosition(summary.code_offset()); | 2254 summary.abstract_code()->SourcePosition(summary.code_offset()); |
| 2276 Handle<Object> script_obj(summary.function()->shared()->script(), isolate_); | 2255 Handle<Object> script_obj(summary.function()->shared()->script(), isolate_); |
| 2277 PrintF("[debug] break in function '"); | 2256 PrintF("[debug] break in function '"); |
| 2278 summary.function()->PrintName(); | 2257 summary.function()->PrintName(); |
| 2279 PrintF("'.\n"); | 2258 PrintF("'.\n"); |
| 2280 if (script_obj->IsScript()) { | 2259 if (script_obj->IsScript()) { |
| 2281 Handle<Script> script = Handle<Script>::cast(script_obj); | 2260 Handle<Script> script = Handle<Script>::cast(script_obj); |
| 2282 Handle<String> source(String::cast(script->source())); | 2261 Handle<String> source(String::cast(script->source())); |
| 2283 Script::InitLineEnds(script); | 2262 Script::InitLineEnds(script); |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2607 } | 2586 } |
| 2608 | 2587 |
| 2609 | 2588 |
| 2610 void LockingCommandMessageQueue::Clear() { | 2589 void LockingCommandMessageQueue::Clear() { |
| 2611 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2590 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 2612 queue_.Clear(); | 2591 queue_.Clear(); |
| 2613 } | 2592 } |
| 2614 | 2593 |
| 2615 } // namespace internal | 2594 } // namespace internal |
| 2616 } // namespace v8 | 2595 } // namespace v8 |
| OLD | NEW |