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

Side by Side Diff: src/debug.cc

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