LCOV - code coverage report
Current view: top level - src/debug - debug.h (source / functions) Hit Total Coverage
Test: app.info Lines: 27 27 100.0 %
Date: 2019-04-18 Functions: 0 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      180610 :   inline bool IsReturn() const { return type_ == DEBUG_BREAK_SLOT_AT_RETURN; }
      69             :   inline bool IsReturnOrSuspend() const {
      70        7886 :     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      435693 :         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         480 :         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 V8_EXPORT_PRIVATE BreakIterator {
     125             :  public:
     126             :   explicit BreakIterator(Handle<DebugInfo> debug_info);
     127             : 
     128             :   BreakLocation GetBreakLocation();
     129             :   bool Done() const { return source_position_iterator_.done(); }
     130             :   void Next();
     131             : 
     132             :   void SkipToPosition(int position);
     133             :   void SkipTo(int count) {
     134    12314069 :     while (count-- > 0) Next();
     135             :   }
     136             : 
     137             :   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       30843 :   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       62440 :       : 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 V8_EXPORT_PRIVATE 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             :   MaybeHandle<JSArray> GetPrivateFields(Handle<JSReceiver> receiver);
     266             : 
     267             :   bool IsBlackboxed(Handle<SharedFunctionInfo> shared);
     268             : 
     269             :   bool CanBreakAtEntry(Handle<SharedFunctionInfo> shared);
     270             : 
     271             :   void SetDebugDelegate(debug::DebugDelegate* delegate);
     272             : 
     273             :   // Returns whether the operation succeeded.
     274             :   bool EnsureBreakInfo(Handle<SharedFunctionInfo> shared);
     275             :   void CreateBreakInfo(Handle<SharedFunctionInfo> shared);
     276             :   Handle<DebugInfo> GetOrCreateDebugInfo(Handle<SharedFunctionInfo> shared);
     277             : 
     278             :   void InstallCoverageInfo(Handle<SharedFunctionInfo> shared,
     279             :                            Handle<CoverageInfo> coverage_info);
     280             :   void RemoveAllCoverageInfos();
     281             : 
     282             :   // This function is used in FunctionNameUsing* tests.
     283             :   Handle<Object> FindSharedFunctionInfoInScript(Handle<Script> script,
     284             :                                                 int position);
     285             : 
     286             :   static Handle<Object> GetSourceBreakLocations(
     287             :       Isolate* isolate, Handle<SharedFunctionInfo> shared);
     288             : 
     289             :   // Check whether this frame is just about to return.
     290             :   bool IsBreakAtReturn(JavaScriptFrame* frame);
     291             : 
     292             :   // Support for LiveEdit
     293             :   void ScheduleFrameRestart(StackFrame* frame);
     294             : 
     295             :   bool AllFramesOnStackAreBlackboxed();
     296             : 
     297             :   // Set new script source, throw an exception if error occurred. When preview
     298             :   // is true: try to set source, throw exception if any without actual script
     299             :   // change. stack_changed is true if after editing script on pause stack is
     300             :   // changed and client should request stack trace again.
     301             :   bool SetScriptSource(Handle<Script> script, Handle<String> source,
     302             :                        bool preview, debug::LiveEditResult* result);
     303             : 
     304             :   int GetFunctionDebuggingId(Handle<JSFunction> function);
     305             : 
     306             :   // Threading support.
     307             :   char* ArchiveDebug(char* to);
     308             :   char* RestoreDebug(char* from);
     309             :   static int ArchiveSpacePerThread();
     310             :   void FreeThreadResources() { }
     311             :   void Iterate(RootVisitor* v);
     312       11836 :   void InitThread(const ExecutionAccess& lock) { ThreadInit(); }
     313             : 
     314             :   bool CheckExecutionState() { return is_active(); }
     315             : 
     316             :   void StartSideEffectCheckMode();
     317             :   void StopSideEffectCheckMode();
     318             : 
     319             :   void ApplySideEffectChecks(Handle<DebugInfo> debug_info);
     320             :   void ClearSideEffectChecks(Handle<DebugInfo> debug_info);
     321             : 
     322             :   bool PerformSideEffectCheck(Handle<JSFunction> function,
     323             :                               Handle<Object> receiver);
     324             : 
     325             :   enum AccessorKind { kNotAccessor, kGetter, kSetter };
     326             :   bool PerformSideEffectCheckForCallback(Handle<Object> callback_info,
     327             :                                          Handle<Object> receiver,
     328             :                                          AccessorKind accessor_kind);
     329             :   bool PerformSideEffectCheckAtBytecode(InterpretedFrame* frame);
     330             :   bool PerformSideEffectCheckForObject(Handle<Object> object);
     331             : 
     332             :   // Flags and states.
     333             :   inline bool is_active() const { return is_active_; }
     334             :   inline bool in_debug_scope() const {
     335     1936032 :     return !!base::Relaxed_Load(&thread_local_.current_debug_scope_);
     336             :   }
     337             :   inline bool needs_check_on_function_call() const {
     338             :     return hook_on_function_call_;
     339             :   }
     340             : 
     341        7107 :   void set_break_points_active(bool v) { break_points_active_ = v; }
     342             :   bool break_points_active() const { return break_points_active_; }
     343             : 
     344             :   StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
     345             : 
     346             :   Handle<Object> return_value_handle();
     347             :   Object return_value() { return thread_local_.return_value_; }
     348      133398 :   void set_return_value(Object value) { thread_local_.return_value_ = value; }
     349             : 
     350             :   // Support for embedding into generated code.
     351             :   Address is_active_address() {
     352       62954 :     return reinterpret_cast<Address>(&is_active_);
     353             :   }
     354             : 
     355             :   Address hook_on_function_call_address() {
     356       62834 :     return reinterpret_cast<Address>(&hook_on_function_call_);
     357             :   }
     358             : 
     359             :   Address suspended_generator_address() {
     360       62498 :     return reinterpret_cast<Address>(&thread_local_.suspended_generator_);
     361             :   }
     362             : 
     363             :   Address restart_fp_address() {
     364       63674 :     return reinterpret_cast<Address>(&thread_local_.restart_fp_);
     365             :   }
     366             :   bool will_restart() const {
     367             :     return thread_local_.restart_fp_ != kNullAddress;
     368             :   }
     369             : 
     370             :   StepAction last_step_action() { return thread_local_.last_step_action_; }
     371             :   bool break_on_next_function_call() const {
     372             :     return thread_local_.break_on_next_function_call_;
     373             :   }
     374             : 
     375        1276 :   DebugFeatureTracker* feature_tracker() { return &feature_tracker_; }
     376             : 
     377             :   // For functions in which we cannot set a break point, use a canonical
     378             :   // source position for break points.
     379             :   static const int kBreakAtEntryPosition = 0;
     380             : 
     381             :   void RemoveBreakInfoAndMaybeFree(Handle<DebugInfo> debug_info);
     382             : 
     383             :  private:
     384             :   explicit Debug(Isolate* isolate);
     385             :   ~Debug();
     386             : 
     387             :   void UpdateDebugInfosForExecutionMode();
     388             :   void UpdateState();
     389             :   void UpdateHookOnFunctionCall();
     390             :   void Unload();
     391             : 
     392             :   // Return the number of virtual frames below debugger entry.
     393             :   int CurrentFrameCount();
     394             : 
     395             :   inline bool ignore_events() const {
     396     7006898 :     return is_suppressed_ || !is_active_ ||
     397      677441 :            isolate_->debug_execution_mode() == DebugInfo::kSideEffects;
     398             :   }
     399             :   inline bool break_disabled() const { return break_disabled_; }
     400             : 
     401             :   void clear_suspended_generator() {
     402      135868 :     thread_local_.suspended_generator_ = Smi::kZero;
     403             :   }
     404             : 
     405             :   bool has_suspended_generator() const {
     406             :     return thread_local_.suspended_generator_ != Smi::kZero;
     407             :   }
     408             : 
     409             :   bool IsExceptionBlackboxed(bool uncaught);
     410             : 
     411             :   void OnException(Handle<Object> exception, Handle<Object> promise,
     412             :                    v8::debug::ExceptionType exception_type);
     413             : 
     414             :   void ProcessCompileEvent(bool has_compile_error, Handle<Script> script);
     415             : 
     416             :   // Find the closest source position for a break point for a given position.
     417             :   int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position);
     418             :   // Instrument code to break at break points.
     419             :   void ApplyBreakPoints(Handle<DebugInfo> debug_info);
     420             :   // Clear code from instrumentation.
     421             :   void ClearBreakPoints(Handle<DebugInfo> debug_info);
     422             :   // Clear all code from instrumentation.
     423             :   void ClearAllBreakPoints();
     424             :   // Instrument a function with one-shots.
     425             :   void FloodWithOneShot(Handle<SharedFunctionInfo> function,
     426             :                         bool returns_only = false);
     427             :   // Clear all one-shot instrumentations, but restore break points.
     428             :   void ClearOneShot();
     429             : 
     430             :   bool IsFrameBlackboxed(JavaScriptFrame* frame);
     431             : 
     432             :   void ActivateStepOut(StackFrame* frame);
     433             :   MaybeHandle<FixedArray> CheckBreakPoints(Handle<DebugInfo> debug_info,
     434             :                                            BreakLocation* location,
     435             :                                            bool* has_break_points = nullptr);
     436             :   bool IsMutedAtCurrentLocation(JavaScriptFrame* frame);
     437             :   // Check whether a BreakPoint object is hit. Evaluate condition depending
     438             :   // on whether this is a regular break location or a break at function entry.
     439             :   bool CheckBreakPoint(Handle<BreakPoint> break_point, bool is_break_at_entry);
     440             : 
     441             :   inline void AssertDebugContext() {
     442             :     DCHECK(in_debug_scope());
     443             :   }
     444             : 
     445             :   void ThreadInit();
     446             : 
     447             :   void PrintBreakLocation();
     448             : 
     449             :   void ClearAllDebuggerHints();
     450             : 
     451             :   // Wraps logic for clearing and maybe freeing all debug infos.
     452             :   using DebugInfoClearFunction = std::function<void(Handle<DebugInfo>)>;
     453             :   void ClearAllDebugInfos(const DebugInfoClearFunction& clear_function);
     454             : 
     455             :   void FindDebugInfo(Handle<DebugInfo> debug_info, DebugInfoListNode** prev,
     456             :                      DebugInfoListNode** curr);
     457             :   void FreeDebugInfoListNode(DebugInfoListNode* prev, DebugInfoListNode* node);
     458             : 
     459             :   debug::DebugDelegate* debug_delegate_ = nullptr;
     460             : 
     461             :   // Debugger is active, i.e. there is a debug event listener attached.
     462             :   bool is_active_;
     463             :   // Debugger needs to be notified on every new function call.
     464             :   // Used for stepping and read-only checks
     465             :   bool hook_on_function_call_;
     466             :   // Suppress debug events.
     467             :   bool is_suppressed_;
     468             :   // Running liveedit.
     469             :   bool running_live_edit_ = false;
     470             :   // Do not trigger debug break events.
     471             :   bool break_disabled_;
     472             :   // Do not break on break points.
     473             :   bool break_points_active_;
     474             :   // Trigger debug break events for all exceptions.
     475             :   bool break_on_exception_;
     476             :   // Trigger debug break events for uncaught exceptions.
     477             :   bool break_on_uncaught_exception_;
     478             :   // Termination exception because side effect check has failed.
     479             :   bool side_effect_check_failed_;
     480             : 
     481             :   // List of active debug info objects.
     482             :   DebugInfoListNode* debug_info_list_;
     483             : 
     484             :   // Used for side effect check to mark temporary objects.
     485             :   class TemporaryObjectsTracker;
     486             :   std::unique_ptr<TemporaryObjectsTracker> temporary_objects_;
     487             : 
     488             :   Handle<RegExpMatchInfo> regexp_match_info_;
     489             : 
     490             :   // Used to collect histogram data on debugger feature usage.
     491             :   DebugFeatureTracker feature_tracker_;
     492             : 
     493             :   // Per-thread data.
     494             :   class ThreadLocal {
     495             :    public:
     496             :     // Top debugger entry.
     497             :     base::AtomicWord current_debug_scope_;
     498             : 
     499             :     // Frame id for the frame of the current break.
     500             :     StackFrame::Id break_frame_id_;
     501             : 
     502             :     // Step action for last step performed.
     503             :     StepAction last_step_action_;
     504             : 
     505             :     // If set, next PrepareStepIn will ignore this function until stepped into
     506             :     // another function, at which point this will be cleared.
     507             :     Object ignore_step_into_function_;
     508             : 
     509             :     // If set then we need to repeat StepOut action at return.
     510             :     bool fast_forward_to_return_;
     511             : 
     512             :     // Source statement position from last step next action.
     513             :     int last_statement_position_;
     514             : 
     515             :     // Frame pointer from last step next or step frame action.
     516             :     int last_frame_count_;
     517             : 
     518             :     // Frame pointer of the target frame we want to arrive at.
     519             :     int target_frame_count_;
     520             : 
     521             :     // Value of the accumulator at the point of entering the debugger.
     522             :     Object return_value_;
     523             : 
     524             :     // The suspended generator object to track when stepping.
     525             :     Object suspended_generator_;
     526             : 
     527             :     // The new frame pointer to drop to when restarting a frame.
     528             :     Address restart_fp_;
     529             : 
     530             :     // Last used inspector breakpoint id.
     531             :     int last_breakpoint_id_;
     532             : 
     533             :     // This flag is true when SetBreakOnNextFunctionCall is called and it forces
     534             :     // debugger to break on next function call.
     535             :     bool break_on_next_function_call_;
     536             :   };
     537             : 
     538             :   // Storage location for registers when handling debug break calls
     539             :   ThreadLocal thread_local_;
     540             : 
     541             :   Isolate* isolate_;
     542             : 
     543             :   friend class Isolate;
     544             :   friend class DebugScope;
     545             :   friend class DisableBreak;
     546             :   friend class LiveEdit;
     547             :   friend class SuppressDebug;
     548             : 
     549             :   friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
     550             :   friend void CheckDebuggerUnloaded();               // In test-debug.cc
     551             : 
     552             :   DISALLOW_COPY_AND_ASSIGN(Debug);
     553             : };
     554             : 
     555             : // This scope is used to load and enter the debug context and create a new
     556             : // break state.  Leaving the scope will restore the previous state.
     557             : class DebugScope {
     558             :  public:
     559             :   explicit DebugScope(Debug* debug);
     560             :   ~DebugScope();
     561             : 
     562             :  private:
     563      256297 :   Isolate* isolate() { return debug_->isolate_; }
     564             : 
     565             :   Debug* debug_;
     566             :   DebugScope* prev_;               // Previous scope if entered recursively.
     567             :   StackFrame::Id break_frame_id_;  // Previous break frame id.
     568             :   PostponeInterruptsScope no_interrupts_;
     569             : };
     570             : 
     571             : // This scope is used to handle return values in nested debug break points.
     572             : // When there are nested debug breaks, we use this to restore the return
     573             : // value to the previous state. This is not merged with DebugScope because
     574             : // return_value_ will not be cleared when we use DebugScope.
     575             : class ReturnValueScope {
     576             :  public:
     577             :   explicit ReturnValueScope(Debug* debug);
     578             :   ~ReturnValueScope();
     579             : 
     580             :  private:
     581             :   Debug* debug_;
     582             :   Handle<Object> return_value_;  // Previous result.
     583             : };
     584             : 
     585             : // Stack allocated class for disabling break.
     586             : class DisableBreak {
     587             :  public:
     588             :   explicit DisableBreak(Debug* debug, bool disable = true)
     589      254302 :       : debug_(debug), previous_break_disabled_(debug->break_disabled_) {
     590      254302 :     debug_->break_disabled_ = disable;
     591             :   }
     592             :   ~DisableBreak() {
     593      254302 :     debug_->break_disabled_ = previous_break_disabled_;
     594             :   }
     595             : 
     596             :  private:
     597             :   Debug* debug_;
     598             :   bool previous_break_disabled_;
     599             :   DISALLOW_COPY_AND_ASSIGN(DisableBreak);
     600             : };
     601             : 
     602             : class SuppressDebug {
     603             :  public:
     604             :   explicit SuppressDebug(Debug* debug)
     605       38197 :       : debug_(debug), old_state_(debug->is_suppressed_) {
     606       38197 :     debug_->is_suppressed_ = true;
     607             :   }
     608       38197 :   ~SuppressDebug() { debug_->is_suppressed_ = old_state_; }
     609             : 
     610             :  private:
     611             :   Debug* debug_;
     612             :   bool old_state_;
     613             :   DISALLOW_COPY_AND_ASSIGN(SuppressDebug);
     614             : };
     615             : 
     616             : // Code generator routines.
     617             : class DebugCodegen : public AllStatic {
     618             :  public:
     619             :   enum DebugBreakCallHelperMode {
     620             :     SAVE_RESULT_REGISTER,
     621             :     IGNORE_RESULT_REGISTER
     622             :   };
     623             : 
     624             :   // Builtin to drop frames to restart function.
     625             :   static void GenerateFrameDropperTrampoline(MacroAssembler* masm);
     626             : 
     627             :   // Builtin to atomically (wrt deopts) handle debugger statement and
     628             :   // drop frames to restart function if necessary.
     629             :   static void GenerateHandleDebuggerStatement(MacroAssembler* masm);
     630             : 
     631             :   // Builtin to trigger a debug break before entering the function.
     632             :   static void GenerateDebugBreakTrampoline(MacroAssembler* masm);
     633             : };
     634             : 
     635             : 
     636             : }  // namespace internal
     637             : }  // namespace v8
     638             : 
     639             : #endif  // V8_DEBUG_DEBUG_H_

Generated by: LCOV version 1.10