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 FixedArrayLengthForSlotCount(int slot_count)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: FirstIndexForSlot(int slot_index)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