• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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