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 |