Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/debug.cc

Issue 292713002: Revert "Simplify debugger state." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "v8.h" 5 #include "v8.h"
6 6
7 #include "api.h" 7 #include "api.h"
8 #include "arguments.h" 8 #include "arguments.h"
9 #include "bootstrapper.h" 9 #include "bootstrapper.h"
10 #include "code-stubs.h" 10 #include "code-stubs.h"
(...skipping 27 matching lines...) Expand all
38 break_on_exception_(false), 38 break_on_exception_(false),
39 break_on_uncaught_exception_(false), 39 break_on_uncaught_exception_(false),
40 promise_catch_handlers_(0), 40 promise_catch_handlers_(0),
41 promise_getters_(0), 41 promise_getters_(0),
42 isolate_(isolate) { 42 isolate_(isolate) {
43 memset(registers_, 0, sizeof(JSCallerSavedBuffer)); 43 memset(registers_, 0, sizeof(JSCallerSavedBuffer));
44 ThreadInit(); 44 ThreadInit();
45 } 45 }
46 46
47 47
48 Debug::~Debug() {
49 }
50
51
48 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { 52 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
49 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); 53 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
50 // Isolate::context() may have been NULL when "script collected" event 54 // Isolate::context() may have been NULL when "script collected" event
51 // occured. 55 // occured.
52 if (context.is_null()) return v8::Local<v8::Context>(); 56 if (context.is_null()) return v8::Local<v8::Context>();
53 Handle<Context> native_context(context->native_context()); 57 Handle<Context> native_context(context->native_context());
54 return v8::Utils::ToLocal(native_context); 58 return v8::Utils::ToLocal(native_context);
55 } 59 }
56 60
57 61
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 DebugInfoListNode::~DebugInfoListNode() { 687 DebugInfoListNode::~DebugInfoListNode() {
684 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location())); 688 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_.location()));
685 } 689 }
686 690
687 691
688 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) { 692 bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
689 Factory* factory = isolate->factory(); 693 Factory* factory = isolate->factory();
690 HandleScope scope(isolate); 694 HandleScope scope(isolate);
691 695
692 // Bail out if the index is invalid. 696 // Bail out if the index is invalid.
693 if (index == -1) return false; 697 if (index == -1) {
698 return false;
699 }
694 700
695 // Find source and name for the requested script. 701 // Find source and name for the requested script.
696 Handle<String> source_code = 702 Handle<String> source_code =
697 isolate->bootstrapper()->NativesSourceLookup(index); 703 isolate->bootstrapper()->NativesSourceLookup(index);
698 Vector<const char> name = Natives::GetScriptName(index); 704 Vector<const char> name = Natives::GetScriptName(index);
699 Handle<String> script_name = 705 Handle<String> script_name =
700 factory->NewStringFromAscii(name).ToHandleChecked(); 706 factory->NewStringFromAscii(name).ToHandleChecked();
701 Handle<Context> context = isolate->native_context(); 707 Handle<Context> context = isolate->native_context();
702 708
703 // Compile the script. 709 // Compile the script.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 Handle<Script> script(Script::cast(function->shared()->script())); 755 Handle<Script> script(Script::cast(function->shared()->script()));
750 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 756 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
751 return true; 757 return true;
752 } 758 }
753 759
754 760
755 bool Debug::Load() { 761 bool Debug::Load() {
756 // Return if debugger is already loaded. 762 // Return if debugger is already loaded.
757 if (IsLoaded()) return true; 763 if (IsLoaded()) return true;
758 764
765 Debugger* debugger = isolate_->debugger();
766
759 // Bail out if we're already in the process of compiling the native 767 // Bail out if we're already in the process of compiling the native
760 // JavaScript source code for the debugger. 768 // JavaScript source code for the debugger.
761 if (isolate_->debugger()->ignore_debugger()) return false; 769 if (debugger->ignore_debugger()) return false;
762 Debugger::IgnoreScope during_create(isolate_->debugger());
763 770
771 Debugger::IgnoreScope during_load(debugger);
764 // Disable breakpoints and interrupts while compiling and running the 772 // Disable breakpoints and interrupts while compiling and running the
765 // debugger scripts including the context creation code. 773 // debugger scripts including the context creation code.
766 DisableBreak disable(isolate_, true); 774 DisableBreak disable(isolate_, true);
767 PostponeInterruptsScope postpone(isolate_); 775 PostponeInterruptsScope postpone(isolate_);
768 776
769 // Create the debugger context. 777 // Create the debugger context.
770 HandleScope scope(isolate_); 778 HandleScope scope(isolate_);
771 ExtensionConfiguration no_extensions; 779 ExtensionConfiguration no_extensions;
772 Handle<Context> context = 780 Handle<Context> context =
773 isolate_->bootstrapper()->CreateEnvironment( 781 isolate_->bootstrapper()->CreateEnvironment(
774 Handle<Object>::null(), 782 Handle<Object>::null(),
775 v8::Handle<ObjectTemplate>(), 783 v8::Handle<ObjectTemplate>(),
776 &no_extensions); 784 &no_extensions);
777 785
778 // Fail if no context could be created. 786 // Fail if no context could be created.
779 if (context.is_null()) return false; 787 if (context.is_null()) return false;
780 788
781 // Use the debugger context. 789 // Use the debugger context.
782 SaveContext save(isolate_); 790 SaveContext save(isolate_);
783 isolate_->set_context(*context); 791 isolate_->set_context(*context);
784 792
785 // Expose the builtins object in the debugger context. 793 // Expose the builtins object in the debugger context.
786 Handle<String> key = isolate_->factory()->InternalizeOneByteString( 794 Handle<String> key = isolate_->factory()->InternalizeOneByteString(
787 STATIC_ASCII_VECTOR("builtins")); 795 STATIC_ASCII_VECTOR("builtins"));
788 Handle<GlobalObject> global = 796 Handle<GlobalObject> global = Handle<GlobalObject>(context->global_object());
789 Handle<GlobalObject>(context->global_object(), isolate_);
790 Handle<JSBuiltinsObject> builtin =
791 Handle<JSBuiltinsObject>(global->builtins(), isolate_);
792 RETURN_ON_EXCEPTION_VALUE( 797 RETURN_ON_EXCEPTION_VALUE(
793 isolate_, 798 isolate_,
794 JSReceiver::SetProperty(global, key, builtin, NONE, SLOPPY), 799 JSReceiver::SetProperty(global,
800 key,
801 Handle<Object>(global->builtins(), isolate_),
802 NONE,
803 SLOPPY),
795 false); 804 false);
796 805
797 // Compile the JavaScript for the debugger in the debugger context. 806 // Compile the JavaScript for the debugger in the debugger context.
798 bool caught_exception = 807 bool caught_exception =
799 !CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) || 808 !CompileDebuggerScript(isolate_, Natives::GetIndex("mirror")) ||
800 !CompileDebuggerScript(isolate_, Natives::GetIndex("debug")); 809 !CompileDebuggerScript(isolate_, Natives::GetIndex("debug"));
801 810
802 if (FLAG_enable_liveedit) { 811 if (FLAG_enable_liveedit) {
803 caught_exception = caught_exception || 812 caught_exception = caught_exception ||
804 !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit")); 813 !CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
805 } 814 }
815
816 // Make sure we mark the debugger as not loading before we might
817 // return.
818
806 // Check for caught exceptions. 819 // Check for caught exceptions.
807 if (caught_exception) return false; 820 if (caught_exception) return false;
808 821
822 // Debugger loaded, create debugger context global handle.
809 debug_context_ = Handle<Context>::cast( 823 debug_context_ = Handle<Context>::cast(
810 isolate_->global_handles()->Create(*context)); 824 isolate_->global_handles()->Create(*context));
825
811 return true; 826 return true;
812 } 827 }
813 828
814 829
815 void Debug::Unload() { 830 void Debug::Unload() {
816 // Return debugger is not loaded. 831 // Return debugger is not loaded.
817 if (!IsLoaded()) return; 832 if (!IsLoaded()) {
833 return;
834 }
818 835
819 // Clear the script cache. 836 // Clear the script cache.
820 DestroyScriptCache(); 837 DestroyScriptCache();
821 838
822 // Clear debugger context global handle. 839 // Clear debugger context global handle.
823 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); 840 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
824 debug_context_ = Handle<Context>(); 841 debug_context_ = Handle<Context>();
825 } 842 }
826 843
827 844
828 Object* Debug::Break(Arguments args) { 845 Object* Debug::Break(Arguments args) {
829 Heap* heap = isolate_->heap(); 846 Heap* heap = isolate_->heap();
830 HandleScope scope(isolate_); 847 HandleScope scope(isolate_);
831 ASSERT(args.length() == 0); 848 ASSERT(args.length() == 0);
832 849
833 thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED; 850 thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED;
834 851
835 // Get the top-most JavaScript frame. 852 // Get the top-most JavaScript frame.
836 JavaScriptFrameIterator it(isolate_); 853 JavaScriptFrameIterator it(isolate_);
837 JavaScriptFrame* frame = it.frame(); 854 JavaScriptFrame* frame = it.frame();
838 855
839 // Just continue if breaks are disabled or debugger cannot be loaded. 856 // Just continue if breaks are disabled or debugger cannot be loaded.
840 if (disable_break()) { 857 if (disable_break() || !Load()) {
841 SetAfterBreakTarget(frame); 858 SetAfterBreakTarget(frame);
842 return heap->undefined_value(); 859 return heap->undefined_value();
843 } 860 }
844 861
845 // Enter the debugger. 862 // Enter the debugger.
846 EnterDebugger debugger(isolate_); 863 EnterDebugger debugger(isolate_);
847 if (debugger.FailedToEnter()) { 864 if (debugger.FailedToEnter()) {
848 return heap->undefined_value(); 865 return heap->undefined_value();
849 } 866 }
850 867
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 } 2622 }
2606 } 2623 }
2607 2624
2608 2625
2609 Debugger::Debugger(Isolate* isolate) 2626 Debugger::Debugger(Isolate* isolate)
2610 : event_listener_(Handle<Object>()), 2627 : event_listener_(Handle<Object>()),
2611 event_listener_data_(Handle<Object>()), 2628 event_listener_data_(Handle<Object>()),
2612 is_active_(false), 2629 is_active_(false),
2613 ignore_debugger_(false), 2630 ignore_debugger_(false),
2614 live_edit_enabled_(true), 2631 live_edit_enabled_(true),
2632 never_unload_debugger_(false),
2615 message_handler_(NULL), 2633 message_handler_(NULL),
2634 debugger_unload_pending_(false),
2616 command_queue_(isolate->logger(), kQueueInitialSize), 2635 command_queue_(isolate->logger(), kQueueInitialSize),
2617 command_received_(0), 2636 command_received_(0),
2618 event_command_queue_(isolate->logger(), kQueueInitialSize), 2637 event_command_queue_(isolate->logger(), kQueueInitialSize),
2619 isolate_(isolate) { 2638 isolate_(isolate) {
2620 } 2639 }
2621 2640
2622 2641
2623 Debugger::~Debugger() {} 2642 Debugger::~Debugger() {}
2624 2643
2625 2644
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
2962 event_listener_data_ }; 2981 event_listener_data_ };
2963 Execution::TryCall(fun, 2982 Execution::TryCall(fun,
2964 isolate_->global_object(), 2983 isolate_->global_object(),
2965 ARRAY_SIZE(argv), 2984 ARRAY_SIZE(argv),
2966 argv); 2985 argv);
2967 // Silently ignore exceptions from debug event listeners. 2986 // Silently ignore exceptions from debug event listeners.
2968 } 2987 }
2969 2988
2970 2989
2971 Handle<Context> Debugger::GetDebugContext() { 2990 Handle<Context> Debugger::GetDebugContext() {
2991 never_unload_debugger_ = true;
2972 EnterDebugger debugger(isolate_); 2992 EnterDebugger debugger(isolate_);
2973 return isolate_->debug()->debug_context(); 2993 return isolate_->debug()->debug_context();
2974 } 2994 }
2975 2995
2976 2996
2997 void Debugger::UnloadDebugger() {
2998 Debug* debug = isolate_->debug();
2999
3000 // Make sure that there are no breakpoints left.
3001 debug->ClearAllBreakPoints();
3002
3003 // Unload the debugger if feasible.
3004 if (!never_unload_debugger_) {
3005 debug->Unload();
3006 }
3007
3008 // Clear the flag indicating that the debugger should be unloaded.
3009 debugger_unload_pending_ = false;
3010 }
3011
3012
2977 void Debugger::NotifyMessageHandler(v8::DebugEvent event, 3013 void Debugger::NotifyMessageHandler(v8::DebugEvent event,
2978 Handle<JSObject> exec_state, 3014 Handle<JSObject> exec_state,
2979 Handle<JSObject> event_data, 3015 Handle<JSObject> event_data,
2980 bool auto_continue) { 3016 bool auto_continue) {
2981 ASSERT(is_active_);
2982 HandleScope scope(isolate_); 3017 HandleScope scope(isolate_);
3018
3019 if (!isolate_->debug()->Load()) return;
3020
2983 // Process the individual events. 3021 // Process the individual events.
2984 bool sendEventMessage = false; 3022 bool sendEventMessage = false;
2985 switch (event) { 3023 switch (event) {
2986 case v8::Break: 3024 case v8::Break:
2987 case v8::BreakForCommand: 3025 case v8::BreakForCommand:
2988 sendEventMessage = !auto_continue; 3026 sendEventMessage = !auto_continue;
2989 break; 3027 break;
2990 case v8::Exception: 3028 case v8::Exception:
2991 sendEventMessage = true; 3029 sendEventMessage = true;
2992 break; 3030 break;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 3138
3101 // Return from debug event processing if either the VM is put into the 3139 // Return from debug event processing if either the VM is put into the
3102 // running state (through a continue command) or auto continue is active 3140 // running state (through a continue command) or auto continue is active
3103 // and there are no more commands queued. 3141 // and there are no more commands queued.
3104 } while (!running || HasCommands()); 3142 } while (!running || HasCommands());
3105 } 3143 }
3106 3144
3107 3145
3108 void Debugger::SetEventListener(Handle<Object> callback, 3146 void Debugger::SetEventListener(Handle<Object> callback,
3109 Handle<Object> data) { 3147 Handle<Object> data) {
3148 HandleScope scope(isolate_);
3110 GlobalHandles* global_handles = isolate_->global_handles(); 3149 GlobalHandles* global_handles = isolate_->global_handles();
3111 3150
3112 // Remove existing entry. 3151 // Clear the global handles for the event listener and the event listener data
3113 GlobalHandles::Destroy(event_listener_.location()); 3152 // object.
3114 event_listener_ = Handle<Object>(); 3153 if (!event_listener_.is_null()) {
3115 GlobalHandles::Destroy(event_listener_data_.location()); 3154 GlobalHandles::Destroy(
3116 event_listener_data_ = Handle<Object>(); 3155 reinterpret_cast<Object**>(event_listener_.location()));
3117 3156 event_listener_ = Handle<Object>();
3118 // Set new entry. 3157 }
3119 if (!callback->IsUndefined() && !callback->IsNull()) { 3158 if (!event_listener_data_.is_null()) {
3120 event_listener_ = global_handles->Create(*callback); 3159 GlobalHandles::Destroy(
3121 if (data.is_null()) data = isolate_->factory()->undefined_value(); 3160 reinterpret_cast<Object**>(event_listener_data_.location()));
3122 event_listener_data_ = global_handles->Create(*data); 3161 event_listener_data_ = Handle<Object>();
3123 } 3162 }
3124 3163
3125 UpdateState(); 3164 // If there is a new debug event listener register it together with its data
3165 // object.
3166 if (!callback->IsUndefined() && !callback->IsNull()) {
3167 event_listener_ = Handle<Object>::cast(
3168 global_handles->Create(*callback));
3169 if (data.is_null()) {
3170 data = isolate_->factory()->undefined_value();
3171 }
3172 event_listener_data_ = Handle<Object>::cast(
3173 global_handles->Create(*data));
3174 }
3175
3176 ListenersChanged();
3126 } 3177 }
3127 3178
3128 3179
3129 void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler) { 3180 void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler) {
3181 LockGuard<RecursiveMutex> with(&debugger_access_);
3182
3130 message_handler_ = handler; 3183 message_handler_ = handler;
3131 UpdateState(); 3184 ListenersChanged();
3132 if (handler == NULL && isolate_->debug()->InDebugger()) { 3185 if (handler == NULL) {
3133 // Send an empty command to the debugger if in a break to make JavaScript 3186 // Send an empty command to the debugger if in a break to make JavaScript
3134 // run again if the debugger is closed. 3187 // run again if the debugger is closed.
3135 EnqueueCommandMessage(Vector<const uint16_t>::empty()); 3188 if (isolate_->debug()->InDebugger()) {
3189 EnqueueCommandMessage(Vector<const uint16_t>::empty());
3190 }
3136 } 3191 }
3137 } 3192 }
3138 3193
3139 3194
3140 void Debugger::UpdateState() { 3195 void Debugger::ListenersChanged() {
3141 bool activate = message_handler_ != NULL || 3196 LockGuard<RecursiveMutex> with(&debugger_access_);
3142 !event_listener_.is_null() || 3197 is_active_ = message_handler_ != NULL || !event_listener_.is_null();
3143 isolate_->debug()->InDebugger(); 3198 if (is_active_) {
3144 if (!is_active_ && activate) { 3199 // Disable the compilation cache when the debugger is active.
3145 // Note that the debug context could have already been loaded to
3146 // bootstrap test cases.
3147 isolate_->compilation_cache()->Disable(); 3200 isolate_->compilation_cache()->Disable();
3148 activate = isolate_->debug()->Load(); 3201 debugger_unload_pending_ = false;
3149 } else if (is_active_ && !activate) { 3202 } else {
3150 isolate_->compilation_cache()->Enable(); 3203 isolate_->compilation_cache()->Enable();
3151 isolate_->debug()->ClearAllBreakPoints(); 3204 // Unload the debugger if event listener and message handler cleared.
3152 isolate_->debug()->Unload(); 3205 // Schedule this for later, because we may be in non-V8 thread.
3206 debugger_unload_pending_ = true;
3153 } 3207 }
3154 is_active_ = activate;
3155 // At this point the debug context is loaded iff the debugger is active.
3156 ASSERT(isolate_->debug()->IsLoaded() == is_active_);
3157 } 3208 }
3158 3209
3159 3210
3160 // Calls the registered debug message handler. This callback is part of the 3211 // Calls the registered debug message handler. This callback is part of the
3161 // public API. 3212 // public API.
3162 void Debugger::InvokeMessageHandler(MessageImpl message) { 3213 void Debugger::InvokeMessageHandler(MessageImpl message) {
3163 if (message_handler_ != NULL) message_handler_(message); 3214 LockGuard<RecursiveMutex> with(&debugger_access_);
3215
3216 if (message_handler_ != NULL) {
3217 message_handler_(message);
3218 }
3164 } 3219 }
3165 3220
3166 3221
3167 // Puts a command coming from the public API on the queue. Creates 3222 // Puts a command coming from the public API on the queue. Creates
3168 // a copy of the command string managed by the debugger. Up to this 3223 // a copy of the command string managed by the debugger. Up to this
3169 // point, the command data was managed by the API client. Called 3224 // point, the command data was managed by the API client. Called
3170 // by the API client thread. 3225 // by the API client thread.
3171 void Debugger::EnqueueCommandMessage(Vector<const uint16_t> command, 3226 void Debugger::EnqueueCommandMessage(Vector<const uint16_t> command,
3172 v8::Debug::ClientData* client_data) { 3227 v8::Debug::ClientData* client_data) {
3173 // Need to cast away const. 3228 // Need to cast away const.
(...skipping 23 matching lines...) Expand all
3197 3252
3198 // Set the debug command break flag to have the command processed. 3253 // Set the debug command break flag to have the command processed.
3199 if (!isolate_->debug()->InDebugger()) { 3254 if (!isolate_->debug()->InDebugger()) {
3200 isolate_->stack_guard()->RequestDebugCommand(); 3255 isolate_->stack_guard()->RequestDebugCommand();
3201 } 3256 }
3202 } 3257 }
3203 3258
3204 3259
3205 MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun, 3260 MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun,
3206 Handle<Object> data) { 3261 Handle<Object> data) {
3262 // When calling functions in the debugger prevent it from beeing unloaded.
3263 Debugger::never_unload_debugger_ = true;
3264
3207 // Enter the debugger. 3265 // Enter the debugger.
3208 EnterDebugger debugger(isolate_); 3266 EnterDebugger debugger(isolate_);
3209 if (debugger.FailedToEnter()) { 3267 if (debugger.FailedToEnter()) {
3210 return isolate_->factory()->undefined_value(); 3268 return isolate_->factory()->undefined_value();
3211 } 3269 }
3212 3270
3213 // Create the execution state. 3271 // Create the execution state.
3214 Handle<Object> exec_state; 3272 Handle<Object> exec_state;
3215 if (!MakeExecutionState().ToHandle(&exec_state)) { 3273 if (!MakeExecutionState().ToHandle(&exec_state)) {
3216 return isolate_->factory()->undefined_value(); 3274 return isolate_->factory()->undefined_value();
3217 } 3275 }
3218 3276
3219 Handle<Object> argv[] = { exec_state, data }; 3277 Handle<Object> argv[] = { exec_state, data };
3220 return Execution::Call( 3278 return Execution::Call(
3221 isolate_, 3279 isolate_,
3222 fun, 3280 fun,
3223 Handle<Object>(isolate_->debug()->debug_context_->global_proxy(), 3281 Handle<Object>(isolate_->debug()->debug_context_->global_proxy(),
3224 isolate_), 3282 isolate_),
3225 ARRAY_SIZE(argv), 3283 ARRAY_SIZE(argv),
3226 argv); 3284 argv);
3227 } 3285 }
3228 3286
3229 3287
3230 EnterDebugger::EnterDebugger(Isolate* isolate) 3288 EnterDebugger::EnterDebugger(Isolate* isolate)
3231 : isolate_(isolate), 3289 : isolate_(isolate),
3232 prev_(isolate_->debug()->debugger_entry()), 3290 prev_(isolate_->debug()->debugger_entry()),
3291 it_(isolate_),
3292 has_js_frames_(!it_.done()),
3233 save_(isolate_) { 3293 save_(isolate_) {
3234 Debug* debug = isolate_->debug(); 3294 Debug* debug = isolate_->debug();
3235
3236 // Link recursive debugger entry. 3295 // Link recursive debugger entry.
3237 debug->set_debugger_entry(this); 3296 debug->set_debugger_entry(this);
3238 3297
3239 // Store the previous break id and frame id. 3298 // Store the previous break id and frame id.
3240 break_id_ = debug->break_id(); 3299 break_id_ = debug->break_id();
3241 break_frame_id_ = debug->break_frame_id(); 3300 break_frame_id_ = debug->break_frame_id();
3242 3301
3243 // Create the new break info. If there is no JavaScript frames there is no 3302 // Create the new break info. If there is no JavaScript frames there is no
3244 // break frame id. 3303 // break frame id.
3245 JavaScriptFrameIterator it(isolate_); 3304 if (has_js_frames_) {
3246 has_js_frames_ = !it.done(); 3305 debug->NewBreak(it_.frame()->id());
3247 debug->NewBreak(has_js_frames_ ? it.frame()->id() : StackFrame::NO_ID); 3306 } else {
3307 debug->NewBreak(StackFrame::NO_ID);
3308 }
3248 3309
3249 isolate_->debugger()->UpdateState();
3250 // Make sure that debugger is loaded and enter the debugger context. 3310 // Make sure that debugger is loaded and enter the debugger context.
3251 // The previous context is kept in save_. 3311 load_failed_ = !debug->Load();
3252 load_failed_ = !debug->IsLoaded(); 3312 if (!load_failed_) {
3253 if (!load_failed_) isolate_->set_context(*debug->debug_context()); 3313 // NOTE the member variable save which saves the previous context before
3314 // this change.
3315 isolate_->set_context(*debug->debug_context());
3316 }
3254 } 3317 }
3255 3318
3256 3319
3257 EnterDebugger::~EnterDebugger() { 3320 EnterDebugger::~EnterDebugger() {
3258 Debug* debug = isolate_->debug(); 3321 Debug* debug = isolate_->debug();
3259 3322
3260 // Leaving this debugger entry.
3261 debug->set_debugger_entry(prev_);
3262
3263 // Restore to the previous break state. 3323 // Restore to the previous break state.
3264 debug->SetBreak(break_frame_id_, break_id_); 3324 debug->SetBreak(break_frame_id_, break_id_);
3265 3325
3266 // Check for leaving the debugger. 3326 // Check for leaving the debugger.
3267 if (!load_failed_ && prev_ == NULL) { 3327 if (!load_failed_ && prev_ == NULL) {
3268 // Clear mirror cache when leaving the debugger. Skip this if there is a 3328 // Clear mirror cache when leaving the debugger. Skip this if there is a
3269 // pending exception as clearing the mirror cache calls back into 3329 // pending exception as clearing the mirror cache calls back into
3270 // JavaScript. This can happen if the v8::Debug::Call is used in which 3330 // JavaScript. This can happen if the v8::Debug::Call is used in which
3271 // case the exception should end up in the calling code. 3331 // case the exception should end up in the calling code.
3272 if (!isolate_->has_pending_exception()) { 3332 if (!isolate_->has_pending_exception()) {
(...skipping 11 matching lines...) Expand all
3284 if (debug->has_pending_interrupt()) { 3344 if (debug->has_pending_interrupt()) {
3285 debug->set_has_pending_interrupt(false); 3345 debug->set_has_pending_interrupt(false);
3286 isolate_->stack_guard()->RequestDebugBreak(); 3346 isolate_->stack_guard()->RequestDebugBreak();
3287 } 3347 }
3288 3348
3289 // If there are commands in the queue when leaving the debugger request 3349 // If there are commands in the queue when leaving the debugger request
3290 // that these commands are processed. 3350 // that these commands are processed.
3291 if (isolate_->debugger()->HasCommands()) { 3351 if (isolate_->debugger()->HasCommands()) {
3292 isolate_->stack_guard()->RequestDebugCommand(); 3352 isolate_->stack_guard()->RequestDebugCommand();
3293 } 3353 }
3354
3355 // If leaving the debugger with the debugger no longer active unload it.
3356 if (!isolate_->debugger()->is_active()) {
3357 isolate_->debugger()->UnloadDebugger();
3358 }
3294 } 3359 }
3295 3360
3296 isolate_->debugger()->UpdateState(); 3361 // Leaving this debugger entry.
3362 debug->set_debugger_entry(prev_);
3297 } 3363 }
3298 3364
3299 3365
3300 MessageImpl MessageImpl::NewEvent(DebugEvent event, 3366 MessageImpl MessageImpl::NewEvent(DebugEvent event,
3301 bool running, 3367 bool running,
3302 Handle<JSObject> exec_state, 3368 Handle<JSObject> exec_state,
3303 Handle<JSObject> event_data) { 3369 Handle<JSObject> event_data) {
3304 MessageImpl message(true, event, running, 3370 MessageImpl message(true, event, running,
3305 exec_state, event_data, Handle<String>(), NULL); 3371 exec_state, event_data, Handle<String>(), NULL);
3306 return message; 3372 return message;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
3550 logger_->DebugEvent("Put", message.text()); 3616 logger_->DebugEvent("Put", message.text());
3551 } 3617 }
3552 3618
3553 3619
3554 void LockingCommandMessageQueue::Clear() { 3620 void LockingCommandMessageQueue::Clear() {
3555 LockGuard<Mutex> lock_guard(&mutex_); 3621 LockGuard<Mutex> lock_guard(&mutex_);
3556 queue_.Clear(); 3622 queue_.Clear();
3557 } 3623 }
3558 3624
3559 } } // namespace v8::internal 3625 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698