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