blob: 243caaa526845c509fa099fc1d51563ab2fe7b56 [file] [log] [blame]
// 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.
#include "src/objects/fixed-array.h"
#include "src/objects/objects.h"
#include "src/objects/struct.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 {
enum Flag {
kNone = 0,
kHasBreakInfo = 1 << 0,
kPreparedForDebugExecution = 1 << 1,
kHasCoverageInfo = 1 << 2,
kBreakAtEntry = 1 << 3,
kCanBreakAtEntry = 1 << 4,
kDebugExecutionMode = 1 << 5
using Flags = base::Flags<Flag>;
// A bitfield that lists uses of the current instance.
// The shared function info for the source being debugged.
DECL_ACCESSORS(shared, SharedFunctionInfo)
// Bit field containing various information collected for debugging.
// 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)
// The debug instrumented bytecode array for functions with break points
// - also pointed to by the shared function info.
DECL_ACCESSORS(debug_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.
// Indicates that |debug_is_blackboxed| has been computed and set.
// Indicates the 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.
// Bit positions in |debugger_hints|.
V(SideEffectStateBits, int, 2, _) \
V(DebugIsBlackboxedBit, bool, 1, _) \
V(ComputedDebugIsBlackboxedBit, bool, 1, _) \
V(DebuggingIdBits, int, 20, _)
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)
// Dispatched behavior.
// Layout description.
static const int kEstimatedNofBreakPointsInFunction = 4;
// Get the break point info object for a source position.
Object GetBreakPointInfo(Isolate* isolate, int source_position);
// 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 {
// The position in the source for the break 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);
static const int kSourcePositionOffset = kValue1Offset;
static const int kBreakPointsOffset = kValue2Offset;
OBJECT_CONSTRUCTORS(BreakPointInfo, Tuple2);
// Holds information related to block code coverage.
class CoverageInfo : public FixedArray {
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;
// Print debug info.
void Print(std::unique_ptr<char[]> function_name);
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 kSlotPaddingIndex = 3; // Padding to make the index count 4.
static const int kSlotIndexCount = 4;
static const int kSlotIndexCountLog2 = 2;
static const int kSlotIndexCountMask = (kSlotIndexCount - 1);
STATIC_ASSERT(1 << kSlotIndexCountLog2 == kSlotIndexCount);
static int FirstIndexForSlot(int slot_index) {
return kFirstSlotIndex + slot_index * kSlotIndexCount;
OBJECT_CONSTRUCTORS(CoverageInfo, FixedArray);
// Holds breakpoint related information. This object is used by inspector.
class BreakPoint : public Tuple2 {
DECL_ACCESSORS(condition, String)
static const int kIdOffset = kValue1Offset;
static const int kConditionOffset = kValue2Offset;
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"