GHC.ByteCode.Breakpoints

ghc-lib-parser-9.14.1.20251220: The GHC API, decoupled from GHC versions

Safe Haskell | Ignore
Language | GHC2021

GHC.ByteCode.Breakpoints

Contents

- Internal Mod Breaks
  - Internal breakpoint identifier
- Operations
  - Internal-level operations
  - Source-level information operations
- Utils

Description

Breakpoint information constructed during ByteCode generation.

Specifically, code-generation breakpoints are referred to as "internal breakpoints", the internal breakpoint data for a module is stored in `InternalModBreaks`, and is uniquely identified at runtime by an `InternalBreakpointId`.

See Note [ModBreaks vs InternalModBreaks] and Note [Breakpoint identifiers]

Synopsis

- data InternalModBreaks = InternalModBreaks {
  - imodBreaks_breakInfo :: !(IntMap CgBreakInfo)
  - imodBreaks_modBreaks :: !ModBreaks
  }
- data CgBreakInfo = CgBreakInfo {
  - cgb_tyvars :: ![IfaceTvBndr]
  - cgb_vars :: ![Maybe (IfaceIdBndr, Word)]
  - cgb_resty :: !IfaceType
  - cgb_tick_id :: !(Either InternalBreakLoc BreakpointId)
  }
- mkInternalModBreaks :: Module -> IntMap CgBreakInfo -> ModBreaks -> InternalModBreaks
- imodBreaks_module :: InternalModBreaks -> Module
- data InternalBreakpointId = InternalBreakpointId {
  - ibi_info_mod :: !Module
  - ibi_info_index :: !BreakInfoIndex
  }
- type BreakInfoIndex = Int
- newtype InternalBreakLoc = InternalBreakLoc {
  - internalBreakLoc :: BreakpointId
  }
- getInternalBreak :: InternalBreakpointId -> InternalModBreaks -> CgBreakInfo
- getBreakLoc :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO SrcSpan
- getBreakVars :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [OccName]
- getBreakDecls :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [String]
- getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO (String, String)
- getBreakSourceId :: InternalBreakpointId -> InternalModBreaks -> BreakpointId
- getBreakSourceMod :: InternalBreakpointId -> InternalModBreaks -> Module
- seqInternalModBreaks :: InternalModBreaks -> ()

# Internal Mod Breaks

data InternalModBreaks #

Internal mod breaks store the runtime-relevant information of breakpoints.

Importantly, it maps `InternalBreakpointId`s to `CgBreakInfo`.

`InternalModBreaks` are constructed during bytecode generation and stored in `CompiledByteCode` afterwards.

Constructors

InternalModBreaks |
Fields imodBreaks_breakInfo :: !(IntMap CgBreakInfo) Access code-gen time information about a breakpoint, indexed by `InternalBreakpointId`. imodBreaks_modBreaks :: !ModBreaks Store the ModBreaks for this module Recall Note [Breakpoint identifiers]: for some module A, an *occurrence* of a breakpoint in A may have been inlined from some breakpoint *defined* in module B. This `ModBreaks` contains information regarding all the breakpoints defined in the module this `InternalModBreaks` corresponds to. It does not necessarily have information regarding all the breakpoint occurrences registered in `imodBreaks_breakInfo`. Some of those occurrences may refer breakpoints inlined from other modules.

data CgBreakInfo #

Information about a breakpoint that we know at code-generation time In order to be used, this needs to be hydrated relative to the current HscEnv by `hydrateCgBreakInfo`. Everything here can be fully forced and that's critical for preventing space leaks (see #22530)

Constructors

CgBreakInfo |
Fields cgb_tyvars :: ![IfaceTvBndr] Type variables in scope at the breakpoint cgb_vars :: ![Maybe (IfaceIdBndr, Word)] cgb_resty :: !IfaceType cgb_tick_id :: !(Either InternalBreakLoc BreakpointId) This field records the original breakpoint tick identifier for this internal breakpoint info. It is used to convert a breakpoint *occurrence* index (`InternalBreakpointId`) into a *definition* index (`BreakpointId`). The modules of breakpoint occurrence and breakpoint definition are not necessarily the same: See Note [Breakpoint identifiers]. If there is no original tick identifier (that is, the breakpoint was created during code generation), we re-use the BreakpointId of something else. It would also be reasonable to have an `Either something BreakpointId` for `cgb_tick_id`, but currently we can always re-use a source-level BreakpointId. In the case of step-out, see Note [Debugger: Stepout internal break locs]

#### Instances

Instances details

Outputable CgBreakInfo # |
Instance details Defined in GHC.ByteCode.Breakpoints Methods ppr :: CgBreakInfo -> SDoc #

mkInternalModBreaks :: Module -> IntMap CgBreakInfo -> ModBreaks -> InternalModBreaks #

Construct an `InternalModBreaks`.

INVARIANT: The given `ModBreaks` correspond to the same module as this `InternalModBreaks` module (the first argument) and its breakpoint infos (the `IntMap CgBreakInfo` argument)

imodBreaks_module :: InternalModBreaks -> Module #

Get the module to which these `InternalModBreaks` correspond

## Internal breakpoint identifier

data InternalBreakpointId #

Internal breakpoint identifier

Indexes into the structures in the ``InternalModBreaks`` produced during ByteCode generation. See Note [Breakpoint identifiers]

Constructors

InternalBreakpointId |
Fields ibi_info_mod :: !Module Breakpoint info module ibi_info_index :: !BreakInfoIndex Breakpoint info index

#### Instances

Instances details

NFData InternalBreakpointId # |
Instance details Defined in GHC.ByteCode.Breakpoints Methods rnf :: InternalBreakpointId -> () #
Outputable InternalBreakpointId # |
Instance details Defined in GHC.ByteCode.Breakpoints Methods ppr :: InternalBreakpointId -> SDoc #
Eq InternalBreakpointId # |
Instance details Defined in GHC.ByteCode.Breakpoints Methods (==) :: InternalBreakpointId -> InternalBreakpointId -> Bool # (/=) :: InternalBreakpointId -> InternalBreakpointId -> Bool #
Ord InternalBreakpointId # |
Instance details Defined in GHC.ByteCode.Breakpoints Methods compare :: InternalBreakpointId -> InternalBreakpointId -> Ordering # (<) :: InternalBreakpointId -> InternalBreakpointId -> Bool # (<=) :: InternalBreakpointId -> InternalBreakpointId -> Bool # (>) :: InternalBreakpointId -> InternalBreakpointId -> Bool # (>=) :: InternalBreakpointId -> InternalBreakpointId -> Bool # max :: InternalBreakpointId -> InternalBreakpointId -> InternalBreakpointId # min :: InternalBreakpointId -> InternalBreakpointId -> InternalBreakpointId #

type BreakInfoIndex = Int #

Internal breakpoint info index

newtype InternalBreakLoc #

Breakpoints created during code generation don't have a source-level tick location. Instead, we re-use an existing one.

Constructors

InternalBreakLoc |
Fields internalBreakLoc :: BreakpointId

#### Instances

Instances details

NFData InternalBreakLoc # |
Instance details Defined in GHC.ByteCode.Breakpoints Methods rnf :: InternalBreakLoc -> () #
Outputable InternalBreakLoc # |
Instance details Defined in GHC.ByteCode.Breakpoints Methods ppr :: InternalBreakLoc -> SDoc #
Eq InternalBreakLoc # |
Instance details Defined in GHC.ByteCode.Breakpoints Methods (==) :: InternalBreakLoc -> InternalBreakLoc -> Bool # (/=) :: InternalBreakLoc -> InternalBreakLoc -> Bool #

# Operations

## Internal-level operations

getInternalBreak :: InternalBreakpointId -> InternalModBreaks -> CgBreakInfo #

Get an internal breakpoint info by `InternalBreakpointId`

## Source-level information operations

getBreakLoc :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO SrcSpan #

Get the source span for this breakpoint

getBreakVars :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [OccName] #

Get the vars for this breakpoint

getBreakDecls :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [String] #

Get the decls for this breakpoint

getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO (String, String) #

Get the decls for this breakpoint

getBreakSourceId :: InternalBreakpointId -> InternalModBreaks -> BreakpointId #

Get the source module and tick index for this breakpoint (as opposed to the module where this breakpoint occurs, which is in `InternalBreakpointId`)

getBreakSourceMod :: InternalBreakpointId -> InternalModBreaks -> Module #

Get the source module for this breakpoint (where the breakpoint is defined)

# Utils

seqInternalModBreaks :: InternalModBreaks -> () #

Fully force an `InternalModBreaks` value