summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects/debug-objects.h
blob: 84f244c7580f8d7d57601f8c8caa328bb78ba332 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_DEBUG_OBJECTS_H_
#define V8_OBJECTS_DEBUG_OBJECTS_H_

#include "src/objects.h"
#include "src/objects/fixed-array.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

class BreakPoint;
class BytecodeArray;

// The DebugInfo class holds additional information for a function being
// debugged.
class DebugInfo : public Struct, public NeverReadOnlySpaceObject {
 public:
  enum Flag {
    kNone = 0,
    kHasBreakInfo = 1 << 0,
    kPreparedForDebugExecution = 1 << 1,
    kHasCoverageInfo = 1 << 2,
    kBreakAtEntry = 1 << 3,
    kCanBreakAtEntry = 1 << 4,
    kDebugExecutionMode = 1 << 5
  };

  typedef base::Flags<Flag> Flags;

  // A bitfield that lists uses of the current instance.
  DECL_INT_ACCESSORS(flags)

  // The shared function info for the source being debugged.
  DECL_ACCESSORS(shared, SharedFunctionInfo)

  // Bit field containing various information collected for debugging.
  DECL_INT_ACCESSORS(debugger_hints)

  // Script field from shared function info.
  DECL_ACCESSORS(script, Object)

  // DebugInfo can be detached from the SharedFunctionInfo iff it is empty.
  bool IsEmpty() const;

  // --- Debug execution ---
  // -----------------------

  enum ExecutionMode { kBreakpoints = 0, kSideEffects = kDebugExecutionMode };

  // Returns current debug execution mode. Debug execution mode defines by
  // applied to bytecode patching. False for breakpoints, true for side effect
  // checks.
  ExecutionMode DebugExecutionMode() const;
  void SetDebugExecutionMode(ExecutionMode value);

  // Specifies whether the associated function has an instrumented bytecode
  // array. If so, OriginalBytecodeArray returns the non-instrumented bytecode,
  // and DebugBytecodeArray returns the instrumented bytecode.
  inline bool HasInstrumentedBytecodeArray();

  inline BytecodeArray* OriginalBytecodeArray();
  inline BytecodeArray* DebugBytecodeArray();

  // --- Break points ---
  // --------------------

  bool HasBreakInfo() const;

  // Clears all fields related to break points.
  void ClearBreakInfo(Isolate* isolate);

  // Accessors to flag whether to break before entering the function.
  // This is used to break for functions with no source, e.g. builtins.
  void SetBreakAtEntry();
  void ClearBreakAtEntry();
  bool BreakAtEntry() const;

  // The original uninstrumented bytecode array for functions with break
  // points - the instrumented bytecode is held in the shared function info.
  DECL_ACCESSORS(original_bytecode_array, Object)

  // Fixed array holding status information for each active break point.
  DECL_ACCESSORS(break_points, FixedArray)

  // Check if there is a break point at a source position.
  bool HasBreakPoint(Isolate* isolate, int source_position);
  // Attempt to clear a break point. Return true if successful.
  static bool ClearBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
                              Handle<BreakPoint> break_point);
  // Set a break point.
  static void SetBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
                            int source_position,
                            Handle<BreakPoint> break_point);
  // Get the break point objects for a source position.
  Handle<Object> GetBreakPoints(Isolate* isolate, int source_position);
  // Find the break point info holding this break point object.
  static Handle<Object> FindBreakPointInfo(Isolate* isolate,
                                           Handle<DebugInfo> debug_info,
                                           Handle<BreakPoint> break_point);
  // Get the number of break points for this function.
  int GetBreakPointCount(Isolate* isolate);

  // Returns whether we should be able to break before entering the function.
  // This is true for functions with no source, e.g. builtins.
  bool CanBreakAtEntry() const;

  // --- Debugger hint flags ---
  // ---------------------------

  // Indicates that the function should be skipped during stepping.
  DECL_BOOLEAN_ACCESSORS(debug_is_blackboxed)

  // Indicates that |debug_is_blackboxed| has been computed and set.
  DECL_BOOLEAN_ACCESSORS(computed_debug_is_blackboxed)

  // Indicates the side effect state.
  DECL_INT_ACCESSORS(side_effect_state)

  enum SideEffectState {
    kNotComputed = 0,
    kHasSideEffects = 1,
    kRequiresRuntimeChecks = 2,
    kHasNoSideEffect = 3,
  };

  SideEffectState GetSideEffectState(Isolate* isolate);

  // Id assigned to the function for debugging.
  // This could also be implemented as a weak hash table.
  DECL_INT_ACCESSORS(debugging_id);

// Bit positions in |debugger_hints|.
#define DEBUGGER_HINTS_BIT_FIELDS(V, _)       \
  V(SideEffectStateBits, int, 2, _)           \
  V(DebugIsBlackboxedBit, bool, 1, _)         \
  V(ComputedDebugIsBlackboxedBit, bool, 1, _) \
  V(DebuggingIdBits, int, 20, _)

  DEFINE_BIT_FIELDS(DEBUGGER_HINTS_BIT_FIELDS)
#undef DEBUGGER_HINTS_BIT_FIELDS

  static const int kNoDebuggingId = 0;

  // --- Block Coverage ---
  // ----------------------

  bool HasCoverageInfo() const;

  // Clears all fields related to block coverage.
  void ClearCoverageInfo(Isolate* isolate);
  DECL_ACCESSORS(coverage_info, Object)

  DECL_CAST(DebugInfo)

  // Dispatched behavior.
  DECL_PRINTER(DebugInfo)
  DECL_VERIFIER(DebugInfo)

  static const int kSharedFunctionInfoOffset = Struct::kHeaderSize;
  static const int kDebuggerHintsOffset =
      kSharedFunctionInfoOffset + kPointerSize;
  static const int kScriptOffset = kDebuggerHintsOffset + kPointerSize;
  static const int kOriginalBytecodeArrayOffset = kScriptOffset + kPointerSize;
  static const int kBreakPointsStateOffset =
      kOriginalBytecodeArrayOffset + kPointerSize;
  static const int kFlagsOffset = kBreakPointsStateOffset + kPointerSize;
  static const int kCoverageInfoOffset = kFlagsOffset + kPointerSize;
  static const int kSize = kCoverageInfoOffset + kPointerSize;

  static const int kEstimatedNofBreakPointsInFunction = 4;

 private:
  // Get the break point info object for a source position.
  Object* GetBreakPointInfo(Isolate* isolate, int source_position);

  DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
};

// The BreakPointInfo class holds information for break points set in a
// function. The DebugInfo object holds a BreakPointInfo object for each code
// position with one or more break points.
class BreakPointInfo : public Tuple2 {
 public:
  // The position in the source for the break position.
  DECL_INT_ACCESSORS(source_position)
  // List of related JavaScript break points.
  DECL_ACCESSORS(break_points, Object)

  // Removes a break point.
  static void ClearBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
                              Handle<BreakPoint> break_point);
  // Set a break point.
  static void SetBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
                            Handle<BreakPoint> break_point);
  // Check if break point info has this break point.
  static bool HasBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
                            Handle<BreakPoint> break_point);
  // Get the number of break points for this code offset.
  int GetBreakPointCount(Isolate* isolate);

  int GetStatementPosition(Handle<DebugInfo> debug_info);

  DECL_CAST(BreakPointInfo)

  static const int kSourcePositionOffset = kValue1Offset;
  static const int kBreakPointsOffset = kValue2Offset;

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
};

// Holds information related to block code coverage.
class CoverageInfo : public FixedArray {
 public:
  int SlotCount() const;

  int StartSourcePosition(int slot_index) const;
  int EndSourcePosition(int slot_index) const;
  int BlockCount(int slot_index) const;

  void InitializeSlot(int slot_index, int start_pos, int end_pos);
  void IncrementBlockCount(int slot_index);
  void ResetBlockCount(int slot_index);

  static int FixedArrayLengthForSlotCount(int slot_count) {
    return slot_count * kSlotIndexCount + kFirstSlotIndex;
  }

  DECL_CAST(CoverageInfo)

  // Print debug info.
  void Print(std::unique_ptr<char[]> function_name);

 private:
  static int FirstIndexForSlot(int slot_index) {
    return kFirstSlotIndex + slot_index * kSlotIndexCount;
  }

  static const int kFirstSlotIndex = 0;

  // Each slot is assigned a group of indices starting at kFirstSlotIndex.
  // Within this group, semantics are as follows:
  static const int kSlotStartSourcePositionIndex = 0;
  static const int kSlotEndSourcePositionIndex = 1;
  static const int kSlotBlockCountIndex = 2;
  static const int kSlotIndexCount = 3;

  DISALLOW_IMPLICIT_CONSTRUCTORS(CoverageInfo);
};

// Holds breakpoint related information. This object is used by inspector.
class BreakPoint : public Tuple2 {
 public:
  DECL_INT_ACCESSORS(id)
  DECL_ACCESSORS(condition, String)

  DECL_CAST(BreakPoint)

  static const int kIdOffset = kValue1Offset;
  static const int kConditionOffset = kValue2Offset;

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPoint);
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_DEBUG_OBJECTS_H_