// 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 #include "src/base/bit-field.h" #include "src/objects/fixed-array.h" #include "src/objects/objects.h" #include "src/objects/struct.h" #include "torque-generated/bit-fields.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; class StructBodyDescriptor; #include "torque-generated/src/objects/debug-objects-tq.inc" // The DebugInfo class holds additional information for a function being // debugged. class DebugInfo : public TorqueGeneratedDebugInfo { public: NEVER_READ_ONLY_SPACE DEFINE_TORQUE_GENERATED_DEBUG_INFO_FLAGS() // DebugInfo can be detached from the SharedFunctionInfo iff it is empty. bool IsEmpty() const; // --- Debug execution --- // ----------------------- enum ExecutionMode : uint8_t { 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. V8_EXPORT_PRIVATE 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; // 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 debug_info, Handle break_point); // Set a break point. static void SetBreakPoint(Isolate* isolate, Handle debug_info, int source_position, Handle break_point); // Get the break point objects for a source position. Handle GetBreakPoints(Isolate* isolate, int source_position); // Find the break point info holding this break point object. static Handle FindBreakPointInfo(Isolate* isolate, Handle debug_info, Handle 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_TORQUE_GENERATED_DEBUGGER_HINTS() static const int kNoDebuggingId = 0; // --- Block Coverage --- // ---------------------- bool HasCoverageInfo() const; // Clears all fields related to block coverage. void ClearCoverageInfo(Isolate* isolate); static const int kEstimatedNofBreakPointsInFunction = 4; using BodyDescriptor = StructBodyDescriptor; private: // Get the break point info object for a source position. Object GetBreakPointInfo(Isolate* isolate, int source_position); TQ_OBJECT_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 TorqueGeneratedBreakPointInfo { public: // Removes a break point. static void ClearBreakPoint(Isolate* isolate, Handle info, Handle break_point); // Set a break point. static void SetBreakPoint(Isolate* isolate, Handle info, Handle break_point); // Check if break point info has this break point. static bool HasBreakPoint(Isolate* isolate, Handle info, Handle break_point); // Check if break point info has break point with this id. static MaybeHandle GetBreakPointById(Isolate* isolate, Handle info, int breakpoint_id); // Get the number of break points for this code offset. int GetBreakPointCount(Isolate* isolate); int GetStatementPosition(Handle debug_info); using BodyDescriptor = StructBodyDescriptor; TQ_OBJECT_CONSTRUCTORS(BreakPointInfo) }; // Holds information related to block code coverage. class CoverageInfo : public TorqueGeneratedCoverageInfo { public: void InitializeSlot(int slot_index, int start_pos, int end_pos); void ResetBlockCount(int slot_index); // Computes the size for a CoverageInfo instance of a given length. static int SizeFor(int slot_count) { return OBJECT_POINTER_ALIGN(kHeaderSize + slot_count * Slot::kSize); } // Print debug info. void CoverageInfoPrint(std::ostream& os, std::unique_ptr function_name = nullptr); class BodyDescriptor; // GC visitor. // Description of layout within each slot. using Slot = TorqueGeneratedCoverageInfoSlotOffsets; TQ_OBJECT_CONSTRUCTORS(CoverageInfo) }; // Holds breakpoint related information. This object is used by inspector. class BreakPoint : public TorqueGeneratedBreakPoint { public: using BodyDescriptor = StructBodyDescriptor; TQ_OBJECT_CONSTRUCTORS(BreakPoint) }; class StackFrameInfo : public TorqueGeneratedStackFrameInfo { public: NEVER_READ_ONLY_SPACE static int GetSourcePosition(Handle info); // The script for the stack frame. inline Script script() const; // The bytecode offset or source position for the stack frame. DECL_INT_ACCESSORS(bytecode_offset_or_source_position) // Indicates that the frame corresponds to a 'new' invocation. DECL_BOOLEAN_ACCESSORS(is_constructor) // Dispatched behavior. DECL_VERIFIER(StackFrameInfo) // Bit positions in |flags|. DEFINE_TORQUE_GENERATED_STACK_FRAME_INFO_FLAGS() using BodyDescriptor = StructBodyDescriptor; private: TQ_OBJECT_CONSTRUCTORS(StackFrameInfo) }; class ErrorStackData : public TorqueGeneratedErrorStackData { public: NEVER_READ_ONLY_SPACE inline bool HasFormattedStack() const; DECL_ACCESSORS(formatted_stack, Object) inline bool HasCallSiteInfos() const; DECL_ACCESSORS(call_site_infos, FixedArray) static void EnsureStackFrameInfos(Isolate* isolate, Handle error_stack); DECL_VERIFIER(ErrorStackData) using BodyDescriptor = StructBodyDescriptor; TQ_OBJECT_CONSTRUCTORS(ErrorStackData) }; class PromiseOnStack : public TorqueGeneratedPromiseOnStack { public: NEVER_READ_ONLY_SPACE static MaybeHandle GetPromise( Handle promise_on_stack); class BodyDescriptor; TQ_OBJECT_CONSTRUCTORS(PromiseOnStack) }; } // namespace internal } // namespace v8 #include "src/objects/object-macros-undef.h" #endif // V8_OBJECTS_DEBUG_OBJECTS_H_