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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 #endif | 393 #endif |
394 } | 394 } |
395 | 395 |
396 | 396 |
397 bool Debug::has_break_points_ = false; | 397 bool Debug::has_break_points_ = false; |
398 DebugInfoListNode* Debug::debug_info_list_ = NULL; | 398 DebugInfoListNode* Debug::debug_info_list_ = NULL; |
399 | 399 |
400 | 400 |
401 // Threading support. | 401 // Threading support. |
402 void Debug::ThreadInit() { | 402 void Debug::ThreadInit() { |
| 403 thread_local_.break_count_ = 0; |
| 404 thread_local_.break_id_ = 0; |
| 405 thread_local_.break_frame_id_ = StackFrame::NO_ID; |
403 thread_local_.last_step_action_ = StepNone; | 406 thread_local_.last_step_action_ = StepNone; |
404 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; | 407 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; |
405 thread_local_.step_count_ = 0; | 408 thread_local_.step_count_ = 0; |
406 thread_local_.last_fp_ = 0; | 409 thread_local_.last_fp_ = 0; |
407 thread_local_.step_into_fp_ = 0; | 410 thread_local_.step_into_fp_ = 0; |
408 thread_local_.after_break_target_ = 0; | 411 thread_local_.after_break_target_ = 0; |
| 412 thread_local_.debugger_entry_ = NULL; |
| 413 thread_local_.preemption_pending_ = false; |
409 } | 414 } |
410 | 415 |
411 | 416 |
412 JSCallerSavedBuffer Debug::registers_; | 417 JSCallerSavedBuffer Debug::registers_; |
413 Debug::ThreadLocal Debug::thread_local_; | 418 Debug::ThreadLocal Debug::thread_local_; |
414 | 419 |
415 | 420 |
416 char* Debug::ArchiveDebug(char* storage) { | 421 char* Debug::ArchiveDebug(char* storage) { |
417 char* to = storage; | 422 char* to = storage; |
418 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); | 423 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 | 609 |
605 // Get rid of all break points and related information. | 610 // Get rid of all break points and related information. |
606 ClearAllBreakPoints(); | 611 ClearAllBreakPoints(); |
607 | 612 |
608 // Clear debugger context global handle. | 613 // Clear debugger context global handle. |
609 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); | 614 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); |
610 debug_context_ = Handle<Context>(); | 615 debug_context_ = Handle<Context>(); |
611 } | 616 } |
612 | 617 |
613 | 618 |
| 619 // Set the flag indicating that preemption happened during debugging. |
| 620 void Debug::PreemptionWhileInDebugger() { |
| 621 ASSERT(InDebugger()); |
| 622 Debug::set_preemption_pending(true); |
| 623 } |
| 624 |
| 625 |
614 void Debug::Iterate(ObjectVisitor* v) { | 626 void Debug::Iterate(ObjectVisitor* v) { |
615 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_))); | 627 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_))); |
616 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_))); | 628 v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_))); |
617 } | 629 } |
618 | 630 |
619 | 631 |
620 Object* Debug::Break(Arguments args) { | 632 Object* Debug::Break(Arguments args) { |
621 HandleScope scope; | 633 HandleScope scope; |
622 ASSERT(args.length() == 0); | 634 ASSERT(args.length() == 0); |
623 | 635 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 // Ignore check if break point object is not a JSObject. | 748 // Ignore check if break point object is not a JSObject. |
737 if (!break_point_object->IsJSObject()) return true; | 749 if (!break_point_object->IsJSObject()) return true; |
738 | 750 |
739 // Get the function CheckBreakPoint (defined in debug.js). | 751 // Get the function CheckBreakPoint (defined in debug.js). |
740 Handle<JSFunction> check_break_point = | 752 Handle<JSFunction> check_break_point = |
741 Handle<JSFunction>(JSFunction::cast( | 753 Handle<JSFunction>(JSFunction::cast( |
742 debug_context()->global()->GetProperty( | 754 debug_context()->global()->GetProperty( |
743 *Factory::LookupAsciiSymbol("IsBreakPointTriggered")))); | 755 *Factory::LookupAsciiSymbol("IsBreakPointTriggered")))); |
744 | 756 |
745 // Get the break id as an object. | 757 // Get the break id as an object. |
746 Handle<Object> break_id = Factory::NewNumberFromInt(Top::break_id()); | 758 Handle<Object> break_id = Factory::NewNumberFromInt(Debug::break_id()); |
747 | 759 |
748 // Call HandleBreakPointx. | 760 // Call HandleBreakPointx. |
749 bool caught_exception = false; | 761 bool caught_exception = false; |
750 const int argc = 2; | 762 const int argc = 2; |
751 Object** argv[argc] = { | 763 Object** argv[argc] = { |
752 break_id.location(), | 764 break_id.location(), |
753 reinterpret_cast<Object**>(break_point_object.location()) | 765 reinterpret_cast<Object**>(break_point_object.location()) |
754 }; | 766 }; |
755 Handle<Object> result = Execution::TryCall(check_break_point, | 767 Handle<Object> result = Execution::TryCall(check_break_point, |
756 Top::builtins(), argc, argv, | 768 Top::builtins(), argc, argv, |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); | 878 BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS); |
867 while (!it.Done()) { | 879 while (!it.Done()) { |
868 it.SetOneShot(); | 880 it.SetOneShot(); |
869 it.Next(); | 881 it.Next(); |
870 } | 882 } |
871 } | 883 } |
872 | 884 |
873 | 885 |
874 void Debug::FloodHandlerWithOneShot() { | 886 void Debug::FloodHandlerWithOneShot() { |
875 // Iterate through the JavaScript stack looking for handlers. | 887 // Iterate through the JavaScript stack looking for handlers. |
876 StackFrame::Id id = Top::break_frame_id(); | 888 StackFrame::Id id = break_frame_id(); |
877 if (id == StackFrame::NO_ID) { | 889 if (id == StackFrame::NO_ID) { |
878 // If there is no JavaScript stack don't do anything. | 890 // If there is no JavaScript stack don't do anything. |
879 return; | 891 return; |
880 } | 892 } |
881 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) { | 893 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) { |
882 JavaScriptFrame* frame = it.frame(); | 894 JavaScriptFrame* frame = it.frame(); |
883 if (frame->HasHandler()) { | 895 if (frame->HasHandler()) { |
884 Handle<SharedFunctionInfo> shared = | 896 Handle<SharedFunctionInfo> shared = |
885 Handle<SharedFunctionInfo>( | 897 Handle<SharedFunctionInfo>( |
886 JSFunction::cast(frame->function())->shared()); | 898 JSFunction::cast(frame->function())->shared()); |
(...skipping 19 matching lines...) Expand all Loading... |
906 ASSERT(Debug::InDebugger()); | 918 ASSERT(Debug::InDebugger()); |
907 | 919 |
908 // Remember this step action and count. | 920 // Remember this step action and count. |
909 thread_local_.last_step_action_ = step_action; | 921 thread_local_.last_step_action_ = step_action; |
910 thread_local_.step_count_ = step_count; | 922 thread_local_.step_count_ = step_count; |
911 | 923 |
912 // Get the frame where the execution has stopped and skip the debug frame if | 924 // Get the frame where the execution has stopped and skip the debug frame if |
913 // any. The debug frame will only be present if execution was stopped due to | 925 // any. The debug frame will only be present if execution was stopped due to |
914 // hitting a break point. In other situations (e.g. unhandled exception) the | 926 // hitting a break point. In other situations (e.g. unhandled exception) the |
915 // debug frame is not present. | 927 // debug frame is not present. |
916 StackFrame::Id id = Top::break_frame_id(); | 928 StackFrame::Id id = break_frame_id(); |
917 if (id == StackFrame::NO_ID) { | 929 if (id == StackFrame::NO_ID) { |
918 // If there is no JavaScript stack don't do anything. | 930 // If there is no JavaScript stack don't do anything. |
919 return; | 931 return; |
920 } | 932 } |
921 JavaScriptFrameIterator frames_it(id); | 933 JavaScriptFrameIterator frames_it(id); |
922 JavaScriptFrame* frame = frames_it.frame(); | 934 JavaScriptFrame* frame = frames_it.frame(); |
923 | 935 |
924 // First of all ensure there is one-shot break points in the top handler | 936 // First of all ensure there is one-shot break points in the top handler |
925 // if any. | 937 // if any. |
926 FloodHandlerWithOneShot(); | 938 FloodHandlerWithOneShot(); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 BreakPointInfo::cast(debug_info->break_points()->get(i)); | 1123 BreakPointInfo::cast(debug_info->break_points()->get(i)); |
1112 if (break_point_info->GetBreakPointCount() > 0) { | 1124 if (break_point_info->GetBreakPointCount() > 0) { |
1113 locations->set(count++, break_point_info->statement_position()); | 1125 locations->set(count++, break_point_info->statement_position()); |
1114 } | 1126 } |
1115 } | 1127 } |
1116 } | 1128 } |
1117 return locations; | 1129 return locations; |
1118 } | 1130 } |
1119 | 1131 |
1120 | 1132 |
| 1133 void Debug::NewBreak(StackFrame::Id break_frame_id) { |
| 1134 thread_local_.break_frame_id_ = break_frame_id; |
| 1135 thread_local_.break_id_ = ++thread_local_.break_count_; |
| 1136 } |
| 1137 |
| 1138 |
| 1139 void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) { |
| 1140 thread_local_.break_frame_id_ = break_frame_id; |
| 1141 thread_local_.break_id_ = break_id; |
| 1142 } |
| 1143 |
| 1144 |
1121 // Handle stepping into a function. | 1145 // Handle stepping into a function. |
1122 void Debug::HandleStepIn(Handle<JSFunction> function, | 1146 void Debug::HandleStepIn(Handle<JSFunction> function, |
1123 Address fp, | 1147 Address fp, |
1124 bool is_constructor) { | 1148 bool is_constructor) { |
1125 // If the frame pointer is not supplied by the caller find it. | 1149 // If the frame pointer is not supplied by the caller find it. |
1126 if (fp == 0) { | 1150 if (fp == 0) { |
1127 StackFrameIterator it; | 1151 StackFrameIterator it; |
1128 it.Advance(); | 1152 it.Advance(); |
1129 // For constructor functions skip another frame. | 1153 // For constructor functions skip another frame. |
1130 if (is_constructor) { | 1154 if (is_constructor) { |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 Handle<Object> js_object = Execution::TryCall( | 1398 Handle<Object> js_object = Execution::TryCall( |
1375 Handle<JSFunction>::cast(constructor), | 1399 Handle<JSFunction>::cast(constructor), |
1376 Handle<JSObject>(Debug::debug_context()->global()), argc, argv, | 1400 Handle<JSObject>(Debug::debug_context()->global()), argc, argv, |
1377 caught_exception); | 1401 caught_exception); |
1378 return js_object; | 1402 return js_object; |
1379 } | 1403 } |
1380 | 1404 |
1381 | 1405 |
1382 Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) { | 1406 Handle<Object> Debugger::MakeExecutionState(bool* caught_exception) { |
1383 // Create the execution state object. | 1407 // Create the execution state object. |
1384 Handle<Object> break_id = Factory::NewNumberFromInt(Top::break_id()); | 1408 Handle<Object> break_id = Factory::NewNumberFromInt(Debug::break_id()); |
1385 const int argc = 1; | 1409 const int argc = 1; |
1386 Object** argv[argc] = { break_id.location() }; | 1410 Object** argv[argc] = { break_id.location() }; |
1387 return MakeJSObject(CStrVector("MakeExecutionState"), | 1411 return MakeJSObject(CStrVector("MakeExecutionState"), |
1388 argc, argv, caught_exception); | 1412 argc, argv, caught_exception); |
1389 } | 1413 } |
1390 | 1414 |
1391 | 1415 |
1392 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state, | 1416 Handle<Object> Debugger::MakeBreakEvent(Handle<Object> exec_state, |
1393 Handle<Object> break_points_hit, | 1417 Handle<Object> break_points_hit, |
1394 bool* caught_exception) { | 1418 bool* caught_exception) { |
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2119 } | 2143 } |
2120 | 2144 |
2121 | 2145 |
2122 void LockingMessageQueue::Clear() { | 2146 void LockingMessageQueue::Clear() { |
2123 ScopedLock sl(lock_); | 2147 ScopedLock sl(lock_); |
2124 queue_.Clear(); | 2148 queue_.Clear(); |
2125 } | 2149 } |
2126 | 2150 |
2127 | 2151 |
2128 } } // namespace v8::internal | 2152 } } // namespace v8::internal |
OLD | NEW |