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 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 Debug::set_interrupts_pending(PREEMPT); | 907 Debug::set_interrupts_pending(PREEMPT); |
908 } | 908 } |
909 | 909 |
910 | 910 |
911 void Debug::Iterate(ObjectVisitor* v) { | 911 void Debug::Iterate(ObjectVisitor* v) { |
912 v->VisitPointer(BitCast<Object**>(&(debug_break_return_))); | 912 v->VisitPointer(BitCast<Object**>(&(debug_break_return_))); |
913 v->VisitPointer(BitCast<Object**>(&(debug_break_slot_))); | 913 v->VisitPointer(BitCast<Object**>(&(debug_break_slot_))); |
914 } | 914 } |
915 | 915 |
916 | 916 |
917 // This remains a static method so that generated code can call it. | 917 Object* Debug::Break(Arguments args) { |
918 Object* Debug::Break(RUNTIME_CALLING_CONVENTION) { | 918 Heap* heap = isolate_->heap(); |
919 RUNTIME_GET_ISOLATE; | 919 HandleScope scope(isolate_); |
920 | |
921 Debug* debug = isolate->debug(); | |
922 Heap* heap = isolate->heap(); | |
923 HandleScope scope; | |
924 ASSERT(args.length() == 0); | 920 ASSERT(args.length() == 0); |
925 | 921 |
926 debug->thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED; | 922 thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED; |
927 | 923 |
928 // Get the top-most JavaScript frame. | 924 // Get the top-most JavaScript frame. |
929 JavaScriptFrameIterator it; | 925 JavaScriptFrameIterator it; |
930 JavaScriptFrame* frame = it.frame(); | 926 JavaScriptFrame* frame = it.frame(); |
931 | 927 |
932 // Just continue if breaks are disabled or debugger cannot be loaded. | 928 // Just continue if breaks are disabled or debugger cannot be loaded. |
933 if (debug->disable_break() || !debug->Load()) { | 929 if (disable_break() || !Load()) { |
934 debug->SetAfterBreakTarget(frame); | 930 SetAfterBreakTarget(frame); |
935 return heap->undefined_value(); | 931 return heap->undefined_value(); |
936 } | 932 } |
937 | 933 |
938 // Enter the debugger. | 934 // Enter the debugger. |
939 EnterDebugger debugger; | 935 EnterDebugger debugger; |
940 if (debugger.FailedToEnter()) { | 936 if (debugger.FailedToEnter()) { |
941 return heap->undefined_value(); | 937 return heap->undefined_value(); |
942 } | 938 } |
943 | 939 |
944 // Postpone interrupt during breakpoint processing. | 940 // Postpone interrupt during breakpoint processing. |
945 PostponeInterruptsScope postpone(isolate); | 941 PostponeInterruptsScope postpone(isolate_); |
946 | 942 |
947 // Get the debug info (create it if it does not exist). | 943 // Get the debug info (create it if it does not exist). |
948 Handle<SharedFunctionInfo> shared = | 944 Handle<SharedFunctionInfo> shared = |
949 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); | 945 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); |
950 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 946 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
951 | 947 |
952 // Find the break point where execution has stopped. | 948 // Find the break point where execution has stopped. |
953 BreakLocationIterator break_location_iterator(debug_info, | 949 BreakLocationIterator break_location_iterator(debug_info, |
954 ALL_BREAK_LOCATIONS); | 950 ALL_BREAK_LOCATIONS); |
955 break_location_iterator.FindBreakLocationFromAddress(frame->pc()); | 951 break_location_iterator.FindBreakLocationFromAddress(frame->pc()); |
956 | 952 |
957 // Check whether step next reached a new statement. | 953 // Check whether step next reached a new statement. |
958 if (!debug->StepNextContinue(&break_location_iterator, frame)) { | 954 if (!StepNextContinue(&break_location_iterator, frame)) { |
959 // Decrease steps left if performing multiple steps. | 955 // Decrease steps left if performing multiple steps. |
960 if (debug->thread_local_.step_count_ > 0) { | 956 if (thread_local_.step_count_ > 0) { |
961 debug->thread_local_.step_count_--; | 957 thread_local_.step_count_--; |
962 } | 958 } |
963 } | 959 } |
964 | 960 |
965 // If there is one or more real break points check whether any of these are | 961 // If there is one or more real break points check whether any of these are |
966 // triggered. | 962 // triggered. |
967 Handle<Object> break_points_hit(heap->undefined_value()); | 963 Handle<Object> break_points_hit(heap->undefined_value()); |
968 if (break_location_iterator.HasBreakPoint()) { | 964 if (break_location_iterator.HasBreakPoint()) { |
969 Handle<Object> break_point_objects = | 965 Handle<Object> break_point_objects = |
970 Handle<Object>(break_location_iterator.BreakPointObjects()); | 966 Handle<Object>(break_location_iterator.BreakPointObjects()); |
971 break_points_hit = debug->CheckBreakPoints(break_point_objects); | 967 break_points_hit = CheckBreakPoints(break_point_objects); |
972 } | 968 } |
973 | 969 |
974 // If step out is active skip everything until the frame where we need to step | 970 // If step out is active skip everything until the frame where we need to step |
975 // out to is reached, unless real breakpoint is hit. | 971 // out to is reached, unless real breakpoint is hit. |
976 if (debug->StepOutActive() && frame->fp() != debug->step_out_fp() && | 972 if (StepOutActive() && frame->fp() != step_out_fp() && |
977 break_points_hit->IsUndefined() ) { | 973 break_points_hit->IsUndefined() ) { |
978 // Step count should always be 0 for StepOut. | 974 // Step count should always be 0 for StepOut. |
979 ASSERT(debug->thread_local_.step_count_ == 0); | 975 ASSERT(thread_local_.step_count_ == 0); |
980 } else if (!break_points_hit->IsUndefined() || | 976 } else if (!break_points_hit->IsUndefined() || |
981 (debug->thread_local_.last_step_action_ != StepNone && | 977 (thread_local_.last_step_action_ != StepNone && |
982 debug->thread_local_.step_count_ == 0)) { | 978 thread_local_.step_count_ == 0)) { |
983 // Notify debugger if a real break point is triggered or if performing | 979 // Notify debugger if a real break point is triggered or if performing |
984 // single stepping with no more steps to perform. Otherwise do another step. | 980 // single stepping with no more steps to perform. Otherwise do another step. |
985 | 981 |
986 // Clear all current stepping setup. | 982 // Clear all current stepping setup. |
987 debug->ClearStepping(); | 983 ClearStepping(); |
988 | 984 |
989 // Notify the debug event listeners. | 985 // Notify the debug event listeners. |
990 isolate->debugger()->OnDebugBreak(break_points_hit, false); | 986 isolate_->debugger()->OnDebugBreak(break_points_hit, false); |
991 } else if (debug->thread_local_.last_step_action_ != StepNone) { | 987 } else if (thread_local_.last_step_action_ != StepNone) { |
992 // Hold on to last step action as it is cleared by the call to | 988 // Hold on to last step action as it is cleared by the call to |
993 // ClearStepping. | 989 // ClearStepping. |
994 StepAction step_action = debug->thread_local_.last_step_action_; | 990 StepAction step_action = thread_local_.last_step_action_; |
995 int step_count = debug->thread_local_.step_count_; | 991 int step_count = thread_local_.step_count_; |
996 | 992 |
997 // Clear all current stepping setup. | 993 // Clear all current stepping setup. |
998 debug->ClearStepping(); | 994 ClearStepping(); |
999 | 995 |
1000 // Set up for the remaining steps. | 996 // Set up for the remaining steps. |
1001 debug->PrepareStep(step_action, step_count); | 997 PrepareStep(step_action, step_count); |
1002 } | 998 } |
1003 | 999 |
1004 if (debug->thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) { | 1000 if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) { |
1005 debug->SetAfterBreakTarget(frame); | 1001 SetAfterBreakTarget(frame); |
1006 } else if (debug->thread_local_.frame_drop_mode_ == | 1002 } else if (thread_local_.frame_drop_mode_ == |
1007 FRAME_DROPPED_IN_IC_CALL) { | 1003 FRAME_DROPPED_IN_IC_CALL) { |
1008 // We must have been calling IC stub. Do not go there anymore. | 1004 // We must have been calling IC stub. Do not go there anymore. |
1009 Code* plain_return = | 1005 Code* plain_return = isolate_->builtins()->builtin( |
1010 Isolate::Current()->builtins()->builtin( | 1006 Builtins::kPlainReturn_LiveEdit); |
1011 Builtins::kPlainReturn_LiveEdit); | 1007 thread_local_.after_break_target_ = plain_return->entry(); |
1012 debug->thread_local_.after_break_target_ = plain_return->entry(); | 1008 } else if (thread_local_.frame_drop_mode_ == |
1013 } else if (debug->thread_local_.frame_drop_mode_ == | |
1014 FRAME_DROPPED_IN_DEBUG_SLOT_CALL) { | 1009 FRAME_DROPPED_IN_DEBUG_SLOT_CALL) { |
1015 // Debug break slot stub does not return normally, instead it manually | 1010 // Debug break slot stub does not return normally, instead it manually |
1016 // cleans the stack and jumps. We should patch the jump address. | 1011 // cleans the stack and jumps. We should patch the jump address. |
1017 Code* plain_return = Isolate::Current()->builtins()->builtin( | 1012 Code* plain_return = isolate_->builtins()->builtin( |
1018 Builtins::kFrameDropper_LiveEdit); | 1013 Builtins::kFrameDropper_LiveEdit); |
1019 debug->thread_local_.after_break_target_ = plain_return->entry(); | 1014 thread_local_.after_break_target_ = plain_return->entry(); |
1020 } else if (debug->thread_local_.frame_drop_mode_ == | 1015 } else if (thread_local_.frame_drop_mode_ == |
1021 FRAME_DROPPED_IN_DIRECT_CALL) { | 1016 FRAME_DROPPED_IN_DIRECT_CALL) { |
1022 // Nothing to do, after_break_target is not used here. | 1017 // Nothing to do, after_break_target is not used here. |
1023 } else { | 1018 } else { |
1024 UNREACHABLE(); | 1019 UNREACHABLE(); |
1025 } | 1020 } |
1026 | 1021 |
1027 return heap->undefined_value(); | 1022 return heap->undefined_value(); |
1028 } | 1023 } |
1029 | 1024 |
1030 | 1025 |
| 1026 RUNTIME_FUNCTION(Object*, Debug_Break) { |
| 1027 return isolate->debug()->Break(args); |
| 1028 } |
| 1029 |
| 1030 |
1031 // Check the break point objects for whether one or more are actually | 1031 // Check the break point objects for whether one or more are actually |
1032 // triggered. This function returns a JSArray with the break point objects | 1032 // triggered. This function returns a JSArray with the break point objects |
1033 // which is triggered. | 1033 // which is triggered. |
1034 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { | 1034 Handle<Object> Debug::CheckBreakPoints(Handle<Object> break_point_objects) { |
1035 // Count the number of break points hit. If there are multiple break points | 1035 // Count the number of break points hit. If there are multiple break points |
1036 // they are in a FixedArray. | 1036 // they are in a FixedArray. |
1037 Handle<FixedArray> break_points_hit; | 1037 Handle<FixedArray> break_points_hit; |
1038 int break_points_hit_count = 0; | 1038 int break_points_hit_count = 0; |
1039 ASSERT(!break_point_objects->IsUndefined()); | 1039 ASSERT(!break_point_objects->IsUndefined()); |
1040 if (break_point_objects->IsFixedArray()) { | 1040 if (break_point_objects->IsFixedArray()) { |
(...skipping 2114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3155 { | 3155 { |
3156 Locker locker; | 3156 Locker locker; |
3157 Isolate::Current()->debugger()->CallMessageDispatchHandler(); | 3157 Isolate::Current()->debugger()->CallMessageDispatchHandler(); |
3158 } | 3158 } |
3159 } | 3159 } |
3160 } | 3160 } |
3161 | 3161 |
3162 #endif // ENABLE_DEBUGGER_SUPPORT | 3162 #endif // ENABLE_DEBUGGER_SUPPORT |
3163 | 3163 |
3164 } } // namespace v8::internal | 3164 } } // namespace v8::internal |
OLD | NEW |