Home | History | Annotate | Download | only in objects
      1 // Copyright 2017 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_OBJECTS_DEBUG_OBJECTS_H_
      6 #define V8_OBJECTS_DEBUG_OBJECTS_H_
      7 
      8 #include "src/objects.h"
      9 #include "src/objects/fixed-array.h"
     10 
     11 // Has to be the last include (doesn't have include guards):
     12 #include "src/objects/object-macros.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 class BreakPoint;
     18 class BytecodeArray;
     19 
     20 // The DebugInfo class holds additional information for a function being
     21 // debugged.
     22 class DebugInfo : public Struct, public NeverReadOnlySpaceObject {
     23  public:
     24   using NeverReadOnlySpaceObject::GetHeap;
     25   using NeverReadOnlySpaceObject::GetIsolate;
     26 
     27   enum Flag {
     28     kNone = 0,
     29     kHasBreakInfo = 1 << 0,
     30     kPreparedForDebugExecution = 1 << 1,
     31     kHasCoverageInfo = 1 << 2,
     32     kBreakAtEntry = 1 << 3,
     33     kCanBreakAtEntry = 1 << 4,
     34     kDebugExecutionMode = 1 << 5
     35   };
     36 
     37   typedef base::Flags<Flag> Flags;
     38 
     39   // A bitfield that lists uses of the current instance.
     40   DECL_INT_ACCESSORS(flags)
     41 
     42   // The shared function info for the source being debugged.
     43   DECL_ACCESSORS(shared, SharedFunctionInfo)
     44 
     45   // Bit field containing various information collected for debugging.
     46   DECL_INT_ACCESSORS(debugger_hints)
     47 
     48   // Script field from shared function info.
     49   DECL_ACCESSORS(script, Object)
     50 
     51   // DebugInfo can be detached from the SharedFunctionInfo iff it is empty.
     52   bool IsEmpty() const;
     53 
     54   // --- Debug execution ---
     55   // -----------------------
     56 
     57   enum ExecutionMode { kBreakpoints = 0, kSideEffects = kDebugExecutionMode };
     58 
     59   // Returns current debug execution mode. Debug execution mode defines by
     60   // applied to bytecode patching. False for breakpoints, true for side effect
     61   // checks.
     62   ExecutionMode DebugExecutionMode() const;
     63   void SetDebugExecutionMode(ExecutionMode value);
     64 
     65   // Specifies whether the associated function has an instrumented bytecode
     66   // array. If so, OriginalBytecodeArray returns the non-instrumented bytecode,
     67   // and DebugBytecodeArray returns the instrumented bytecode.
     68   inline bool HasInstrumentedBytecodeArray();
     69 
     70   inline BytecodeArray* OriginalBytecodeArray();
     71   inline BytecodeArray* DebugBytecodeArray();
     72 
     73   // --- Break points ---
     74   // --------------------
     75 
     76   bool HasBreakInfo() const;
     77 
     78   // Clears all fields related to break points.
     79   void ClearBreakInfo(Isolate* isolate);
     80 
     81   // Accessors to flag whether to break before entering the function.
     82   // This is used to break for functions with no source, e.g. builtins.
     83   void SetBreakAtEntry();
     84   void ClearBreakAtEntry();
     85   bool BreakAtEntry() const;
     86 
     87   // The original uninstrumented bytecode array for functions with break
     88   // points - the instrumented bytecode is held in the shared function info.
     89   DECL_ACCESSORS(original_bytecode_array, Object)
     90 
     91   // Fixed array holding status information for each active break point.
     92   DECL_ACCESSORS(break_points, FixedArray)
     93 
     94   // Check if there is a break point at a source position.
     95   bool HasBreakPoint(Isolate* isolate, int source_position);
     96   // Attempt to clear a break point. Return true if successful.
     97   static bool ClearBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
     98                               Handle<BreakPoint> break_point);
     99   // Set a break point.
    100   static void SetBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
    101                             int source_position,
    102                             Handle<BreakPoint> break_point);
    103   // Get the break point objects for a source position.
    104   Handle<Object> GetBreakPoints(Isolate* isolate, int source_position);
    105   // Find the break point info holding this break point object.
    106   static Handle<Object> FindBreakPointInfo(Isolate* isolate,
    107                                            Handle<DebugInfo> debug_info,
    108                                            Handle<BreakPoint> break_point);
    109   // Get the number of break points for this function.
    110   int GetBreakPointCount(Isolate* isolate);
    111 
    112   // Returns whether we should be able to break before entering the function.
    113   // This is true for functions with no source, e.g. builtins.
    114   bool CanBreakAtEntry() const;
    115 
    116   // --- Debugger hint flags ---
    117   // ---------------------------
    118 
    119   // Indicates that the function should be skipped during stepping.
    120   DECL_BOOLEAN_ACCESSORS(debug_is_blackboxed)
    121 
    122   // Indicates that |debug_is_blackboxed| has been computed and set.
    123   DECL_BOOLEAN_ACCESSORS(computed_debug_is_blackboxed)
    124 
    125   // Indicates the side effect state.
    126   DECL_INT_ACCESSORS(side_effect_state)
    127 
    128   enum SideEffectState {
    129     kNotComputed = 0,
    130     kHasSideEffects = 1,
    131     kRequiresRuntimeChecks = 2,
    132     kHasNoSideEffect = 3,
    133   };
    134 
    135   SideEffectState GetSideEffectState(Isolate* isolate);
    136 
    137   // Id assigned to the function for debugging.
    138   // This could also be implemented as a weak hash table.
    139   DECL_INT_ACCESSORS(debugging_id);
    140 
    141 // Bit positions in |debugger_hints|.
    142 #define DEBUGGER_HINTS_BIT_FIELDS(V, _)       \
    143   V(SideEffectStateBits, int, 2, _)           \
    144   V(DebugIsBlackboxedBit, bool, 1, _)         \
    145   V(ComputedDebugIsBlackboxedBit, bool, 1, _) \
    146   V(DebuggingIdBits, int, 20, _)
    147 
    148   DEFINE_BIT_FIELDS(DEBUGGER_HINTS_BIT_FIELDS)
    149 #undef DEBUGGER_HINTS_BIT_FIELDS
    150 
    151   static const int kNoDebuggingId = 0;
    152 
    153   // --- Block Coverage ---
    154   // ----------------------
    155 
    156   bool HasCoverageInfo() const;
    157 
    158   // Clears all fields related to block coverage.
    159   void ClearCoverageInfo(Isolate* isolate);
    160   DECL_ACCESSORS(coverage_info, Object)
    161 
    162   DECL_CAST(DebugInfo)
    163 
    164   // Dispatched behavior.
    165   DECL_PRINTER(DebugInfo)
    166   DECL_VERIFIER(DebugInfo)
    167 
    168   static const int kSharedFunctionInfoOffset = Struct::kHeaderSize;
    169   static const int kDebuggerHintsOffset =
    170       kSharedFunctionInfoOffset + kPointerSize;
    171   static const int kScriptOffset = kDebuggerHintsOffset + kPointerSize;
    172   static const int kOriginalBytecodeArrayOffset = kScriptOffset + kPointerSize;
    173   static const int kBreakPointsStateOffset =
    174       kOriginalBytecodeArrayOffset + kPointerSize;
    175   static const int kFlagsOffset = kBreakPointsStateOffset + kPointerSize;
    176   static const int kCoverageInfoOffset = kFlagsOffset + kPointerSize;
    177   static const int kSize = kCoverageInfoOffset + kPointerSize;
    178 
    179   static const int kEstimatedNofBreakPointsInFunction = 4;
    180 
    181  private:
    182   // Get the break point info object for a source position.
    183   Object* GetBreakPointInfo(Isolate* isolate, int source_position);
    184 
    185   DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
    186 };
    187 
    188 // The BreakPointInfo class holds information for break points set in a
    189 // function. The DebugInfo object holds a BreakPointInfo object for each code
    190 // position with one or more break points.
    191 class BreakPointInfo : public Tuple2 {
    192  public:
    193   // The position in the source for the break position.
    194   DECL_INT_ACCESSORS(source_position)
    195   // List of related JavaScript break points.
    196   DECL_ACCESSORS(break_points, Object)
    197 
    198   // Removes a break point.
    199   static void ClearBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
    200                               Handle<BreakPoint> break_point);
    201   // Set a break point.
    202   static void SetBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
    203                             Handle<BreakPoint> break_point);
    204   // Check if break point info has this break point.
    205   static bool HasBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
    206                             Handle<BreakPoint> break_point);
    207   // Get the number of break points for this code offset.
    208   int GetBreakPointCount(Isolate* isolate);
    209 
    210   int GetStatementPosition(Handle<DebugInfo> debug_info);
    211 
    212   DECL_CAST(BreakPointInfo)
    213 
    214   static const int kSourcePositionOffset = kValue1Offset;
    215   static const int kBreakPointsOffset = kValue2Offset;
    216 
    217  private:
    218   DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
    219 };
    220 
    221 // Holds information related to block code coverage.
    222 class CoverageInfo : public FixedArray {
    223  public:
    224   int SlotCount() const;
    225 
    226   int StartSourcePosition(int slot_index) const;
    227   int EndSourcePosition(int slot_index) const;
    228   int BlockCount(int slot_index) const;
    229 
    230   void InitializeSlot(int slot_index, int start_pos, int end_pos);
    231   void IncrementBlockCount(int slot_index);
    232   void ResetBlockCount(int slot_index);
    233 
    234   static int FixedArrayLengthForSlotCount(int slot_count) {
    235     return slot_count * kSlotIndexCount + kFirstSlotIndex;
    236   }
    237 
    238   DECL_CAST(CoverageInfo)
    239 
    240   // Print debug info.
    241   void Print(std::unique_ptr<char[]> function_name);
    242 
    243  private:
    244   static int FirstIndexForSlot(int slot_index) {
    245     return kFirstSlotIndex + slot_index * kSlotIndexCount;
    246   }
    247 
    248   static const int kFirstSlotIndex = 0;
    249 
    250   // Each slot is assigned a group of indices starting at kFirstSlotIndex.
    251   // Within this group, semantics are as follows:
    252   static const int kSlotStartSourcePositionIndex = 0;
    253   static const int kSlotEndSourcePositionIndex = 1;
    254   static const int kSlotBlockCountIndex = 2;
    255   static const int kSlotIndexCount = 3;
    256 
    257   DISALLOW_IMPLICIT_CONSTRUCTORS(CoverageInfo);
    258 };
    259 
    260 // Holds breakpoint related information. This object is used by inspector.
    261 class BreakPoint : public Tuple2 {
    262  public:
    263   DECL_INT_ACCESSORS(id)
    264   DECL_ACCESSORS(condition, String)
    265 
    266   DECL_CAST(BreakPoint)
    267 
    268   static const int kIdOffset = kValue1Offset;
    269   static const int kConditionOffset = kValue2Offset;
    270 
    271  private:
    272   DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPoint);
    273 };
    274 
    275 }  // namespace internal
    276 }  // namespace v8
    277 
    278 #include "src/objects/object-macros-undef.h"
    279 
    280 #endif  // V8_OBJECTS_DEBUG_OBJECTS_H_
    281