Rodrigo Mesquita pushed to branch wip/romes/step-out-11 at Glasgow Haskell Compiler / GHC

Commits:

28 changed files:

Changes:

  • cabal.project-reinstall
    ... ... @@ -59,6 +59,7 @@ constraints: ghc +internal-interpreter +dynamic-system-linke,
    59 59
                  ghc-bin +internal-interpreter +threaded,
    
    60 60
                  ghci +internal-interpreter,
    
    61 61
                  haddock +in-ghc-tree,
    
    62
    +             haddock-api +in-ghc-tree,
    
    62 63
                  any.array installed,
    
    63 64
                  any.base installed,
    
    64 65
                  any.deepseq installed,
    
    ... ... @@ -69,6 +70,9 @@ constraints: ghc +internal-interpreter +dynamic-system-linke,
    69 70
                  any.template-haskell installed
    
    70 71
     
    
    71 72
     
    
    73
    +package *
    
    74
    +    happy-options: --strict
    
    75
    +
    
    72 76
     benchmarks: False
    
    73 77
     tests: False
    
    74 78
     allow-boot-library-installs: True
    

  • compiler/GHC/ByteCode/Asm.hs
    ... ... @@ -841,24 +841,18 @@ assembleI platform i = case i of
    841 841
         W8                   -> emit_ bci_OP_INDEX_ADDR_08 []
    
    842 842
         _                    -> unsupported_width
    
    843 843
     
    
    844
    -  BRK_FUN (InternalBreakpointId tick_mod tickx info_mod infox) -> do
    
    844
    +  BRK_FUN ibi@(InternalBreakpointId info_mod infox) byteOff -> do
    
    845
    +    p1 <- ptr $ BCOPtrBreakArray info_mod
    
    845 846
         let -- cast that checks that round-tripping through Word16 doesn't change the value
    
    846 847
             toW16 x = let r = fromIntegral x :: Word16
    
    847 848
                       in if fromIntegral r == x
    
    848 849
                         then r
    
    849 850
                         else pprPanic "schemeER_wrk: breakpoint tick/info index too large!" (ppr x)
    
    850
    -    p1 <- ptr $ BCOPtrBreakArray tick_mod
    
    851
    -    tick_addr <- lit1 $ BCONPtrFS $ moduleNameFS $ moduleName tick_mod
    
    852
    -    info_addr <- lit1 $ BCONPtrFS $ moduleNameFS $ moduleName info_mod
    
    853
    -    tick_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS $ moduleUnitId $ tick_mod
    
    854
    -    info_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS $ moduleUnitId $ info_mod
    
    855
    -    np <- lit1 $ BCONPtrCostCentre (BreakpointId tick_mod tickx)
    
    856
    -    emit_ bci_BRK_FUN [ Op p1
    
    857
    -                     , Op tick_addr, Op info_addr
    
    858
    -                     , Op tick_unitid_addr, Op info_unitid_addr
    
    859
    -                     , SmallOp (toW16 tickx), SmallOp (toW16 infox)
    
    860
    -                     , Op np
    
    861
    -                     ]
    
    851
    +    info_addr        <- lit1 $ BCONPtrFS $ moduleNameFS $ moduleName info_mod
    
    852
    +    info_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS     $ moduleUnitId info_mod
    
    853
    +    np               <- lit1 $ BCONPtrCostCentre ibi
    
    854
    +    emit_ bci_BRK_FUN [ Op p1, Op info_addr, Op info_unitid_addr
    
    855
    +                      , SmallOp (toW16 infox), SmallOp (toW16 byteOff), Op np ]
    
    862 856
     
    
    863 857
       BRK_ALTS active -> emit_ bci_BRK_ALTS [SmallOp (if active then 1 else 0)]
    
    864 858
     
    

  • compiler/GHC/ByteCode/Breakpoints.hs
    1 1
     {-# LANGUAGE RecordWildCards #-}
    
    2
    +{-# LANGUAGE DerivingStrategies #-}
    
    2 3
     
    
    3 4
     -- | Breakpoint information constructed during ByteCode generation.
    
    4 5
     --
    
    ... ... @@ -7,23 +8,24 @@
    7 8
     -- 'InternalModBreaks', and is uniquely identified at runtime by an
    
    8 9
     -- 'InternalBreakpointId'.
    
    9 10
     --
    
    10
    --- See Note [Breakpoint identifiers]
    
    11
    +-- See Note [ModBreaks vs InternalModBreaks] and Note [Breakpoint identifiers]
    
    11 12
     module GHC.ByteCode.Breakpoints
    
    12 13
       ( -- * Internal Mod Breaks
    
    13 14
         InternalModBreaks(..), CgBreakInfo(..)
    
    14
    -  , mkInternalModBreaks
    
    15
    +  , mkInternalModBreaks, imodBreaks_module
    
    15 16
     
    
    16 17
         -- ** Internal breakpoint identifier
    
    17 18
       , InternalBreakpointId(..), BreakInfoIndex
    
    19
    +  , InternalBreakLoc(..)
    
    18 20
     
    
    19 21
         -- * Operations
    
    20
    -  , toBreakpointId
    
    21 22
     
    
    22 23
         -- ** Internal-level operations
    
    23
    -  , getInternalBreak, addInternalBreak
    
    24
    +  , getInternalBreak
    
    24 25
     
    
    25 26
         -- ** Source-level information operations
    
    26 27
       , getBreakLoc, getBreakVars, getBreakDecls, getBreakCCS
    
    28
    +  , getBreakSourceId, getBreakSourceMod
    
    27 29
     
    
    28 30
         -- * Utils
    
    29 31
       , seqInternalModBreaks
    
    ... ... @@ -47,6 +49,31 @@ import GHC.Utils.Panic
    47 49
     import Data.Array
    
    48 50
     
    
    49 51
     {-
    
    52
    +Note [ModBreaks vs InternalModBreaks]
    
    53
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    54
    +'ModBreaks' and 'BreakpointId's must not to be confused with
    
    55
    +'InternalModBreaks' and 'InternalBreakId's.
    
    56
    +
    
    57
    +'ModBreaks' is constructed once during HsToCore from the information attached
    
    58
    +to source-level breakpoint ticks and is never changed afterwards. A 'ModBreaks'
    
    59
    +can be queried using 'BreakpointId's, which uniquely identifies a breakpoint
    
    60
    +within the list of breakpoint information for a given module's 'ModBreaks'.
    
    61
    +
    
    62
    +'InternalModBreaks' are constructed during bytecode generation and are indexed
    
    63
    +by a 'InternalBreakpointId'. They contain all the information relevant to a
    
    64
    +breakpoint for code generation that can be accessed during runtime execution
    
    65
    +(such as a 'BreakArray' for triggering breakpoints). 'InternalBreakpointId's
    
    66
    +are used at runtime to trigger and inspect breakpoints -- a 'BRK_FUN'
    
    67
    +instruction receives 'InternalBreakpointId' as an argument.
    
    68
    +
    
    69
    +We keep a mapping from 'InternalModBreaks' to a 'BreakpointId', which can then be used
    
    70
    +to get source-level information about a breakpoint via the corresponding 'ModBreaks'.
    
    71
    +
    
    72
    +Notably, 'InternalModBreaks' can contain entries for so-called internal
    
    73
    +breakpoints, which do not necessarily have a source-level location attached to
    
    74
    +it (i.e. do not have a matching entry in 'ModBreaks'). We may leverage this to
    
    75
    +introduce breakpoints during code generation for features such as stepping-out.
    
    76
    +
    
    50 77
     Note [Breakpoint identifiers]
    
    51 78
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    52 79
     Before optimization a breakpoint is identified uniquely with a tick module
    
    ... ... @@ -64,6 +91,10 @@ So every breakpoint occurrence gets assigned a module-unique *info index* and
    64 91
     we store it alongside the occurrence module (*info module*) in the
    
    65 92
     'InternalBreakpointId' datatype. This is the index that we use at runtime to
    
    66 93
     identify a breakpoint.
    
    94
    +
    
    95
    +When the internal breakpoint has a matching tick-level breakpoint we can fetch
    
    96
    +the related tick-level information by first looking up a mapping
    
    97
    +@'InternalBreakpointId' -> 'BreakpointId'@ in @'CgBreakInfo'@.
    
    67 98
     -}
    
    68 99
     
    
    69 100
     --------------------------------------------------------------------------------
    
    ... ... @@ -78,19 +109,11 @@ type BreakInfoIndex = Int
    78 109
     -- Indexes into the structures in the @'InternalModBreaks'@ produced during ByteCode generation.
    
    79 110
     -- See Note [Breakpoint identifiers]
    
    80 111
     data InternalBreakpointId = InternalBreakpointId
    
    81
    -  { ibi_tick_mod   :: !Module         -- ^ Breakpoint tick module
    
    82
    -  , ibi_tick_index :: !Int            -- ^ Breakpoint tick index
    
    83
    -  , ibi_info_mod   :: !Module         -- ^ Breakpoint tick module
    
    112
    +  { ibi_info_mod   :: !Module         -- ^ Breakpoint tick module
    
    84 113
       , ibi_info_index :: !BreakInfoIndex -- ^ Breakpoint tick index
    
    85 114
       }
    
    86 115
       deriving (Eq, Ord)
    
    87 116
     
    
    88
    -toBreakpointId :: InternalBreakpointId -> BreakpointId
    
    89
    -toBreakpointId ibi = BreakpointId
    
    90
    -  { bi_tick_mod   = ibi_tick_mod ibi
    
    91
    -  , bi_tick_index = ibi_tick_index ibi
    
    92
    -  }
    
    93
    -
    
    94 117
     --------------------------------------------------------------------------------
    
    95 118
     -- * Internal Mod Breaks
    
    96 119
     --------------------------------------------------------------------------------
    
    ... ... @@ -107,18 +130,34 @@ data InternalModBreaks = InternalModBreaks
    107 130
             -- 'InternalBreakpointId'.
    
    108 131
     
    
    109 132
           , imodBreaks_modBreaks :: !ModBreaks
    
    110
    -        -- ^ Store the original ModBreaks for this module, unchanged.
    
    111
    -        -- Allows us to query about source-level breakpoint information using
    
    112
    -        -- an internal breakpoint id.
    
    133
    +        -- ^ Store the ModBreaks for this module
    
    134
    +        --
    
    135
    +        -- Recall Note [Breakpoint identifiers]: for some module A, an
    
    136
    +        -- *occurrence* of a breakpoint in A may have been inlined from some
    
    137
    +        -- breakpoint *defined* in module B.
    
    138
    +        --
    
    139
    +        -- This 'ModBreaks' contains information regarding all the breakpoints
    
    140
    +        -- defined in the module this 'InternalModBreaks' corresponds to. It
    
    141
    +        -- /does not/ necessarily have information regarding all the breakpoint
    
    142
    +        -- occurrences registered in 'imodBreaks_breakInfo'. Some of those
    
    143
    +        -- occurrences may refer breakpoints inlined from other modules.
    
    113 144
           }
    
    114 145
     
    
    115
    --- | Construct an 'InternalModBreaks'
    
    146
    +-- | Construct an 'InternalModBreaks'.
    
    147
    +--
    
    148
    +-- INVARIANT: The given 'ModBreaks' correspond to the same module as this
    
    149
    +-- 'InternalModBreaks' module (the first argument) and its breakpoint infos
    
    150
    +-- (the @IntMap CgBreakInfo@ argument)
    
    116 151
     mkInternalModBreaks :: Module -> IntMap CgBreakInfo -> ModBreaks -> InternalModBreaks
    
    117 152
     mkInternalModBreaks mod im mbs =
    
    118 153
       assertPpr (mod == modBreaks_module mbs)
    
    119 154
         (text "Constructing InternalModBreaks with the ModBreaks of a different module!") $
    
    120 155
           InternalModBreaks im mbs
    
    121 156
     
    
    157
    +-- | Get the module to which these 'InternalModBreaks' correspond
    
    158
    +imodBreaks_module :: InternalModBreaks -> Module
    
    159
    +imodBreaks_module = modBreaks_module . imodBreaks_modBreaks
    
    160
    +
    
    122 161
     -- | Information about a breakpoint that we know at code-generation time
    
    123 162
     -- In order to be used, this needs to be hydrated relative to the current HscEnv by
    
    124 163
     -- 'hydrateCgBreakInfo'. Everything here can be fully forced and that's critical for
    
    ... ... @@ -128,20 +167,32 @@ data CgBreakInfo
    128 167
        { cgb_tyvars  :: ![IfaceTvBndr] -- ^ Type variables in scope at the breakpoint
    
    129 168
        , cgb_vars    :: ![Maybe (IfaceIdBndr, Word)]
    
    130 169
        , cgb_resty   :: !IfaceType
    
    170
    +   , cgb_tick_id :: !(Either InternalBreakLoc BreakpointId)
    
    171
    +     -- ^ This field records the original breakpoint tick identifier for this
    
    172
    +     -- internal breakpoint info. It is used to convert a breakpoint
    
    173
    +     -- *occurrence* index ('InternalBreakpointId') into a *definition* index
    
    174
    +     -- ('BreakpointId').
    
    175
    +     --
    
    176
    +     -- The modules of breakpoint occurrence and breakpoint definition are not
    
    177
    +     -- necessarily the same: See Note [Breakpoint identifiers].
    
    178
    +     --
    
    179
    +     -- If there is no original tick identifier (that is, the breakpoint was
    
    180
    +     -- created during code generation), instead refer directly to the SrcSpan
    
    181
    +     -- we want to use for it. See Note [Internal Breakpoint Locations]
    
    131 182
        }
    
    132 183
     -- See Note [Syncing breakpoint info] in GHC.Runtime.Eval
    
    133 184
     
    
    185
    +-- | Breakpoints created during code generation don't have a source-level tick
    
    186
    +-- location. Instead, we come up with one ourselves.
    
    187
    +-- See Note [Internal Breakpoint Locations]
    
    188
    +newtype InternalBreakLoc = InternalBreakLoc SrcSpan
    
    189
    +  deriving newtype (Eq, Show, NFData, Outputable)
    
    190
    +
    
    134 191
     -- | Get an internal breakpoint info by 'InternalBreakpointId'
    
    135 192
     getInternalBreak :: InternalBreakpointId -> InternalModBreaks -> CgBreakInfo
    
    136
    -getInternalBreak (InternalBreakpointId _ _ info_mod info_ix) imbs =
    
    137
    -  assert_modules_match info_mod (modBreaks_module $ imodBreaks_modBreaks imbs) $
    
    138
    -    imodBreaks_breakInfo imbs IM.! info_ix
    
    139
    -
    
    140
    --- | Add a CgBreakInfo to an 'InternalModBreaks' at 'InternalBreakpointId'
    
    141
    -addInternalBreak :: InternalBreakpointId -> CgBreakInfo -> InternalModBreaks -> InternalModBreaks
    
    142
    -addInternalBreak (InternalBreakpointId _ _ info_mod info_ix) info imbs =
    
    143
    -  assert_modules_match info_mod (modBreaks_module $ imodBreaks_modBreaks imbs) $
    
    144
    -    imbs{imodBreaks_breakInfo = IM.insert info_ix info (imodBreaks_breakInfo imbs)}
    
    193
    +getInternalBreak (InternalBreakpointId mod ix) imbs =
    
    194
    +  assert_modules_match mod (imodBreaks_module imbs) $
    
    195
    +    imodBreaks_breakInfo imbs IM.! ix
    
    145 196
     
    
    146 197
     -- | Assert that the module in the 'InternalBreakpointId' and in
    
    147 198
     -- 'InternalModBreaks' match.
    
    ... ... @@ -155,27 +206,70 @@ assert_modules_match ibi_mod imbs_mod =
    155 206
     -- Tick-level Breakpoint information
    
    156 207
     --------------------------------------------------------------------------------
    
    157 208
     
    
    209
    +-- | Get the source module and tick index for this breakpoint
    
    210
    +-- (as opposed to the module where this breakpoint occurs, which is in 'InternalBreakpointId')
    
    211
    +getBreakSourceId :: InternalBreakpointId -> InternalModBreaks -> Either InternalBreakLoc BreakpointId
    
    212
    +getBreakSourceId (InternalBreakpointId ibi_mod ibi_ix) imbs =
    
    213
    +  assert_modules_match ibi_mod (imodBreaks_module imbs) $
    
    214
    +    let cgb = imodBreaks_breakInfo imbs IM.! ibi_ix
    
    215
    +     in cgb_tick_id cgb
    
    216
    +
    
    217
    +-- | Get the source module for this breakpoint (where the breakpoint is defined)
    
    218
    +getBreakSourceMod :: InternalBreakpointId -> InternalModBreaks -> Module
    
    219
    +getBreakSourceMod (InternalBreakpointId ibi_mod ibi_ix) imbs =
    
    220
    +  assert_modules_match ibi_mod (imodBreaks_module imbs) $
    
    221
    +    let cgb = imodBreaks_breakInfo imbs IM.! ibi_ix
    
    222
    +     in case cgb_tick_id cgb of
    
    223
    +      Left InternalBreakLoc{} -> imodBreaks_module imbs
    
    224
    +      Right BreakpointId{bi_tick_mod} -> bi_tick_mod
    
    225
    +
    
    158 226
     -- | Get the source span for this breakpoint
    
    159
    -getBreakLoc  :: InternalBreakpointId -> InternalModBreaks -> SrcSpan
    
    160
    -getBreakLoc = getBreakXXX modBreaks_locs
    
    227
    +getBreakLoc :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO SrcSpan
    
    228
    +getBreakLoc = getBreakXXX modBreaks_locs (\(InternalBreakLoc x) -> x)
    
    161 229
     
    
    162 230
     -- | Get the vars for this breakpoint
    
    163
    -getBreakVars  :: InternalBreakpointId -> InternalModBreaks -> [OccName]
    
    164
    -getBreakVars = getBreakXXX modBreaks_vars
    
    231
    +getBreakVars :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [OccName]
    
    232
    +getBreakVars = getBreakXXX modBreaks_vars (const [])
    
    165 233
     
    
    166 234
     -- | Get the decls for this breakpoint
    
    167
    -getBreakDecls :: InternalBreakpointId -> InternalModBreaks -> [String]
    
    168
    -getBreakDecls = getBreakXXX modBreaks_decls
    
    235
    +getBreakDecls :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [String]
    
    236
    +getBreakDecls = getBreakXXX modBreaks_decls (const [])
    
    169 237
     
    
    170 238
     -- | Get the decls for this breakpoint
    
    171
    -getBreakCCS :: InternalBreakpointId -> InternalModBreaks -> (String, String)
    
    172
    -getBreakCCS = getBreakXXX modBreaks_ccs
    
    239
    +getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO (Maybe (String, String))
    
    240
    +getBreakCCS = getBreakXXX (fmap Just . modBreaks_ccs) (const Nothing)
    
    173 241
     
    
    174 242
     -- | Internal utility to access a ModBreaks field at a particular breakpoint index
    
    175
    -getBreakXXX :: (ModBreaks -> Array BreakTickIndex a) -> InternalBreakpointId -> InternalModBreaks -> a
    
    176
    -getBreakXXX view (InternalBreakpointId tick_mod tick_id _ _) imbs =
    
    177
    -  assert_modules_match tick_mod (modBreaks_module $ imodBreaks_modBreaks imbs) $ do
    
    178
    -    view (imodBreaks_modBreaks imbs) ! tick_id
    
    243
    +--
    
    244
    +-- Recall Note [Breakpoint identifiers]: the internal breakpoint module (the
    
    245
    +-- *occurrence* module) doesn't necessarily match the module where the
    
    246
    +-- tick breakpoint was defined with the relevant 'ModBreaks'.
    
    247
    +--
    
    248
    +-- When the tick module is the same as the internal module, we use the stored
    
    249
    +-- 'ModBreaks'. When the tick module is different, we need to look up the
    
    250
    +-- 'ModBreaks' in the HUG for that other module.
    
    251
    +--
    
    252
    +-- When there is no tick module (the breakpoint was generated at codegen), use
    
    253
    +-- the function on internal mod breaks.
    
    254
    +--
    
    255
    +-- To avoid cyclic dependencies, we instead receive a function that looks up
    
    256
    +-- the 'ModBreaks' given a 'Module'
    
    257
    +getBreakXXX :: (ModBreaks -> Array BreakTickIndex a) -> (InternalBreakLoc -> a) -> (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO a
    
    258
    +getBreakXXX view viewInternal lookupModule (InternalBreakpointId ibi_mod ibi_ix) imbs =
    
    259
    +  assert_modules_match ibi_mod (imodBreaks_module imbs) $ do
    
    260
    +    let cgb = imodBreaks_breakInfo imbs IM.! ibi_ix
    
    261
    +    case cgb_tick_id cgb of
    
    262
    +      Right BreakpointId{bi_tick_mod, bi_tick_index}
    
    263
    +        | bi_tick_mod == ibi_mod
    
    264
    +        -> do
    
    265
    +          let these_mbs = imodBreaks_modBreaks imbs
    
    266
    +          return $ view these_mbs ! bi_tick_index
    
    267
    +        | otherwise
    
    268
    +        -> do
    
    269
    +          other_mbs <- lookupModule bi_tick_mod
    
    270
    +          return $ view other_mbs ! bi_tick_index
    
    271
    +      Left l ->
    
    272
    +          return $ viewInternal l
    
    179 273
     
    
    180 274
     --------------------------------------------------------------------------------
    
    181 275
     -- Instances
    
    ... ... @@ -190,7 +284,8 @@ seqInternalModBreaks InternalModBreaks{..} =
    190 284
         seqCgBreakInfo CgBreakInfo{..} =
    
    191 285
             rnf cgb_tyvars `seq`
    
    192 286
             rnf cgb_vars `seq`
    
    193
    -        rnf cgb_resty
    
    287
    +        rnf cgb_resty `seq`
    
    288
    +        rnf cgb_tick_id
    
    194 289
     
    
    195 290
     instance Outputable InternalBreakpointId where
    
    196 291
       ppr InternalBreakpointId{..} =
    
    ... ... @@ -203,4 +298,5 @@ instance NFData InternalBreakpointId where
    203 298
     instance Outputable CgBreakInfo where
    
    204 299
        ppr info = text "CgBreakInfo" <+>
    
    205 300
                   parens (ppr (cgb_vars info) <+>
    
    206
    -                      ppr (cgb_resty info))
    301
    +                      ppr (cgb_resty info) <+>
    
    302
    +                      ppr (cgb_tick_id info))

  • compiler/GHC/ByteCode/Instr.hs
    ... ... @@ -258,7 +258,7 @@ data BCInstr
    258 258
                        -- Note [unboxed tuple bytecodes and tuple_BCO] in GHC.StgToByteCode
    
    259 259
     
    
    260 260
        -- Breakpoints
    
    261
    -   | BRK_FUN          !InternalBreakpointId
    
    261
    +   | BRK_FUN          !InternalBreakpointId !ByteOff
    
    262 262
     
    
    263 263
        -- An internal breakpoint for triggering a break on any case alternative
    
    264 264
        -- See Note [Debugger: BRK_ALTS]
    
    ... ... @@ -454,10 +454,10 @@ instance Outputable BCInstr where
    454 454
        ppr ENTER                 = text "ENTER"
    
    455 455
        ppr (RETURN pk)           = text "RETURN  " <+> ppr pk
    
    456 456
        ppr (RETURN_TUPLE)        = text "RETURN_TUPLE"
    
    457
    -   ppr (BRK_FUN (InternalBreakpointId tick_mod tickx info_mod infox))
    
    457
    +   ppr (BRK_FUN (InternalBreakpointId info_mod infox) bo)
    
    458 458
                                  = text "BRK_FUN" <+> text "<breakarray>"
    
    459
    -                               <+> ppr tick_mod <+> ppr tickx
    
    460 459
                                    <+> ppr info_mod <+> ppr infox
    
    460
    +                               <+> ppr bo
    
    461 461
                                    <+> text "<cc>"
    
    462 462
        ppr (BRK_ALTS active)     = text "BRK_ALTS" <+> ppr active
    
    463 463
     #if MIN_VERSION_rts(1,0,3)
    

  • compiler/GHC/ByteCode/Linker.hs
    ... ... @@ -98,9 +98,9 @@ lookupLiteral interp pkgs_loaded le lb ptr = case ptr of
    98 98
       BCONPtrFFIInfo (FFIInfo {..}) -> do
    
    99 99
         RemotePtr p <- interpCmd interp $ PrepFFI ffiInfoArgs ffiInfoRet
    
    100 100
         pure $ fromIntegral p
    
    101
    -  BCONPtrCostCentre BreakpointId{..}
    
    101
    +  BCONPtrCostCentre InternalBreakpointId{..}
    
    102 102
         | interpreterProfiled interp -> do
    
    103
    -        case expectJust (lookupModuleEnv (ccs_env lb) bi_tick_mod) ! bi_tick_index of
    
    103
    +        case expectJust (lookupModuleEnv (ccs_env lb) ibi_info_mod) ! ibi_info_index of
    
    104 104
               RemotePtr p -> pure $ fromIntegral p
    
    105 105
         | otherwise ->
    
    106 106
             case toRemotePtr nullPtr of
    

  • compiler/GHC/ByteCode/Types.hs
    ... ... @@ -285,7 +285,7 @@ data BCONPtr
    285 285
       -- | A libffi ffi_cif function prototype.
    
    286 286
       | BCONPtrFFIInfo !FFIInfo
    
    287 287
       -- | A 'CostCentre' remote pointer array's respective 'BreakpointId'
    
    288
    -  | BCONPtrCostCentre !BreakpointId
    
    288
    +  | BCONPtrCostCentre !InternalBreakpointId
    
    289 289
     
    
    290 290
     instance NFData BCONPtr where
    
    291 291
       rnf x = x `seq` ()
    

  • compiler/GHC/CoreToIface.hs
    ... ... @@ -44,16 +44,12 @@ module GHC.CoreToIface
    44 44
           -- * Other stuff
    
    45 45
         , toIfaceLFInfo
    
    46 46
         , toIfaceBooleanFormula
    
    47
    -      -- * CgBreakInfo
    
    48
    -    , dehydrateCgBreakInfo
    
    49 47
         ) where
    
    50 48
     
    
    51 49
     import GHC.Prelude
    
    52 50
     
    
    53 51
     import GHC.StgToCmm.Types
    
    54 52
     
    
    55
    -import GHC.ByteCode.Types
    
    56
    -
    
    57 53
     import GHC.Core
    
    58 54
     import GHC.Core.TyCon hiding ( pprPromotionQuote )
    
    59 55
     import GHC.Core.Coercion.Axiom
    
    ... ... @@ -702,15 +698,6 @@ toIfaceLFInfo nm lfi = case lfi of
    702 698
         LFLetNoEscape ->
    
    703 699
           panic "toIfaceLFInfo: LFLetNoEscape"
    
    704 700
     
    
    705
    --- Dehydrating CgBreakInfo
    
    706
    -
    
    707
    -dehydrateCgBreakInfo :: [TyVar] -> [Maybe (Id, Word)] -> Type -> CgBreakInfo
    
    708
    -dehydrateCgBreakInfo ty_vars idOffSets tick_ty =
    
    709
    -          CgBreakInfo
    
    710
    -            { cgb_tyvars = map toIfaceTvBndr ty_vars
    
    711
    -            , cgb_vars = map (fmap (\(i, offset) -> (toIfaceIdBndr i, offset))) idOffSets
    
    712
    -            , cgb_resty = toIfaceType tick_ty
    
    713
    -            }
    
    714 701
     
    
    715 702
     {- Note [Inlining and hs-boot files]
    
    716 703
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

  • compiler/GHC/HsToCore/Breakpoints.hs
    ... ... @@ -12,7 +12,7 @@
    12 12
     -- 'InternalModBreaks' and 'InternalBreakId's. The latter are constructed
    
    13 13
     -- during bytecode generation and can be found in 'GHC.ByteCode.Breakpoints'.
    
    14 14
     --
    
    15
    --- See Note [Breakpoint identifiers]
    
    15
    +-- See Note [ModBreaks vs InternalModBreaks] and Note [Breakpoint identifiers]
    
    16 16
     module GHC.HsToCore.Breakpoints
    
    17 17
       ( -- * ModBreaks
    
    18 18
         mkModBreaks, ModBreaks(..)
    

  • compiler/GHC/Linker/Loader.hs
    ... ... @@ -58,6 +58,7 @@ import GHCi.RemoteTypes
    58 58
     import GHC.Iface.Load
    
    59 59
     import GHCi.Message (ConInfoTable(..), LoadedDLL)
    
    60 60
     
    
    61
    +import GHC.ByteCode.Breakpoints
    
    61 62
     import GHC.ByteCode.Linker
    
    62 63
     import GHC.ByteCode.Asm
    
    63 64
     import GHC.ByteCode.Types
    
    ... ... @@ -124,7 +125,9 @@ import GHC.Utils.Exception
    124 125
     import GHC.Unit.Home.Graph (lookupHug, unitEnv_foldWithKey)
    
    125 126
     import GHC.Driver.Downsweep
    
    126 127
     import qualified GHC.Runtime.Interpreter as GHCi
    
    127
    -import Data.Array.Base (numElements)
    
    128
    +import qualified Data.IntMap.Strict as IM
    
    129
    +import qualified Data.Map.Strict as M
    
    130
    +import Foreign.Ptr (nullPtr)
    
    128 131
     
    
    129 132
     -- Note [Linkers and loaders]
    
    130 133
     -- ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -1666,10 +1669,10 @@ allocateBreakArrays ::
    1666 1669
       IO (ModuleEnv (ForeignRef BreakArray))
    
    1667 1670
     allocateBreakArrays interp =
    
    1668 1671
       foldlM
    
    1669
    -    ( \be0 InternalModBreaks{imodBreaks_modBreaks=ModBreaks {..}} -> do
    
    1672
    +    ( \be0 InternalModBreaks{imodBreaks_breakInfo, imodBreaks_modBreaks=ModBreaks {..}} -> do
    
    1670 1673
             -- If no BreakArray is assigned to this module yet, create one
    
    1671 1674
             if not $ elemModuleEnv modBreaks_module be0 then do
    
    1672
    -          let count = numElements modBreaks_locs
    
    1675
    +          let count = 1 + (maybe 0 fst $ IM.lookupMax imodBreaks_breakInfo)
    
    1673 1676
               breakArray <- GHCi.newBreakArray interp count
    
    1674 1677
               evaluate $ extendModuleEnv be0 modBreaks_module breakArray
    
    1675 1678
             else
    
    ... ... @@ -1679,29 +1682,53 @@ allocateBreakArrays interp =
    1679 1682
     -- | Given a list of 'InternalModBreaks' collected from a list
    
    1680 1683
     -- of 'CompiledByteCode', allocate the 'CostCentre' arrays when profiling is
    
    1681 1684
     -- enabled.
    
    1685
    +--
    
    1686
    +-- Note that the resulting arrays are indexed by 'BreakInfoIndex' (internal
    
    1687
    +-- breakpoint index), not by tick index
    
    1682 1688
     allocateCCS ::
    
    1683 1689
       Interp ->
    
    1684
    -  ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre)) ->
    
    1690
    +  ModuleEnv (Array BreakInfoIndex (RemotePtr CostCentre)) ->
    
    1685 1691
       [InternalModBreaks] ->
    
    1686
    -  IO (ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre)))
    
    1692
    +  IO (ModuleEnv (Array BreakInfoIndex (RemotePtr CostCentre)))
    
    1687 1693
     allocateCCS interp ce mbss
    
    1688
    -  | interpreterProfiled interp =
    
    1689
    -      foldlM
    
    1690
    -        ( \ce0 InternalModBreaks{imodBreaks_modBreaks=ModBreaks {..}} -> do
    
    1691
    -            ccs <-
    
    1694
    +  | interpreterProfiled interp = do
    
    1695
    +      -- 1. Create a mapping from source BreakpointId to CostCentre ptr
    
    1696
    +      ccss <- M.unions <$> mapM
    
    1697
    +        ( \InternalModBreaks{imodBreaks_modBreaks=ModBreaks{..}} -> do
    
    1698
    +            ccs <- {- one ccs ptr per tick index -}
    
    1692 1699
                   mkCostCentres
    
    1693 1700
                     interp
    
    1694 1701
                     (moduleNameString $ moduleName modBreaks_module)
    
    1695 1702
                     (elems modBreaks_ccs)
    
    1696
    -            if not $ elemModuleEnv modBreaks_module ce0 then do
    
    1697
    -              evaluate $
    
    1698
    -                extendModuleEnv ce0 modBreaks_module $
    
    1699
    -                  listArray
    
    1700
    -                    (0, length ccs - 1)
    
    1701
    -                    ccs
    
    1703
    +            return $ M.fromList $
    
    1704
    +              zipWith (\el ix -> (BreakpointId modBreaks_module ix, el)) ccs [0..]
    
    1705
    +        )
    
    1706
    +        mbss
    
    1707
    +      -- 2. Create an array with one element for every InternalBreakpointId,
    
    1708
    +      --    where every element has the CCS for the corresponding BreakpointId
    
    1709
    +      foldlM
    
    1710
    +        (\ce0 InternalModBreaks{imodBreaks_breakInfo, imodBreaks_modBreaks=ModBreaks{..}} -> do
    
    1711
    +            if not $ elemModuleEnv modBreaks_module ce then do
    
    1712
    +              let count = 1 + (maybe 0 fst $ IM.lookupMax imodBreaks_breakInfo)
    
    1713
    +              let ccs = IM.map
    
    1714
    +                    (\info ->
    
    1715
    +                      case cgb_tick_id info of
    
    1716
    +                        Right bi -> fromMaybe (toRemotePtr nullPtr)
    
    1717
    +                          (M.lookup bi ccss)
    
    1718
    +                        Left InternalBreakLoc{} -> toRemotePtr nullPtr
    
    1719
    +                    )
    
    1720
    +                    imodBreaks_breakInfo
    
    1721
    +              assertPpr (count == length ccs)
    
    1722
    +                (text "expected CgBreakInfo map to have one entry per valid ix") $
    
    1723
    +                evaluate $
    
    1724
    +                  extendModuleEnv ce0 modBreaks_module $
    
    1725
    +                    listArray
    
    1726
    +                      (0, count)
    
    1727
    +                      (IM.elems ccs)
    
    1702 1728
                 else
    
    1703 1729
                   return ce0
    
    1704 1730
             )
    
    1705 1731
             ce
    
    1706 1732
             mbss
    
    1733
    +
    
    1707 1734
       | otherwise = pure ce

  • compiler/GHC/Runtime/Debugger/Breakpoints.hs
    ... ... @@ -31,6 +31,9 @@ import GHC.Unit.Module.ModSummary
    31 31
     import GHC.Utils.Outputable
    
    32 32
     import GHC.Utils.Panic
    
    33 33
     import qualified GHC.Data.Strict as Strict
    
    34
    +import qualified Data.IntMap.Strict as IntMap
    
    35
    +import qualified GHC.Unit.Home.Graph as HUG
    
    36
    +import qualified GHC.Unit.Home.PackageTable as HPT
    
    34 37
     
    
    35 38
     --------------------------------------------------------------------------------
    
    36 39
     -- Finding Module breakpoints
    
    ... ... @@ -213,6 +216,50 @@ getModBreak m = do
    213 216
        mod_info <- fromMaybe (panic "getModBreak") <$> getModuleInfo m
    
    214 217
        pure $ imodBreaks_modBreaks <$> modInfoModBreaks mod_info
    
    215 218
     
    
    219
    +--------------------------------------------------------------------------------
    
    220
    +-- Mapping source-level BreakpointIds to IBI occurrences
    
    221
    +-- (See Note [Breakpoint identifiers])
    
    222
    +--------------------------------------------------------------------------------
    
    223
    +
    
    224
    +-- | A source-level breakpoint may have been inlined into many occurrences, now
    
    225
    +-- referred by 'InternalBreakpointId'. When a breakpoint is set on a certain
    
    226
    +-- source breakpoint, it means all *ocurrences* of that breakpoint across
    
    227
    +-- modules should be stopped at -- hence we keep a trie from BreakpointId to
    
    228
    +-- the list of internal break ids using it.
    
    229
    +-- See also Note [Breakpoint identifiers]
    
    230
    +type BreakpointOccurrences = ModuleEnv (IntMap.IntMap [InternalBreakpointId])
    
    231
    +
    
    232
    +-- | Lookup all InternalBreakpointIds matching the given BreakpointId
    
    233
    +-- Nothing if BreakpointId not in map
    
    234
    +lookupBreakpointOccurrences :: BreakpointOccurrences -> BreakpointId -> Maybe [InternalBreakpointId]
    
    235
    +lookupBreakpointOccurrences bmp (BreakpointId md tick) =
    
    236
    +  lookupModuleEnv bmp md >>= IntMap.lookup tick
    
    237
    +
    
    238
    +-- | Construct a mapping from Source 'BreakpointId's to 'InternalBreakpointId's from the given list of 'ModInfo's
    
    239
    +mkBreakpointOccurrences :: forall m. GhcMonad m => m BreakpointOccurrences
    
    240
    +mkBreakpointOccurrences = do
    
    241
    +  hug <- hsc_HUG <$> getSession
    
    242
    +  liftIO $ foldr go (pure emptyModuleEnv) hug
    
    243
    +  where
    
    244
    +    go :: HUG.HomeUnitEnv -> IO BreakpointOccurrences -> IO BreakpointOccurrences
    
    245
    +    go hue mbmp = do
    
    246
    +      bmp <- mbmp
    
    247
    +      ibrkss <- HPT.concatHpt (\hmi -> maybeToList (getModBreaks hmi))
    
    248
    +                             (HUG.homeUnitEnv_hpt hue)
    
    249
    +      return $ foldr addBreakToMap bmp ibrkss
    
    250
    +
    
    251
    +    addBreakToMap :: InternalModBreaks -> BreakpointOccurrences -> BreakpointOccurrences
    
    252
    +    addBreakToMap ibrks bmp0 = do
    
    253
    +      let imod = modBreaks_module $ imodBreaks_modBreaks ibrks
    
    254
    +      IntMap.foldrWithKey (\info_ix cgi bmp -> do
    
    255
    +          let ibi = InternalBreakpointId imod info_ix
    
    256
    +          case cgb_tick_id cgi of
    
    257
    +            Right (BreakpointId tick_mod tick_ix)
    
    258
    +              -> extendModuleEnvWith (IntMap.unionWith (S.<>)) bmp tick_mod (IntMap.singleton tick_ix [ibi])
    
    259
    +            Left _
    
    260
    +              -> bmp
    
    261
    +        ) bmp0 (imodBreaks_breakInfo ibrks)
    
    262
    +
    
    216 263
     --------------------------------------------------------------------------------
    
    217 264
     -- Getting current breakpoint information
    
    218 265
     --------------------------------------------------------------------------------
    
    ... ... @@ -235,9 +282,15 @@ getCurrentBreakSpan = do
    235 282
     getCurrentBreakModule :: GhcMonad m => m (Maybe Module)
    
    236 283
     getCurrentBreakModule = do
    
    237 284
       resumes <- getResumeContext
    
    238
    -  return $ case resumes of
    
    239
    -    [] -> Nothing
    
    285
    +  hug <- hsc_HUG <$> getSession
    
    286
    +  liftIO $ case resumes of
    
    287
    +    [] -> pure Nothing
    
    240 288
         (r:_) -> case resumeHistoryIx r of
    
    241
    -      0  -> ibi_tick_mod <$> resumeBreakpointId r
    
    242
    -      ix -> Just $ getHistoryModule $ resumeHistory r !! (ix-1)
    
    289
    +      0  -> case resumeBreakpointId r of
    
    290
    +        Nothing -> pure Nothing
    
    291
    +        Just ibi -> do
    
    292
    +          brks <- readIModBreaks hug ibi
    
    293
    +          return $ Just $ getBreakSourceMod ibi brks
    
    294
    +      ix ->
    
    295
    +          Just <$> getHistoryModule hug (resumeHistory r !! (ix-1))
    
    243 296
     

  • compiler/GHC/Runtime/Eval.hs
    ... ... @@ -18,7 +18,7 @@ module GHC.Runtime.Eval (
    18 18
             abandon, abandonAll,
    
    19 19
             getResumeContext,
    
    20 20
             getHistorySpan,
    
    21
    -        getModBreaks, readModBreaks,
    
    21
    +        getModBreaks, readIModBreaks, readIModModBreaks,
    
    22 22
             getHistoryModule,
    
    23 23
             setupBreakpoint,
    
    24 24
             back, forward,
    
    ... ... @@ -147,14 +147,17 @@ getResumeContext = withSession (return . ic_resume . hsc_IC)
    147 147
     mkHistory :: HUG.HomeUnitGraph -> ForeignHValue -> InternalBreakpointId -> IO History
    
    148 148
     mkHistory hug hval ibi = History hval ibi <$> findEnclosingDecls hug ibi
    
    149 149
     
    
    150
    -getHistoryModule :: History -> Module
    
    151
    -getHistoryModule = ibi_tick_mod . historyBreakpointId
    
    150
    +getHistoryModule :: HUG.HomeUnitGraph -> History -> IO Module
    
    151
    +getHistoryModule hug hist = do
    
    152
    +  let ibi = historyBreakpointId hist
    
    153
    +  brks <- readIModBreaks hug ibi
    
    154
    +  return $ getBreakSourceMod ibi brks
    
    152 155
     
    
    153 156
     getHistorySpan :: HUG.HomeUnitGraph -> History -> IO SrcSpan
    
    154 157
     getHistorySpan hug hist = do
    
    155 158
       let ibi = historyBreakpointId hist
    
    156
    -  brks <- readModBreaks hug (ibi_tick_mod ibi)
    
    157
    -  return $ getBreakLoc ibi brks
    
    159
    +  brks <- readIModBreaks hug ibi
    
    160
    +  getBreakLoc (readIModModBreaks hug) ibi brks
    
    158 161
     
    
    159 162
     {- | Finds the enclosing top level function name -}
    
    160 163
     -- ToDo: a better way to do this would be to keep hold of the decl_path computed
    
    ... ... @@ -162,8 +165,8 @@ getHistorySpan hug hist = do
    162 165
     -- for each tick.
    
    163 166
     findEnclosingDecls :: HUG.HomeUnitGraph -> InternalBreakpointId -> IO [String]
    
    164 167
     findEnclosingDecls hug ibi = do
    
    165
    -  brks <- readModBreaks hug (ibi_tick_mod ibi)
    
    166
    -  return $ getBreakDecls ibi brks
    
    168
    +  brks <- readIModBreaks hug ibi
    
    169
    +  getBreakDecls (readIModModBreaks hug) ibi brks
    
    167 170
     
    
    168 171
     -- | Update fixity environment in the current interactive context.
    
    169 172
     updateFixityEnv :: GhcMonad m => FixityEnv -> m ()
    
    ... ... @@ -350,15 +353,14 @@ handleRunStatus step expr bindings final_ids status history0 = do
    350 353
         EvalBreak apStack_ref (Just eval_break) resume_ctxt ccs -> do
    
    351 354
           let ibi = evalBreakpointToId eval_break
    
    352 355
           let hug = hsc_HUG hsc_env
    
    353
    -      tick_brks  <- liftIO $ readModBreaks hug (ibi_tick_mod ibi)
    
    354
    -      let
    
    355
    -        span = getBreakLoc ibi tick_brks
    
    356
    -        decl = intercalate "." $ getBreakDecls ibi tick_brks
    
    356
    +      info_brks  <- liftIO $ readIModBreaks hug ibi
    
    357
    +      span <- liftIO $ getBreakLoc (readIModModBreaks hug) ibi info_brks
    
    358
    +      decl <- liftIO $ intercalate "." <$> getBreakDecls (readIModModBreaks hug) ibi info_brks
    
    357 359
     
    
    358 360
           -- Was this breakpoint explicitly enabled (ie. in @BreakArray@)?
    
    359 361
           bactive <- liftIO $ do
    
    360
    -        breakArray <- getBreakArray interp (toBreakpointId ibi) tick_brks
    
    361
    -        breakpointStatus interp breakArray (ibi_tick_index ibi)
    
    362
    +        breakArray <- getBreakArray interp ibi info_brks
    
    363
    +        breakpointStatus interp breakArray (ibi_info_index ibi)
    
    362 364
     
    
    363 365
           apStack_fhv <- liftIO $ mkFinalizedHValue interp apStack_ref
    
    364 366
           resume_ctxt_fhv   <- liftIO $ mkFinalizedHValue interp resume_ctxt
    
    ... ... @@ -446,7 +448,7 @@ resumeExec step mbCnt
    446 448
                     -- When the user specified a break ignore count, set it
    
    447 449
                     -- in the interpreter
    
    448 450
                     case (mb_brkpt, mbCnt) of
    
    449
    -                  (Just brkpt, Just cnt) -> setupBreakpoint interp (toBreakpointId brkpt) cnt
    
    451
    +                  (Just brkpt, Just cnt) -> setupBreakpoint interp brkpt cnt
    
    450 452
                       _ -> return ()
    
    451 453
     
    
    452 454
                     let eval_opts = initEvalOpts dflags (enableGhcStepMode step)
    
    ... ... @@ -462,17 +464,18 @@ resumeExec step mbCnt
    462 464
                              | otherwise -> pure prevHistoryLst
    
    463 465
                     handleRunStatus step expr bindings final_ids status =<< hist'
    
    464 466
     
    
    465
    -setupBreakpoint :: GhcMonad m => Interp -> BreakpointId -> Int -> m ()   -- #19157
    
    466
    -setupBreakpoint interp bi cnt = do
    
    467
    +setupBreakpoint :: GhcMonad m => Interp -> InternalBreakpointId -> Int -> m ()   -- #19157
    
    468
    +setupBreakpoint interp ibi cnt = do
    
    467 469
       hug <- hsc_HUG <$> getSession
    
    468
    -  modBreaks <- liftIO $ readModBreaks hug (bi_tick_mod bi)
    
    469
    -  breakArray <- liftIO $ getBreakArray interp bi modBreaks
    
    470
    -  liftIO $ GHCi.storeBreakpoint interp breakArray (bi_tick_index bi) cnt
    
    470
    +  liftIO $ do
    
    471
    +    modBreaks <- readIModBreaks hug ibi
    
    472
    +    breakArray <- getBreakArray interp ibi modBreaks
    
    473
    +    GHCi.storeBreakpoint interp breakArray (ibi_info_index ibi) cnt
    
    471 474
     
    
    472
    -getBreakArray :: Interp -> BreakpointId -> InternalModBreaks -> IO (ForeignRef BreakArray)
    
    473
    -getBreakArray interp BreakpointId{bi_tick_mod} imbs = do
    
    475
    +getBreakArray :: Interp -> InternalBreakpointId -> InternalModBreaks -> IO (ForeignRef BreakArray)
    
    476
    +getBreakArray interp InternalBreakpointId{ibi_info_mod} imbs = do
    
    474 477
       breaks0 <- linked_breaks . fromMaybe (panic "Loader not initialised") <$> getLoaderState interp
    
    475
    -  case lookupModuleEnv (breakarray_env breaks0) bi_tick_mod of
    
    478
    +  case lookupModuleEnv (breakarray_env breaks0) ibi_info_mod of
    
    476 479
         Just ba -> return ba
    
    477 480
         Nothing -> do
    
    478 481
           modifyLoaderState interp $ \ld_st -> do
    
    ... ... @@ -483,13 +486,12 @@ getBreakArray interp BreakpointId{bi_tick_mod} imbs = do
    483 486
             ba_env <- allocateBreakArrays interp (breakarray_env lb) [imbs]
    
    484 487
     
    
    485 488
             let ld_st' = ld_st { linked_breaks = lb{breakarray_env = ba_env} }
    
    486
    -        let ba = expectJust {- just computed -} $ lookupModuleEnv ba_env bi_tick_mod
    
    489
    +        let ba = expectJust {- just computed -} $ lookupModuleEnv ba_env ibi_info_mod
    
    487 490
     
    
    488 491
             return
    
    489 492
               ( ld_st'
    
    490 493
               , ba
    
    491 494
               )
    
    492
    -
    
    493 495
     back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
    
    494 496
     back n = moveHist (+n)
    
    495 497
     
    
    ... ... @@ -517,8 +519,9 @@ moveHist fn = do
    517 519
                 span <- case mb_info of
    
    518 520
                           Nothing  -> return $ mkGeneralSrcSpan (fsLit "<unknown>")
    
    519 521
                           Just ibi -> liftIO $ do
    
    520
    -                        brks <- readModBreaks (hsc_HUG hsc_env) (ibi_tick_mod ibi)
    
    521
    -                        return $ getBreakLoc ibi brks
    
    522
    +                        let hug = hsc_HUG hsc_env
    
    523
    +                        brks <- readIModBreaks hug ibi
    
    524
    +                        getBreakLoc (readIModModBreaks hug) ibi brks
    
    522 525
                 (hsc_env1, names) <-
    
    523 526
                   liftIO $ bindLocalsAtBreakpoint hsc_env apStack span mb_info
    
    524 527
                 let ic = hsc_IC hsc_env1
    
    ... ... @@ -579,11 +582,10 @@ bindLocalsAtBreakpoint hsc_env apStack span Nothing = do
    579 582
     -- of the breakpoint and the free variables of the expression.
    
    580 583
     bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi) = do
    
    581 584
        let hug = hsc_HUG hsc_env
    
    582
    -   info_brks <- readModBreaks hug (ibi_info_mod ibi)
    
    583
    -   tick_brks <- readModBreaks hug (ibi_tick_mod ibi)
    
    584
    -   let info   = getInternalBreak ibi (info_brks)
    
    585
    +   info_brks <- readIModBreaks hug ibi
    
    586
    +   let info   = getInternalBreak ibi info_brks
    
    585 587
            interp = hscInterp hsc_env
    
    586
    -       occs   = getBreakVars ibi tick_brks
    
    588
    +   occs <- getBreakVars (readIModModBreaks hug) ibi info_brks
    
    587 589
     
    
    588 590
       -- Rehydrate to understand the breakpoint info relative to the current environment.
    
    589 591
       -- This design is critical to preventing leaks (#22530)
    

  • compiler/GHC/Runtime/Interpreter.hs
    ... ... @@ -27,7 +27,9 @@ module GHC.Runtime.Interpreter
    27 27
       , getClosure
    
    28 28
       , whereFrom
    
    29 29
       , getModBreaks
    
    30
    -  , readModBreaks
    
    30
    +  , readIModBreaks
    
    31
    +  , readIModBreaksMaybe
    
    32
    +  , readIModModBreaks
    
    31 33
       , seqHValue
    
    32 34
       , evalBreakpointToId
    
    33 35
     
    
    ... ... @@ -92,7 +94,6 @@ import GHC.Utils.Fingerprint
    92 94
     
    
    93 95
     import GHC.Unit.Module
    
    94 96
     import GHC.Unit.Home.ModInfo
    
    95
    -import GHC.Unit.Home.Graph (lookupHugByModule)
    
    96 97
     import GHC.Unit.Env
    
    97 98
     
    
    98 99
     #if defined(HAVE_INTERNAL_INTERPRETER)
    
    ... ... @@ -411,15 +412,10 @@ evalBreakpointToId :: EvalBreakpoint -> InternalBreakpointId
    411 412
     evalBreakpointToId eval_break =
    
    412 413
       let
    
    413 414
         mkUnitId u = fsToUnit $ mkFastStringShortByteString u
    
    414
    -
    
    415 415
         toModule u n = mkModule (mkUnitId u) (mkModuleName n)
    
    416
    -    tickl = toModule (eb_tick_mod_unit eval_break) (eb_tick_mod eval_break)
    
    417
    -    infol = toModule (eb_info_mod_unit eval_break) (eb_info_mod eval_break)
    
    418 416
       in
    
    419 417
         InternalBreakpointId
    
    420
    -      { ibi_tick_mod   = tickl
    
    421
    -      , ibi_tick_index = eb_tick_index eval_break
    
    422
    -      , ibi_info_mod   = infol
    
    418
    +      { ibi_info_mod   = toModule (eb_info_mod_unit eval_break) (eb_info_mod eval_break)
    
    423 419
           , ibi_info_index = eb_info_index eval_break
    
    424 420
           }
    
    425 421
     
    
    ... ... @@ -440,17 +436,18 @@ handleSeqHValueStatus interp unit_env eval_status =
    440 436
               -- Reason: Setting of flags in libraries/ghci/GHCi/Run.hs:evalOptsSeq
    
    441 437
     
    
    442 438
             Just break -> do
    
    443
    -          let bi = evalBreakpointToId break
    
    439
    +          let ibi = evalBreakpointToId break
    
    440
    +              hug = ue_home_unit_graph unit_env
    
    444 441
     
    
    445 442
               -- Just case: Stopped at a breakpoint, extract SrcSpan information
    
    446 443
               -- from the breakpoint.
    
    447
    -          mb_modbreaks <- getModBreaks . expectJust <$>
    
    448
    -                          lookupHugByModule (ibi_tick_mod bi) (ue_home_unit_graph unit_env)
    
    444
    +          mb_modbreaks <- readIModBreaksMaybe hug (ibi_info_mod ibi)
    
    449 445
               case mb_modbreaks of
    
    450 446
                 -- Nothing case - should not occur! We should have the appropriate
    
    451 447
                 -- breakpoint information
    
    452 448
                 Nothing -> nothing_case
    
    453
    -            Just modbreaks -> put $ brackets . ppr $ getBreakLoc bi modbreaks
    
    449
    +            Just modbreaks -> put . brackets . ppr =<<
    
    450
    +              getBreakLoc (readIModModBreaks hug) ibi modbreaks
    
    454 451
     
    
    455 452
           -- resume the seq (:force) processing in the iserv process
    
    456 453
           withForeignRef resume_ctxt_fhv $ \hval -> do
    
    ... ... @@ -745,10 +742,18 @@ getModBreaks hmi
    745 742
       | otherwise
    
    746 743
       = Nothing -- probably object code
    
    747 744
     
    
    748
    --- | Read the 'InternalModBreaks' and 'ModBreaks' of the given home 'Module'
    
    749
    --- from the 'HomeUnitGraph'.
    
    750
    -readModBreaks :: HomeUnitGraph -> Module -> IO InternalModBreaks
    
    751
    -readModBreaks hug modl = expectJust . getModBreaks . expectJust <$> HUG.lookupHugByModule modl hug
    
    745
    +-- | Read the 'InternalModBreaks' of the given home 'Module' (via
    
    746
    +-- 'InternalBreakpointId') from the 'HomeUnitGraph'.
    
    747
    +readIModBreaks :: HomeUnitGraph -> InternalBreakpointId -> IO InternalModBreaks
    
    748
    +readIModBreaks hug ibi = expectJust <$> readIModBreaksMaybe hug (ibi_info_mod ibi)
    
    749
    +
    
    750
    +-- | Read the 'InternalModBreaks' of the given home 'Module' from the 'HomeUnitGraph'.
    
    751
    +readIModBreaksMaybe :: HomeUnitGraph -> Module -> IO (Maybe InternalModBreaks)
    
    752
    +readIModBreaksMaybe hug mod = getModBreaks . expectJust <$> HUG.lookupHugByModule mod hug
    
    753
    +
    
    754
    +-- | Read the 'ModBreaks' from the given module's 'InternalModBreaks'
    
    755
    +readIModModBreaks :: HUG.HomeUnitGraph -> Module -> IO ModBreaks
    
    756
    +readIModModBreaks hug mod = imodBreaks_modBreaks . expectJust <$> readIModBreaksMaybe hug mod
    
    752 757
     
    
    753 758
     -- -----------------------------------------------------------------------------
    
    754 759
     -- Misc utils
    

  • compiler/GHC/StgToByteCode.hs
    ... ... @@ -31,7 +31,6 @@ import GHC.Cmm.Utils
    31 31
     import GHC.Platform
    
    32 32
     import GHC.Platform.Profile
    
    33 33
     
    
    34
    -import GHC.Runtime.Interpreter
    
    35 34
     import GHCi.FFI
    
    36 35
     import GHC.Types.Basic
    
    37 36
     import GHC.Utils.Outputable
    
    ... ... @@ -64,6 +63,7 @@ import GHC.StgToCmm.Closure ( NonVoid(..), fromNonVoid, idPrimRepU,
    64 63
                                   assertNonVoidIds, assertNonVoidStgArgs )
    
    65 64
     import GHC.StgToCmm.Layout
    
    66 65
     import GHC.Runtime.Heap.Layout hiding (WordOff, ByteOff, wordsToBytes)
    
    66
    +import GHC.Runtime.Interpreter ( interpreterProfiled, readIModModBreaks )
    
    67 67
     import GHC.Data.Bitmap
    
    68 68
     import GHC.Data.FlatBag as FlatBag
    
    69 69
     import GHC.Data.OrdList
    
    ... ... @@ -79,7 +79,6 @@ import Control.Monad
    79 79
     import Data.Char
    
    80 80
     
    
    81 81
     import GHC.Unit.Module
    
    82
    -import qualified GHC.Unit.Home.Graph as HUG
    
    83 82
     
    
    84 83
     import Data.Coerce (coerce)
    
    85 84
     #if MIN_VERSION_rts(1,0,3)
    
    ... ... @@ -100,6 +99,7 @@ import GHC.CoreToIface
    100 99
     import Control.Monad.IO.Class
    
    101 100
     import Control.Monad.Trans.Reader (ReaderT(..))
    
    102 101
     import Control.Monad.Trans.State  (StateT(..))
    
    102
    +import Data.Array ((!))
    
    103 103
     
    
    104 104
     -- -----------------------------------------------------------------------------
    
    105 105
     -- Generating byte code for a complete module
    
    ... ... @@ -394,65 +394,32 @@ schemeR_wrk fvs nm original_body (args, body)
    394 394
     -- | Introduce break instructions for ticked expressions.
    
    395 395
     -- If no breakpoint information is available, the instruction is omitted.
    
    396 396
     schemeER_wrk :: StackDepth -> BCEnv -> CgStgExpr -> BcM BCInstrList
    
    397
    -schemeER_wrk d p (StgTick (Breakpoint tick_ty (BreakpointId tick_mod tick_no) fvs) rhs) = do
    
    398
    -  code <- schemeE d 0 p rhs
    
    399
    -  hsc_env <- getHscEnv
    
    400
    -  current_mod <- getCurrentModule
    
    401
    -  mb_current_mod_breaks <- getCurrentModBreaks
    
    402
    -  case mb_current_mod_breaks of
    
    403
    -    -- if we're not generating ModBreaks for this module for some reason, we
    
    404
    -    -- can't store breakpoint occurrence information.
    
    405
    -    Nothing -> pure code
    
    406
    -    Just current_mod_breaks -> break_info hsc_env tick_mod current_mod mb_current_mod_breaks >>= \case
    
    407
    -      Nothing -> pure code
    
    408
    -      Just ModBreaks{modBreaks_module = tick_mod} -> do
    
    409
    -        platform <- profilePlatform <$> getProfile
    
    410
    -        let idOffSets = getVarOffSets platform d p fvs
    
    411
    -            ty_vars   = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)
    
    412
    -            toWord :: Maybe (Id, WordOff) -> Maybe (Id, Word)
    
    413
    -            toWord = fmap (\(i, wo) -> (i, fromIntegral wo))
    
    414
    -            breakInfo  = dehydrateCgBreakInfo ty_vars (map toWord idOffSets) tick_ty
    
    415
    -
    
    416
    -        let info_mod = modBreaks_module current_mod_breaks
    
    417
    -        infox <- newBreakInfo breakInfo
    
    397
    +schemeER_wrk d p (StgTick bp@(Breakpoint tick_ty tick_id fvs) rhs) = do
    
    398
    +  platform <- profilePlatform <$> getProfile
    
    399
    +
    
    400
    +  code <- case rhs of
    
    401
    +    -- When we find a tick surrounding a case expression we introduce a new BRK_FUN
    
    402
    +    -- instruction at the start of the case *continuation*, in addition to the
    
    403
    +    -- usual BRK_FUN surrounding the StgCase)
    
    404
    +    -- See Note [TODO]
    
    405
    +    StgCase scrut bndr _ alts
    
    406
    +      -> doCase d 0 p (Just bp) scrut bndr alts
    
    407
    +    _ -> schemeE d 0 p rhs
    
    408
    +
    
    409
    +  let idOffSets = getVarOffSets platform d p fvs
    
    410
    +      ty_vars   = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)
    
    411
    +      toWord :: Maybe (Id, WordOff) -> Maybe (Id, Word)
    
    412
    +      toWord = fmap (\(i, wo) -> (i, fromIntegral wo))
    
    413
    +      breakInfo = dehydrateCgBreakInfo ty_vars (map toWord idOffSets) tick_ty (Right tick_id)
    
    414
    +
    
    415
    +  mibi <- newBreakInfo breakInfo
    
    416
    +
    
    417
    +  return $ case mibi of
    
    418
    +    Nothing  -> code
    
    419
    +    Just ibi -> BRK_FUN ibi 0 `consOL` code
    
    418 420
     
    
    419
    -        let breakInstr = BRK_FUN (InternalBreakpointId tick_mod tick_no info_mod infox)
    
    420
    -        return $ breakInstr `consOL` code
    
    421 421
     schemeER_wrk d p rhs = schemeE d 0 p rhs
    
    422 422
     
    
    423
    --- | Determine the GHCi-allocated 'BreakArray' and module pointer for the module
    
    424
    --- from which the breakpoint originates.
    
    425
    --- These are stored in 'ModBreaks' as remote pointers in order to allow the BCOs
    
    426
    --- to refer to pointers in GHCi's address space.
    
    427
    --- They are initialized in 'GHC.HsToCore.Breakpoints.mkModBreaks', called by
    
    428
    --- 'GHC.HsToCore.deSugar'.
    
    429
    ---
    
    430
    --- Breakpoints might be disabled because we're in TH, because
    
    431
    --- @-fno-break-points@ was specified, or because a module was reloaded without
    
    432
    --- reinitializing 'ModBreaks'.
    
    433
    ---
    
    434
    --- If the module stored in the breakpoint is the currently processed module, use
    
    435
    --- the 'ModBreaks' from the state.
    
    436
    --- If that is 'Nothing', consider breakpoints to be disabled and skip the
    
    437
    --- instruction.
    
    438
    ---
    
    439
    --- If the breakpoint is inlined from another module, look it up in the HUG (home unit graph).
    
    440
    --- If the module doesn't exist there, or if the 'ModBreaks' value is
    
    441
    --- uninitialized, skip the instruction (i.e. return Nothing).
    
    442
    -break_info ::
    
    443
    -  HscEnv ->
    
    444
    -  Module ->
    
    445
    -  Module ->
    
    446
    -  Maybe ModBreaks ->
    
    447
    -  BcM (Maybe ModBreaks)
    
    448
    -break_info hsc_env mod current_mod current_mod_breaks
    
    449
    -  | mod == current_mod
    
    450
    -  = pure current_mod_breaks
    
    451
    -  | otherwise
    
    452
    -  = liftIO (HUG.lookupHugByModule mod (hsc_HUG hsc_env)) >>= \case
    
    453
    -      Just hp -> pure $ imodBreaks_modBreaks <$> getModBreaks hp
    
    454
    -      Nothing -> pure Nothing
    
    455
    -
    
    456 423
     getVarOffSets :: Platform -> StackDepth -> BCEnv -> [Id] -> [Maybe (Id, WordOff)]
    
    457 424
     getVarOffSets platform depth env = map getOffSet
    
    458 425
       where
    
    ... ... @@ -652,7 +619,7 @@ schemeE d s p (StgTick _ rhs) = schemeE d s p rhs
    652 619
     schemeE d s p (StgCase scrut _ _ []) = schemeE d s p scrut
    
    653 620
     
    
    654 621
     schemeE d s p (StgCase scrut bndr _ alts)
    
    655
    -   = doCase d s p scrut bndr alts
    
    622
    +   = doCase d s p Nothing scrut bndr alts
    
    656 623
     
    
    657 624
     
    
    658 625
     {-
    
    ... ... @@ -1144,11 +1111,15 @@ doCase
    1144 1111
         :: StackDepth
    
    1145 1112
         -> Sequel
    
    1146 1113
         -> BCEnv
    
    1114
    +    -> Maybe StgTickish
    
    1115
    +    -- ^ The breakpoint surrounding the full case expression, if any (only
    
    1116
    +    -- source-level cases get breakpoint ticks, and those are the only we care
    
    1117
    +    -- about). See Note [TODO]
    
    1147 1118
         -> CgStgExpr
    
    1148 1119
         -> Id
    
    1149 1120
         -> [CgStgAlt]
    
    1150 1121
         -> BcM BCInstrList
    
    1151
    -doCase d s p scrut bndr alts
    
    1122
    +doCase d s p m_bid scrut bndr alts
    
    1152 1123
       = do
    
    1153 1124
          profile <- getProfile
    
    1154 1125
          hsc_env <- getHscEnv
    
    ... ... @@ -1209,12 +1180,12 @@ doCase d s p scrut bndr alts
    1209 1180
     
    
    1210 1181
             -- depth of stack after the return value has been pushed
    
    1211 1182
             d_bndr =
    
    1212
    -            d + ret_frame_size_b + bndr_size
    
    1183
    +            d + bndr_size
    
    1213 1184
     
    
    1214 1185
             -- depth of stack after the extra info table for an unlifted return
    
    1215 1186
             -- has been pushed, if any.  This is the stack depth at the
    
    1216 1187
             -- continuation.
    
    1217
    -        d_alts = d + ret_frame_size_b + bndr_size + unlifted_itbl_size_b
    
    1188
    +        d_alts = d + bndr_size + unlifted_itbl_size_b
    
    1218 1189
     
    
    1219 1190
             -- Env in which to compile the alts, not including
    
    1220 1191
             -- any vars bound by the alts themselves
    
    ... ... @@ -1365,11 +1336,28 @@ doCase d s p scrut bndr alts
    1365 1336
          let alt_final1
    
    1366 1337
                | ubx_tuple_frame    = SLIDE 0 2 `consOL` alt_final0
    
    1367 1338
                | otherwise          = alt_final0
    
    1368
    -         alt_final
    
    1369
    -           | gopt Opt_InsertBreakpoints (hsc_dflags hsc_env)
    
    1370
    -                                -- See Note [Debugger: BRK_ALTS]
    
    1371
    -                                = BRK_ALTS False `consOL` alt_final1
    
    1372
    -           | otherwise          = alt_final1
    
    1339
    +
    
    1340
    +     alt_final <- case m_bid of
    
    1341
    +       Just (Breakpoint tick_ty tick_id fvs)
    
    1342
    +         | gopt Opt_InsertBreakpoints (hsc_dflags hsc_env)
    
    1343
    +         -- Construct an internal breakpoint to put at the start of this case
    
    1344
    +         -- continuation BCO.
    
    1345
    +         -- See Note [TODO]
    
    1346
    +         -> do
    
    1347
    +          internal_tick_loc <- makeCaseInternalBreakLoc tick_id
    
    1348
    +
    
    1349
    +          -- same fvs available in the case expression are available in the case continuation
    
    1350
    +          let idOffSets = getVarOffSets platform d p fvs
    
    1351
    +              ty_vars   = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)
    
    1352
    +              toWord :: Maybe (Id, WordOff) -> Maybe (Id, Word)
    
    1353
    +              toWord = fmap (\(i, wo) -> (i, fromIntegral wo))
    
    1354
    +              breakInfo = dehydrateCgBreakInfo ty_vars (map toWord idOffSets) tick_ty (Left internal_tick_loc)
    
    1355
    +
    
    1356
    +          mibi <- newBreakInfo breakInfo
    
    1357
    +          return $ case mibi of
    
    1358
    +            Nothing  -> alt_final1
    
    1359
    +            Just ibi -> {- BRK_FUN ibi (d_alts - d) `consOL` -} alt_final1
    
    1360
    +       _ -> pure alt_final1
    
    1373 1361
     
    
    1374 1362
          add_bco_name <- shouldAddBcoName
    
    1375 1363
          let
    
    ... ... @@ -1389,6 +1377,24 @@ doCase d s p scrut bndr alts
    1389 1377
                       _     -> panic "schemeE(StgCase).push_alts"
    
    1390 1378
                 in return (PUSH_ALTS alt_bco scrut_rep `consOL` scrut_code)
    
    1391 1379
     
    
    1380
    +makeCaseInternalBreakLoc :: BreakpointId -> BcM InternalBreakLoc
    
    1381
    +makeCaseInternalBreakLoc bid = do
    
    1382
    +  hug         <- hsc_HUG <$> getHscEnv
    
    1383
    +  curr_mod    <- getCurrentModule
    
    1384
    +  mb_mod_brks <- getCurrentModBreaks
    
    1385
    +
    
    1386
    +  -- TODO: Subtract the scrutinee loc from the case loc to get continuation loc
    
    1387
    +  InternalBreakLoc <$> case bid of
    
    1388
    +    BreakpointId{bi_tick_mod, bi_tick_index}
    
    1389
    +      | bi_tick_mod == curr_mod
    
    1390
    +      , Just these_mbs <- mb_mod_brks
    
    1391
    +      -> do
    
    1392
    +        return $ modBreaks_locs these_mbs ! bi_tick_index
    
    1393
    +      | otherwise
    
    1394
    +      -> do
    
    1395
    +        other_mbs <- liftIO $ readIModModBreaks hug bi_tick_mod
    
    1396
    +        return $ modBreaks_locs other_mbs ! bi_tick_index
    
    1397
    +
    
    1392 1398
     {-
    
    1393 1399
     Note [Debugger: BRK_ALTS]
    
    1394 1400
     ~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -1756,6 +1762,10 @@ tupleBCO platform args_info args =
    1756 1762
           with using a fake name here. We will need to change this if we want
    
    1757 1763
           to save some memory by sharing the BCO between places that have
    
    1758 1764
           the same tuple shape
    
    1765
    +
    
    1766
    +      ROMES:TODO: This seems like it would have a pretty good impact.
    
    1767
    +      Looking at examples like UnboxedTuple.hs shows many occurrences of the
    
    1768
    +      same tuple_BCO
    
    1759 1769
         -}
    
    1760 1770
         invented_name  = mkSystemVarName (mkPseudoUniqueE 0) (fsLit "tuple")
    
    1761 1771
     
    
    ... ... @@ -2705,14 +2715,19 @@ getLabelsBc n = BcM $ \_ st ->
    2705 2715
       let ctr = nextlabel st
    
    2706 2716
        in return (coerce [ctr .. ctr+n-1], st{nextlabel = ctr+n})
    
    2707 2717
     
    
    2708
    -newBreakInfo :: CgBreakInfo -> BcM Int
    
    2709
    -newBreakInfo info = BcM $ \_ st ->
    
    2710
    -  let ix = breakInfoIdx st
    
    2711
    -      st' = st
    
    2712
    -        { breakInfo = IntMap.insert ix info (breakInfo st)
    
    2713
    -        , breakInfoIdx = ix + 1
    
    2714
    -        }
    
    2715
    -  in return (ix, st')
    
    2718
    +newBreakInfo :: CgBreakInfo -> BcM (Maybe InternalBreakpointId)
    
    2719
    +newBreakInfo info = BcM $ \env st -> do
    
    2720
    +  -- if we're not generating ModBreaks for this module for some reason, we
    
    2721
    +  -- can't store breakpoint occurrence information.
    
    2722
    +  case modBreaks env of
    
    2723
    +    Nothing -> pure (Nothing, st)
    
    2724
    +    Just modBreaks -> do
    
    2725
    +      let ix = breakInfoIdx st
    
    2726
    +          st' = st
    
    2727
    +            { breakInfo = IntMap.insert ix info (breakInfo st)
    
    2728
    +            , breakInfoIdx = ix + 1
    
    2729
    +            }
    
    2730
    +      return (Just $ InternalBreakpointId (modBreaks_module modBreaks) ix, st')
    
    2716 2731
     
    
    2717 2732
     getCurrentModule :: BcM Module
    
    2718 2733
     getCurrentModule = BcM $ \env st -> return (bcm_module env, st)
    
    ... ... @@ -2722,3 +2737,14 @@ getCurrentModBreaks = BcM $ \env st -> return (modBreaks env, st)
    2722 2737
     
    
    2723 2738
     tickFS :: FastString
    
    2724 2739
     tickFS = fsLit "ticked"
    
    2740
    +
    
    2741
    +-- Dehydrating CgBreakInfo
    
    2742
    +
    
    2743
    +dehydrateCgBreakInfo :: [TyVar] -> [Maybe (Id, Word)] -> Type -> Either InternalBreakLoc BreakpointId -> CgBreakInfo
    
    2744
    +dehydrateCgBreakInfo ty_vars idOffSets tick_ty bid =
    
    2745
    +          CgBreakInfo
    
    2746
    +            { cgb_tyvars = map toIfaceTvBndr ty_vars
    
    2747
    +            , cgb_vars = map (fmap (\(i, offset) -> (toIfaceIdBndr i, offset))) idOffSets
    
    2748
    +            , cgb_resty = toIfaceType tick_ty
    
    2749
    +            , cgb_tick_id = bid
    
    2750
    +            }

  • compiler/Setup.hs
    1 1
     {-# LANGUAGE NamedFieldPuns #-}
    
    2
    +{-# LANGUAGE CPP #-}
    
    2 3
     module Main where
    
    3 4
     
    
    4 5
     import Distribution.Simple
    
    ... ... @@ -12,6 +13,8 @@ import Distribution.Simple.Program
    12 13
     import Distribution.Simple.Utils
    
    13 14
     import Distribution.Simple.Setup
    
    14 15
     import Distribution.Simple.PackageIndex
    
    16
    +import qualified Distribution.Simple.LocalBuildInfo as LBI
    
    17
    +
    
    15 18
     
    
    16 19
     import System.IO
    
    17 20
     import System.Process
    
    ... ... @@ -59,8 +62,9 @@ primopIncls =
    59 62
     ghcAutogen :: Verbosity -> LocalBuildInfo -> IO ()
    
    60 63
     ghcAutogen verbosity lbi@LocalBuildInfo{pkgDescrFile,withPrograms,componentNameMap,installedPkgs}
    
    61 64
       = do
    
    65
    +  let i = LBI.interpretSymbolicPathLBI lbi
    
    62 66
       -- Get compiler/ root directory from the cabal file
    
    63
    -  let Just compilerRoot = takeDirectory <$> pkgDescrFile
    
    67
    +  let Just compilerRoot = takeDirectory . i <$> pkgDescrFile
    
    64 68
     
    
    65 69
       -- Require the necessary programs
    
    66 70
       (gcc   ,withPrograms) <- requireProgram normal gccProgram withPrograms
    
    ... ... @@ -80,15 +84,19 @@ ghcAutogen verbosity lbi@LocalBuildInfo{pkgDescrFile,withPrograms,componentNameM
    80 84
       -- Call genprimopcode to generate *.hs-incl
    
    81 85
       forM_ primopIncls $ \(file,command) -> do
    
    82 86
         contents <- readProcess "genprimopcode" [command] primopsStr
    
    83
    -    rewriteFileEx verbosity (buildDir lbi </> file) contents
    
    87
    +    rewriteFileEx verbosity (i (buildDir lbi) </> file) contents
    
    84 88
     
    
    85 89
       -- Write GHC.Platform.Constants
    
    86
    -  let platformConstantsPath = autogenPackageModulesDir lbi </> "GHC/Platform/Constants.hs"
    
    90
    +  let platformConstantsPath = i (autogenPackageModulesDir lbi) </> "GHC/Platform/Constants.hs"
    
    87 91
           targetOS = case lookup "target os" settings of
    
    88 92
             Nothing -> error "no target os in settings"
    
    89 93
             Just os -> os
    
    90 94
       createDirectoryIfMissingVerbose verbosity True (takeDirectory platformConstantsPath)
    
    95
    +#if MIN_VERSION_Cabal(3,14,0)
    
    96
    +  withTempFile "Constants_tmp.hs" $ \tmp h -> do
    
    97
    +#else
    
    91 98
       withTempFile (takeDirectory platformConstantsPath) "Constants_tmp.hs" $ \tmp h -> do
    
    99
    +#endif
    
    92 100
         hClose h
    
    93 101
         callProcess "deriveConstants" ["--gen-haskell-type","-o",tmp,"--target-os",targetOS]
    
    94 102
         renameFile tmp platformConstantsPath
    
    ... ... @@ -103,7 +111,7 @@ ghcAutogen verbosity lbi@LocalBuildInfo{pkgDescrFile,withPrograms,componentNameM
    103 111
             _ -> error "Couldn't find unique ghc-internal library when building ghc"
    
    104 112
     
    
    105 113
       -- Write GHC.Settings.Config
    
    106
    -      configHsPath = autogenPackageModulesDir lbi </> "GHC/Settings/Config.hs"
    
    114
    +      configHsPath = i (autogenPackageModulesDir lbi) </> "GHC/Settings/Config.hs"
    
    107 115
           configHs = generateConfigHs cProjectUnitId cGhcInternalUnitId settings
    
    108 116
       createDirectoryIfMissingVerbose verbosity True (takeDirectory configHsPath)
    
    109 117
       rewriteFileEx verbosity configHsPath configHs
    

  • compiler/ghc.cabal.in
    ... ... @@ -50,7 +50,7 @@ extra-source-files:
    50 50
     
    
    51 51
     
    
    52 52
     custom-setup
    
    53
    -    setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.14, directory, process, filepath, containers
    
    53
    +    setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.16, directory, process, filepath, containers
    
    54 54
     
    
    55 55
     Flag internal-interpreter
    
    56 56
         Description: Build with internal interpreter support.
    

  • docs/users_guide/eventlog-formats.rst
    ... ... @@ -779,9 +779,9 @@ the total time spent profiling.
    779 779
     Cost-centre break-down
    
    780 780
     ^^^^^^^^^^^^^^^^^^^^^^
    
    781 781
     
    
    782
    -A variable-length packet encoding a heap profile sample broken down by,
    
    783
    - * cost-centre (:rts-flag:`-hc`)
    
    784
    -
    
    782
    +A variable-length packet encoding a heap profile sample.
    
    783
    +This event is only emitted when the heap profile type is set to :rts-flag:`-hc` or :rts-flag:`-hb`.
    
    784
    +Otherwise, a :event-type:`HEAP_PROF_SAMPLE_STRING` event is emitted instead.
    
    785 785
     
    
    786 786
     .. event-type:: HEAP_PROF_SAMPLE_COST_CENTRE
    
    787 787
     
    
    ... ... @@ -796,11 +796,19 @@ A variable-length packet encoding a heap profile sample broken down by,
    796 796
     String break-down
    
    797 797
     ^^^^^^^^^^^^^^^^^
    
    798 798
     
    
    799
    -A variable-length event encoding a heap sample broken down by,
    
    799
    +A variable-length event encoding a heap sample.
    
    800
    +The content of the sample label varies depending on the heap profile type:
    
    801
    +
    
    802
    +   * :rts-flag:`-hT` The sample label contains a closure type, e.g., ``"ghc-bignum:GHC.Num.Integer.IS"``.
    
    803
    +   * :rts-flag:`-hm` The sample label contains a module name, e.g., ``"GHC.Num.Integer"``.
    
    804
    +   * :rts-flag:`-hd` The sample label contains a closure description, e.g., ``"IS"``.
    
    805
    +   * :rts-flag:`-hy` The sample label contains a type description, e.g., ``"Integer"``.
    
    806
    +   * :rts-flag:`-he` The sample label contains a stringified era, e.g., ``"1"``.
    
    807
    +   * :rts-flag:`-hr` The sample label contains a retainer set description, e.g., ``"(184)$stoIntegralSized1"``.
    
    808
    +   * :rts-flag:`-hi` The sample label contains a stringified pointer, e.g., ``"0x1008b7588"``,
    
    809
    +     which can be matched to an info table description emitted by the :event-type:`IPE` event.
    
    800 810
     
    
    801
    - * type description (:rts-flag:`-hy`)
    
    802
    - * closure description (:rts-flag:`-hd`)
    
    803
    - * module (:rts-flag:`-hm`)
    
    811
    +If the heap profile type is set to :rts-flag:`-hc` or :rts-flag:`-hb`, a :event-type:`HEAP_PROF_SAMPLE_COST_CENTRE` event is emitted instead.
    
    804 812
     
    
    805 813
     .. event-type:: HEAP_PROF_SAMPLE_STRING
    
    806 814
     
    
    ... ... @@ -808,7 +816,7 @@ A variable-length event encoding a heap sample broken down by,
    808 816
        :length: variable
    
    809 817
        :field Word8: profile ID
    
    810 818
        :field Word64: heap residency in bytes
    
    811
    -   :field String: type or closure description, or module name
    
    819
    +   :field String: sample label
    
    812 820
     
    
    813 821
     .. _time-profiler-events:
    
    814 822
     
    

  • ghc/GHCi/UI.hs
    ... ... @@ -45,7 +45,7 @@ import GHC.Runtime.Eval (mkTopLevEnv)
    45 45
     import GHC.Runtime.Eval.Utils
    
    46 46
     
    
    47 47
     -- The GHC interface
    
    48
    -import GHC.ByteCode.Breakpoints (imodBreaks_modBreaks)
    
    48
    +import GHC.ByteCode.Breakpoints (imodBreaks_modBreaks, InternalBreakpointId(..), getBreakSourceId, getBreakSourceMod)
    
    49 49
     import GHC.Runtime.Interpreter
    
    50 50
     import GHCi.RemoteTypes
    
    51 51
     import GHCi.BreakArray( breakOn, breakOff )
    
    ... ... @@ -68,7 +68,7 @@ import GHC ( LoadHowMuch(..), Target(..), TargetId(..),
    68 68
                  Resume, SingleStep, Ghc,
    
    69 69
                  GetDocsFailure(..), pushLogHookM,
    
    70 70
                  getModuleGraph, handleSourceError,
    
    71
    -             InternalBreakpointId(..) )
    
    71
    +             BreakpointId(..) )
    
    72 72
     import GHC.Driver.Main (hscParseModuleWithLocation, hscParseStmtWithLocation)
    
    73 73
     import GHC.Hs.ImpExp
    
    74 74
     import GHC.Hs
    
    ... ... @@ -546,6 +546,7 @@ interactiveUI config srcs maybe_exprs = do
    546 546
                        break_ctr          = 0,
    
    547 547
                        breaks             = IntMap.empty,
    
    548 548
                        tickarrays         = emptyModuleEnv,
    
    549
    +                   internalBreaks     = emptyModuleEnv,
    
    549 550
                        ghci_commands      = availableCommands config,
    
    550 551
                        ghci_macros        = [],
    
    551 552
                        last_command       = Nothing,
    
    ... ... @@ -1616,13 +1617,15 @@ toBreakIdAndLocation :: GhciMonad m
    1616 1617
     toBreakIdAndLocation Nothing = return Nothing
    
    1617 1618
     toBreakIdAndLocation (Just inf) = do
    
    1618 1619
       st <- getGHCiState
    
    1620
    +  hug <- hsc_HUG <$> GHC.getSession
    
    1621
    +  brks <- liftIO $ readIModBreaks hug inf
    
    1622
    +  let bi = getBreakSourceId inf brks
    
    1619 1623
       return $ listToMaybe [ id_loc | id_loc@(_,loc) <- IntMap.assocs (breaks st),
    
    1620
    -                                  breakModule loc == ibi_tick_mod inf,
    
    1621
    -                                  breakTick loc == ibi_tick_index inf ]
    
    1624
    +                                  Right (breakId loc) == bi ]
    
    1622 1625
     
    
    1623 1626
     printStoppedAtBreakInfo :: GHC.GhcMonad m => Resume -> [Name] -> m ()
    
    1624 1627
     printStoppedAtBreakInfo res names = do
    
    1625
    -  printForUser $ pprStopped res
    
    1628
    +  printForUser =<< pprStopped res
    
    1626 1629
       --  printTypeOfNames session names
    
    1627 1630
       let namesSorted = sortBy compareNames names
    
    1628 1631
       tythings <- catMaybes `liftM` mapM GHC.lookupName namesSorted
    
    ... ... @@ -3804,22 +3807,32 @@ showBkptTable = do
    3804 3807
     showContext :: GHC.GhcMonad m => m ()
    
    3805 3808
     showContext = do
    
    3806 3809
        resumes <- GHC.getResumeContext
    
    3807
    -   printForUser $ vcat (map pp_resume (reverse resumes))
    
    3810
    +   docs <- mapM pp_resume (reverse resumes)
    
    3811
    +   printForUser $ vcat docs
    
    3808 3812
       where
    
    3809
    -   pp_resume res =
    
    3810
    -        text "--> " <> text (GHC.resumeStmt res)
    
    3811
    -        $$ nest 2 (pprStopped res)
    
    3812
    -
    
    3813
    -pprStopped :: GHC.Resume -> SDoc
    
    3814
    -pprStopped res =
    
    3815
    -  text "Stopped in"
    
    3816
    -    <+> ((case mb_mod_name of
    
    3817
    -           Nothing -> empty
    
    3818
    -           Just mod_name -> ftext (moduleNameFS mod_name) <> char '.')
    
    3819
    -         <> text (GHC.resumeDecl res))
    
    3820
    -    <> char ',' <+> ppr (GHC.resumeSpan res)
    
    3821
    - where
    
    3822
    -  mb_mod_name = moduleName <$> ibi_tick_mod <$> GHC.resumeBreakpointId res
    
    3813
    +   pp_resume res = do
    
    3814
    +    stopped <- pprStopped res
    
    3815
    +    return $
    
    3816
    +      text "--> " <> text (GHC.resumeStmt res)
    
    3817
    +      $$ nest 2 stopped
    
    3818
    +
    
    3819
    +pprStopped :: GHC.GhcMonad m => GHC.Resume -> m SDoc
    
    3820
    +pprStopped res = do
    
    3821
    +  let mibi = GHC.resumeBreakpointId res
    
    3822
    +  mb_mod_name <- case mibi of
    
    3823
    +    Nothing -> pure Nothing
    
    3824
    +    Just ibi -> do
    
    3825
    +      hug <- hsc_HUG <$> GHC.getSession
    
    3826
    +      brks <- liftIO $ readIModBreaks hug ibi
    
    3827
    +      return $ Just $ moduleName $
    
    3828
    +        getBreakSourceMod ibi brks
    
    3829
    +  return $
    
    3830
    +    text "Stopped in"
    
    3831
    +      <+> ((case mb_mod_name of
    
    3832
    +             Nothing -> empty
    
    3833
    +             Just mod_name -> ftext (moduleNameFS mod_name) <> char '.')
    
    3834
    +           <> text (GHC.resumeDecl res))
    
    3835
    +      <> char ',' <+> ppr (GHC.resumeSpan res)
    
    3823 3836
     
    
    3824 3837
     showUnits :: GHC.GhcMonad m => m ()
    
    3825 3838
     showUnits = mapNonInteractiveHomeUnitsM $ \dflags -> do
    
    ... ... @@ -4373,12 +4386,8 @@ ignoreCmd argLine = withSandboxOnly ":ignore" $ do
    4373 4386
         result <- ignoreSwitch (words argLine)
    
    4374 4387
         case result of
    
    4375 4388
           Left sdoc -> printForUser sdoc
    
    4376
    -      Right (loc, count)   -> do
    
    4377
    -        let bi = GHC.BreakpointId
    
    4378
    -                  { bi_tick_mod   = breakModule loc
    
    4379
    -                  , bi_tick_index = breakTick loc
    
    4380
    -                  }
    
    4381
    -        setupBreakpoint bi count
    
    4389
    +      Right (loc, count) -> do
    
    4390
    +        setupBreakpoint (breakId loc) count
    
    4382 4391
     
    
    4383 4392
     ignoreSwitch :: GhciMonad m => [String] -> m (Either SDoc (BreakLocation, Int))
    
    4384 4393
     ignoreSwitch [break, count] = do
    
    ... ... @@ -4395,10 +4404,13 @@ getIgnoreCount str =
    4395 4404
         where
    
    4396 4405
           sdocIgnore = text "Ignore count" <+> quotes (text str)
    
    4397 4406
     
    
    4398
    -setupBreakpoint :: GhciMonad m => GHC.BreakpointId -> Int -> m()
    
    4399
    -setupBreakpoint loc count = do
    
    4407
    +setupBreakpoint :: GhciMonad m => GHC.BreakpointId -> Int -> m ()
    
    4408
    +setupBreakpoint bi count = do
    
    4400 4409
         hsc_env <- GHC.getSession
    
    4401
    -    GHC.setupBreakpoint (hscInterp hsc_env) loc count
    
    4410
    +    -- Trigger all internal breaks that match this source break id
    
    4411
    +    internal_break_ids <- getInternalBreaksOf bi
    
    4412
    +    forM_ internal_break_ids $ \ibi -> do
    
    4413
    +      GHC.setupBreakpoint (hscInterp hsc_env) ibi count
    
    4402 4414
     
    
    4403 4415
     backCmd :: GhciMonad m => String -> m ()
    
    4404 4416
     backCmd arg
    
    ... ... @@ -4489,20 +4501,20 @@ findBreakAndSet md lookupTickTree = do
    4489 4501
           some -> mapM_ breakAt some
    
    4490 4502
      where
    
    4491 4503
        breakAt (tick, pan) = do
    
    4492
    -         setBreakFlag md tick True
    
    4493
    -         (alreadySet, nm) <-
    
    4494
    -               recordBreak $ BreakLocation
    
    4495
    -                       { breakModule = md
    
    4496
    -                       , breakLoc = RealSrcSpan pan Strict.Nothing
    
    4497
    -                       , breakTick = tick
    
    4498
    -                       , onBreakCmd = ""
    
    4499
    -                       , breakEnabled = True
    
    4500
    -                       }
    
    4501
    -         printForUser $
    
    4502
    -            text "Breakpoint " <> ppr nm <>
    
    4503
    -            if alreadySet
    
    4504
    -               then text " was already set at " <> ppr pan
    
    4505
    -               else text " activated at " <> ppr pan
    
    4504
    +      let bi = BreakpointId md tick
    
    4505
    +      setBreakFlag bi True
    
    4506
    +      (alreadySet, nm) <-
    
    4507
    +            recordBreak $ BreakLocation
    
    4508
    +                    { breakLoc = RealSrcSpan pan Strict.Nothing
    
    4509
    +                    , breakId = bi
    
    4510
    +                    , onBreakCmd = ""
    
    4511
    +                    , breakEnabled = True
    
    4512
    +                    }
    
    4513
    +      printForUser $
    
    4514
    +         text "Breakpoint " <> ppr nm <>
    
    4515
    +         if alreadySet
    
    4516
    +            then text " was already set at " <> ppr pan
    
    4517
    +            else text " activated at " <> ppr pan
    
    4506 4518
     
    
    4507 4519
     -- For now, use ANSI bold on terminals that we know support it.
    
    4508 4520
     -- Otherwise, we add a line of carets under the active expression instead.
    
    ... ... @@ -4749,14 +4761,32 @@ turnBreakOnOff :: GhciMonad m => Bool -> BreakLocation -> m BreakLocation
    4749 4761
     turnBreakOnOff onOff loc
    
    4750 4762
       | onOff == breakEnabled loc = return loc
    
    4751 4763
       | otherwise = do
    
    4752
    -      setBreakFlag (breakModule loc) (breakTick loc)  onOff
    
    4764
    +      setBreakFlag (breakId loc) onOff
    
    4753 4765
           return loc { breakEnabled = onOff }
    
    4754 4766
     
    
    4755
    -setBreakFlag :: GhciMonad m => Module -> Int -> Bool ->m ()
    
    4756
    -setBreakFlag  md ix enaDisa = do
    
    4767
    +setBreakFlag :: GhciMonad m => GHC.BreakpointId -> Bool -> m ()
    
    4768
    +setBreakFlag (BreakpointId md ix) enaDisa = do
    
    4757 4769
       let enaDisaToCount True = breakOn
    
    4758 4770
           enaDisaToCount False = breakOff
    
    4759
    -  setupBreakpoint (GHC.BreakpointId md ix) $ enaDisaToCount enaDisa
    
    4771
    +  setupBreakpoint (BreakpointId md ix) $ enaDisaToCount enaDisa
    
    4772
    +
    
    4773
    +-- --------------------------------------------------------------------------
    
    4774
    +-- Find matching Internal Breakpoints
    
    4775
    +
    
    4776
    +-- | Find all the internal breakpoints that use the given source-level breakpoint id
    
    4777
    +getInternalBreaksOf :: GhciMonad m => BreakpointId -> m [InternalBreakpointId]
    
    4778
    +getInternalBreaksOf bi = do
    
    4779
    +    st <- getGHCiState
    
    4780
    +    let ibrks = internalBreaks st
    
    4781
    +    case lookupBreakpointOccurrences ibrks bi of
    
    4782
    +      Just bs -> return bs
    
    4783
    +      Nothing -> do
    
    4784
    +        -- Refresh the internal breakpoints map
    
    4785
    +        bs <- mkBreakpointOccurrences
    
    4786
    +        setGHCiState st{internalBreaks = bs}
    
    4787
    +        return $
    
    4788
    +          fromMaybe [] {- still not found after refresh -} $
    
    4789
    +            lookupBreakpointOccurrences bs bi
    
    4760 4790
     
    
    4761 4791
     -- ---------------------------------------------------------------------------
    
    4762 4792
     -- User code exception handling
    

  • ghc/GHCi/UI/Monad.hs
    ... ... @@ -100,6 +100,14 @@ data GHCiState = GHCiState
    100 100
                 -- ^ 'tickarrays' caches the 'TickArray' for loaded modules,
    
    101 101
                 -- so that we don't rebuild it each time the user sets
    
    102 102
                 -- a breakpoint.
    
    103
    +
    
    104
    +        internalBreaks :: BreakpointOccurrences,
    
    105
    +            -- ^ Keep a mapping from the source-level 'BreakpointId' to the
    
    106
    +            -- occurrences of that breakpoint across modules.
    
    107
    +            -- When we want to stop at a source 'BreakpointId', we essentially
    
    108
    +            -- trigger a breakpoint for all 'InternalBreakpointId's matching
    
    109
    +            -- the same source-id.
    
    110
    +
    
    103 111
             ghci_commands  :: [Command],
    
    104 112
                 -- ^ available ghci commands
    
    105 113
             ghci_macros    :: [Command],
    
    ... ... @@ -238,16 +246,15 @@ data LocalConfigBehaviour
    238 246
     
    
    239 247
     data BreakLocation
    
    240 248
        = BreakLocation
    
    241
    -   { breakModule :: !GHC.Module
    
    242
    -   , breakLoc    :: !SrcSpan
    
    243
    -   , breakTick   :: {-# UNPACK #-} !Int
    
    249
    +   { breakLoc    :: !SrcSpan
    
    250
    +   , breakId     :: !GHC.BreakpointId
    
    251
    +     -- ^ The 'BreakpointId' uniquely identifies a source-level breakpoint
    
    244 252
        , breakEnabled:: !Bool
    
    245 253
        , onBreakCmd  :: String
    
    246 254
        }
    
    247 255
     
    
    248 256
     instance Eq BreakLocation where
    
    249
    -  loc1 == loc2 = breakModule loc1 == breakModule loc2 &&
    
    250
    -                 breakTick loc1   == breakTick loc2
    
    257
    +  loc1 == loc2 = breakId loc1 == breakId loc2
    
    251 258
     
    
    252 259
     prettyLocations :: IntMap.IntMap BreakLocation -> SDoc
    
    253 260
     prettyLocations  locs =
    
    ... ... @@ -256,7 +263,7 @@ prettyLocations locs =
    256 263
           False -> vcat $ map (\(i, loc) -> brackets (int i) <+> ppr loc) $ IntMap.toAscList locs
    
    257 264
     
    
    258 265
     instance Outputable BreakLocation where
    
    259
    -   ppr loc = (ppr $ breakModule loc) <+> ppr (breakLoc loc) <+> pprEnaDisa <+>
    
    266
    +   ppr loc = (ppr $ GHC.bi_tick_mod $ breakId loc) <+> ppr (breakLoc loc) <+> pprEnaDisa <+>
    
    260 267
                     if null (onBreakCmd loc)
    
    261 268
                        then empty
    
    262 269
                        else doubleQuotes (text (onBreakCmd loc))
    

  • libraries/ghc-boot/Setup.hs
    ... ... @@ -10,6 +10,7 @@ import Distribution.Verbosity
    10 10
     import Distribution.Simple.Program
    
    11 11
     import Distribution.Simple.Utils
    
    12 12
     import Distribution.Simple.Setup
    
    13
    +import qualified Distribution.Simple.LocalBuildInfo as LBI
    
    13 14
     
    
    14 15
     import System.IO
    
    15 16
     import System.Directory
    
    ... ... @@ -32,12 +33,13 @@ main = defaultMainWithHooks ghcHooks
    32 33
     ghcAutogen :: Verbosity -> LocalBuildInfo -> IO ()
    
    33 34
     ghcAutogen verbosity lbi@LocalBuildInfo{..} = do
    
    34 35
       -- Get compiler/ root directory from the cabal file
    
    35
    -  let Just compilerRoot = takeDirectory <$> pkgDescrFile
    
    36
    +  let Just compilerRoot = takeDirectory . i <$> pkgDescrFile
    
    36 37
     
    
    37
    -  let platformHostFile = "GHC/Platform/Host.hs"
    
    38
    -      platformHostPath = autogenPackageModulesDir lbi </> platformHostFile
    
    38
    +      i = LBI.interpretSymbolicPathLBI lbi
    
    39
    +      platformHostFile = "GHC/Platform/Host.hs"
    
    40
    +      platformHostPath = i (autogenPackageModulesDir lbi) </> platformHostFile
    
    39 41
           ghcVersionFile = "GHC/Version.hs"
    
    40
    -      ghcVersionPath = autogenPackageModulesDir lbi </> ghcVersionFile
    
    42
    +      ghcVersionPath = i (autogenPackageModulesDir lbi) </> ghcVersionFile
    
    41 43
     
    
    42 44
       -- Get compiler settings
    
    43 45
       settings <- lookupEnv "HADRIAN_SETTINGS" >>= \case
    

  • libraries/ghc-boot/ghc-boot.cabal.in
    ... ... @@ -28,7 +28,7 @@ build-type: Custom
    28 28
     extra-source-files: changelog.md
    
    29 29
     
    
    30 30
     custom-setup
    
    31
    -    setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.14, directory, filepath
    
    31
    +    setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.16, directory, filepath
    
    32 32
     
    
    33 33
     source-repository head
    
    34 34
         type:     git
    

  • libraries/ghc-internal/src/GHC/Internal/Base.hs
    ... ... @@ -1047,7 +1047,7 @@ class Functor f where
    1047 1047
     -- * sequence computations and combine their results ('<*>' and 'liftA2').
    
    1048 1048
     --
    
    1049 1049
     -- A minimal complete definition must include implementations of 'pure'
    
    1050
    +-- and one of either '<*>' or 'liftA2'. If it defines both, then they must behave
    
    1050 1051
     -- the same as their default definitions:
    
    1051 1052
     --
    
    1052 1053
     --      @('<*>') = 'liftA2' 'id'@
    

  • libraries/ghci/GHCi/Debugger.hs
    ... ... @@ -65,10 +65,7 @@ foreign import ccall "&rts_stop_on_exception" exceptionFlag :: Ptr CInt
    65 65
     --------------------------------------------------------------------------------
    
    66 66
     
    
    67 67
     type BreakpointCallback
    
    68
    -     = Addr#   -- pointer to the breakpoint tick module name
    
    69
    -    -> Addr#   -- pointer to the breakpoint tick module unit id
    
    70
    -    -> Int#    -- breakpoint tick index
    
    71
    -    -> Addr#   -- pointer to the breakpoint info module name
    
    68
    +     = Addr#   -- pointer to the breakpoint info module name
    
    72 69
         -> Addr#   -- pointer to the breakpoint info module unit id
    
    73 70
         -> Int#    -- breakpoint info index
    
    74 71
         -> Bool    -- exception?
    

  • libraries/ghci/GHCi/Message.hs
    ... ... @@ -418,10 +418,7 @@ data EvalStatus_ a b
    418 418
     instance Binary a => Binary (EvalStatus_ a b)
    
    419 419
     
    
    420 420
     data EvalBreakpoint = EvalBreakpoint
    
    421
    -  { eb_tick_mod      :: String -- ^ Breakpoint tick module
    
    422
    -  , eb_tick_mod_unit :: BS.ShortByteString -- ^ Breakpoint tick module unit id
    
    423
    -  , eb_tick_index    :: Int    -- ^ Breakpoint tick index
    
    424
    -  , eb_info_mod      :: String -- ^ Breakpoint info module
    
    421
    +  { eb_info_mod      :: String -- ^ Breakpoint info module
    
    425 422
       , eb_info_mod_unit :: BS.ShortByteString -- ^ Breakpoint tick module unit id
    
    426 423
       , eb_info_index    :: Int    -- ^ Breakpoint info index
    
    427 424
       }
    

  • libraries/ghci/GHCi/Run.hs
    ... ... @@ -345,7 +345,7 @@ withBreakAction opts breakMVar statusMVar mtid act
    345 345
             -- as soon as it is hit, or in resetBreakAction below.
    
    346 346
     
    
    347 347
        onBreak :: BreakpointCallback
    
    348
    -   onBreak tick_mod# tick_mod_uid# tickx# info_mod# info_mod_uid# infox# is_exception apStack = do
    
    348
    +   onBreak info_mod# info_mod_uid# infox# is_exception apStack = do
    
    349 349
          tid <- myThreadId
    
    350 350
          let resume = ResumeContext
    
    351 351
                { resumeBreakMVar = breakMVar
    
    ... ... @@ -358,11 +358,9 @@ withBreakAction opts breakMVar statusMVar mtid act
    358 358
            if is_exception
    
    359 359
            then pure Nothing
    
    360 360
            else do
    
    361
    -         tick_mod <- peekCString (Ptr tick_mod#)
    
    362
    -         tick_mod_uid <- BS.packCString (Ptr tick_mod_uid#)
    
    363 361
              info_mod <- peekCString (Ptr info_mod#)
    
    364 362
              info_mod_uid <- BS.packCString (Ptr info_mod_uid#)
    
    365
    -         pure (Just (EvalBreakpoint tick_mod tick_mod_uid (I# tickx#) info_mod info_mod_uid (I# infox#)))
    
    363
    +         pure (Just (EvalBreakpoint info_mod info_mod_uid (I# infox#)))
    
    366 364
          putMVar statusMVar $ EvalBreak apStack_r breakpoint resume_r ccs
    
    367 365
          takeMVar breakMVar
    
    368 366
     
    
    ... ... @@ -409,8 +407,8 @@ noBreakStablePtr :: StablePtr BreakpointCallback
    409 407
     noBreakStablePtr = unsafePerformIO $ newStablePtr noBreakAction
    
    410 408
     
    
    411 409
     noBreakAction :: BreakpointCallback
    
    412
    -noBreakAction _ _ _ _ _ _ False _ = putStrLn "*** Ignoring breakpoint"
    
    413
    -noBreakAction _ _ _ _ _ _ True  _ = return () -- exception: just continue
    
    410
    +noBreakAction _ _ _ False _ = putStrLn "*** Ignoring breakpoint"
    
    411
    +noBreakAction _ _ _ True  _ = return () -- exception: just continue
    
    414 412
     
    
    415 413
     -- Malloc and copy the bytes.  We don't have any way to monitor the
    
    416 414
     -- lifetime of this memory, so it just leaks.
    

  • rts/Disassembler.c
    ... ... @@ -84,16 +84,25 @@ disInstr ( StgBCO *bco, int pc )
    84 84
     
    
    85 85
     
    
    86 86
        switch (instr & 0xff) {
    
    87
    -      case bci_BRK_FUN:
    
    88
    -         debugBelch ("BRK_FUN  " );  printPtr( ptrs[instrs[pc]] );
    
    89
    -         debugBelch (" %d ", instrs[pc+1]); printPtr( ptrs[instrs[pc+2]] );
    
    90
    -         CostCentre* cc = (CostCentre*)literals[instrs[pc+5]];
    
    87
    +      case bci_BRK_FUN: {
    
    88
    +         W_ p1, info_mod, info_unit_id, info_wix, byte_off, np;
    
    89
    +         p1           = BCO_GET_LARGE_ARG;
    
    90
    +         info_mod     = BCO_GET_LARGE_ARG;
    
    91
    +         info_unit_id = BCO_GET_LARGE_ARG;
    
    92
    +         info_wix     = BCO_NEXT;
    
    93
    +         byte_off     = BCO_NEXT;
    
    94
    +         np           = BCO_GET_LARGE_ARG;
    
    95
    +         debugBelch ("BRK_FUN " );  printPtr( ptrs[p1] );
    
    96
    +         debugBelch(" %" FMT_Word, literals[info_mod] );
    
    97
    +         debugBelch(" %" FMT_Word, literals[info_unit_id] );
    
    98
    +         debugBelch(" %" FMT_Word, info_wix );
    
    99
    +         debugBelch(" %" FMT_Word, byte_off );
    
    100
    +         CostCentre* cc = (CostCentre*)literals[np];
    
    91 101
              if (cc) {
    
    92 102
                debugBelch(" %s", cc->label);
    
    93 103
              }
    
    94 104
              debugBelch("\n");
    
    95
    -         pc += 6;
    
    96
    -         break;
    
    105
    +         break; }
    
    97 106
           case bci_BRK_ALTS:
    
    98 107
              debugBelch ("BRK_ALTS %d\n", BCO_NEXT);
    
    99 108
              break;
    

  • rts/Exception.cmm
    ... ... @@ -535,23 +535,17 @@ retry_pop_stack:
    535 535
                 // be per-thread.
    
    536 536
                 CInt[rts_stop_on_exception] = 0;
    
    537 537
                 ("ptr" ioAction) = ccall deRefStablePtr (W_[rts_breakpoint_io_action] "ptr");
    
    538
    -            Sp = Sp - WDS(17);
    
    539
    -            Sp(16) = exception;
    
    540
    -            Sp(15) = stg_raise_ret_info;
    
    541
    -            Sp(14) = exception;
    
    542
    -            Sp(13) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
    
    543
    -            Sp(12) = stg_ap_ppv_info;
    
    544
    -            Sp(11) = 0;
    
    545
    -            Sp(10) = stg_ap_n_info;
    
    546
    -            Sp(9)  = 0;
    
    547
    -            Sp(8)  = stg_ap_n_info;
    
    548
    -            Sp(7)  = 0;
    
    549
    -            Sp(6)  = stg_ap_n_info;
    
    550
    -            Sp(5)  = 0;
    
    551
    -            Sp(4)  = stg_ap_n_info;
    
    552
    -            Sp(3)  = 0;
    
    553
    -            Sp(2)  = stg_ap_n_info;
    
    554
    -            Sp(1)  = 0;
    
    538
    +            Sp = Sp - WDS(11);
    
    539
    +            Sp(10) = exception;
    
    540
    +            Sp(9) = stg_raise_ret_info;
    
    541
    +            Sp(8) = exception;
    
    542
    +            Sp(7) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
    
    543
    +            Sp(6) = stg_ap_ppv_info;
    
    544
    +            Sp(5) = 0;
    
    545
    +            Sp(4) = stg_ap_n_info;
    
    546
    +            Sp(3) = 0;
    
    547
    +            Sp(2) = stg_ap_n_info;
    
    548
    +            Sp(1) = 0;
    
    555 549
                 R1 = ioAction;
    
    556 550
                 jump RET_LBL(stg_ap_n) [R1];
    
    557 551
             }
    

  • rts/Interpreter.c
    ... ... @@ -207,6 +207,19 @@ See also Note [Width of parameters] for some more motivation.
    207 207
     // Perhaps confusingly this still reads a full word, merely the offset is in bytes.
    
    208 208
     #define ReadSpB(n)       (*((StgWord*)   SafeSpBP(n)))
    
    209 209
     
    
    210
    +/*
    
    211
    + * SLIDE "n" words "by" words
    
    212
    + * a_1 ... a_n, b_1 ... b_by, k
    
    213
    + *           =>
    
    214
    + * a_1 ... a_n, k
    
    215
    + */
    
    216
    +#define SpSlide(n, by)          \
    
    217
    +    while(n-- > 0) {            \
    
    218
    +        SpW(n+by) = ReadSpW(n); \
    
    219
    +    }                           \
    
    220
    +    Sp_addW(by);                \
    
    221
    +
    
    222
    +
    
    210 223
     /* Note [PUSH_L underflow]
    
    211 224
        ~~~~~~~~~~~~~~~~~~~~~~~
    
    212 225
     BCOs can be nested, resulting in nested BCO stack frames where the inner most
    
    ... ... @@ -284,6 +297,19 @@ allocate_NONUPD (Capability *cap, int n_words)
    284 297
         return allocate(cap, stg_max(sizeofW(StgHeader)+MIN_PAYLOAD_SIZE, n_words));
    
    285 298
     }
    
    286 299
     
    
    300
    +STATIC_INLINE int
    
    301
    +is_ctoi_nontuple_frame(const StgClosure* frame) {
    
    302
    +  const StgInfoTable* info = frame->header.info;
    
    303
    +  return (
    
    304
    +      (W_)info == (W_)&stg_ctoi_R1p_info ||
    
    305
    +      (W_)info == (W_)&stg_ctoi_R1n_info ||
    
    306
    +      (W_)info == (W_)&stg_ctoi_F1_info ||
    
    307
    +      (W_)info == (W_)&stg_ctoi_D1_info ||
    
    308
    +      (W_)info == (W_)&stg_ctoi_L1_info ||
    
    309
    +      (W_)info == (W_)&stg_ctoi_V_info
    
    310
    +    );
    
    311
    +}
    
    312
    +
    
    287 313
     int rts_stop_on_exception = 0;
    
    288 314
     
    
    289 315
     /* ---------------------------------------------------------------------------
    
    ... ... @@ -473,6 +499,72 @@ void interp_shutdown( void ){
    473 499
     
    
    474 500
     #endif
    
    475 501
     
    
    502
    +const StgPtr ctoi_tuple_infos[] = {
    
    503
    +    (StgPtr) &stg_ctoi_t0_info,
    
    504
    +    (StgPtr) &stg_ctoi_t1_info,
    
    505
    +    (StgPtr) &stg_ctoi_t2_info,
    
    506
    +    (StgPtr) &stg_ctoi_t3_info,
    
    507
    +    (StgPtr) &stg_ctoi_t4_info,
    
    508
    +    (StgPtr) &stg_ctoi_t5_info,
    
    509
    +    (StgPtr) &stg_ctoi_t6_info,
    
    510
    +    (StgPtr) &stg_ctoi_t7_info,
    
    511
    +    (StgPtr) &stg_ctoi_t8_info,
    
    512
    +    (StgPtr) &stg_ctoi_t9_info,
    
    513
    +    (StgPtr) &stg_ctoi_t10_info,
    
    514
    +    (StgPtr) &stg_ctoi_t11_info,
    
    515
    +    (StgPtr) &stg_ctoi_t12_info,
    
    516
    +    (StgPtr) &stg_ctoi_t13_info,
    
    517
    +    (StgPtr) &stg_ctoi_t14_info,
    
    518
    +    (StgPtr) &stg_ctoi_t15_info,
    
    519
    +    (StgPtr) &stg_ctoi_t16_info,
    
    520
    +    (StgPtr) &stg_ctoi_t17_info,
    
    521
    +    (StgPtr) &stg_ctoi_t18_info,
    
    522
    +    (StgPtr) &stg_ctoi_t19_info,
    
    523
    +    (StgPtr) &stg_ctoi_t20_info,
    
    524
    +    (StgPtr) &stg_ctoi_t21_info,
    
    525
    +    (StgPtr) &stg_ctoi_t22_info,
    
    526
    +    (StgPtr) &stg_ctoi_t23_info,
    
    527
    +    (StgPtr) &stg_ctoi_t24_info,
    
    528
    +    (StgPtr) &stg_ctoi_t25_info,
    
    529
    +    (StgPtr) &stg_ctoi_t26_info,
    
    530
    +    (StgPtr) &stg_ctoi_t27_info,
    
    531
    +    (StgPtr) &stg_ctoi_t28_info,
    
    532
    +    (StgPtr) &stg_ctoi_t29_info,
    
    533
    +    (StgPtr) &stg_ctoi_t30_info,
    
    534
    +    (StgPtr) &stg_ctoi_t31_info,
    
    535
    +    (StgPtr) &stg_ctoi_t32_info,
    
    536
    +    (StgPtr) &stg_ctoi_t33_info,
    
    537
    +    (StgPtr) &stg_ctoi_t34_info,
    
    538
    +    (StgPtr) &stg_ctoi_t35_info,
    
    539
    +    (StgPtr) &stg_ctoi_t36_info,
    
    540
    +    (StgPtr) &stg_ctoi_t37_info,
    
    541
    +    (StgPtr) &stg_ctoi_t38_info,
    
    542
    +    (StgPtr) &stg_ctoi_t39_info,
    
    543
    +    (StgPtr) &stg_ctoi_t40_info,
    
    544
    +    (StgPtr) &stg_ctoi_t41_info,
    
    545
    +    (StgPtr) &stg_ctoi_t42_info,
    
    546
    +    (StgPtr) &stg_ctoi_t43_info,
    
    547
    +    (StgPtr) &stg_ctoi_t44_info,
    
    548
    +    (StgPtr) &stg_ctoi_t45_info,
    
    549
    +    (StgPtr) &stg_ctoi_t46_info,
    
    550
    +    (StgPtr) &stg_ctoi_t47_info,
    
    551
    +    (StgPtr) &stg_ctoi_t48_info,
    
    552
    +    (StgPtr) &stg_ctoi_t49_info,
    
    553
    +    (StgPtr) &stg_ctoi_t50_info,
    
    554
    +    (StgPtr) &stg_ctoi_t51_info,
    
    555
    +    (StgPtr) &stg_ctoi_t52_info,
    
    556
    +    (StgPtr) &stg_ctoi_t53_info,
    
    557
    +    (StgPtr) &stg_ctoi_t54_info,
    
    558
    +    (StgPtr) &stg_ctoi_t55_info,
    
    559
    +    (StgPtr) &stg_ctoi_t56_info,
    
    560
    +    (StgPtr) &stg_ctoi_t57_info,
    
    561
    +    (StgPtr) &stg_ctoi_t58_info,
    
    562
    +    (StgPtr) &stg_ctoi_t59_info,
    
    563
    +    (StgPtr) &stg_ctoi_t60_info,
    
    564
    +    (StgPtr) &stg_ctoi_t61_info,
    
    565
    +    (StgPtr) &stg_ctoi_t62_info,
    
    566
    +};
    
    567
    +
    
    476 568
     #if defined(PROFILING)
    
    477 569
     
    
    478 570
     //
    
    ... ... @@ -619,8 +711,6 @@ interpretBCO (Capability* cap)
    619 711
          */
    
    620 712
         if (cap->r.rCurrentTSO->flags & TSO_STOP_AFTER_RETURN) {
    
    621 713
     
    
    622
    -      StgBCO* bco;
    
    623
    -      StgWord16* bco_instrs;
    
    624 714
           StgHalfWord type;
    
    625 715
     
    
    626 716
           /* Store the entry Sp; traverse the stack modifying Sp (using Sp macros);
    
    ... ... @@ -640,28 +730,34 @@ interpretBCO (Capability* cap)
    640 730
           ASSERT(type == RET_BCO || type == STOP_FRAME);
    
    641 731
           if (type == RET_BCO) {
    
    642 732
     
    
    643
    -        bco = (StgBCO*)(SpW(1)); // BCO is first arg of a RET_BCO
    
    733
    +        StgBCO* bco = (StgBCO*)(SpW(1)); // BCO is first arg of a RET_BCO
    
    644 734
             ASSERT(get_itbl((StgClosure*)bco)->type == BCO);
    
    645
    -        bco_instrs = (StgWord16*)(bco->instrs->payload);
    
    735
    +
    
    736
    +        StgWord16* instrs = (StgWord16*)(bco->instrs->payload);
    
    737
    +        StgWord16 bci = instrs[0];
    
    646 738
     
    
    647 739
             /* A breakpoint instruction (BRK_FUN or BRK_ALTS) is always the first
    
    648 740
              * instruction in a BCO */
    
    649
    -        if ((bco_instrs[0] & 0xFF) == bci_BRK_FUN) {
    
    650
    -            int brk_array, tick_index;
    
    651
    -            StgArrBytes *breakPoints;
    
    652
    -            StgPtr* ptrs;
    
    741
    +        if ((bci & 0xFF) == bci_BRK_FUN) {
    
    742
    +            // Define rest of variables used by BCO_* Macros
    
    743
    +            int bciPtr = 0;
    
    653 744
     
    
    654
    -            ptrs = (StgPtr*)(&bco->ptrs->payload[0]);
    
    655
    -            brk_array  = bco_instrs[1];
    
    656
    -            tick_index = bco_instrs[6];
    
    745
    +            W_ arg1_brk_array, arg4_info_index;
    
    746
    +            arg1_brk_array      = BCO_GET_LARGE_ARG;
    
    747
    +            /* info_mod_name = */ BCO_GET_LARGE_ARG;
    
    748
    +            /* info_mod_id   = */ BCO_GET_LARGE_ARG;
    
    749
    +            arg4_info_index     = BCO_NEXT;
    
    750
    +            /* byte_off      = BCO_NEXT; */
    
    751
    +
    
    752
    +            StgPtr* ptrs = (StgPtr*)(&bco->ptrs->payload[0]);
    
    753
    +            StgArrBytes* breakPoints = (StgArrBytes *) BCO_PTR(arg1_brk_array);
    
    657 754
     
    
    658
    -            breakPoints = (StgArrBytes *) BCO_PTR(brk_array);
    
    659 755
                 // ACTIVATE the breakpoint by tick index
    
    660
    -            ((StgInt*)breakPoints->payload)[tick_index] = 0;
    
    756
    +            ((StgInt*)breakPoints->payload)[arg4_info_index] = 0;
    
    661 757
             }
    
    662
    -        else if ((bco_instrs[0] & 0xFF) == bci_BRK_ALTS) {
    
    758
    +        else if ((bci & 0xFF) == bci_BRK_ALTS) {
    
    663 759
                 // ACTIVATE BRK_ALTS by setting its only argument to ON
    
    664
    -            bco_instrs[1] = 1;
    
    760
    +            instrs[1] = 1;
    
    665 761
             }
    
    666 762
             // else: if there is no BRK instruction perhaps we should keep
    
    667 763
             // traversing; that said, the continuation should always have a BRK
    
    ... ... @@ -776,7 +872,6 @@ eval_obj:
    776 872
                  debugBelch("\n\n");
    
    777 873
                 );
    
    778 874
     
    
    779
    -//    IF_DEBUG(sanity,checkStackChunk(Sp, cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size));
    
    780 875
         IF_DEBUG(sanity,checkStackFrame(Sp));
    
    781 876
     
    
    782 877
         switch ( get_itbl(obj)->type ) {
    
    ... ... @@ -1018,11 +1113,36 @@ do_return_pointer:
    1018 1113
             // Returning to an interpreted continuation: put the object on
    
    1019 1114
             // the stack, and start executing the BCO.
    
    1020 1115
             INTERP_TICK(it_retto_BCO);
    
    1021
    -        Sp_subW(1);
    
    1022
    -        SpW(0) = (W_)tagged_obj;
    
    1023
    -        obj = (StgClosure*)ReadSpW(2);
    
    1116
    +        obj = (StgClosure*)ReadSpW(1);
    
    1024 1117
             ASSERT(get_itbl(obj)->type == BCO);
    
    1025
    -        goto run_BCO_return_pointer;
    
    1118
    +
    
    1119
    +        // Heap check
    
    1120
    +        if (doYouWantToGC(cap)) {
    
    1121
    +            Sp_subW(2);
    
    1122
    +            SpW(1) = (W_)tagged_obj;
    
    1123
    +            SpW(0) = (W_)&stg_ret_p_info;
    
    1124
    +            RETURN_TO_SCHEDULER(ThreadInterpret, HeapOverflow);
    
    1125
    +        }
    
    1126
    +        else {
    
    1127
    +
    
    1128
    +          // Stack checks aren't necessary at return points, the stack use
    
    1129
    +          // is aggregated into the enclosing function entry point.
    
    1130
    +
    
    1131
    +          // Make sure to drop the RET_BCO frame header,
    
    1132
    +          // but not its arguments (which are expected at the top when running the BCO).
    
    1133
    +          // NOTE: Always a return_pointer (ie not a tuple ctoi frame!)
    
    1134
    +
    
    1135
    +          // Make sure stack is headed by a ctoi nontuple frame then drop it.
    
    1136
    +          // The arguments to the BCO continuation stay on top of the stack
    
    1137
    +          ASSERT(is_ctoi_nontuple_frame(Sp));
    
    1138
    +          Sp_addW(2);
    
    1139
    +
    
    1140
    +          // Plus the return value on top of the args
    
    1141
    +          Sp_subW(1);
    
    1142
    +          SpW(0) = (W_)tagged_obj;
    
    1143
    +        }
    
    1144
    +
    
    1145
    +        goto run_BCO;
    
    1026 1146
     
    
    1027 1147
         default:
    
    1028 1148
         do_return_unrecognised:
    
    ... ... @@ -1091,8 +1211,9 @@ do_return_nonpointer:
    1091 1211
     
    
    1092 1212
             // get the offset of the header of the next stack frame
    
    1093 1213
             offset = stack_frame_sizeW((StgClosure *)Sp);
    
    1214
    +        StgClosure* next_frame = (StgClosure*)(SafeSpWP(offset));
    
    1094 1215
     
    
    1095
    -        switch (get_itbl((StgClosure*)(SafeSpWP(offset)))->type) {
    
    1216
    +        switch (get_itbl(next_frame)->type) {
    
    1096 1217
     
    
    1097 1218
             case RET_BCO:
    
    1098 1219
                 // Returning to an interpreted continuation: pop the return frame
    
    ... ... @@ -1100,8 +1221,72 @@ do_return_nonpointer:
    1100 1221
                 // executing the BCO.
    
    1101 1222
                 INTERP_TICK(it_retto_BCO);
    
    1102 1223
                 obj = (StgClosure*)ReadSpW(offset+1);
    
    1224
    +
    
    1103 1225
                 ASSERT(get_itbl(obj)->type == BCO);
    
    1104
    -            goto run_BCO_return_nonpointer;
    
    1226
    +
    
    1227
    +            // Heap check
    
    1228
    +            if (doYouWantToGC(cap)) {
    
    1229
    +                RETURN_TO_SCHEDULER(ThreadInterpret, HeapOverflow);
    
    1230
    +            }
    
    1231
    +            else {
    
    1232
    +              // Stack checks aren't necessary at return points, the stack use
    
    1233
    +              // is aggregated into the enclosing function entry point.
    
    1234
    +
    
    1235
    +#if defined(PROFILING)
    
    1236
    +              /*
    
    1237
    +                 Restore the current cost centre stack if a tuple is being returned.
    
    1238
    +
    
    1239
    +                 When a "simple" unlifted value is returned, the cccs is restored with
    
    1240
    +                 an stg_restore_cccs frame on the stack, for example:
    
    1241
    +
    
    1242
    +                     ...
    
    1243
    +                     stg_ctoi_D1
    
    1244
    +                     <CCCS>
    
    1245
    +                     stg_restore_cccs
    
    1246
    +
    
    1247
    +                 But stg_restore_cccs cannot deal with tuples, which may have more
    
    1248
    +                 things on the stack. Therefore we store the CCCS inside the
    
    1249
    +                 stg_ctoi_t frame.
    
    1250
    +
    
    1251
    +                 If we have a tuple being returned, the stack looks like this:
    
    1252
    +
    
    1253
    +                     ...
    
    1254
    +                     <CCCS>           <- to restore, Sp offset <next frame + 4 words>
    
    1255
    +                     tuple_BCO
    
    1256
    +                     tuple_info
    
    1257
    +                     cont_BCO
    
    1258
    +                     stg_ctoi_t       <- next frame
    
    1259
    +                     tuple_data_1
    
    1260
    +                     ...
    
    1261
    +                     tuple_data_n
    
    1262
    +                     tuple_info
    
    1263
    +                     tuple_BCO
    
    1264
    +                     stg_ret_t        <- Sp
    
    1265
    +               */
    
    1266
    +
    
    1267
    +              if(SpW(0) == (W_)&stg_ret_t_info) {
    
    1268
    +                  cap->r.rCCCS = (CostCentreStack*)ReadSpW(stack_frame_sizeW((StgClosure *)Sp) + 4);
    
    1269
    +              }
    
    1270
    +#endif
    
    1271
    +              /* Drop the RET_BCO header (next_frame),
    
    1272
    +               * but not its arguments (which are expected at the top when running the BCO)
    
    1273
    +               */
    
    1274
    +              W_ n  = offset;
    
    1275
    +              W_ by = is_ctoi_nontuple_frame(next_frame)
    
    1276
    +                          ? 2 // info+bco
    
    1277
    +#if defined(PROFILING)
    
    1278
    +                          : 5;  // or info+bco+tuple_info+tuple_BCO+CCS
    
    1279
    +#else
    
    1280
    +                          : 4;  // or info+bco+tuple_info+tuple_BCO
    
    1281
    +#endif
    
    1282
    +              SpSlide(n, by);
    
    1283
    +
    
    1284
    +              if (SpW(0) != (W_)&stg_ret_t_info) {
    
    1285
    +                Sp_addW(1);
    
    1286
    +              }
    
    1287
    +
    
    1288
    +              goto run_BCO;
    
    1289
    +            }
    
    1105 1290
     
    
    1106 1291
             default:
    
    1107 1292
             {
    
    ... ... @@ -1268,8 +1453,8 @@ do_apply:
    1268 1453
         // Ok, we now have a bco (obj), and its arguments are all on the
    
    1269 1454
         // stack.  We can start executing the byte codes.
    
    1270 1455
         //
    
    1271
    -    // The stack is in one of two states.  First, if this BCO is a
    
    1272
    -    // function:
    
    1456
    +    // The stack is in one of two states. First, if this BCO is a
    
    1457
    +    // function
    
    1273 1458
         //
    
    1274 1459
         //    |     ....      |
    
    1275 1460
         //    +---------------+
    
    ... ... @@ -1286,10 +1471,6 @@ do_apply:
    1286 1471
         //    +---------------+
    
    1287 1472
         //    |     fv1       |
    
    1288 1473
         //    +---------------+
    
    1289
    -    //    |     BCO       |
    
    1290
    -    //    +---------------+
    
    1291
    -    //    | stg_ctoi_ret_ |
    
    1292
    -    //    +---------------+
    
    1293 1474
         //    |    retval     |
    
    1294 1475
         //    +---------------+
    
    1295 1476
         //
    
    ... ... @@ -1307,68 +1488,6 @@ do_apply:
    1307 1488
         // Sadly we have three different kinds of stack/heap/cswitch check
    
    1308 1489
         // to do:
    
    1309 1490
     
    
    1310
    -
    
    1311
    -run_BCO_return_pointer:
    
    1312
    -    // Heap check
    
    1313
    -    if (doYouWantToGC(cap)) {
    
    1314
    -        Sp_subW(1); SpW(0) = (W_)&stg_ret_p_info;
    
    1315
    -        RETURN_TO_SCHEDULER(ThreadInterpret, HeapOverflow);
    
    1316
    -    }
    
    1317
    -    // Stack checks aren't necessary at return points, the stack use
    
    1318
    -    // is aggregated into the enclosing function entry point.
    
    1319
    -
    
    1320
    -    goto run_BCO;
    
    1321
    -
    
    1322
    -run_BCO_return_nonpointer:
    
    1323
    -    // Heap check
    
    1324
    -    if (doYouWantToGC(cap)) {
    
    1325
    -        RETURN_TO_SCHEDULER(ThreadInterpret, HeapOverflow);
    
    1326
    -    }
    
    1327
    -    // Stack checks aren't necessary at return points, the stack use
    
    1328
    -    // is aggregated into the enclosing function entry point.
    
    1329
    -
    
    1330
    -#if defined(PROFILING)
    
    1331
    -    /*
    
    1332
    -       Restore the current cost centre stack if a tuple is being returned.
    
    1333
    -
    
    1334
    -       When a "simple" unlifted value is returned, the cccs is restored with
    
    1335
    -       an stg_restore_cccs frame on the stack, for example:
    
    1336
    -
    
    1337
    -           ...
    
    1338
    -           stg_ctoi_D1
    
    1339
    -           <CCCS>
    
    1340
    -           stg_restore_cccs
    
    1341
    -
    
    1342
    -       But stg_restore_cccs cannot deal with tuples, which may have more
    
    1343
    -       things on the stack. Therefore we store the CCCS inside the
    
    1344
    -       stg_ctoi_t frame.
    
    1345
    -
    
    1346
    -       If we have a tuple being returned, the stack looks like this:
    
    1347
    -
    
    1348
    -           ...
    
    1349
    -           <CCCS>           <- to restore, Sp offset <next frame + 4 words>
    
    1350
    -           tuple_BCO
    
    1351
    -           tuple_info
    
    1352
    -           cont_BCO
    
    1353
    -           stg_ctoi_t       <- next frame
    
    1354
    -           tuple_data_1
    
    1355
    -           ...
    
    1356
    -           tuple_data_n
    
    1357
    -           tuple_info
    
    1358
    -           tuple_BCO
    
    1359
    -           stg_ret_t        <- Sp
    
    1360
    -     */
    
    1361
    -
    
    1362
    -    if(SpW(0) == (W_)&stg_ret_t_info) {
    
    1363
    -        cap->r.rCCCS = (CostCentreStack*)ReadSpW(stack_frame_sizeW((StgClosure *)Sp) + 4);
    
    1364
    -    }
    
    1365
    -#endif
    
    1366
    -
    
    1367
    -    if (SpW(0) != (W_)&stg_ret_t_info) {
    
    1368
    -      Sp_addW(1);
    
    1369
    -    }
    
    1370
    -    goto run_BCO;
    
    1371
    -
    
    1372 1491
     run_BCO_fun:
    
    1373 1492
         IF_DEBUG(sanity,
    
    1374 1493
                  Sp_subW(2);
    
    ... ... @@ -1454,9 +1573,9 @@ run_BCO:
    1454 1573
             /* check for a breakpoint on the beginning of a let binding */
    
    1455 1574
             case bci_BRK_FUN:
    
    1456 1575
             {
    
    1457
    -            int arg1_brk_array, arg2_tick_mod, arg3_info_mod, arg4_tick_mod_id, arg5_info_mod_id, arg6_tick_index, arg7_info_index;
    
    1576
    +            W_ arg1_brk_array, arg2_info_mod_name, arg3_info_mod_id, arg4_info_index, arg5_byte_off;
    
    1458 1577
     #if defined(PROFILING)
    
    1459
    -            int arg8_cc;
    
    1578
    +            W_ arg6_cc;
    
    1460 1579
     #endif
    
    1461 1580
                 StgArrBytes *breakPoints;
    
    1462 1581
                 int returning_from_break, stop_next_breakpoint;
    
    ... ... @@ -1471,14 +1590,12 @@ run_BCO:
    1471 1590
                 int size_words;
    
    1472 1591
     
    
    1473 1592
                 arg1_brk_array      = BCO_GET_LARGE_ARG;
    
    1474
    -            arg2_tick_mod       = BCO_GET_LARGE_ARG;
    
    1475
    -            arg3_info_mod       = BCO_GET_LARGE_ARG;
    
    1476
    -            arg4_tick_mod_id    = BCO_GET_LARGE_ARG;
    
    1477
    -            arg5_info_mod_id    = BCO_GET_LARGE_ARG;
    
    1478
    -            arg6_tick_index     = BCO_NEXT;
    
    1479
    -            arg7_info_index     = BCO_NEXT;
    
    1593
    +            arg2_info_mod_name  = BCO_GET_LARGE_ARG;
    
    1594
    +            arg3_info_mod_id    = BCO_GET_LARGE_ARG;
    
    1595
    +            arg4_info_index     = BCO_NEXT;
    
    1596
    +            arg5_byte_off       = BCO_NEXT;
    
    1480 1597
     #if defined(PROFILING)
    
    1481
    -            arg8_cc             = BCO_GET_LARGE_ARG;
    
    1598
    +            arg6_cc             = BCO_GET_LARGE_ARG;
    
    1482 1599
     #else
    
    1483 1600
                 BCO_GET_LARGE_ARG;
    
    1484 1601
     #endif
    
    ... ... @@ -1498,7 +1615,7 @@ run_BCO:
    1498 1615
     
    
    1499 1616
     #if defined(PROFILING)
    
    1500 1617
                 cap->r.rCCCS = pushCostCentre(cap->r.rCCCS,
    
    1501
    -                                          (CostCentre*)BCO_LIT(arg8_cc));
    
    1618
    +                                          (CostCentre*)BCO_LIT(arg6_cc));
    
    1502 1619
     #endif
    
    1503 1620
     
    
    1504 1621
                 // if we are returning from a break then skip this section
    
    ... ... @@ -1509,11 +1626,11 @@ run_BCO:
    1509 1626
     
    
    1510 1627
                    // stop the current thread if either `stop_next_breakpoint` is
    
    1511 1628
                    // true OR if the ignore count for this particular breakpoint is zero
    
    1512
    -               StgInt ignore_count = ((StgInt*)breakPoints->payload)[arg6_tick_index];
    
    1629
    +               StgInt ignore_count = ((StgInt*)breakPoints->payload)[arg4_info_index];
    
    1513 1630
                    if (stop_next_breakpoint == false && ignore_count > 0)
    
    1514 1631
                    {
    
    1515 1632
                       // decrement and write back ignore count
    
    1516
    -                  ((StgInt*)breakPoints->payload)[arg6_tick_index] = --ignore_count;
    
    1633
    +                  ((StgInt*)breakPoints->payload)[arg4_info_index] = --ignore_count;
    
    1517 1634
                    }
    
    1518 1635
                    else if (stop_next_breakpoint == true || ignore_count == 0)
    
    1519 1636
                    {
    
    ... ... @@ -1538,7 +1655,12 @@ run_BCO:
    1538 1655
                       // copy the contents of the top stack frame into the AP_STACK
    
    1539 1656
                       for (i = 2; i < size_words; i++)
    
    1540 1657
                       {
    
    1541
    -                     new_aps->payload[i] = (StgClosure *)ReadSpW(i-2);
    
    1658
    +                     // BAD ASSUMPTION: BITMAP Vars are on top of the stack.
    
    1659
    +                     // THEY ARE NOT FOR PUSH_ALTS:
    
    1660
    +                     //   THE FIRST THING ON THE STACK IS GOING TO BE
    
    1661
    +                     //       ctoi_***
    
    1662
    +                     //TODO UPDATE DOCUMENTATION EXPLANING ARG5_BYTE_OFF
    
    1663
    +                     new_aps->payload[i] = (StgClosure *)ReadSpB(((ptrdiff_t)(i-2) * (ptrdiff_t)sizeof(W_)) + arg5_byte_off);
    
    1542 1664
                       }
    
    1543 1665
     
    
    1544 1666
                       // No write barrier is needed here as this is a new allocation
    
    ... ... @@ -1547,10 +1669,7 @@ run_BCO:
    1547 1669
                       // Arrange the stack to call the breakpoint IO action, and
    
    1548 1670
                       // continue execution of this BCO when the IO action returns.
    
    1549 1671
                       //
    
    1550
    -                  // ioAction :: Addr#       -- the breakpoint tick module
    
    1551
    -                  //          -> Addr#       -- the breakpoint tick module unit id
    
    1552
    -                  //          -> Int#        -- the breakpoint tick index
    
    1553
    -                  //          -> Addr#       -- the breakpoint info module
    
    1672
    +                  // ioAction :: Addr#       -- the breakpoint info module
    
    1554 1673
                       //          -> Addr#       -- the breakpoint info module unit id
    
    1555 1674
                       //          -> Int#        -- the breakpoint info index
    
    1556 1675
                       //          -> Bool        -- exception?
    
    ... ... @@ -1560,23 +1679,17 @@ run_BCO:
    1560 1679
                       ioAction = (StgClosure *) deRefStablePtr (
    
    1561 1680
                           rts_breakpoint_io_action);
    
    1562 1681
     
    
    1563
    -                  Sp_subW(19);
    
    1564
    -                  SpW(18) = (W_)obj;
    
    1565
    -                  SpW(17) = (W_)&stg_apply_interp_info;
    
    1566
    -                  SpW(16) = (W_)new_aps;
    
    1567
    -                  SpW(15) = (W_)False_closure;         // True <=> an exception
    
    1568
    -                  SpW(14) = (W_)&stg_ap_ppv_info;
    
    1569
    -                  SpW(13)  = (W_)arg7_info_index;
    
    1570
    -                  SpW(12)  = (W_)&stg_ap_n_info;
    
    1571
    -                  SpW(11)  = (W_)BCO_LIT(arg5_info_mod_id);
    
    1572
    -                  SpW(10)  = (W_)&stg_ap_n_info;
    
    1573
    -                  SpW(9)  = (W_)BCO_LIT(arg3_info_mod);
    
    1574
    -                  SpW(8)  = (W_)&stg_ap_n_info;
    
    1575
    -                  SpW(7)  = (W_)arg6_tick_index;
    
    1682
    +                  Sp_subW(13);
    
    1683
    +                  SpW(12) = (W_)obj;
    
    1684
    +                  SpW(11) = (W_)&stg_apply_interp_info;
    
    1685
    +                  SpW(10) = (W_)new_aps;
    
    1686
    +                  SpW(9) = (W_)False_closure;         // True <=> an exception
    
    1687
    +                  SpW(8) = (W_)&stg_ap_ppv_info;
    
    1688
    +                  SpW(7)  = (W_)arg4_info_index;
    
    1576 1689
                       SpW(6)  = (W_)&stg_ap_n_info;
    
    1577
    -                  SpW(5)  = (W_)BCO_LIT(arg4_tick_mod_id);
    
    1690
    +                  SpW(5)  = (W_)BCO_LIT(arg3_info_mod_id);
    
    1578 1691
                       SpW(4)  = (W_)&stg_ap_n_info;
    
    1579
    -                  SpW(3)  = (W_)BCO_LIT(arg2_tick_mod);
    
    1692
    +                  SpW(3)  = (W_)BCO_LIT(arg2_info_mod_name);
    
    1580 1693
                       SpW(2)  = (W_)&stg_ap_n_info;
    
    1581 1694
                       SpW(1)  = (W_)ioAction;
    
    1582 1695
                       SpW(0)  = (W_)&stg_enter_info;
    
    ... ... @@ -1742,6 +1855,10 @@ run_BCO:
    1742 1855
                 Sp_subW(2);
    
    1743 1856
                 SpW(1) = BCO_PTR(o_bco);
    
    1744 1857
                 SpW(0) = (W_)&stg_ctoi_R1p_info;
    
    1858
    +
    
    1859
    +            // The o_bco expects its arguments (as per the BCO_BITMAP_SIZE) to
    
    1860
    +            // be found on the stack before it.
    
    1861
    +            IF_DEBUG(sanity, checkStackChunk(Sp, cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size););
    
    1745 1862
     #if defined(PROFILING)
    
    1746 1863
                 Sp_subW(2);
    
    1747 1864
                 SpW(1) = (W_)cap->r.rCCCS;
    
    ... ... @@ -1755,6 +1872,8 @@ run_BCO:
    1755 1872
                 SpW(-2) = (W_)&stg_ctoi_R1n_info;
    
    1756 1873
                 SpW(-1) = BCO_PTR(o_bco);
    
    1757 1874
                 Sp_subW(2);
    
    1875
    +
    
    1876
    +            IF_DEBUG(sanity, checkStackChunk(Sp, cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size););
    
    1758 1877
     #if defined(PROFILING)
    
    1759 1878
                 Sp_subW(2);
    
    1760 1879
                 SpW(1) = (W_)cap->r.rCCCS;
    
    ... ... @@ -1768,6 +1887,8 @@ run_BCO:
    1768 1887
                 SpW(-2) = (W_)&stg_ctoi_F1_info;
    
    1769 1888
                 SpW(-1) = BCO_PTR(o_bco);
    
    1770 1889
                 Sp_subW(2);
    
    1890
    +
    
    1891
    +            IF_DEBUG(sanity, checkStackChunk(Sp, cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size););
    
    1771 1892
     #if defined(PROFILING)
    
    1772 1893
                 Sp_subW(2);
    
    1773 1894
                 SpW(1) = (W_)cap->r.rCCCS;
    
    ... ... @@ -1781,6 +1902,8 @@ run_BCO:
    1781 1902
                 SpW(-2) = (W_)&stg_ctoi_D1_info;
    
    1782 1903
                 SpW(-1) = BCO_PTR(o_bco);
    
    1783 1904
                 Sp_subW(2);
    
    1905
    +
    
    1906
    +            IF_DEBUG(sanity, checkStackChunk(Sp, cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size););
    
    1784 1907
     #if defined(PROFILING)
    
    1785 1908
                 Sp_subW(2);
    
    1786 1909
                 SpW(1) = (W_)cap->r.rCCCS;
    
    ... ... @@ -1794,6 +1917,8 @@ run_BCO:
    1794 1917
                 SpW(-2) = (W_)&stg_ctoi_L1_info;
    
    1795 1918
                 SpW(-1) = BCO_PTR(o_bco);
    
    1796 1919
                 Sp_subW(2);
    
    1920
    +
    
    1921
    +            IF_DEBUG(sanity, checkStackChunk(Sp, cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size););
    
    1797 1922
     #if defined(PROFILING)
    
    1798 1923
                 Sp_subW(2);
    
    1799 1924
                 SpW(1) = (W_)cap->r.rCCCS;
    
    ... ... @@ -1807,6 +1932,8 @@ run_BCO:
    1807 1932
                 SpW(-2) = (W_)&stg_ctoi_V_info;
    
    1808 1933
                 SpW(-1) = BCO_PTR(o_bco);
    
    1809 1934
                 Sp_subW(2);
    
    1935
    +
    
    1936
    +            IF_DEBUG(sanity, checkStackChunk(Sp, cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size););
    
    1810 1937
     #if defined(PROFILING)
    
    1811 1938
                 Sp_subW(2);
    
    1812 1939
                 SpW(1) = (W_)cap->r.rCCCS;
    
    ... ... @@ -1820,6 +1947,7 @@ run_BCO:
    1820 1947
                 W_ tuple_info = (W_)BCO_LIT(BCO_GET_LARGE_ARG);
    
    1821 1948
                 W_ o_tuple_bco = BCO_GET_LARGE_ARG;
    
    1822 1949
     
    
    1950
    +            IF_DEBUG(sanity, checkStackChunk(Sp, cap->r.rCurrentTSO->stackobj->stack+cap->r.rCurrentTSO->stackobj->stack_size););
    
    1823 1951
     #if defined(PROFILING)
    
    1824 1952
                 SpW(-1) = (W_)cap->r.rCCCS;
    
    1825 1953
                 Sp_subW(1);
    
    ... ... @@ -1828,82 +1956,11 @@ run_BCO:
    1828 1956
                 SpW(-1) = BCO_PTR(o_tuple_bco);
    
    1829 1957
                 SpW(-2) = tuple_info;
    
    1830 1958
                 SpW(-3) = BCO_PTR(o_bco);
    
    1831
    -            W_ ctoi_t_offset;
    
    1832 1959
                 int tuple_stack_words = (tuple_info >> 24) & 0xff;
    
    1833
    -            switch(tuple_stack_words) {
    
    1834
    -                case 0:  ctoi_t_offset = (W_)&stg_ctoi_t0_info;  break;
    
    1835
    -                case 1:  ctoi_t_offset = (W_)&stg_ctoi_t1_info;  break;
    
    1836
    -                case 2:  ctoi_t_offset = (W_)&stg_ctoi_t2_info;  break;
    
    1837
    -                case 3:  ctoi_t_offset = (W_)&stg_ctoi_t3_info;  break;
    
    1838
    -                case 4:  ctoi_t_offset = (W_)&stg_ctoi_t4_info;  break;
    
    1839
    -                case 5:  ctoi_t_offset = (W_)&stg_ctoi_t5_info;  break;
    
    1840
    -                case 6:  ctoi_t_offset = (W_)&stg_ctoi_t6_info;  break;
    
    1841
    -                case 7:  ctoi_t_offset = (W_)&stg_ctoi_t7_info;  break;
    
    1842
    -                case 8:  ctoi_t_offset = (W_)&stg_ctoi_t8_info;  break;
    
    1843
    -                case 9:  ctoi_t_offset = (W_)&stg_ctoi_t9_info;  break;
    
    1844
    -
    
    1845
    -                case 10: ctoi_t_offset = (W_)&stg_ctoi_t10_info; break;
    
    1846
    -                case 11: ctoi_t_offset = (W_)&stg_ctoi_t11_info; break;
    
    1847
    -                case 12: ctoi_t_offset = (W_)&stg_ctoi_t12_info; break;
    
    1848
    -                case 13: ctoi_t_offset = (W_)&stg_ctoi_t13_info; break;
    
    1849
    -                case 14: ctoi_t_offset = (W_)&stg_ctoi_t14_info; break;
    
    1850
    -                case 15: ctoi_t_offset = (W_)&stg_ctoi_t15_info; break;
    
    1851
    -                case 16: ctoi_t_offset = (W_)&stg_ctoi_t16_info; break;
    
    1852
    -                case 17: ctoi_t_offset = (W_)&stg_ctoi_t17_info; break;
    
    1853
    -                case 18: ctoi_t_offset = (W_)&stg_ctoi_t18_info; break;
    
    1854
    -                case 19: ctoi_t_offset = (W_)&stg_ctoi_t19_info; break;
    
    1855
    -
    
    1856
    -                case 20: ctoi_t_offset = (W_)&stg_ctoi_t20_info; break;
    
    1857
    -                case 21: ctoi_t_offset = (W_)&stg_ctoi_t21_info; break;
    
    1858
    -                case 22: ctoi_t_offset = (W_)&stg_ctoi_t22_info; break;
    
    1859
    -                case 23: ctoi_t_offset = (W_)&stg_ctoi_t23_info; break;
    
    1860
    -                case 24: ctoi_t_offset = (W_)&stg_ctoi_t24_info; break;
    
    1861
    -                case 25: ctoi_t_offset = (W_)&stg_ctoi_t25_info; break;
    
    1862
    -                case 26: ctoi_t_offset = (W_)&stg_ctoi_t26_info; break;
    
    1863
    -                case 27: ctoi_t_offset = (W_)&stg_ctoi_t27_info; break;
    
    1864
    -                case 28: ctoi_t_offset = (W_)&stg_ctoi_t28_info; break;
    
    1865
    -                case 29: ctoi_t_offset = (W_)&stg_ctoi_t29_info; break;
    
    1866
    -
    
    1867
    -                case 30: ctoi_t_offset = (W_)&stg_ctoi_t30_info; break;
    
    1868
    -                case 31: ctoi_t_offset = (W_)&stg_ctoi_t31_info; break;
    
    1869
    -                case 32: ctoi_t_offset = (W_)&stg_ctoi_t32_info; break;
    
    1870
    -                case 33: ctoi_t_offset = (W_)&stg_ctoi_t33_info; break;
    
    1871
    -                case 34: ctoi_t_offset = (W_)&stg_ctoi_t34_info; break;
    
    1872
    -                case 35: ctoi_t_offset = (W_)&stg_ctoi_t35_info; break;
    
    1873
    -                case 36: ctoi_t_offset = (W_)&stg_ctoi_t36_info; break;
    
    1874
    -                case 37: ctoi_t_offset = (W_)&stg_ctoi_t37_info; break;
    
    1875
    -                case 38: ctoi_t_offset = (W_)&stg_ctoi_t38_info; break;
    
    1876
    -                case 39: ctoi_t_offset = (W_)&stg_ctoi_t39_info; break;
    
    1877
    -
    
    1878
    -                case 40: ctoi_t_offset = (W_)&stg_ctoi_t40_info; break;
    
    1879
    -                case 41: ctoi_t_offset = (W_)&stg_ctoi_t41_info; break;
    
    1880
    -                case 42: ctoi_t_offset = (W_)&stg_ctoi_t42_info; break;
    
    1881
    -                case 43: ctoi_t_offset = (W_)&stg_ctoi_t43_info; break;
    
    1882
    -                case 44: ctoi_t_offset = (W_)&stg_ctoi_t44_info; break;
    
    1883
    -                case 45: ctoi_t_offset = (W_)&stg_ctoi_t45_info; break;
    
    1884
    -                case 46: ctoi_t_offset = (W_)&stg_ctoi_t46_info; break;
    
    1885
    -                case 47: ctoi_t_offset = (W_)&stg_ctoi_t47_info; break;
    
    1886
    -                case 48: ctoi_t_offset = (W_)&stg_ctoi_t48_info; break;
    
    1887
    -                case 49: ctoi_t_offset = (W_)&stg_ctoi_t49_info; break;
    
    1888
    -
    
    1889
    -                case 50: ctoi_t_offset = (W_)&stg_ctoi_t50_info; break;
    
    1890
    -                case 51: ctoi_t_offset = (W_)&stg_ctoi_t51_info; break;
    
    1891
    -                case 52: ctoi_t_offset = (W_)&stg_ctoi_t52_info; break;
    
    1892
    -                case 53: ctoi_t_offset = (W_)&stg_ctoi_t53_info; break;
    
    1893
    -                case 54: ctoi_t_offset = (W_)&stg_ctoi_t54_info; break;
    
    1894
    -                case 55: ctoi_t_offset = (W_)&stg_ctoi_t55_info; break;
    
    1895
    -                case 56: ctoi_t_offset = (W_)&stg_ctoi_t56_info; break;
    
    1896
    -                case 57: ctoi_t_offset = (W_)&stg_ctoi_t57_info; break;
    
    1897
    -                case 58: ctoi_t_offset = (W_)&stg_ctoi_t58_info; break;
    
    1898
    -                case 59: ctoi_t_offset = (W_)&stg_ctoi_t59_info; break;
    
    1899
    -
    
    1900
    -                case 60: ctoi_t_offset = (W_)&stg_ctoi_t60_info; break;
    
    1901
    -                case 61: ctoi_t_offset = (W_)&stg_ctoi_t61_info; break;
    
    1902
    -                case 62: ctoi_t_offset = (W_)&stg_ctoi_t62_info; break;
    
    1903
    -
    
    1904
    -                default: barf("unsupported tuple size %d", tuple_stack_words);
    
    1960
    +            if (tuple_stack_words > 62) {
    
    1961
    +                barf("unsupported tuple size %d", tuple_stack_words);
    
    1905 1962
                 }
    
    1906
    -
    
    1963
    +            W_ ctoi_t_offset = (W_) ctoi_tuple_infos[tuple_stack_words];
    
    1907 1964
                 SpW(-4) = ctoi_t_offset;
    
    1908 1965
                 Sp_subW(4);
    
    1909 1966
                 goto nextInsn;
    
    ... ... @@ -1996,15 +2053,7 @@ run_BCO:
    1996 2053
             case bci_SLIDE: {
    
    1997 2054
                 W_ n  = BCO_GET_LARGE_ARG;
    
    1998 2055
                 W_ by = BCO_GET_LARGE_ARG;
    
    1999
    -            /*
    
    2000
    -             * a_1 ... a_n, b_1 ... b_by, k
    
    2001
    -             *           =>
    
    2002
    -             * a_1 ... a_n, k
    
    2003
    -             */
    
    2004
    -            while(n-- > 0) {
    
    2005
    -                SpW(n+by) = ReadSpW(n);
    
    2006
    -            }
    
    2007
    -            Sp_addW(by);
    
    2056
    +            SpSlide(n, by);
    
    2008 2057
                 INTERP_TICK(it_slides);
    
    2009 2058
                 goto nextInsn;
    
    2010 2059
             }
    

  • testsuite/tests/ghci.debugger/scripts/all.T
    ... ... @@ -147,7 +147,7 @@ test('T25932', extra_files(['T25932.hs']), ghci_script, ['T25932.script'])
    147 147
     
    
    148 148
     # Step out tests
    
    149 149
     test('T26042b', [extra_hc_opts('-O -fno-unoptimized-core-for-interpreter'), extra_files(['T26042b.hs'])], ghci_script, ['T26042b.script'])
    
    150
    -test('T26042c', [expect_broken(26042),extra_hc_opts('-O -fno-unoptimized-core-for-interpreter'), extra_files(['T26042c.hs'])], ghci_script, ['T26042c.script'])
    
    150
    +test('T26042c', [extra_hc_opts('-O -fno-unoptimized-core-for-interpreter'), extra_files(['T26042c.hs'])], ghci_script, ['T26042c.script'])
    
    151 151
     test('T26042d', [extra_hc_opts('-O -fno-unoptimized-core-for-interpreter'), extra_files(['T26042d.hs'])], ghci_script, ['T26042d.script'])
    
    152 152
     test('T26042e', extra_files(['T26042e.hs']), ghci_script, ['T26042e.script'])
    
    153 153
     test('T26042f1', extra_files(['T26042f.hs', 'T26042f.script']), ghci_script, ['T26042f.script']) # >> is not inlined, so stepout has nowhere to stop