| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/debugger.h" | 5 #include "vm/debugger.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| (...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1540 // measured in token index distance. | 1540 // measured in token index distance. |
| 1541 best_fit_index = lowest_pc_index; | 1541 best_fit_index = lowest_pc_index; |
| 1542 } | 1542 } |
| 1543 if (best_fit_index >= 0) { | 1543 if (best_fit_index >= 0) { |
| 1544 return desc.TokenPos(best_fit_index); | 1544 return desc.TokenPos(best_fit_index); |
| 1545 } | 1545 } |
| 1546 return -1; | 1546 return -1; |
| 1547 } | 1547 } |
| 1548 | 1548 |
| 1549 | 1549 |
| 1550 void Debugger::MakeCodeBreakpointsAt(const Function& func, | 1550 void Debugger::MakeCodeBreakpointAt(const Function& func, |
| 1551 SourceBreakpoint* bpt) { | 1551 SourceBreakpoint* bpt) { |
| 1552 ASSERT((bpt != NULL) && bpt->IsResolved()); | 1552 ASSERT((bpt != NULL) && bpt->IsResolved()); |
| 1553 ASSERT(!func.HasOptimizedCode()); | 1553 ASSERT(!func.HasOptimizedCode()); |
| 1554 Code& code = Code::Handle(func.unoptimized_code()); | 1554 Code& code = Code::Handle(func.unoptimized_code()); |
| 1555 ASSERT(!code.IsNull()); | 1555 ASSERT(!code.IsNull()); |
| 1556 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1556 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 1557 uword lowest_pc = kUwordMax; |
| 1558 intptr_t lowest_pc_index = -1; |
| 1559 // Find the safe point with the lowest compiled code address |
| 1560 // that maps to the token position of the source breakpoint. |
| 1557 for (intptr_t i = 0; i < desc.Length(); i++) { | 1561 for (intptr_t i = 0; i < desc.Length(); i++) { |
| 1558 intptr_t desc_token_pos = desc.TokenPos(i); | 1562 intptr_t desc_token_pos = desc.TokenPos(i); |
| 1559 if ((desc_token_pos == bpt->token_pos_) && IsSafePoint(desc, i)) { | 1563 if ((desc_token_pos == bpt->token_pos_) && IsSafePoint(desc, i)) { |
| 1560 CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(i)); | 1564 if (desc.PC(i) < lowest_pc) { |
| 1561 if (code_bpt == NULL) { | 1565 // This descriptor so far has the lowest code address. |
| 1562 // No code breakpoint for this code exists; create one. | 1566 lowest_pc = desc.PC(i); |
| 1563 code_bpt = new CodeBreakpoint(code, i); | 1567 lowest_pc_index = i; |
| 1564 RegisterCodeBreakpoint(code_bpt); | |
| 1565 } | |
| 1566 code_bpt->set_src_bpt(bpt); | |
| 1567 if (bpt->IsEnabled()) { | |
| 1568 code_bpt->Enable(); | |
| 1569 } | 1568 } |
| 1570 } | 1569 } |
| 1571 } | 1570 } |
| 1571 if (lowest_pc_index < 0) { |
| 1572 return; |
| 1573 } |
| 1574 CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(lowest_pc_index)); |
| 1575 if (code_bpt == NULL) { |
| 1576 // No code breakpoint for this code exists; create one. |
| 1577 code_bpt = new CodeBreakpoint(code, lowest_pc_index); |
| 1578 RegisterCodeBreakpoint(code_bpt); |
| 1579 } |
| 1580 code_bpt->set_src_bpt(bpt); |
| 1581 if (bpt->IsEnabled()) { |
| 1582 code_bpt->Enable(); |
| 1583 } |
| 1572 } | 1584 } |
| 1573 | 1585 |
| 1574 | 1586 |
| 1575 void Debugger::FindCompiledFunctions(const Script& script, | 1587 void Debugger::FindCompiledFunctions(const Script& script, |
| 1576 intptr_t start_pos, | 1588 intptr_t start_pos, |
| 1577 intptr_t end_pos, | 1589 intptr_t end_pos, |
| 1578 GrowableObjectArray* function_list) { | 1590 GrowableObjectArray* function_list) { |
| 1579 Class& cls = Class::Handle(isolate_); | 1591 Class& cls = Class::Handle(isolate_); |
| 1580 Array& functions = Array::Handle(isolate_); | 1592 Array& functions = Array::Handle(isolate_); |
| 1581 GrowableObjectArray& closures = GrowableObjectArray::Handle(isolate_); | 1593 GrowableObjectArray& closures = GrowableObjectArray::Handle(isolate_); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1763 } | 1775 } |
| 1764 bpt = new SourceBreakpoint(nextId(), script, token_pos, last_token_pos); | 1776 bpt = new SourceBreakpoint(nextId(), script, token_pos, last_token_pos); |
| 1765 bpt->SetResolved(func, breakpoint_pos); | 1777 bpt->SetResolved(func, breakpoint_pos); |
| 1766 RegisterSourceBreakpoint(bpt); | 1778 RegisterSourceBreakpoint(bpt); |
| 1767 | 1779 |
| 1768 // Create code breakpoints for all compiled functions we found. | 1780 // Create code breakpoints for all compiled functions we found. |
| 1769 const intptr_t num_functions = functions.Length(); | 1781 const intptr_t num_functions = functions.Length(); |
| 1770 for (intptr_t i = 0; i < num_functions; i++) { | 1782 for (intptr_t i = 0; i < num_functions; i++) { |
| 1771 func ^= functions.At(i); | 1783 func ^= functions.At(i); |
| 1772 ASSERT(func.HasCode()); | 1784 ASSERT(func.HasCode()); |
| 1773 MakeCodeBreakpointsAt(func, bpt); | 1785 MakeCodeBreakpointAt(func, bpt); |
| 1774 } | 1786 } |
| 1775 bpt->Enable(); | 1787 bpt->Enable(); |
| 1776 if (FLAG_verbose_debug) { | 1788 if (FLAG_verbose_debug) { |
| 1777 intptr_t line_number; | 1789 intptr_t line_number; |
| 1778 script.GetTokenLocation(breakpoint_pos, &line_number, NULL); | 1790 script.GetTokenLocation(breakpoint_pos, &line_number, NULL); |
| 1779 OS::Print("Resolved breakpoint for " | 1791 OS::Print("Resolved breakpoint for " |
| 1780 "function '%s' at line %" Pd "\n", | 1792 "function '%s' at line %" Pd "\n", |
| 1781 func.ToFullyQualifiedCString(), | 1793 func.ToFullyQualifiedCString(), |
| 1782 line_number); | 1794 line_number); |
| 1783 } | 1795 } |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 SignalBpResolved(bpt); | 2384 SignalBpResolved(bpt); |
| 2373 } | 2385 } |
| 2374 ASSERT(bpt->IsResolved()); | 2386 ASSERT(bpt->IsResolved()); |
| 2375 if (FLAG_verbose_debug) { | 2387 if (FLAG_verbose_debug) { |
| 2376 OS::Print("Setting breakpoint %" Pd " at line %" Pd " for %s '%s'\n", | 2388 OS::Print("Setting breakpoint %" Pd " at line %" Pd " for %s '%s'\n", |
| 2377 bpt->id(), | 2389 bpt->id(), |
| 2378 bpt->LineNumber(), | 2390 bpt->LineNumber(), |
| 2379 func.IsClosureFunction() ? "closure" : "function", | 2391 func.IsClosureFunction() ? "closure" : "function", |
| 2380 String::Handle(func.name()).ToCString()); | 2392 String::Handle(func.name()).ToCString()); |
| 2381 } | 2393 } |
| 2382 MakeCodeBreakpointsAt(func, bpt); | 2394 MakeCodeBreakpointAt(func, bpt); |
| 2383 } | 2395 } |
| 2384 } | 2396 } |
| 2385 } | 2397 } |
| 2386 | 2398 |
| 2387 | 2399 |
| 2388 // TODO(hausner): Could potentially make this faster by checking | 2400 // TODO(hausner): Could potentially make this faster by checking |
| 2389 // whether the call target at pc is a debugger stub. | 2401 // whether the call target at pc is a debugger stub. |
| 2390 bool Debugger::HasActiveBreakpoint(uword pc) { | 2402 bool Debugger::HasActiveBreakpoint(uword pc) { |
| 2391 CodeBreakpoint* bpt = GetCodeBreakpoint(pc); | 2403 CodeBreakpoint* bpt = GetCodeBreakpoint(pc); |
| 2392 return (bpt != NULL) && (bpt->IsEnabled()); | 2404 return (bpt != NULL) && (bpt->IsEnabled()); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2514 } | 2526 } |
| 2515 | 2527 |
| 2516 | 2528 |
| 2517 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2529 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2518 ASSERT(bpt->next() == NULL); | 2530 ASSERT(bpt->next() == NULL); |
| 2519 bpt->set_next(code_breakpoints_); | 2531 bpt->set_next(code_breakpoints_); |
| 2520 code_breakpoints_ = bpt; | 2532 code_breakpoints_ = bpt; |
| 2521 } | 2533 } |
| 2522 | 2534 |
| 2523 } // namespace dart | 2535 } // namespace dart |
| OLD | NEW |