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

Side by Side Diff: src/debug.cc

Issue 264233005: Clean up stack guard interrupts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments 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.h » ('j') | src/execution.cc » ('J')
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 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 thread_local_.last_step_action_ = StepNone; 519 thread_local_.last_step_action_ = StepNone;
520 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; 520 thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
521 thread_local_.step_count_ = 0; 521 thread_local_.step_count_ = 0;
522 thread_local_.last_fp_ = 0; 522 thread_local_.last_fp_ = 0;
523 thread_local_.queued_step_count_ = 0; 523 thread_local_.queued_step_count_ = 0;
524 thread_local_.step_into_fp_ = 0; 524 thread_local_.step_into_fp_ = 0;
525 thread_local_.step_out_fp_ = 0; 525 thread_local_.step_out_fp_ = 0;
526 thread_local_.after_break_target_ = 0; 526 thread_local_.after_break_target_ = 0;
527 // TODO(isolates): frames_are_dropped_? 527 // TODO(isolates): frames_are_dropped_?
528 thread_local_.debugger_entry_ = NULL; 528 thread_local_.debugger_entry_ = NULL;
529 thread_local_.pending_interrupts_ = 0; 529 thread_local_.has_pending_interrupt_ = false;
530 thread_local_.restarter_frame_function_pointer_ = NULL; 530 thread_local_.restarter_frame_function_pointer_ = NULL;
531 } 531 }
532 532
533 533
534 char* Debug::ArchiveDebug(char* storage) { 534 char* Debug::ArchiveDebug(char* storage) {
535 char* to = storage; 535 char* to = storage;
536 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 536 OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
537 to += sizeof(ThreadLocal); 537 to += sizeof(ThreadLocal);
538 OS::MemCopy(to, reinterpret_cast<char*>(&registers_), sizeof(registers_)); 538 OS::MemCopy(to, reinterpret_cast<char*>(&registers_), sizeof(registers_));
539 ThreadInit(); 539 ThreadInit();
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 853
854 // Clear the script cache. 854 // Clear the script cache.
855 DestroyScriptCache(); 855 DestroyScriptCache();
856 856
857 // Clear debugger context global handle. 857 // Clear debugger context global handle.
858 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); 858 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
859 debug_context_ = Handle<Context>(); 859 debug_context_ = Handle<Context>();
860 } 860 }
861 861
862 862
863 // Set the flag indicating that preemption happened during debugging.
864 void Debug::PreemptionWhileInDebugger() {
865 ASSERT(InDebugger());
866 Debug::set_interrupts_pending(PREEMPT);
867 }
868
869
870 Object* Debug::Break(Arguments args) { 863 Object* Debug::Break(Arguments args) {
871 Heap* heap = isolate_->heap(); 864 Heap* heap = isolate_->heap();
872 HandleScope scope(isolate_); 865 HandleScope scope(isolate_);
873 ASSERT(args.length() == 0); 866 ASSERT(args.length() == 0);
874 867
875 thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED; 868 thread_local_.frame_drop_mode_ = FRAMES_UNTOUCHED;
876 869
877 // Get the top-most JavaScript frame. 870 // Get the top-most JavaScript frame.
878 JavaScriptFrameIterator it(isolate_); 871 JavaScriptFrameIterator it(isolate_);
879 JavaScriptFrame* frame = it.frame(); 872 JavaScriptFrame* frame = it.frame();
(...skipping 2068 matching lines...) Expand 10 before | Expand all | Expand 10 after
2948 } 2941 }
2949 2942
2950 2943
2951 void Debugger::ProcessDebugEvent(v8::DebugEvent event, 2944 void Debugger::ProcessDebugEvent(v8::DebugEvent event,
2952 Handle<JSObject> event_data, 2945 Handle<JSObject> event_data,
2953 bool auto_continue) { 2946 bool auto_continue) {
2954 HandleScope scope(isolate_); 2947 HandleScope scope(isolate_);
2955 2948
2956 // Clear any pending debug break if this is a real break. 2949 // Clear any pending debug break if this is a real break.
2957 if (!auto_continue) { 2950 if (!auto_continue) {
2958 isolate_->debug()->clear_interrupt_pending(DEBUGBREAK); 2951 isolate_->debug()->set_has_pending_interrupt(false);
2959 } 2952 }
2960 2953
2961 // Create the execution state. 2954 // Create the execution state.
2962 Handle<Object> exec_state; 2955 Handle<Object> exec_state;
2963 // Bail out and don't call debugger if exception. 2956 // Bail out and don't call debugger if exception.
2964 if (!MakeExecutionState().ToHandle(&exec_state)) return; 2957 if (!MakeExecutionState().ToHandle(&exec_state)) return;
2965 2958
2966 // First notify the message handler if any. 2959 // First notify the message handler if any.
2967 if (message_handler_ != NULL) { 2960 if (message_handler_ != NULL) {
2968 NotifyMessageHandler(event, 2961 NotifyMessageHandler(event,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
3094 case v8::NewFunction: 3087 case v8::NewFunction:
3095 break; 3088 break;
3096 default: 3089 default:
3097 UNREACHABLE(); 3090 UNREACHABLE();
3098 } 3091 }
3099 3092
3100 // The debug command interrupt flag might have been set when the command was 3093 // The debug command interrupt flag might have been set when the command was
3101 // added. It should be enough to clear the flag only once while we are in the 3094 // added. It should be enough to clear the flag only once while we are in the
3102 // debugger. 3095 // debugger.
3103 ASSERT(isolate_->debug()->InDebugger()); 3096 ASSERT(isolate_->debug()->InDebugger());
3104 isolate_->stack_guard()->Continue(DEBUGCOMMAND); 3097 isolate_->stack_guard()->ClearDebugCommand();
3105 3098
3106 // Notify the debugger that a debug event has occurred unless auto continue is 3099 // Notify the debugger that a debug event has occurred unless auto continue is
3107 // active in which case no event is send. 3100 // active in which case no event is send.
3108 if (sendEventMessage) { 3101 if (sendEventMessage) {
3109 MessageImpl message = MessageImpl::NewEvent( 3102 MessageImpl message = MessageImpl::NewEvent(
3110 event, 3103 event,
3111 auto_continue, 3104 auto_continue,
3112 Handle<JSObject>::cast(exec_state), 3105 Handle<JSObject>::cast(exec_state),
3113 Handle<JSObject>::cast(event_data)); 3106 Handle<JSObject>::cast(event_data));
3114 InvokeMessageHandler(message); 3107 InvokeMessageHandler(message);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
3342 CommandMessage message = CommandMessage::New( 3335 CommandMessage message = CommandMessage::New(
3343 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), 3336 Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
3344 command.length()), 3337 command.length()),
3345 client_data); 3338 client_data);
3346 isolate_->logger()->DebugTag("Put command on command_queue."); 3339 isolate_->logger()->DebugTag("Put command on command_queue.");
3347 command_queue_.Put(message); 3340 command_queue_.Put(message);
3348 command_received_.Signal(); 3341 command_received_.Signal();
3349 3342
3350 // Set the debug command break flag to have the command processed. 3343 // Set the debug command break flag to have the command processed.
3351 if (!isolate_->debug()->InDebugger()) { 3344 if (!isolate_->debug()->InDebugger()) {
3352 isolate_->stack_guard()->DebugCommand(); 3345 isolate_->stack_guard()->RequestDebugCommand();
3353 } 3346 }
3354 3347
3355 MessageDispatchHelperThread* dispatch_thread; 3348 MessageDispatchHelperThread* dispatch_thread;
3356 { 3349 {
3357 LockGuard<Mutex> lock_guard(&dispatch_handler_access_); 3350 LockGuard<Mutex> lock_guard(&dispatch_handler_access_);
3358 dispatch_thread = message_dispatch_helper_thread_; 3351 dispatch_thread = message_dispatch_helper_thread_;
3359 } 3352 }
3360 3353
3361 if (dispatch_thread == NULL) { 3354 if (dispatch_thread == NULL) {
3362 CallMessageDispatchHandler(); 3355 CallMessageDispatchHandler();
3363 } else { 3356 } else {
3364 dispatch_thread->Schedule(); 3357 dispatch_thread->Schedule();
3365 } 3358 }
3366 } 3359 }
3367 3360
3368 3361
3369 bool Debugger::HasCommands() { 3362 bool Debugger::HasCommands() {
3370 return !command_queue_.IsEmpty(); 3363 return !command_queue_.IsEmpty();
3371 } 3364 }
3372 3365
3373 3366
3374 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { 3367 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
3375 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); 3368 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
3376 event_command_queue_.Put(message); 3369 event_command_queue_.Put(message);
3377 3370
3378 // Set the debug command break flag to have the command processed. 3371 // Set the debug command break flag to have the command processed.
3379 if (!isolate_->debug()->InDebugger()) { 3372 if (!isolate_->debug()->InDebugger()) {
3380 isolate_->stack_guard()->DebugCommand(); 3373 isolate_->stack_guard()->RequestDebugCommand();
3381 } 3374 }
3382 } 3375 }
3383 3376
3384 3377
3385 bool Debugger::IsDebuggerActive() { 3378 bool Debugger::IsDebuggerActive() {
3386 LockGuard<RecursiveMutex> with(debugger_access_); 3379 LockGuard<RecursiveMutex> with(debugger_access_);
3387 3380
3388 return message_handler_ != NULL || 3381 return message_handler_ != NULL ||
3389 !event_listener_.is_null() || 3382 !event_listener_.is_null() ||
3390 force_debugger_active_; 3383 force_debugger_active_;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3473 } 3466 }
3474 3467
3475 3468
3476 EnterDebugger::EnterDebugger(Isolate* isolate) 3469 EnterDebugger::EnterDebugger(Isolate* isolate)
3477 : isolate_(isolate), 3470 : isolate_(isolate),
3478 prev_(isolate_->debug()->debugger_entry()), 3471 prev_(isolate_->debug()->debugger_entry()),
3479 it_(isolate_), 3472 it_(isolate_),
3480 has_js_frames_(!it_.done()), 3473 has_js_frames_(!it_.done()),
3481 save_(isolate_) { 3474 save_(isolate_) {
3482 Debug* debug = isolate_->debug(); 3475 Debug* debug = isolate_->debug();
3483 ASSERT(prev_ != NULL || !debug->is_interrupt_pending(PREEMPT));
3484 ASSERT(prev_ != NULL || !debug->is_interrupt_pending(DEBUGBREAK));
3485
3486 // Link recursive debugger entry. 3476 // Link recursive debugger entry.
3487 debug->set_debugger_entry(this); 3477 debug->set_debugger_entry(this);
3488 3478
3489 // Store the previous break id and frame id. 3479 // Store the previous break id and frame id.
3490 break_id_ = debug->break_id(); 3480 break_id_ = debug->break_id();
3491 break_frame_id_ = debug->break_frame_id(); 3481 break_frame_id_ = debug->break_frame_id();
3492 3482
3493 // Create the new break info. If there is no JavaScript frames there is no 3483 // Create the new break info. If there is no JavaScript frames there is no
3494 // break frame id. 3484 // break frame id.
3495 if (has_js_frames_) { 3485 if (has_js_frames_) {
(...skipping 20 matching lines...) Expand all
3516 3506
3517 // Check for leaving the debugger. 3507 // Check for leaving the debugger.
3518 if (!load_failed_ && prev_ == NULL) { 3508 if (!load_failed_ && prev_ == NULL) {
3519 // Clear mirror cache when leaving the debugger. Skip this if there is a 3509 // Clear mirror cache when leaving the debugger. Skip this if there is a
3520 // pending exception as clearing the mirror cache calls back into 3510 // pending exception as clearing the mirror cache calls back into
3521 // JavaScript. This can happen if the v8::Debug::Call is used in which 3511 // JavaScript. This can happen if the v8::Debug::Call is used in which
3522 // case the exception should end up in the calling code. 3512 // case the exception should end up in the calling code.
3523 if (!isolate_->has_pending_exception()) { 3513 if (!isolate_->has_pending_exception()) {
3524 // Try to avoid any pending debug break breaking in the clear mirror 3514 // Try to avoid any pending debug break breaking in the clear mirror
3525 // cache JavaScript code. 3515 // cache JavaScript code.
3526 if (isolate_->stack_guard()->IsDebugBreak()) { 3516 if (isolate_->stack_guard()->CheckDebugBreak()) {
3527 debug->set_interrupts_pending(DEBUGBREAK); 3517 debug->set_has_pending_interrupt(true);
3528 isolate_->stack_guard()->Continue(DEBUGBREAK); 3518 isolate_->stack_guard()->ClearDebugBreak();
3529 } 3519 }
3530 debug->ClearMirrorCache(); 3520 debug->ClearMirrorCache();
3531 } 3521 }
3532 3522
3533 // Request preemption and debug break when leaving the last debugger entry 3523 // Request debug break when leaving the last debugger entry
3534 // if any of these where recorded while debugging. 3524 // if one was recorded while debugging.
3535 if (debug->is_interrupt_pending(PREEMPT)) { 3525 if (debug->has_pending_interrupt()) {
3536 // This re-scheduling of preemption is to avoid starvation in some 3526 debug->set_has_pending_interrupt(false);
3537 // debugging scenarios. 3527 isolate_->stack_guard()->RequestDebugBreak();
3538 debug->clear_interrupt_pending(PREEMPT);
3539 isolate_->stack_guard()->Preempt();
3540 }
3541 if (debug->is_interrupt_pending(DEBUGBREAK)) {
3542 debug->clear_interrupt_pending(DEBUGBREAK);
3543 isolate_->stack_guard()->DebugBreak();
3544 } 3528 }
3545 3529
3546 // If there are commands in the queue when leaving the debugger request 3530 // If there are commands in the queue when leaving the debugger request
3547 // that these commands are processed. 3531 // that these commands are processed.
3548 if (isolate_->debugger()->HasCommands()) { 3532 if (isolate_->debugger()->HasCommands()) {
3549 isolate_->stack_guard()->DebugCommand(); 3533 isolate_->stack_guard()->RequestDebugCommand();
3550 } 3534 }
3551 3535
3552 // If leaving the debugger with the debugger no longer active unload it. 3536 // If leaving the debugger with the debugger no longer active unload it.
3553 if (!isolate_->debugger()->IsDebuggerActive()) { 3537 if (!isolate_->debugger()->IsDebuggerActive()) {
3554 isolate_->debugger()->UnloadDebugger(); 3538 isolate_->debugger()->UnloadDebugger();
3555 } 3539 }
3556 } 3540 }
3557 3541
3558 // Leaving this debugger entry. 3542 // Leaving this debugger entry.
3559 debug->set_debugger_entry(prev_); 3543 debug->set_debugger_entry(prev_);
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
3847 already_signalled_ = false; 3831 already_signalled_ = false;
3848 } 3832 }
3849 { 3833 {
3850 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); 3834 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_));
3851 isolate_->debugger()->CallMessageDispatchHandler(); 3835 isolate_->debugger()->CallMessageDispatchHandler();
3852 } 3836 }
3853 } 3837 }
3854 } 3838 }
3855 3839
3856 } } // namespace v8::internal 3840 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/execution.h » ('j') | src/execution.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698