LCOV - code coverage report
Current view: top level - src/debug - debug.h (source / functions) Hit Total Coverage
Test: app.info Lines: 40 40 100.0 %
Date: 2019-02-19 Functions: 9 9 100.0 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_DEBUG_DEBUG_H_
       6             : #define V8_DEBUG_DEBUG_H_
       7             : 
       8             : #include <vector>
       9             : 
      10             : #include "src/debug/debug-interface.h"
      11             : #include "src/debug/interface-types.h"
      12             : #include "src/frames.h"
      13             : #include "src/globals.h"
      14             : #include "src/handles.h"
      15             : #include "src/isolate.h"
      16             : #include "src/objects/debug-objects.h"
      17             : #include "src/source-position-table.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : 
      22             : // Forward declarations.
      23             : class AbstractCode;
      24             : class DebugScope;
      25             : class JSGeneratorObject;
      26             : 
      27             : // Step actions. NOTE: These values are in macros.py as well.
      28             : enum StepAction : int8_t {
      29             :   StepNone = -1,  // Stepping not prepared.
      30             :   StepOut = 0,    // Step out of the current function.
      31             :   StepNext = 1,   // Step to the next statement in the current function.
      32             :   StepIn = 2,     // Step into new functions invoked or the next statement
      33             :                   // in the current function.
      34             :   LastStepAction = StepIn
      35             : };
      36             : 
      37             : // Type of exception break. NOTE: These values are in macros.py as well.
      38             : enum ExceptionBreakType {
      39             :   BreakException = 0,
      40             :   BreakUncaughtException = 1
      41             : };
      42             : 
      43             : enum DebugBreakType {
      44             :   NOT_DEBUG_BREAK,
      45             :   DEBUGGER_STATEMENT,
      46             :   DEBUG_BREAK_SLOT,
      47             :   DEBUG_BREAK_SLOT_AT_CALL,
      48             :   DEBUG_BREAK_SLOT_AT_RETURN,
      49             :   DEBUG_BREAK_SLOT_AT_SUSPEND,
      50             :   DEBUG_BREAK_AT_ENTRY,
      51             : };
      52             : 
      53             : enum IgnoreBreakMode {
      54             :   kIgnoreIfAllFramesBlackboxed,
      55             :   kIgnoreIfTopFrameBlackboxed
      56             : };
      57             : 
      58             : class BreakLocation {
      59             :  public:
      60             :   static BreakLocation FromFrame(Handle<DebugInfo> debug_info,
      61             :                                  JavaScriptFrame* frame);
      62             : 
      63             :   static void AllAtCurrentStatement(Handle<DebugInfo> debug_info,
      64             :                                     JavaScriptFrame* frame,
      65             :                                     std::vector<BreakLocation>* result_out);
      66             : 
      67             :   inline bool IsSuspend() const { return type_ == DEBUG_BREAK_SLOT_AT_SUSPEND; }
      68      180070 :   inline bool IsReturn() const { return type_ == DEBUG_BREAK_SLOT_AT_RETURN; }
      69             :   inline bool IsReturnOrSuspend() const {
      70        7984 :     return type_ >= DEBUG_BREAK_SLOT_AT_RETURN;
      71             :   }
      72             :   inline bool IsCall() const { return type_ == DEBUG_BREAK_SLOT_AT_CALL; }
      73           5 :   inline bool IsDebugBreakSlot() const { return type_ >= DEBUG_BREAK_SLOT; }
      74             :   inline bool IsDebuggerStatement() const {
      75             :     return type_ == DEBUGGER_STATEMENT;
      76             :   }
      77             :   inline bool IsDebugBreakAtEntry() const {
      78             :     bool result = type_ == DEBUG_BREAK_AT_ENTRY;
      79             :     return result;
      80             :   }
      81             : 
      82             :   bool HasBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info) const;
      83             : 
      84             :   inline int position() const { return position_; }
      85             : 
      86             :   debug::BreakLocationType type() const;
      87             : 
      88             :   JSGeneratorObject GetGeneratorObjectForSuspendedFrame(
      89             :       JavaScriptFrame* frame) const;
      90             : 
      91             :  private:
      92             :   BreakLocation(Handle<AbstractCode> abstract_code, DebugBreakType type,
      93             :                 int code_offset, int position, int generator_obj_reg_index)
      94             :       : abstract_code_(abstract_code),
      95             :         code_offset_(code_offset),
      96             :         type_(type),
      97             :         position_(position),
      98      435313 :         generator_obj_reg_index_(generator_obj_reg_index) {
      99             :     DCHECK_NE(NOT_DEBUG_BREAK, type_);
     100             :   }
     101             : 
     102             :   BreakLocation(int position, DebugBreakType type)
     103             :       : code_offset_(0),
     104             :         type_(type),
     105             :         position_(position),
     106         470 :         generator_obj_reg_index_(0) {}
     107             : 
     108             :   static int BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info,
     109             :                                       Handle<AbstractCode> abstract_code,
     110             :                                       int offset);
     111             : 
     112             :   void SetDebugBreak();
     113             :   void ClearDebugBreak();
     114             : 
     115             :   Handle<AbstractCode> abstract_code_;
     116             :   int code_offset_;
     117             :   DebugBreakType type_;
     118             :   int position_;
     119             :   int generator_obj_reg_index_;
     120             : 
     121             :   friend class BreakIterator;
     122             : };
     123             : 
     124             : class BreakIterator {
     125             :  public:
     126             :   explicit BreakIterator(Handle<DebugInfo> debug_info);
     127             : 
     128             :   BreakLocation GetBreakLocation();
     129   148220036 :   bool Done() const { return source_position_iterator_.done(); }
     130             :   void Next();
     131             : 
     132             :   void SkipToPosition(int position);
     133             :   void SkipTo(int count) {
     134    11824837 :     while (count-- > 0) Next();
     135             :   }
     136             : 
     137   100621193 :   int code_offset() { return source_position_iterator_.code_offset(); }
     138             :   int break_index() const { return break_index_; }
     139             :   inline int position() const { return position_; }
     140             :   inline int statement_position() const { return statement_position_; }
     141             : 
     142             :   void ClearDebugBreak();
     143             :   void SetDebugBreak();
     144             : 
     145             :  private:
     146             :   int BreakIndexFromPosition(int position);
     147             : 
     148             :   Isolate* isolate();
     149             : 
     150             :   DebugBreakType GetDebugBreakType();
     151             : 
     152             :   Handle<DebugInfo> debug_info_;
     153             :   int break_index_;
     154             :   int position_;
     155             :   int statement_position_;
     156             :   SourcePositionTableIterator source_position_iterator_;
     157             :   DisallowHeapAllocation no_gc_;
     158             : 
     159             :   DISALLOW_COPY_AND_ASSIGN(BreakIterator);
     160             : };
     161             : 
     162             : // Linked list holding debug info objects. The debug info objects are kept as
     163             : // weak handles to avoid a debug info object to keep a function alive.
     164             : class DebugInfoListNode {
     165             :  public:
     166             :   DebugInfoListNode(Isolate* isolate, DebugInfo debug_info);
     167             :   ~DebugInfoListNode();
     168             : 
     169             :   DebugInfoListNode* next() { return next_; }
     170       30749 :   void set_next(DebugInfoListNode* next) { next_ = next; }
     171             :   Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); }
     172             : 
     173             :  private:
     174             :   // Global (weak) handle to the debug info object.
     175             :   Address* debug_info_;
     176             : 
     177             :   // Next pointer for linked list.
     178             :   DebugInfoListNode* next_;
     179             : };
     180             : 
     181             : class DebugFeatureTracker {
     182             :  public:
     183             :   enum Feature {
     184             :     kActive = 1,
     185             :     kBreakPoint = 2,
     186             :     kStepping = 3,
     187             :     kHeapSnapshot = 4,
     188             :     kAllocationTracking = 5,
     189             :     kProfiler = 6,
     190             :     kLiveEdit = 7,
     191             :   };
     192             : 
     193             :   explicit DebugFeatureTracker(Isolate* isolate)
     194       61048 :       : isolate_(isolate), bitfield_(0) {}
     195             :   void Track(Feature feature);
     196             : 
     197             :  private:
     198             :   Isolate* isolate_;
     199             :   uint32_t bitfield_;
     200             : };
     201             : 
     202             : 
     203             : // This class contains the debugger support. The main purpose is to handle
     204             : // setting break points in the code.
     205             : //
     206             : // This class controls the debug info for all functions which currently have
     207             : // active breakpoints in them. This debug info is held in the heap root object
     208             : // debug_info which is a FixedArray. Each entry in this list is of class
     209             : // DebugInfo.
     210             : class Debug {
     211             :  public:
     212             :   // Debug event triggers.
     213             :   void OnDebugBreak(Handle<FixedArray> break_points_hit);
     214             : 
     215             :   void OnThrow(Handle<Object> exception);
     216             :   void OnPromiseReject(Handle<Object> promise, Handle<Object> value);
     217             :   void OnCompileError(Handle<Script> script);
     218             :   void OnAfterCompile(Handle<Script> script);
     219             : 
     220             :   void HandleDebugBreak(IgnoreBreakMode ignore_break_mode);
     221             : 
     222             :   // The break target may not be the top-most frame, since we may be
     223             :   // breaking before entering a function that cannot contain break points.
     224             :   void Break(JavaScriptFrame* frame, Handle<JSFunction> break_target);
     225             : 
     226             :   // Scripts handling.
     227             :   Handle<FixedArray> GetLoadedScripts();
     228             : 
     229             :   // Break point handling.
     230             :   bool SetBreakPoint(Handle<JSFunction> function,
     231             :                      Handle<BreakPoint> break_point, int* source_position);
     232             :   void ClearBreakPoint(Handle<BreakPoint> break_point);
     233             :   void ChangeBreakOnException(ExceptionBreakType type, bool enable);
     234             :   bool IsBreakOnException(ExceptionBreakType type);
     235             : 
     236             :   bool SetBreakPointForScript(Handle<Script> script, Handle<String> condition,
     237             :                               int* source_position, int* id);
     238             :   bool SetBreakpointForFunction(Handle<JSFunction> function,
     239             :                                 Handle<String> condition, int* id);
     240             :   void RemoveBreakpoint(int id);
     241             : 
     242             :   // Find breakpoints from the debug info and the break location and check
     243             :   // whether they are hit. Return an empty handle if not, or a FixedArray with
     244             :   // hit BreakPoint objects.
     245             :   MaybeHandle<FixedArray> GetHitBreakPoints(Handle<DebugInfo> debug_info,
     246             :                                             int position);
     247             : 
     248             :   // Stepping handling.
     249             :   void PrepareStep(StepAction step_action);
     250             :   void PrepareStepIn(Handle<JSFunction> function);
     251             :   void PrepareStepInSuspendedGenerator();
     252             :   void PrepareStepOnThrow();
     253             :   void ClearStepping();
     254             : 
     255             :   void SetBreakOnNextFunctionCall();
     256             :   void ClearBreakOnNextFunctionCall();
     257             : 
     258             :   void DeoptimizeFunction(Handle<SharedFunctionInfo> shared);
     259             :   void PrepareFunctionForDebugExecution(Handle<SharedFunctionInfo> shared);
     260             :   void InstallDebugBreakTrampoline();
     261             :   bool GetPossibleBreakpoints(Handle<Script> script, int start_position,
     262             :                               int end_position, bool restrict_to_function,
     263             :                               std::vector<BreakLocation>* locations);
     264             : 
     265             :   bool IsBlackboxed(Handle<SharedFunctionInfo> shared);
     266             : 
     267             :   bool CanBreakAtEntry(Handle<SharedFunctionInfo> shared);
     268             : 
     269             :   void SetDebugDelegate(debug::DebugDelegate* delegate);
     270             : 
     271             :   // Returns whether the operation succeeded.
     272             :   bool EnsureBreakInfo(Handle<SharedFunctionInfo> shared);
     273             :   void CreateBreakInfo(Handle<SharedFunctionInfo> shared);
     274             :   Handle<DebugInfo> GetOrCreateDebugInfo(Handle<SharedFunctionInfo> shared);
     275             : 
     276             :   void InstallCoverageInfo(Handle<SharedFunctionInfo> shared,
     277             :                            Handle<CoverageInfo> coverage_info);
     278             :   void RemoveAllCoverageInfos();
     279             : 
     280             :   // This function is used in FunctionNameUsing* tests.
     281             :   Handle<Object> FindSharedFunctionInfoInScript(Handle<Script> script,
     282             :                                                 int position);
     283             : 
     284             :   static Handle<Object> GetSourceBreakLocations(
     285             :       Isolate* isolate, Handle<SharedFunctionInfo> shared);
     286             : 
     287             :   // Check whether this frame is just about to return.
     288             :   bool IsBreakAtReturn(JavaScriptFrame* frame);
     289             : 
     290             :   // Support for LiveEdit
     291             :   void ScheduleFrameRestart(StackFrame* frame);
     292             : 
     293             :   bool AllFramesOnStackAreBlackboxed();
     294             : 
     295             :   // Set new script source, throw an exception if error occurred. When preview
     296             :   // is true: try to set source, throw exception if any without actual script
     297             :   // change. stack_changed is true if after editing script on pause stack is
     298             :   // changed and client should request stack trace again.
     299             :   bool SetScriptSource(Handle<Script> script, Handle<String> source,
     300             :                        bool preview, debug::LiveEditResult* result);
     301             : 
     302             :   int GetFunctionDebuggingId(Handle<JSFunction> function);
     303             : 
     304             :   // Threading support.
     305             :   char* ArchiveDebug(char* to);
     306             :   char* RestoreDebug(char* from);
     307             :   static int ArchiveSpacePerThread();
     308             :   void FreeThreadResources() { }
     309             :   void Iterate(RootVisitor* v);
     310       11812 :   void InitThread(const ExecutionAccess& lock) { ThreadInit(); }
     311             : 
     312       44423 :   bool CheckExecutionState() { return is_active(); }
     313             : 
     314             :   void StartSideEffectCheckMode();
     315             :   void StopSideEffectCheckMode();
     316             : 
     317             :   void ApplySideEffectChecks(Handle<DebugInfo> debug_info);
     318             :   void ClearSideEffectChecks(Handle<DebugInfo> debug_info);
     319             : 
     320             :   bool PerformSideEffectCheck(Handle<JSFunction> function,
     321             :                               Handle<Object> receiver);
     322             : 
     323             :   enum AccessorKind { kNotAccessor, kGetter, kSetter };
     324             :   bool PerformSideEffectCheckForCallback(Handle<Object> callback_info,
     325             :                                          Handle<Object> receiver,
     326             :                                          AccessorKind accessor_kind);
     327             :   bool PerformSideEffectCheckAtBytecode(InterpretedFrame* frame);
     328             :   bool PerformSideEffectCheckForObject(Handle<Object> object);
     329             : 
     330             :   // Flags and states.
     331       29072 :   inline bool is_active() const { return is_active_; }
     332             :   inline bool in_debug_scope() const {
     333     1929691 :     return !!base::Relaxed_Load(&thread_local_.current_debug_scope_);
     334             :   }
     335      538837 :   inline bool needs_check_on_function_call() const {
     336      538837 :     return hook_on_function_call_;
     337             :   }
     338             : 
     339        7041 :   void set_break_points_active(bool v) { break_points_active_ = v; }
     340        8493 :   bool break_points_active() const { return break_points_active_; }
     341             : 
     342             :   StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
     343             : 
     344             :   Handle<Object> return_value_handle();
     345       66470 :   Object return_value() { return thread_local_.return_value_; }
     346      133342 :   void set_return_value(Object value) { thread_local_.return_value_ = value; }
     347             : 
     348             :   // Support for embedding into generated code.
     349             :   Address is_active_address() {
     350       61449 :     return reinterpret_cast<Address>(&is_active_);
     351             :   }
     352             : 
     353             :   Address hook_on_function_call_address() {
     354       61441 :     return reinterpret_cast<Address>(&hook_on_function_call_);
     355             :   }
     356             : 
     357             :   Address suspended_generator_address() {
     358       61105 :     return reinterpret_cast<Address>(&thread_local_.suspended_generator_);
     359             :   }
     360             : 
     361             :   Address restart_fp_address() {
     362       62281 :     return reinterpret_cast<Address>(&thread_local_.restart_fp_);
     363             :   }
     364       66666 :   bool will_restart() const {
     365       66666 :     return thread_local_.restart_fp_ != kNullAddress;
     366             :   }
     367             : 
     368      538837 :   StepAction last_step_action() { return thread_local_.last_step_action_; }
     369       17452 :   bool break_on_next_function_call() const {
     370       17452 :     return thread_local_.break_on_next_function_call_;
     371             :   }
     372             : 
     373             :   DebugFeatureTracker* feature_tracker() { return &feature_tracker_; }
     374             : 
     375             :   // For functions in which we cannot set a break point, use a canonical
     376             :   // source position for break points.
     377             :   static const int kBreakAtEntryPosition = 0;
     378             : 
     379             :   void RemoveBreakInfoAndMaybeFree(Handle<DebugInfo> debug_info);
     380             : 
     381             :  private:
     382             :   explicit Debug(Isolate* isolate);
     383             :   ~Debug();
     384             : 
     385             :   void UpdateDebugInfosForExecutionMode();
     386             :   void UpdateState();
     387             :   void UpdateHookOnFunctionCall();
     388             :   void Unload();
     389             : 
     390             :   // Return the number of virtual frames below debugger entry.
     391             :   int CurrentFrameCount();
     392             : 
     393             :   inline bool ignore_events() const {
     394     7001953 :     return is_suppressed_ || !is_active_ ||
     395      686834 :            isolate_->debug_execution_mode() == DebugInfo::kSideEffects;
     396             :   }
     397             :   inline bool break_disabled() const { return break_disabled_; }
     398             : 
     399             :   void clear_suspended_generator() {
     400      134451 :     thread_local_.suspended_generator_ = Smi::kZero;
     401             :   }
     402             : 
     403             :   bool has_suspended_generator() const {
     404             :     return thread_local_.suspended_generator_ != Smi::kZero;
     405             :   }
     406             : 
     407             :   bool IsExceptionBlackboxed(bool uncaught);
     408             : 
     409             :   void OnException(Handle<Object> exception, Handle<Object> promise,
     410             :                    v8::debug::ExceptionType exception_type);
     411             : 
     412             :   void ProcessCompileEvent(bool has_compile_error, Handle<Script> script);
     413             : 
     414             :   // Find the closest source position for a break point for a given position.
     415             :   int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position);
     416             :   // Instrument code to break at break points.
     417             :   void ApplyBreakPoints(Handle<DebugInfo> debug_info);
     418             :   // Clear code from instrumentation.
     419             :   void ClearBreakPoints(Handle<DebugInfo> debug_info);
     420             :   // Clear all code from instrumentation.
     421             :   void ClearAllBreakPoints();
     422             :   // Instrument a function with one-shots.
     423             :   void FloodWithOneShot(Handle<SharedFunctionInfo> function,
     424             :                         bool returns_only = false);
     425             :   // Clear all one-shot instrumentations, but restore break points.
     426             :   void ClearOneShot();
     427             : 
     428             :   bool IsFrameBlackboxed(JavaScriptFrame* frame);
     429             : 
     430             :   void ActivateStepOut(StackFrame* frame);
     431             :   MaybeHandle<FixedArray> CheckBreakPoints(Handle<DebugInfo> debug_info,
     432             :                                            BreakLocation* location,
     433             :                                            bool* has_break_points = nullptr);
     434             :   bool IsMutedAtCurrentLocation(JavaScriptFrame* frame);
     435             :   // Check whether a BreakPoint object is hit. Evaluate condition depending
     436             :   // on whether this is a regular break location or a break at function entry.
     437             :   bool CheckBreakPoint(Handle<BreakPoint> break_point, bool is_break_at_entry);
     438             : 
     439             :   inline void AssertDebugContext() {
     440             :     DCHECK(in_debug_scope());
     441             :   }
     442             : 
     443             :   void ThreadInit();
     444             : 
     445             :   void PrintBreakLocation();
     446             : 
     447             :   void ClearAllDebuggerHints();
     448             : 
     449             :   // Wraps logic for clearing and maybe freeing all debug infos.
     450             :   typedef std::function<void(Handle<DebugInfo>)> DebugInfoClearFunction;
     451             :   void ClearAllDebugInfos(const DebugInfoClearFunction& clear_function);
     452             : 
     453             :   void FindDebugInfo(Handle<DebugInfo> debug_info, DebugInfoListNode** prev,
     454             :                      DebugInfoListNode** curr);
     455             :   void FreeDebugInfoListNode(DebugInfoListNode* prev, DebugInfoListNode* node);
     456             : 
     457             :   debug::DebugDelegate* debug_delegate_ = nullptr;
     458             : 
     459             :   // Debugger is active, i.e. there is a debug event listener attached.
     460             :   bool is_active_;
     461             :   // Debugger needs to be notified on every new function call.
     462             :   // Used for stepping and read-only checks
     463             :   bool hook_on_function_call_;
     464             :   // Suppress debug events.
     465             :   bool is_suppressed_;
     466             :   // Running liveedit.
     467             :   bool running_live_edit_ = false;
     468             :   // Do not trigger debug break events.
     469             :   bool break_disabled_;
     470             :   // Do not break on break points.
     471             :   bool break_points_active_;
     472             :   // Trigger debug break events for all exceptions.
     473             :   bool break_on_exception_;
     474             :   // Trigger debug break events for uncaught exceptions.
     475             :   bool break_on_uncaught_exception_;
     476             :   // Termination exception because side effect check has failed.
     477             :   bool side_effect_check_failed_;
     478             : 
     479             :   // List of active debug info objects.
     480             :   DebugInfoListNode* debug_info_list_;
     481             : 
     482             :   // Used for side effect check to mark temporary objects.
     483             :   class TemporaryObjectsTracker;
     484             :   std::unique_ptr<TemporaryObjectsTracker> temporary_objects_;
     485             : 
     486             :   Handle<RegExpMatchInfo> regexp_match_info_;
     487             : 
     488             :   // Used to collect histogram data on debugger feature usage.
     489             :   DebugFeatureTracker feature_tracker_;
     490             : 
     491             :   // Per-thread data.
     492       61048 :   class ThreadLocal {
     493             :    public:
     494             :     // Top debugger entry.
     495             :     base::AtomicWord current_debug_scope_;
     496             : 
     497             :     // Frame id for the frame of the current break.
     498             :     StackFrame::Id break_frame_id_;
     499             : 
     500             :     // Step action for last step performed.
     501             :     StepAction last_step_action_;
     502             : 
     503             :     // If set, next PrepareStepIn will ignore this function until stepped into
     504             :     // another function, at which point this will be cleared.
     505             :     Object ignore_step_into_function_;
     506             : 
     507             :     // If set then we need to repeat StepOut action at return.
     508             :     bool fast_forward_to_return_;
     509             : 
     510             :     // Source statement position from last step next action.
     511             :     int last_statement_position_;
     512             : 
     513             :     // Frame pointer from last step next or step frame action.
     514             :     int last_frame_count_;
     515             : 
     516             :     // Frame pointer of the target frame we want to arrive at.
     517             :     int target_frame_count_;
     518             : 
     519             :     // Value of the accumulator at the point of entering the debugger.
     520             :     Object return_value_;
     521             : 
     522             :     // The suspended generator object to track when stepping.
     523             :     Object suspended_generator_;
     524             : 
     525             :     // The new frame pointer to drop to when restarting a frame.
     526             :     Address restart_fp_;
     527             : 
     528             :     // Last used inspector breakpoint id.
     529             :     int last_breakpoint_id_;
     530             : 
     531             :     // This flag is true when SetBreakOnNextFunctionCall is called and it forces
     532             :     // debugger to break on next function call.
     533             :     bool break_on_next_function_call_;
     534             :   };
     535             : 
     536             :   // Storage location for registers when handling debug break calls
     537             :   ThreadLocal thread_local_;
     538             : 
     539             :   Isolate* isolate_;
     540             : 
     541             :   friend class Isolate;
     542             :   friend class DebugScope;
     543             :   friend class DisableBreak;
     544             :   friend class LiveEdit;
     545             :   friend class SuppressDebug;
     546             : 
     547             :   friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
     548             :   friend void CheckDebuggerUnloaded();               // In test-debug.cc
     549             : 
     550             :   DISALLOW_COPY_AND_ASSIGN(Debug);
     551             : };
     552             : 
     553             : // This scope is used to load and enter the debug context and create a new
     554             : // break state.  Leaving the scope will restore the previous state.
     555             : class DebugScope {
     556             :  public:
     557             :   explicit DebugScope(Debug* debug);
     558             :   ~DebugScope();
     559             : 
     560             :  private:
     561      251707 :   Isolate* isolate() { return debug_->isolate_; }
     562             : 
     563             :   Debug* debug_;
     564             :   DebugScope* prev_;               // Previous scope if entered recursively.
     565             :   StackFrame::Id break_frame_id_;  // Previous break frame id.
     566             :   PostponeInterruptsScope no_interrupts_;
     567             : };
     568             : 
     569             : // This scope is used to handle return values in nested debug break points.
     570             : // When there are nested debug breaks, we use this to restore the return
     571             : // value to the previous state. This is not merged with DebugScope because
     572             : // return_value_ will not be cleared when we use DebugScope.
     573             : class ReturnValueScope {
     574             :  public:
     575             :   explicit ReturnValueScope(Debug* debug);
     576             :   ~ReturnValueScope();
     577             : 
     578             :  private:
     579             :   Debug* debug_;
     580             :   Handle<Object> return_value_;  // Previous result.
     581             : };
     582             : 
     583             : // Stack allocated class for disabling break.
     584             : class DisableBreak {
     585             :  public:
     586             :   explicit DisableBreak(Debug* debug, bool disable = true)
     587      258085 :       : debug_(debug), previous_break_disabled_(debug->break_disabled_) {
     588      258085 :     debug_->break_disabled_ = disable;
     589             :   }
     590             :   ~DisableBreak() {
     591      258085 :     debug_->break_disabled_ = previous_break_disabled_;
     592             :   }
     593             : 
     594             :  private:
     595             :   Debug* debug_;
     596             :   bool previous_break_disabled_;
     597             :   DISALLOW_COPY_AND_ASSIGN(DisableBreak);
     598             : };
     599             : 
     600             : class SuppressDebug {
     601             :  public:
     602             :   explicit SuppressDebug(Debug* debug)
     603       42732 :       : debug_(debug), old_state_(debug->is_suppressed_) {
     604       42732 :     debug_->is_suppressed_ = true;
     605             :   }
     606       42732 :   ~SuppressDebug() { debug_->is_suppressed_ = old_state_; }
     607             : 
     608             :  private:
     609             :   Debug* debug_;
     610             :   bool old_state_;
     611             :   DISALLOW_COPY_AND_ASSIGN(SuppressDebug);
     612             : };
     613             : 
     614             : // Code generator routines.
     615             : class DebugCodegen : public AllStatic {
     616             :  public:
     617             :   enum DebugBreakCallHelperMode {
     618             :     SAVE_RESULT_REGISTER,
     619             :     IGNORE_RESULT_REGISTER
     620             :   };
     621             : 
     622             :   // Builtin to drop frames to restart function.
     623             :   static void GenerateFrameDropperTrampoline(MacroAssembler* masm);
     624             : 
     625             :   // Builtin to atomically (wrt deopts) handle debugger statement and
     626             :   // drop frames to restart function if necessary.
     627             :   static void GenerateHandleDebuggerStatement(MacroAssembler* masm);
     628             : 
     629             :   // Builtin to trigger a debug break before entering the function.
     630             :   static void GenerateDebugBreakTrampoline(MacroAssembler* masm);
     631             : };
     632             : 
     633             : 
     634             : }  // namespace internal
     635             : }  // namespace v8
     636             : 
     637             : #endif  // V8_DEBUG_DEBUG_H_

Generated by: LCOV version 1.10