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 {
23  public:
24   enum Flag {
25     kNone = 0,
26     kHasBreakInfo = 1 << 0,
27     kPreparedForDebugExecution = 1 << 1,
28     kHasCoverageInfo = 1 << 2,
29     kBreakAtEntry = 1 << 3,
30     kCanBreakAtEntry = 1 << 4,
31     kDebugExecutionMode = 1 << 5
32   };
33 
34   typedef base::Flags<Flag> Flags;
35 
36   // A bitfield that lists uses of the current instance.
37   DECL_INT_ACCESSORS(flags)
38 
39   // The shared function info for the source being debugged.
40   DECL_ACCESSORS(shared, SharedFunctionInfo)
41 
42   // Bit field containing various information collected for debugging.
43   DECL_INT_ACCESSORS(debugger_hints)
44 
45   // DebugInfo can be detached from the SharedFunctionInfo iff it is empty.
46   bool IsEmpty() const;
47 
48   // --- Debug execution ---
49   // -----------------------
50 
51   enum ExecutionMode { kBreakpoints = 0, kSideEffects = kDebugExecutionMode };
52 
53   // Returns current debug execution mode. Debug execution mode defines by
54   // applied to bytecode patching. False for breakpoints, true for side effect
55   // checks.
56   ExecutionMode DebugExecutionMode() const;
57   void SetDebugExecutionMode(ExecutionMode value);
58 
59   inline bool HasDebugBytecodeArray();
60 
61   inline BytecodeArray* OriginalBytecodeArray();
62   inline BytecodeArray* DebugBytecodeArray();
63 
64   // --- Break points ---
65   // --------------------
66 
67   bool HasBreakInfo() const;
68 
69   // Clears all fields related to break points. Returns true iff the
70   // DebugInfo is now empty.
71   bool ClearBreakInfo();
72 
73   // Accessors to flag whether to break before entering the function.
74   // This is used to break for functions with no source, e.g. builtins.
75   void SetBreakAtEntry();
76   void ClearBreakAtEntry();
77   bool BreakAtEntry() const;
78 
79   // The instrumented bytecode array for functions with break points.
80   DECL_ACCESSORS(debug_bytecode_array, Object)
81 
82   // Fixed array holding status information for each active break point.
83   DECL_ACCESSORS(break_points, FixedArray)
84 
85   // Check if there is a break point at a source position.
86   bool HasBreakPoint(int source_position);
87   // Attempt to clear a break point. Return true if successful.
88   static bool ClearBreakPoint(Handle<DebugInfo> debug_info,
89                               Handle<BreakPoint> break_point);
90   // Set a break point.
91   static void SetBreakPoint(Handle<DebugInfo> debug_info, int source_position,
92                             Handle<BreakPoint> break_point);
93   // Get the break point objects for a source position.
94   Handle<Object> GetBreakPoints(int source_position);
95   // Find the break point info holding this break point object.
96   static Handle<Object> FindBreakPointInfo(Handle<DebugInfo> debug_info,
97                                            Handle<BreakPoint> break_point);
98   // Get the number of break points for this function.
99   int GetBreakPointCount();
100 
101   // Returns whether we should be able to break before entering the function.
102   // This is true for functions with no source, e.g. builtins.
103   bool CanBreakAtEntry() const;
104 
105   // --- Block Coverage ---
106   // ----------------------
107 
108   bool HasCoverageInfo() const;
109 
110   // Clears all fields related to block coverage. Returns true iff the
111   // DebugInfo is now empty.
112   bool ClearCoverageInfo();
113   DECL_ACCESSORS(coverage_info, Object)
114 
115   DECL_CAST(DebugInfo)
116 
117   // Dispatched behavior.
118   DECL_PRINTER(DebugInfo)
119   DECL_VERIFIER(DebugInfo)
120 
121   static const int kSharedFunctionInfoOffset = Struct::kHeaderSize;
122   static const int kDebuggerHintsOffset =
123       kSharedFunctionInfoOffset + kPointerSize;
124   static const int kDebugBytecodeArrayOffset =
125       kDebuggerHintsOffset + kPointerSize;
126   static const int kBreakPointsStateOffset =
127       kDebugBytecodeArrayOffset + kPointerSize;
128   static const int kFlagsOffset = kBreakPointsStateOffset + kPointerSize;
129   static const int kCoverageInfoOffset = kFlagsOffset + kPointerSize;
130   static const int kSize = kCoverageInfoOffset + kPointerSize;
131 
132   static const int kEstimatedNofBreakPointsInFunction = 4;
133 
134  private:
135   // Get the break point info object for a source position.
136   Object* GetBreakPointInfo(int source_position);
137 
138   DISALLOW_IMPLICIT_CONSTRUCTORS(DebugInfo);
139 };
140 
141 // The BreakPointInfo class holds information for break points set in a
142 // function. The DebugInfo object holds a BreakPointInfo object for each code
143 // position with one or more break points.
144 class BreakPointInfo : public Tuple2 {
145  public:
146   // The position in the source for the break position.
147   DECL_INT_ACCESSORS(source_position)
148   // List of related JavaScript break points.
149   DECL_ACCESSORS(break_points, Object)
150 
151   // Removes a break point.
152   static void ClearBreakPoint(Handle<BreakPointInfo> info,
153                               Handle<BreakPoint> break_point);
154   // Set a break point.
155   static void SetBreakPoint(Handle<BreakPointInfo> info,
156                             Handle<BreakPoint> break_point);
157   // Check if break point info has this break point.
158   static bool HasBreakPoint(Handle<BreakPointInfo> info,
159                             Handle<BreakPoint> break_point);
160   // Get the number of break points for this code offset.
161   int GetBreakPointCount();
162 
163   int GetStatementPosition(Handle<DebugInfo> debug_info);
164 
165   DECL_CAST(BreakPointInfo)
166 
167   static const int kSourcePositionOffset = kValue1Offset;
168   static const int kBreakPointsOffset = kValue2Offset;
169 
170  private:
171   DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
172 };
173 
174 // Holds information related to block code coverage.
175 class CoverageInfo : public FixedArray {
176  public:
177   int SlotCount() const;
178 
179   int StartSourcePosition(int slot_index) const;
180   int EndSourcePosition(int slot_index) const;
181   int BlockCount(int slot_index) const;
182 
183   void InitializeSlot(int slot_index, int start_pos, int end_pos);
184   void IncrementBlockCount(int slot_index);
185   void ResetBlockCount(int slot_index);
186 
FixedArrayLengthForSlotCount(int slot_count)187   static int FixedArrayLengthForSlotCount(int slot_count) {
188     return slot_count * kSlotIndexCount + kFirstSlotIndex;
189   }
190 
191   DECL_CAST(CoverageInfo)
192 
193   // Print debug info.
194   void Print(std::unique_ptr<char[]> function_name);
195 
196  private:
FirstIndexForSlot(int slot_index)197   static int FirstIndexForSlot(int slot_index) {
198     return kFirstSlotIndex + slot_index * kSlotIndexCount;
199   }
200 
201   static const int kFirstSlotIndex = 0;
202 
203   // Each slot is assigned a group of indices starting at kFirstSlotIndex.
204   // Within this group, semantics are as follows:
205   static const int kSlotStartSourcePositionIndex = 0;
206   static const int kSlotEndSourcePositionIndex = 1;
207   static const int kSlotBlockCountIndex = 2;
208   static const int kSlotIndexCount = 3;
209 
210   DISALLOW_IMPLICIT_CONSTRUCTORS(CoverageInfo);
211 };
212 
213 // Holds breakpoint related information. This object is used by inspector.
214 class BreakPoint : public Tuple2 {
215  public:
216   DECL_INT_ACCESSORS(id)
217   DECL_ACCESSORS(condition, String)
218 
219   DECL_CAST(BreakPoint)
220 
221   static const int kIdOffset = kValue1Offset;
222   static const int kConditionOffset = kValue2Offset;
223 
224  private:
225   DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPoint);
226 };
227 
228 }  // namespace internal
229 }  // namespace v8
230 
231 #include "src/objects/object-macros-undef.h"
232 
233 #endif  // V8_OBJECTS_DEBUG_OBJECTS_H_
234