Line data Source code
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 : #include "src/objects/struct.h"
11 :
12 : // Has to be the last include (doesn't have include guards):
13 : #include "src/objects/object-macros.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : class BreakPoint;
19 : class BytecodeArray;
20 :
21 : // The DebugInfo class holds additional information for a function being
22 : // debugged.
23 : class DebugInfo : public Struct {
24 : public:
25 : NEVER_READ_ONLY_SPACE
26 : enum Flag {
27 : kNone = 0,
28 : kHasBreakInfo = 1 << 0,
29 : kPreparedForDebugExecution = 1 << 1,
30 : kHasCoverageInfo = 1 << 2,
31 : kBreakAtEntry = 1 << 3,
32 : kCanBreakAtEntry = 1 << 4,
33 : kDebugExecutionMode = 1 << 5
34 : };
35 :
36 : using Flags = base::Flags<Flag>;
37 :
38 : // A bitfield that lists uses of the current instance.
39 : DECL_INT_ACCESSORS(flags)
40 :
41 : // The shared function info for the source being debugged.
42 : DECL_ACCESSORS(shared, SharedFunctionInfo)
43 :
44 : // Bit field containing various information collected for debugging.
45 : DECL_INT_ACCESSORS(debugger_hints)
46 :
47 : // Script field from shared function info.
48 : DECL_ACCESSORS(script, Object)
49 :
50 : // DebugInfo can be detached from the SharedFunctionInfo iff it is empty.
51 : bool IsEmpty() const;
52 :
53 : // --- Debug execution ---
54 : // -----------------------
55 :
56 : enum ExecutionMode { kBreakpoints = 0, kSideEffects = kDebugExecutionMode };
57 :
58 : // Returns current debug execution mode. Debug execution mode defines by
59 : // applied to bytecode patching. False for breakpoints, true for side effect
60 : // checks.
61 : ExecutionMode DebugExecutionMode() const;
62 : void SetDebugExecutionMode(ExecutionMode value);
63 :
64 : // Specifies whether the associated function has an instrumented bytecode
65 : // array. If so, OriginalBytecodeArray returns the non-instrumented bytecode,
66 : // and DebugBytecodeArray returns the instrumented bytecode.
67 : inline bool HasInstrumentedBytecodeArray();
68 :
69 : inline BytecodeArray OriginalBytecodeArray();
70 : inline BytecodeArray DebugBytecodeArray();
71 :
72 : // --- Break points ---
73 : // --------------------
74 :
75 : bool HasBreakInfo() const;
76 :
77 : // Clears all fields related to break points.
78 : void ClearBreakInfo(Isolate* isolate);
79 :
80 : // Accessors to flag whether to break before entering the function.
81 : // This is used to break for functions with no source, e.g. builtins.
82 : void SetBreakAtEntry();
83 : void ClearBreakAtEntry();
84 : bool BreakAtEntry() const;
85 :
86 : // The original uninstrumented bytecode array for functions with break
87 : // points - the instrumented bytecode is held in the shared function info.
88 : DECL_ACCESSORS(original_bytecode_array, Object)
89 :
90 : // The debug instrumented bytecode array for functions with break points
91 : // - also pointed to by the shared function info.
92 : DECL_ACCESSORS(debug_bytecode_array, Object)
93 :
94 : // Fixed array holding status information for each active break point.
95 : DECL_ACCESSORS(break_points, FixedArray)
96 :
97 : // Check if there is a break point at a source position.
98 : bool HasBreakPoint(Isolate* isolate, int source_position);
99 : // Attempt to clear a break point. Return true if successful.
100 : static bool ClearBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
101 : Handle<BreakPoint> break_point);
102 : // Set a break point.
103 : static void SetBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
104 : int source_position,
105 : Handle<BreakPoint> break_point);
106 : // Get the break point objects for a source position.
107 : Handle<Object> GetBreakPoints(Isolate* isolate, int source_position);
108 : // Find the break point info holding this break point object.
109 : static Handle<Object> FindBreakPointInfo(Isolate* isolate,
110 : Handle<DebugInfo> debug_info,
111 : Handle<BreakPoint> break_point);
112 : // Get the number of break points for this function.
113 : int GetBreakPointCount(Isolate* isolate);
114 :
115 : // Returns whether we should be able to break before entering the function.
116 : // This is true for functions with no source, e.g. builtins.
117 : bool CanBreakAtEntry() const;
118 :
119 : // --- Debugger hint flags ---
120 : // ---------------------------
121 :
122 : // Indicates that the function should be skipped during stepping.
123 : DECL_BOOLEAN_ACCESSORS(debug_is_blackboxed)
124 :
125 : // Indicates that |debug_is_blackboxed| has been computed and set.
126 : DECL_BOOLEAN_ACCESSORS(computed_debug_is_blackboxed)
127 :
128 : // Indicates the side effect state.
129 : DECL_INT_ACCESSORS(side_effect_state)
130 :
131 : enum SideEffectState {
132 : kNotComputed = 0,
133 : kHasSideEffects = 1,
134 : kRequiresRuntimeChecks = 2,
135 : kHasNoSideEffect = 3,
136 : };
137 :
138 : SideEffectState GetSideEffectState(Isolate* isolate);
139 :
140 : // Id assigned to the function for debugging.
141 : // This could also be implemented as a weak hash table.
142 : DECL_INT_ACCESSORS(debugging_id)
143 :
144 : // Bit positions in |debugger_hints|.
145 : #define DEBUGGER_HINTS_BIT_FIELDS(V, _) \
146 : V(SideEffectStateBits, int, 2, _) \
147 : V(DebugIsBlackboxedBit, bool, 1, _) \
148 : V(ComputedDebugIsBlackboxedBit, bool, 1, _) \
149 : V(DebuggingIdBits, int, 20, _)
150 :
151 : DEFINE_BIT_FIELDS(DEBUGGER_HINTS_BIT_FIELDS)
152 : #undef DEBUGGER_HINTS_BIT_FIELDS
153 :
154 : static const int kNoDebuggingId = 0;
155 :
156 : // --- Block Coverage ---
157 : // ----------------------
158 :
159 : bool HasCoverageInfo() const;
160 :
161 : // Clears all fields related to block coverage.
162 : void ClearCoverageInfo(Isolate* isolate);
163 : DECL_ACCESSORS(coverage_info, Object)
164 :
165 : DECL_CAST(DebugInfo)
166 :
167 : // Dispatched behavior.
168 : DECL_PRINTER(DebugInfo)
169 : DECL_VERIFIER(DebugInfo)
170 :
171 : // Layout description.
172 : #define DEBUG_INFO_FIELDS(V) \
173 : V(kSharedFunctionInfoOffset, kTaggedSize) \
174 : V(kDebuggerHintsOffset, kTaggedSize) \
175 : V(kScriptOffset, kTaggedSize) \
176 : V(kOriginalBytecodeArrayOffset, kTaggedSize) \
177 : V(kDebugBytecodeArrayOffset, kTaggedSize) \
178 : V(kBreakPointsStateOffset, kTaggedSize) \
179 : V(kFlagsOffset, kTaggedSize) \
180 : V(kCoverageInfoOffset, kTaggedSize) \
181 : /* Total size. */ \
182 : V(kSize, 0)
183 :
184 : DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize, DEBUG_INFO_FIELDS)
185 : #undef DEBUG_INFO_FIELDS
186 :
187 : static const int kEstimatedNofBreakPointsInFunction = 4;
188 :
189 : private:
190 : // Get the break point info object for a source position.
191 : Object GetBreakPointInfo(Isolate* isolate, int source_position);
192 :
193 : OBJECT_CONSTRUCTORS(DebugInfo, Struct);
194 : };
195 :
196 : // The BreakPointInfo class holds information for break points set in a
197 : // function. The DebugInfo object holds a BreakPointInfo object for each code
198 : // position with one or more break points.
199 : class BreakPointInfo : public Tuple2 {
200 : public:
201 : // The position in the source for the break position.
202 : DECL_INT_ACCESSORS(source_position)
203 : // List of related JavaScript break points.
204 : DECL_ACCESSORS(break_points, Object)
205 :
206 : // Removes a break point.
207 : static void ClearBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
208 : Handle<BreakPoint> break_point);
209 : // Set a break point.
210 : static void SetBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
211 : Handle<BreakPoint> break_point);
212 : // Check if break point info has this break point.
213 : static bool HasBreakPoint(Isolate* isolate, Handle<BreakPointInfo> info,
214 : Handle<BreakPoint> break_point);
215 : // Get the number of break points for this code offset.
216 : int GetBreakPointCount(Isolate* isolate);
217 :
218 : int GetStatementPosition(Handle<DebugInfo> debug_info);
219 :
220 : DECL_CAST(BreakPointInfo)
221 :
222 : static const int kSourcePositionOffset = kValue1Offset;
223 : static const int kBreakPointsOffset = kValue2Offset;
224 :
225 : OBJECT_CONSTRUCTORS(BreakPointInfo, Tuple2);
226 : };
227 :
228 : // Holds information related to block code coverage.
229 : class CoverageInfo : public FixedArray {
230 : public:
231 : int SlotCount() const;
232 :
233 : int StartSourcePosition(int slot_index) const;
234 : int EndSourcePosition(int slot_index) const;
235 : int BlockCount(int slot_index) const;
236 :
237 : void InitializeSlot(int slot_index, int start_pos, int end_pos);
238 : void IncrementBlockCount(int slot_index);
239 : void ResetBlockCount(int slot_index);
240 :
241 : static int FixedArrayLengthForSlotCount(int slot_count) {
242 892 : return slot_count * kSlotIndexCount + kFirstSlotIndex;
243 : }
244 :
245 : DECL_CAST(CoverageInfo)
246 :
247 : // Print debug info.
248 : void Print(std::unique_ptr<char[]> function_name);
249 :
250 : private:
251 : static int FirstIndexForSlot(int slot_index) {
252 366824 : return kFirstSlotIndex + slot_index * kSlotIndexCount;
253 : }
254 :
255 : static const int kFirstSlotIndex = 0;
256 :
257 : // Each slot is assigned a group of indices starting at kFirstSlotIndex.
258 : // Within this group, semantics are as follows:
259 : static const int kSlotStartSourcePositionIndex = 0;
260 : static const int kSlotEndSourcePositionIndex = 1;
261 : static const int kSlotBlockCountIndex = 2;
262 : static const int kSlotIndexCount = 3;
263 :
264 : OBJECT_CONSTRUCTORS(CoverageInfo, FixedArray);
265 : };
266 :
267 : // Holds breakpoint related information. This object is used by inspector.
268 : class BreakPoint : public Tuple2 {
269 : public:
270 : DECL_INT_ACCESSORS(id)
271 : DECL_ACCESSORS(condition, String)
272 :
273 : DECL_CAST(BreakPoint)
274 :
275 : static const int kIdOffset = kValue1Offset;
276 : static const int kConditionOffset = kValue2Offset;
277 :
278 : OBJECT_CONSTRUCTORS(BreakPoint, Tuple2);
279 : };
280 :
281 : } // namespace internal
282 : } // namespace v8
283 :
284 : #include "src/objects/object-macros-undef.h"
285 :
286 : #endif // V8_OBJECTS_DEBUG_OBJECTS_H_
|