| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 ClearDebugBreakAtReturn(); | 307 ClearDebugBreakAtReturn(); |
| 308 } else { | 308 } else { |
| 309 // Patch the code to the original invoke. | 309 // Patch the code to the original invoke. |
| 310 rinfo()->set_target_address(original_rinfo()->target_address()); | 310 rinfo()->set_target_address(original_rinfo()->target_address()); |
| 311 } | 311 } |
| 312 ASSERT(!IsDebugBreak()); | 312 ASSERT(!IsDebugBreak()); |
| 313 } | 313 } |
| 314 | 314 |
| 315 | 315 |
| 316 void BreakLocationIterator::PrepareStepIn() { | 316 void BreakLocationIterator::PrepareStepIn() { |
| 317 HandleScope scope; |
| 318 |
| 317 // Step in can only be prepared if currently positioned on an IC call or | 319 // Step in can only be prepared if currently positioned on an IC call or |
| 318 // construct call. | 320 // construct call. |
| 319 Address target = rinfo()->target_address(); | 321 Address target = rinfo()->target_address(); |
| 320 Code* code = Code::GetCodeFromTargetAddress(target); | 322 Code* code = Code::GetCodeFromTargetAddress(target); |
| 321 if (code->is_call_stub()) { | 323 if (code->is_call_stub()) { |
| 322 // Step in through IC call is handled by the runtime system. Therefore make | 324 // Step in through IC call is handled by the runtime system. Therefore make |
| 323 // sure that the any current IC is cleared and the runtime system is | 325 // sure that the any current IC is cleared and the runtime system is |
| 324 // called. If the executing code has a debug break at the location change | 326 // called. If the executing code has a debug break at the location change |
| 325 // the call in the original code as it is the code there that will be | 327 // the call in the original code as it is the code there that will be |
| 326 // executed in place of the debug break call. | 328 // executed in place of the debug break call. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 356 return Debug::IsDebugBreak(rinfo()->target_address()); | 358 return Debug::IsDebugBreak(rinfo()->target_address()); |
| 357 } | 359 } |
| 358 } | 360 } |
| 359 | 361 |
| 360 | 362 |
| 361 Object* BreakLocationIterator::BreakPointObjects() { | 363 Object* BreakLocationIterator::BreakPointObjects() { |
| 362 return debug_info_->GetBreakPointObjects(code_position()); | 364 return debug_info_->GetBreakPointObjects(code_position()); |
| 363 } | 365 } |
| 364 | 366 |
| 365 | 367 |
| 368 // Clear out all the debug break code. This is ONLY supposed to be used when |
| 369 // shutting down the debugger as it will leave the break point information in |
| 370 // DebugInfo even though the code is patched back to the non break point state. |
| 371 void BreakLocationIterator::ClearAllDebugBreak() { |
| 372 while (!Done()) { |
| 373 ClearDebugBreak(); |
| 374 Next(); |
| 375 } |
| 376 } |
| 377 |
| 378 |
| 366 bool BreakLocationIterator::RinfoDone() const { | 379 bool BreakLocationIterator::RinfoDone() const { |
| 367 ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); | 380 ASSERT(reloc_iterator_->done() == reloc_iterator_original_->done()); |
| 368 return reloc_iterator_->done(); | 381 return reloc_iterator_->done(); |
| 369 } | 382 } |
| 370 | 383 |
| 371 | 384 |
| 372 void BreakLocationIterator::RinfoNext() { | 385 void BreakLocationIterator::RinfoNext() { |
| 373 reloc_iterator_->next(); | 386 reloc_iterator_->next(); |
| 374 reloc_iterator_original_->next(); | 387 reloc_iterator_original_->next(); |
| 375 #ifdef DEBUG | 388 #ifdef DEBUG |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 return true; | 595 return true; |
| 583 } | 596 } |
| 584 | 597 |
| 585 | 598 |
| 586 void Debug::Unload() { | 599 void Debug::Unload() { |
| 587 // Return debugger is not loaded. | 600 // Return debugger is not loaded. |
| 588 if (!IsLoaded()) { | 601 if (!IsLoaded()) { |
| 589 return; | 602 return; |
| 590 } | 603 } |
| 591 | 604 |
| 605 // Get rid of all break points and related information. |
| 606 ClearAllBreakPoints(); |
| 607 |
| 592 // Clear debugger context global handle. | 608 // Clear debugger context global handle. |
| 593 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); | 609 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); |
| 594 debug_context_ = Handle<Context>(); | 610 debug_context_ = Handle<Context>(); |
| 595 } | 611 } |
| 596 | 612 |
| 597 | 613 |
| 598 void Debug::Iterate(ObjectVisitor* v) { | 614 void Debug::Iterate(ObjectVisitor* v) { |
| 599 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_))); | 615 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_))); |
| 600 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_))); | 616 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_))); |
| 601 } | 617 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 // Return undefined if no break points where triggered. | 724 // Return undefined if no break points where triggered. |
| 709 if (break_points_hit_count == 0) { | 725 if (break_points_hit_count == 0) { |
| 710 return Factory::undefined_value(); | 726 return Factory::undefined_value(); |
| 711 } | 727 } |
| 712 return break_points_hit; | 728 return break_points_hit; |
| 713 } | 729 } |
| 714 | 730 |
| 715 | 731 |
| 716 // Check whether a single break point object is triggered. | 732 // Check whether a single break point object is triggered. |
| 717 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) { | 733 bool Debug::CheckBreakPoint(Handle<Object> break_point_object) { |
| 734 HandleScope scope; |
| 735 |
| 718 // Ignore check if break point object is not a JSObject. | 736 // Ignore check if break point object is not a JSObject. |
| 719 if (!break_point_object->IsJSObject()) return true; | 737 if (!break_point_object->IsJSObject()) return true; |
| 720 | 738 |
| 721 // Get the function CheckBreakPoint (defined in debug.js). | 739 // Get the function CheckBreakPoint (defined in debug.js). |
| 722 Handle<JSFunction> check_break_point = | 740 Handle<JSFunction> check_break_point = |
| 723 Handle<JSFunction>(JSFunction::cast( | 741 Handle<JSFunction>(JSFunction::cast( |
| 724 debug_context()->global()->GetProperty( | 742 debug_context()->global()->GetProperty( |
| 725 *Factory::LookupAsciiSymbol("IsBreakPointTriggered")))); | 743 *Factory::LookupAsciiSymbol("IsBreakPointTriggered")))); |
| 726 | 744 |
| 727 // Get the break id as an object. | 745 // Get the break id as an object. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 758 // prior to ensure the debug info has been generated for shared. | 776 // prior to ensure the debug info has been generated for shared. |
| 759 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { | 777 Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { |
| 760 ASSERT(HasDebugInfo(shared)); | 778 ASSERT(HasDebugInfo(shared)); |
| 761 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); | 779 return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); |
| 762 } | 780 } |
| 763 | 781 |
| 764 | 782 |
| 765 void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, | 783 void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, |
| 766 int source_position, | 784 int source_position, |
| 767 Handle<Object> break_point_object) { | 785 Handle<Object> break_point_object) { |
| 786 HandleScope scope; |
| 787 |
| 768 if (!EnsureDebugInfo(shared)) { | 788 if (!EnsureDebugInfo(shared)) { |
| 769 // Return if retrieving debug info failed. | 789 // Return if retrieving debug info failed. |
| 770 return; | 790 return; |
| 771 } | 791 } |
| 772 | 792 |
| 773 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 793 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 774 // Source positions starts with zero. | 794 // Source positions starts with zero. |
| 775 ASSERT(source_position >= 0); | 795 ASSERT(source_position >= 0); |
| 776 | 796 |
| 777 // Find the break point and change it. | 797 // Find the break point and change it. |
| 778 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); | 798 BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); |
| 779 it.FindBreakLocationFromPosition(source_position); | 799 it.FindBreakLocationFromPosition(source_position); |
| 780 it.SetBreakPoint(break_point_object); | 800 it.SetBreakPoint(break_point_object); |
| 781 | 801 |
| 782 // At least one active break point now. | 802 // At least one active break point now. |
| 783 ASSERT(debug_info->GetBreakPointCount() > 0); | 803 ASSERT(debug_info->GetBreakPointCount() > 0); |
| 784 } | 804 } |
| 785 | 805 |
| 786 | 806 |
| 787 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { | 807 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { |
| 808 HandleScope scope; |
| 809 |
| 788 DebugInfoListNode* node = debug_info_list_; | 810 DebugInfoListNode* node = debug_info_list_; |
| 789 while (node != NULL) { | 811 while (node != NULL) { |
| 790 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), | 812 Object* result = DebugInfo::FindBreakPointInfo(node->debug_info(), |
| 791 break_point_object); | 813 break_point_object); |
| 792 if (!result->IsUndefined()) { | 814 if (!result->IsUndefined()) { |
| 793 // Get information in the break point. | 815 // Get information in the break point. |
| 794 BreakPointInfo* break_point_info = BreakPointInfo::cast(result); | 816 BreakPointInfo* break_point_info = BreakPointInfo::cast(result); |
| 795 Handle<DebugInfo> debug_info = node->debug_info(); | 817 Handle<DebugInfo> debug_info = node->debug_info(); |
| 796 Handle<SharedFunctionInfo> shared(debug_info->shared()); | 818 Handle<SharedFunctionInfo> shared(debug_info->shared()); |
| 797 int source_position = break_point_info->statement_position()->value(); | 819 int source_position = break_point_info->statement_position()->value(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 810 RemoveDebugInfo(debug_info); | 832 RemoveDebugInfo(debug_info); |
| 811 } | 833 } |
| 812 | 834 |
| 813 return; | 835 return; |
| 814 } | 836 } |
| 815 node = node->next(); | 837 node = node->next(); |
| 816 } | 838 } |
| 817 } | 839 } |
| 818 | 840 |
| 819 | 841 |
| 842 void Debug::ClearAllBreakPoints() { |
| 843 DebugInfoListNode* node = debug_info_list_; |
| 844 while (node != NULL) { |
| 845 // Remove all debug break code. |
| 846 BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS); |
| 847 it.ClearAllDebugBreak(); |
| 848 node = node->next(); |
| 849 } |
| 850 |
| 851 // Remove all debug info. |
| 852 while (debug_info_list_ != NULL) { |
| 853 RemoveDebugInfo(debug_info_list_->debug_info()); |
| 854 } |
| 855 } |
| 856 |
| 857 |
| 820 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { | 858 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { |
| 821 // Make sure the function has setup the debug info. | 859 // Make sure the function has setup the debug info. |
| 822 if (!EnsureDebugInfo(shared)) { | 860 if (!EnsureDebugInfo(shared)) { |
| 823 // Return if we failed to retrieve the debug info. | 861 // Return if we failed to retrieve the debug info. |
| 824 return; | 862 return; |
| 825 } | 863 } |
| 826 | 864 |
| 827 // Flood the function with break points. | 865 // Flood the function with break points. |
| 828 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); | 866 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); |
| 829 while (!it.Done()) { | 867 while (!it.Done()) { |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1207 } | 1245 } |
| 1208 // Move to next in list. | 1246 // Move to next in list. |
| 1209 prev = current; | 1247 prev = current; |
| 1210 current = current->next(); | 1248 current = current->next(); |
| 1211 } | 1249 } |
| 1212 UNREACHABLE(); | 1250 UNREACHABLE(); |
| 1213 } | 1251 } |
| 1214 | 1252 |
| 1215 | 1253 |
| 1216 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { | 1254 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { |
| 1255 HandleScope scope; |
| 1256 |
| 1217 // Get the executing function in which the debug break occurred. | 1257 // Get the executing function in which the debug break occurred. |
| 1218 Handle<SharedFunctionInfo> shared = | 1258 Handle<SharedFunctionInfo> shared = |
| 1219 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 1259 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); |
| 1220 if (!EnsureDebugInfo(shared)) { | 1260 if (!EnsureDebugInfo(shared)) { |
| 1221 // Return if we failed to retrieve the debug info. | 1261 // Return if we failed to retrieve the debug info. |
| 1222 return; | 1262 return; |
| 1223 } | 1263 } |
| 1224 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 1264 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 1225 Handle<Code> code(debug_info->code()); | 1265 Handle<Code> code(debug_info->code()); |
| 1226 Handle<Code> original_code(debug_info->original_code()); | 1266 Handle<Code> original_code(debug_info->original_code()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 } | 1322 } |
| 1283 } | 1323 } |
| 1284 | 1324 |
| 1285 | 1325 |
| 1286 bool Debug::IsDebugGlobal(GlobalObject* global) { | 1326 bool Debug::IsDebugGlobal(GlobalObject* global) { |
| 1287 return IsLoaded() && global == Debug::debug_context()->global(); | 1327 return IsLoaded() && global == Debug::debug_context()->global(); |
| 1288 } | 1328 } |
| 1289 | 1329 |
| 1290 | 1330 |
| 1291 void Debug::ClearMirrorCache() { | 1331 void Debug::ClearMirrorCache() { |
| 1332 HandleScope scope; |
| 1292 ASSERT(Top::context() == *Debug::debug_context()); | 1333 ASSERT(Top::context() == *Debug::debug_context()); |
| 1293 | 1334 |
| 1294 // Clear the mirror cache. | 1335 // Clear the mirror cache. |
| 1295 Handle<String> function_name = | 1336 Handle<String> function_name = |
| 1296 Factory::LookupSymbol(CStrVector("ClearMirrorCache")); | 1337 Factory::LookupSymbol(CStrVector("ClearMirrorCache")); |
| 1297 Handle<Object> fun(Top::global()->GetProperty(*function_name)); | 1338 Handle<Object> fun(Top::global()->GetProperty(*function_name)); |
| 1298 ASSERT(fun->IsJSFunction()); | 1339 ASSERT(fun->IsJSFunction()); |
| 1299 bool caught_exception; | 1340 bool caught_exception; |
| 1300 Handle<Object> js_object = Execution::TryCall( | 1341 Handle<Object> js_object = Execution::TryCall( |
| 1301 Handle<JSFunction>::cast(fun), | 1342 Handle<JSFunction>::cast(fun), |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1581 if (caught_exception) { | 1622 if (caught_exception) { |
| 1582 return; | 1623 return; |
| 1583 } | 1624 } |
| 1584 // Process debug event. | 1625 // Process debug event. |
| 1585 ProcessDebugEvent(v8::NewFunction, event_data); | 1626 ProcessDebugEvent(v8::NewFunction, event_data); |
| 1586 } | 1627 } |
| 1587 | 1628 |
| 1588 | 1629 |
| 1589 void Debugger::ProcessDebugEvent(v8::DebugEvent event, | 1630 void Debugger::ProcessDebugEvent(v8::DebugEvent event, |
| 1590 Handle<Object> event_data) { | 1631 Handle<Object> event_data) { |
| 1632 HandleScope scope; |
| 1633 |
| 1591 // Create the execution state. | 1634 // Create the execution state. |
| 1592 bool caught_exception = false; | 1635 bool caught_exception = false; |
| 1593 Handle<Object> exec_state = MakeExecutionState(&caught_exception); | 1636 Handle<Object> exec_state = MakeExecutionState(&caught_exception); |
| 1594 if (caught_exception) { | 1637 if (caught_exception) { |
| 1595 return; | 1638 return; |
| 1596 } | 1639 } |
| 1597 // First notify the builtin debugger. | 1640 // First notify the builtin debugger. |
| 1598 if (message_thread_ != NULL) { | 1641 if (message_thread_ != NULL) { |
| 1599 message_thread_->DebugEvent(event, exec_state, event_data); | 1642 message_thread_->DebugEvent(event, exec_state, event_data); |
| 1600 } | 1643 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1697 } | 1740 } |
| 1698 | 1741 |
| 1699 | 1742 |
| 1700 void Debugger::UpdateActiveDebugger() { | 1743 void Debugger::UpdateActiveDebugger() { |
| 1701 set_debugger_active((message_thread_ != NULL && | 1744 set_debugger_active((message_thread_ != NULL && |
| 1702 debug_message_handler_ != NULL) || | 1745 debug_message_handler_ != NULL) || |
| 1703 !event_listener_.is_null()); | 1746 !event_listener_.is_null()); |
| 1704 if (!debugger_active() && message_thread_) { | 1747 if (!debugger_active() && message_thread_) { |
| 1705 message_thread_->OnDebuggerInactive(); | 1748 message_thread_->OnDebuggerInactive(); |
| 1706 } | 1749 } |
| 1750 if (!debugger_active()) { |
| 1751 Debug::Unload(); |
| 1752 } |
| 1707 } | 1753 } |
| 1708 | 1754 |
| 1709 | 1755 |
| 1710 Handle<Object> Debugger::Call(Handle<JSFunction> fun, | 1756 Handle<Object> Debugger::Call(Handle<JSFunction> fun, |
| 1711 Handle<Object> data, | 1757 Handle<Object> data, |
| 1712 bool* pending_exception) { | 1758 bool* pending_exception) { |
| 1713 // Enter the debugger. | 1759 // Enter the debugger. |
| 1714 EnterDebugger debugger; | 1760 EnterDebugger debugger; |
| 1715 if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) { | 1761 if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) { |
| 1716 return Factory::undefined_value(); | 1762 return Factory::undefined_value(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1801 } | 1847 } |
| 1802 } | 1848 } |
| 1803 } | 1849 } |
| 1804 | 1850 |
| 1805 | 1851 |
| 1806 // This method is called by the V8 thread whenever a debug event occurs in | 1852 // This method is called by the V8 thread whenever a debug event occurs in |
| 1807 // the VM. | 1853 // the VM. |
| 1808 void DebugMessageThread::DebugEvent(v8::DebugEvent event, | 1854 void DebugMessageThread::DebugEvent(v8::DebugEvent event, |
| 1809 Handle<Object> exec_state, | 1855 Handle<Object> exec_state, |
| 1810 Handle<Object> event_data) { | 1856 Handle<Object> event_data) { |
| 1857 HandleScope scope; |
| 1858 |
| 1811 if (!Debug::Load()) return; | 1859 if (!Debug::Load()) return; |
| 1812 | 1860 |
| 1813 // Process the individual events. | 1861 // Process the individual events. |
| 1814 bool interactive = false; | 1862 bool interactive = false; |
| 1815 switch (event) { | 1863 switch (event) { |
| 1816 case v8::Break: | 1864 case v8::Break: |
| 1817 interactive = true; // Break event is always interactive | 1865 interactive = true; // Break event is always interactive |
| 1818 break; | 1866 break; |
| 1819 case v8::Exception: | 1867 case v8::Exception: |
| 1820 interactive = true; // Exception event is always interactive | 1868 interactive = true; // Exception event is always interactive |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2022 } | 2070 } |
| 2023 | 2071 |
| 2024 | 2072 |
| 2025 void LockingMessageQueue::Clear() { | 2073 void LockingMessageQueue::Clear() { |
| 2026 ScopedLock sl(lock_); | 2074 ScopedLock sl(lock_); |
| 2027 queue_.Clear(); | 2075 queue_.Clear(); |
| 2028 } | 2076 } |
| 2029 | 2077 |
| 2030 | 2078 |
| 2031 } } // namespace v8::internal | 2079 } } // namespace v8::internal |
| OLD | NEW |