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 |