Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: src/debug.cc

Issue 21347: Make the debugger completely unload when the debug event listener is unregist... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/debug.h ('k') | src/debug-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/debug-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698