| 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 |