|
40 | 40 | #include "global-handles.h"
|
41 | 41 | #include "ic.h"
|
42 | 42 | #include "ic-inl.h"
|
| 43 | +#include "isolate-inl.h" |
43 | 44 | #include "list.h"
|
44 | 45 | #include "messages.h"
|
45 | 46 | #include "natives.h"
|
@@ -2937,6 +2938,94 @@ void Debugger::CallMessageDispatchHandler() {
|
2937 | 2938 | }
|
2938 | 2939 |
|
2939 | 2940 |
|
| 2941 | +EnterDebugger::EnterDebugger() |
| 2942 | + : isolate_(Isolate::Current()), |
| 2943 | + prev_(isolate_->debug()->debugger_entry()), |
| 2944 | + it_(isolate_), |
| 2945 | + has_js_frames_(!it_.done()), |
| 2946 | + save_(isolate_) { |
| 2947 | + Debug* debug = isolate_->debug(); |
| 2948 | + ASSERT(prev_ != NULL || !debug->is_interrupt_pending(PREEMPT)); |
| 2949 | + ASSERT(prev_ != NULL || !debug->is_interrupt_pending(DEBUGBREAK)); |
| 2950 | + |
| 2951 | + // Link recursive debugger entry. |
| 2952 | + debug->set_debugger_entry(this); |
| 2953 | + |
| 2954 | + // Store the previous break id and frame id. |
| 2955 | + break_id_ = debug->break_id(); |
| 2956 | + break_frame_id_ = debug->break_frame_id(); |
| 2957 | + |
| 2958 | + // Create the new break info. If there is no JavaScript frames there is no |
| 2959 | + // break frame id. |
| 2960 | + if (has_js_frames_) { |
| 2961 | + debug->NewBreak(it_.frame()->id()); |
| 2962 | + } else { |
| 2963 | + debug->NewBreak(StackFrame::NO_ID); |
| 2964 | + } |
| 2965 | + |
| 2966 | + // Make sure that debugger is loaded and enter the debugger context. |
| 2967 | + load_failed_ = !debug->Load(); |
| 2968 | + if (!load_failed_) { |
| 2969 | + // NOTE the member variable save which saves the previous context before |
| 2970 | + // this change. |
| 2971 | + isolate_->set_context(*debug->debug_context()); |
| 2972 | + } |
| 2973 | +} |
| 2974 | + |
| 2975 | + |
| 2976 | +EnterDebugger::~EnterDebugger() { |
| 2977 | + ASSERT(Isolate::Current() == isolate_); |
| 2978 | + Debug* debug = isolate_->debug(); |
| 2979 | + |
| 2980 | + // Restore to the previous break state. |
| 2981 | + debug->SetBreak(break_frame_id_, break_id_); |
| 2982 | + |
| 2983 | + // Check for leaving the debugger. |
| 2984 | + if (prev_ == NULL) { |
| 2985 | + // Clear mirror cache when leaving the debugger. Skip this if there is a |
| 2986 | + // pending exception as clearing the mirror cache calls back into |
| 2987 | + // JavaScript. This can happen if the v8::Debug::Call is used in which |
| 2988 | + // case the exception should end up in the calling code. |
| 2989 | + if (!isolate_->has_pending_exception()) { |
| 2990 | + // Try to avoid any pending debug break breaking in the clear mirror |
| 2991 | + // cache JavaScript code. |
| 2992 | + if (isolate_->stack_guard()->IsDebugBreak()) { |
| 2993 | + debug->set_interrupts_pending(DEBUGBREAK); |
| 2994 | + isolate_->stack_guard()->Continue(DEBUGBREAK); |
| 2995 | + } |
| 2996 | + debug->ClearMirrorCache(); |
| 2997 | + } |
| 2998 | + |
| 2999 | + // Request preemption and debug break when leaving the last debugger entry |
| 3000 | + // if any of these where recorded while debugging. |
| 3001 | + if (debug->is_interrupt_pending(PREEMPT)) { |
| 3002 | + // This re-scheduling of preemption is to avoid starvation in some |
| 3003 | + // debugging scenarios. |
| 3004 | + debug->clear_interrupt_pending(PREEMPT); |
| 3005 | + isolate_->stack_guard()->Preempt(); |
| 3006 | + } |
| 3007 | + if (debug->is_interrupt_pending(DEBUGBREAK)) { |
| 3008 | + debug->clear_interrupt_pending(DEBUGBREAK); |
| 3009 | + isolate_->stack_guard()->DebugBreak(); |
| 3010 | + } |
| 3011 | + |
| 3012 | + // If there are commands in the queue when leaving the debugger request |
| 3013 | + // that these commands are processed. |
| 3014 | + if (isolate_->debugger()->HasCommands()) { |
| 3015 | + isolate_->stack_guard()->DebugCommand(); |
| 3016 | + } |
| 3017 | + |
| 3018 | + // If leaving the debugger with the debugger no longer active unload it. |
| 3019 | + if (!isolate_->debugger()->IsDebuggerActive()) { |
| 3020 | + isolate_->debugger()->UnloadDebugger(); |
| 3021 | + } |
| 3022 | + } |
| 3023 | + |
| 3024 | + // Leaving this debugger entry. |
| 3025 | + debug->set_debugger_entry(prev_); |
| 3026 | +} |
| 3027 | + |
| 3028 | + |
2940 | 3029 | MessageImpl MessageImpl::NewEvent(DebugEvent event,
|
2941 | 3030 | bool running,
|
2942 | 3031 | Handle<JSObject> exec_state,
|
|
0 commit comments