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 <memory>
9
10#include "src/base/bit-field.h"
11#include "src/objects/fixed-array.h"
12#include "src/objects/objects.h"
13#include "src/objects/struct.h"
14#include "torque-generated/bit-fields.h"
15
16// Has to be the last include (doesn't have include guards):
17#include "src/objects/object-macros.h"
18
19namespace v8 {
20namespace internal {
21
22class BreakPoint;
23class BytecodeArray;
24class StructBodyDescriptor;
25
26#include "torque-generated/src/objects/debug-objects-tq.inc"
27
28// The DebugInfo class holds additional information for a function being
29// debugged.
30class DebugInfo : public TorqueGeneratedDebugInfo<DebugInfo, Struct> {
31 public:
32  NEVER_READ_ONLY_SPACE
33  DEFINE_TORQUE_GENERATED_DEBUG_INFO_FLAGS()
34
35  // DebugInfo can be detached from the SharedFunctionInfo iff it is empty.
36  bool IsEmpty() const;
37
38  // --- Debug execution ---
39  // -----------------------
40
41  enum ExecutionMode : uint8_t {
42    kBreakpoints = 0,
43    kSideEffects = kDebugExecutionMode
44  };
45
46  // Returns current debug execution mode. Debug execution mode defines by
47  // applied to bytecode patching. False for breakpoints, true for side effect
48  // checks.
49  ExecutionMode DebugExecutionMode() const;
50  void SetDebugExecutionMode(ExecutionMode value);
51
52  // Specifies whether the associated function has an instrumented bytecode
53  // array. If so, OriginalBytecodeArray returns the non-instrumented bytecode,
54  // and DebugBytecodeArray returns the instrumented bytecode.
55  inline bool HasInstrumentedBytecodeArray();
56
57  inline BytecodeArray OriginalBytecodeArray();
58  inline BytecodeArray DebugBytecodeArray();
59
60  // --- Break points ---
61  // --------------------
62
63  bool HasBreakInfo() const;
64
65  // Clears all fields related to break points.
66  V8_EXPORT_PRIVATE void ClearBreakInfo(Isolate* isolate);
67
68  // Accessors to flag whether to break before entering the function.
69  // This is used to break for functions with no source, e.g. builtins.
70  void SetBreakAtEntry();
71  void ClearBreakAtEntry();
72  bool BreakAtEntry() const;
73
74  // Check if there is a break point at a source position.
75  bool HasBreakPoint(Isolate* isolate, int source_position);
76  // Attempt to clear a break point. Return true if successful.
77  static bool ClearBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
78                              Handle<BreakPoint> break_point);
79  // Set a break point.
80  static void SetBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
81                            int source_position,
82                            Handle<BreakPoint> break_point);
83  // Get the break point objects for a source position.
84  Handle<Object> GetBreakPoints(Isolate* isolate, int source_position);
85  // Find the break point info holding this break point object.
86  static Handle<Object> FindBreakPointInfo(Isolate* isolate,
87                                           Handle<DebugInfo> debug_info,
88                                           Handle<BreakPoint> break_point);
89  // Get the number of break points for this function.
90  int GetBreakPointCount(Isolate* isolate);
91
92  // Returns whether we should be able to break before entering the function.
93  // This is true for functions with no source, e.g. builtins.
94  bool CanBreakAtEntry() const;
95
96  // --- Debugger hint flags ---
97  // ---------------------------
98
99  // Indicates that the function should be skipped during stepping.
100  DECL_BOOLEAN_ACCESSORS(debug_is_blackboxed)
101
102  // Indicates that |debug_is_blackboxed| has been computed and set.
103  DECL_BOOLEAN_ACCESSORS(computed_debug_is_blackboxed)
104
105  // Indicates the side effect state.
106  DECL_INT_ACCESSORS(side_effect_state)
107
108  enum SideEffectState {
109    kNotComputed = 0,
110    kHasSideEffects = 1,
111    kRequiresRuntimeChecks = 2,
112    kHasNoSideEffect = 3,
113  };
114
115  SideEffectState GetSideEffectState(Isolate* isolate);
116
117  // Id assigned to the function for debugging.
118  // This could also be implemented as a weak hash table.
119  DECL_INT_ACCESSORS(debugging_id)
120
121  // Bit positions in |debugger_hints|.
122  DEFINE_TORQUE_GENERATED_DEBUGGER_HINTS()
123
124  static const int kNoDebuggingId = 0;
125
126  // --- Block Coverage ---
127  // ----------------------
128
129  bool HasCoverageInfo() const;
130
131  // Clears all fields related to block coverage.
132  void ClearCoverageInfo(Isolate* isolate);
133
134  static const int kEstimatedNofBreakPointsInFunction = 4;
135
136  using BodyDescriptor = StructBodyDescriptor;
137
138 private:
139  // Get the break point info object for a source position.
140  Object GetBreakPointInfo(Isolate* isolate, int source_position);
141
142  TQ_OBJECT_CONSTRUCTORS(DebugInfo)
143};
144
145// The BreakPointInfo class holds information for break points set in a
146// function. The DebugInfo object holds a BreakPointInfo object for each code
147// position with one or more break points.
148class BreakPointInfo
149    : public TorqueGeneratedBreakPointInfo<BreakPointInfo, Struct> {
150 public:
151  // Removes a break point.
152  static void ClearBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
153                              Handle<BreakPoint> break_point);
154  // Set a break point.
155  static void SetBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
156                            Handle<BreakPoint> break_point);
157  // Check if break point info has this break point.
158  static bool HasBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
159                            Handle<BreakPoint> break_point);
160  // Check if break point info has break point with this id.
161  static MaybeHandle<BreakPoint> GetBreakPointById(Isolate* isolate,
162                                                   Handle<BreakPointInfo> info,
163                                                   int breakpoint_id);
164  // Get the number of break points for this code offset.
165  int GetBreakPointCount(Isolate* isolate);
166
167  int GetStatementPosition(Handle<DebugInfo> debug_info);
168
169  using BodyDescriptor = StructBodyDescriptor;
170
171  TQ_OBJECT_CONSTRUCTORS(BreakPointInfo)
172};
173
174// Holds information related to block code coverage.
175class CoverageInfo
176    : public TorqueGeneratedCoverageInfo<CoverageInfo, HeapObject> {
177 public:
178  void InitializeSlot(int slot_index, int start_pos, int end_pos);
179  void ResetBlockCount(int slot_index);
180
181  // Computes the size for a CoverageInfo instance of a given length.
182  static int SizeFor(int slot_count) {
183    return OBJECT_POINTER_ALIGN(kHeaderSize + slot_count * Slot::kSize);
184  }
185
186  // Print debug info.
187  void CoverageInfoPrint(std::ostream& os,
188                         std::unique_ptr<char[]> function_name = nullptr);
189
190  class BodyDescriptor;  // GC visitor.
191
192  // Description of layout within each slot.
193  using Slot = TorqueGeneratedCoverageInfoSlotOffsets;
194
195  TQ_OBJECT_CONSTRUCTORS(CoverageInfo)
196};
197
198// Holds breakpoint related information. This object is used by inspector.
199class BreakPoint : public TorqueGeneratedBreakPoint<BreakPoint, Struct> {
200 public:
201  using BodyDescriptor = StructBodyDescriptor;
202
203  TQ_OBJECT_CONSTRUCTORS(BreakPoint)
204};
205
206class StackFrameInfo
207    : public TorqueGeneratedStackFrameInfo<StackFrameInfo, Struct> {
208 public:
209  NEVER_READ_ONLY_SPACE
210
211  static int GetSourcePosition(Handle<StackFrameInfo> info);
212
213  // The script for the stack frame.
214  inline Script script() const;
215
216  // The bytecode offset or source position for the stack frame.
217  DECL_INT_ACCESSORS(bytecode_offset_or_source_position)
218
219  // Indicates that the frame corresponds to a 'new' invocation.
220  DECL_BOOLEAN_ACCESSORS(is_constructor)
221
222  // Dispatched behavior.
223  DECL_VERIFIER(StackFrameInfo)
224
225  // Bit positions in |flags|.
226  DEFINE_TORQUE_GENERATED_STACK_FRAME_INFO_FLAGS()
227
228  using BodyDescriptor = StructBodyDescriptor;
229
230 private:
231  TQ_OBJECT_CONSTRUCTORS(StackFrameInfo)
232};
233
234class ErrorStackData
235    : public TorqueGeneratedErrorStackData<ErrorStackData, Struct> {
236 public:
237  NEVER_READ_ONLY_SPACE
238
239  inline bool HasFormattedStack() const;
240  DECL_ACCESSORS(formatted_stack, Object)
241  inline bool HasCallSiteInfos() const;
242  DECL_ACCESSORS(call_site_infos, FixedArray)
243
244  static void EnsureStackFrameInfos(Isolate* isolate,
245                                    Handle<ErrorStackData> error_stack);
246
247  DECL_VERIFIER(ErrorStackData)
248
249  using BodyDescriptor = StructBodyDescriptor;
250
251  TQ_OBJECT_CONSTRUCTORS(ErrorStackData)
252};
253
254class PromiseOnStack
255    : public TorqueGeneratedPromiseOnStack<PromiseOnStack, Struct> {
256 public:
257  NEVER_READ_ONLY_SPACE
258
259  static MaybeHandle<JSObject> GetPromise(
260      Handle<PromiseOnStack> promise_on_stack);
261
262  class BodyDescriptor;
263
264  TQ_OBJECT_CONSTRUCTORS(PromiseOnStack)
265};
266
267}  // namespace internal
268}  // namespace v8
269
270#include "src/objects/object-macros-undef.h"
271
272#endif  // V8_OBJECTS_DEBUG_OBJECTS_H_
273