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

Side by Side Diff: src/debug.h

Issue 115262: Change the handling of the debug break stack guard (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 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 | « no previous file | src/debug.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 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 static Address step_in_fp() { return thread_local_.step_into_fp_; } 275 static Address step_in_fp() { return thread_local_.step_into_fp_; }
276 static Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; } 276 static Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; }
277 277
278 static EnterDebugger* debugger_entry() { 278 static EnterDebugger* debugger_entry() {
279 return thread_local_.debugger_entry_; 279 return thread_local_.debugger_entry_;
280 } 280 }
281 static void set_debugger_entry(EnterDebugger* entry) { 281 static void set_debugger_entry(EnterDebugger* entry) {
282 thread_local_.debugger_entry_ = entry; 282 thread_local_.debugger_entry_ = entry;
283 } 283 }
284 284
285 static bool preemption_pending() { 285 // Check whether any of the specified interrupts are pending.
286 return thread_local_.preemption_pending_; 286 static bool is_interrupt_pending(InterruptFlag what) {
287 return (thread_local_.pending_interrupts_ & what) != 0;
287 } 288 }
288 static void set_preemption_pending(bool preemption_pending) { 289
289 thread_local_.preemption_pending_ = preemption_pending; 290 // Set specified interrupts as pending.
291 static void set_interrupts_pending(InterruptFlag what) {
292 thread_local_.pending_interrupts_ |= what;
293 }
294
295 // Clear specified interrupts from pending.
296 static void clear_interrupt_pending(InterruptFlag what) {
297 thread_local_.pending_interrupts_ &= ~static_cast<int>(what);
290 } 298 }
291 299
292 // Getter and setter for the disable break state. 300 // Getter and setter for the disable break state.
293 static bool disable_break() { return disable_break_; } 301 static bool disable_break() { return disable_break_; }
294 static void set_disable_break(bool disable_break) { 302 static void set_disable_break(bool disable_break) {
295 disable_break_ = disable_break; 303 disable_break_ = disable_break;
296 } 304 }
297 305
298 // Getters for the current exception break state. 306 // Getters for the current exception break state.
299 static bool break_on_exception() { return break_on_exception_; } 307 static bool break_on_exception() { return break_on_exception_; }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 432
425 // Frame pointer for frame from which step in was performed. 433 // Frame pointer for frame from which step in was performed.
426 Address step_into_fp_; 434 Address step_into_fp_;
427 435
428 // Storage location for jump when exiting debug break calls. 436 // Storage location for jump when exiting debug break calls.
429 Address after_break_target_; 437 Address after_break_target_;
430 438
431 // Top debugger entry. 439 // Top debugger entry.
432 EnterDebugger* debugger_entry_; 440 EnterDebugger* debugger_entry_;
433 441
434 // Preemption happened while debugging. 442 // Pending interrupts scheduled while debugging.
435 bool preemption_pending_; 443 int pending_interrupts_;
436 }; 444 };
437 445
438 // Storage location for registers when handling debug break calls 446 // Storage location for registers when handling debug break calls
439 static JSCallerSavedBuffer registers_; 447 static JSCallerSavedBuffer registers_;
440 static ThreadLocal thread_local_; 448 static ThreadLocal thread_local_;
441 static void ThreadInit(); 449 static void ThreadInit();
442 450
443 // Code object for debug break return entry code. 451 // Code object for debug break return entry code.
444 static Code* debug_break_return_entry_; 452 static Code* debug_break_return_entry_;
445 453
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 680
673 // This class is used for entering the debugger. Create an instance in the stack 681 // This class is used for entering the debugger. Create an instance in the stack
674 // to enter the debugger. This will set the current break state, make sure the 682 // to enter the debugger. This will set the current break state, make sure the
675 // debugger is loaded and switch to the debugger context. If the debugger for 683 // debugger is loaded and switch to the debugger context. If the debugger for
676 // some reason could not be entered FailedToEnter will return true. 684 // some reason could not be entered FailedToEnter will return true.
677 class EnterDebugger BASE_EMBEDDED { 685 class EnterDebugger BASE_EMBEDDED {
678 public: 686 public:
679 EnterDebugger() 687 EnterDebugger()
680 : prev_(Debug::debugger_entry()), 688 : prev_(Debug::debugger_entry()),
681 has_js_frames_(!it_.done()) { 689 has_js_frames_(!it_.done()) {
682 ASSERT(prev_ == NULL ? !Debug::preemption_pending() : true); 690 ASSERT(prev_ != NULL || !Debug::is_interrupt_pending(PREEMPT));
691 ASSERT(prev_ != NULL || !Debug::is_interrupt_pending(DEBUGBREAK));
683 692
684 // Link recursive debugger entry. 693 // Link recursive debugger entry.
685 Debug::set_debugger_entry(this); 694 Debug::set_debugger_entry(this);
686 695
687 // Store the previous break id and frame id. 696 // Store the previous break id and frame id.
688 break_id_ = Debug::break_id(); 697 break_id_ = Debug::break_id();
689 break_frame_id_ = Debug::break_frame_id(); 698 break_frame_id_ = Debug::break_frame_id();
690 699
691 // Create the new break info. If there is no JavaScript frames there is no 700 // Create the new break info. If there is no JavaScript frames there is no
692 // break frame id. 701 // break frame id.
693 if (has_js_frames_) { 702 if (has_js_frames_) {
694 Debug::NewBreak(it_.frame()->id()); 703 Debug::NewBreak(it_.frame()->id());
695 } else { 704 } else {
696 Debug::NewBreak(StackFrame::NO_ID); 705 Debug::NewBreak(StackFrame::NO_ID);
697 } 706 }
698 707
699 // Make sure that debugger is loaded and enter the debugger context. 708 // Make sure that debugger is loaded and enter the debugger context.
700 load_failed_ = !Debug::Load(); 709 load_failed_ = !Debug::Load();
701 if (!load_failed_) { 710 if (!load_failed_) {
702 // NOTE the member variable save which saves the previous context before 711 // NOTE the member variable save which saves the previous context before
703 // this change. 712 // this change.
704 Top::set_context(*Debug::debug_context()); 713 Top::set_context(*Debug::debug_context());
705 } 714 }
706 } 715 }
707 716
708 ~EnterDebugger() { 717 ~EnterDebugger() {
709 // Restore to the previous break state. 718 // Restore to the previous break state.
710 Debug::SetBreak(break_frame_id_, break_id_); 719 Debug::SetBreak(break_frame_id_, break_id_);
711 720
712 // Request preemption when leaving the last debugger entry and a preemption 721 // Check for leaving the debugger.
713 // had been recorded while debugging. This is to avoid starvation in some
714 // debugging scenarios.
715 if (prev_ == NULL && Debug::preemption_pending()) {
716 StackGuard::Preempt();
717 Debug::set_preemption_pending(false);
718 }
719
720 // If there are commands in the queue when leaving the debugger request that
721 // these commands are processed.
722 if (prev_ == NULL && Debugger::HasCommands()) {
723 StackGuard::DebugCommand();
724 }
725
726 if (prev_ == NULL) { 722 if (prev_ == NULL) {
727 // Clear mirror cache when leaving the debugger. Skip this if there is a 723 // Clear mirror cache when leaving the debugger. Skip this if there is a
728 // pending exception as clearing the mirror cache calls back into 724 // pending exception as clearing the mirror cache calls back into
729 // JavaScript. This can happen if the v8::Debug::Call is used in which 725 // JavaScript. This can happen if the v8::Debug::Call is used in which
730 // case the exception should end up in the calling code. 726 // case the exception should end up in the calling code.
731 if (!Top::has_pending_exception()) { 727 if (!Top::has_pending_exception()) {
728 // Try to avoid any pending debug break breaking in the clear mirror
729 // cache JavaScript code.
730 if (StackGuard::IsDebugBreak()) {
731 Debug::set_interrupts_pending(DEBUGBREAK);
732 StackGuard::Continue(DEBUGBREAK);
733 }
732 Debug::ClearMirrorCache(); 734 Debug::ClearMirrorCache();
733 } 735 }
736
737 // Request preemption and debug break when leaving the last debugger entry
738 // if any of these where recorded while debugging.
739 if (Debug::is_interrupt_pending(PREEMPT)) {
740 // This re-scheduling of preemption is to avoid starvation in some
741 // debugging scenarios.
742 Debug::clear_interrupt_pending(PREEMPT);
743 StackGuard::Preempt();
744 }
745 if (Debug::is_interrupt_pending(DEBUGBREAK)) {
746 Debug::clear_interrupt_pending(DEBUGBREAK);
747 StackGuard::DebugBreak();
748 }
749
750 // If there are commands in the queue when leaving the debugger request
751 // that these commands are processed.
752 if (Debugger::HasCommands()) {
753 StackGuard::DebugCommand();
754 }
755
734 // If leaving the debugger with the debugger no longer active unload it. 756 // If leaving the debugger with the debugger no longer active unload it.
735 if (!Debugger::IsDebuggerActive()) { 757 if (!Debugger::IsDebuggerActive()) {
736 Debugger::UnloadDebugger(); 758 Debugger::UnloadDebugger();
737 } 759 }
738 } 760 }
739 761
740 // Leaving this debugger entry. 762 // Leaving this debugger entry.
741 Debug::set_debugger_entry(prev_); 763 Debug::set_debugger_entry(prev_);
742 } 764 }
743 765
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 Debug::AddressId id_; 841 Debug::AddressId id_;
820 int reg_; 842 int reg_;
821 }; 843 };
822 844
823 845
824 } } // namespace v8::internal 846 } } // namespace v8::internal
825 847
826 #endif // ENABLE_DEBUGGER_SUPPORT 848 #endif // ENABLE_DEBUGGER_SUPPORT
827 849
828 #endif // V8_DEBUG_H_ 850 #endif // V8_DEBUG_H_
OLDNEW
« no previous file with comments | « no previous file | src/debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698