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

Commits:

15 changed files:

Changes:

  • compiler/GHC.hs
    ... ... @@ -408,6 +408,8 @@ import GHC.Core.FamInstEnv ( FamInst, famInstEnvElts, orphNamesOfFamInst )
    408 408
     import GHC.Core.InstEnv
    
    409 409
     import GHC.Core
    
    410 410
     
    
    411
    +import GHC.HsToCore.Breakpoints
    
    412
    +
    
    411 413
     import GHC.Data.Maybe
    
    412 414
     
    
    413 415
     import GHC.Types.Id
    
    ... ... @@ -427,7 +429,6 @@ import GHC.Types.Basic
    427 429
     import GHC.Types.TyThing
    
    428 430
     import GHC.Types.Name.Env
    
    429 431
     import GHC.Types.TypeEnv
    
    430
    -import GHC.Types.Breakpoint
    
    431 432
     import GHC.Types.PkgQual
    
    432 433
     
    
    433 434
     import GHC.Unit
    

  • compiler/GHC/ByteCode/Asm.hs
    ... ... @@ -28,7 +28,6 @@ import GHC.Prelude hiding ( any )
    28 28
     import GHC.ByteCode.Instr
    
    29 29
     import GHC.ByteCode.InfoTable
    
    30 30
     import GHC.ByteCode.Types
    
    31
    -import GHCi.RemoteTypes
    
    32 31
     import GHC.Runtime.Heap.Layout ( fromStgWord, StgWord )
    
    33 32
     
    
    34 33
     import GHC.Types.Name
    
    ... ... @@ -843,12 +842,12 @@ assembleI platform i = case i of
    843 842
         W8                   -> emit_ bci_OP_INDEX_ADDR_08 []
    
    844 843
         _                    -> unsupported_width
    
    845 844
     
    
    846
    -  BRK_FUN arr (InternalBreakpointId info_mod infox) cc -> do
    
    847
    -    p1 <- ptr (BCOPtrBreakArray arr)
    
    845
    +  BRK_FUN ibi@(InternalBreakpointId info_mod infox) -> do
    
    846
    +    p1 <- ptr $ BCOPtrBreakArray info_mod
    
    848 847
         info_addr <- lit1 $ BCONPtrFS $ moduleNameFS $ moduleName info_mod
    
    849 848
         info_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS $ moduleUnitId info_mod
    
    850 849
         info_wix <- int infox
    
    851
    -    np <- addr cc
    
    850
    +    np <- lit1 $ BCONPtrCostCentre ibi
    
    852 851
         emit_ bci_BRK_FUN [ Op p1, Op info_addr, Op info_unitid_addr
    
    853 852
                           , Op info_wix, Op np ]
    
    854 853
     
    
    ... ... @@ -892,7 +891,6 @@ assembleI platform i = case i of
    892 891
         literal (LitRubbish {}) = word 0
    
    893 892
     
    
    894 893
         litlabel fs = lit1 (BCONPtrLbl fs)
    
    895
    -    addr (RemotePtr a) = word (fromIntegral a)
    
    896 894
         words ws = lit (fmap BCONPtrWord ws)
    
    897 895
         word w = words (OnlyOne w)
    
    898 896
         word2 w1 w2 = words (OnlyTwo w1 w2)
    

  • compiler/GHC/ByteCode/Breakpoints.hs
    ... ... @@ -10,7 +10,7 @@
    10 10
     -- See Note [ModBreaks vs InternalModBreaks] and Note [Breakpoint identifiers]
    
    11 11
     module GHC.ByteCode.Breakpoints
    
    12 12
       ( -- * Internal Mod Breaks
    
    13
    -    InternalModBreaks(imodBreaks_breakInfo), CgBreakInfo(..)
    
    13
    +    InternalModBreaks(..), CgBreakInfo(..)
    
    14 14
       , mkInternalModBreaks
    
    15 15
     
    
    16 16
         -- ** Operations
    
    ... ... @@ -114,12 +114,12 @@ data InternalBreakpointId = InternalBreakpointId
    114 114
     -- 'InternalModBreaks' are constructed during bytecode generation and stored in
    
    115 115
     -- 'CompiledByteCode' afterwards.
    
    116 116
     data InternalModBreaks = InternalModBreaks
    
    117
    -      { imodBreaks_breakInfo :: IntMap CgBreakInfo
    
    117
    +      { imodBreaks_breakInfo :: !(IntMap CgBreakInfo)
    
    118 118
             -- ^ Access code-gen time information about a breakpoint, indexed by
    
    119 119
             -- 'InternalBreakpointId'.
    
    120
    -      , imodBreaks_module :: !Module
    
    121
    -        -- ^ Cache the module corresponding to these 'InternalModBreaks' for
    
    122
    -        -- sanity checks. Don't export it!
    
    120
    +      , imodBreaks_module    :: !Module
    
    121
    +        -- ^ Also cache the module corresponding to these 'InternalModBreaks',
    
    122
    +        -- for instance for internal sanity checks.
    
    123 123
           }
    
    124 124
     
    
    125 125
     -- | Construct an 'InternalModBreaks'
    
    ... ... @@ -161,24 +161,6 @@ assert_modules_match ibi_mod imbs_mod =
    161 161
         (text "Tried to query the InternalModBreaks of module" <+> ppr imbs_mod
    
    162 162
             <+> text "with an InternalBreakpointId for module" <+> ppr ibi_mod)
    
    163 163
     
    
    164
    --- TODO: See what Cheng has in .
    
    165
    --- mkCCSArray
    
    166
    ---   :: Interp -> Module -> Int -> [Tick]
    
    167
    ---   -> IO (Array BreakTickIndex (RemotePtr GHC.Stack.CCS.CostCentre))
    
    168
    --- mkCCSArray interp modul count entries
    
    169
    ---   | interpreterProfiled interp = do
    
    170
    ---       let module_str = moduleNameString (moduleName modul)
    
    171
    ---       costcentres <- GHCi.mkCostCentres interp module_str (map mk_one entries)
    
    172
    ---       return (listArray (0,count-1) costcentres)
    
    173
    ---   | otherwise = return (listArray (0,-1) [])
    
    174
    ---  where
    
    175
    ---     mk_one t = (name, src)
    
    176
    ---       where name = concat $ intersperse "." $ tick_path t
    
    177
    ---             src = renderWithContext defaultSDocContext $ ppr $ tick_loc t
    
    178
    ---   , modBreaks_ccs :: !(Array BreakTickIndex (RemotePtr CostCentre))
    
    179
    ---        -- ^ Array pointing to cost centre for each breakpoint
    
    180
    ---    ccs <- mkCCSArray interpProfiled mod count entries
    
    181
    -
    
    182 164
     --------------------------------------------------------------------------------
    
    183 165
     -- Instances
    
    184 166
     --------------------------------------------------------------------------------
    

  • compiler/GHC/ByteCode/Instr.hs
    ... ... @@ -15,7 +15,6 @@ import GHC.Prelude
    15 15
     
    
    16 16
     import GHC.ByteCode.Types
    
    17 17
     import GHC.Cmm.Type (Width)
    
    18
    -import GHCi.RemoteTypes
    
    19 18
     import GHC.StgToCmm.Layout     ( ArgRep(..) )
    
    20 19
     import GHC.Utils.Outputable
    
    21 20
     import GHC.Types.Name
    
    ... ... @@ -32,10 +31,8 @@ import Data.Word
    32 31
     import Data.ByteString (ByteString)
    
    33 32
     #endif
    
    34 33
     
    
    35
    -import GHC.Stack.CCS (CostCentre)
    
    36 34
     
    
    37 35
     import GHC.Stg.Syntax
    
    38
    -import GHCi.BreakArray (BreakArray)
    
    39 36
     
    
    40 37
     -- ----------------------------------------------------------------------------
    
    41 38
     -- Bytecode instructions
    
    ... ... @@ -261,9 +258,7 @@ data BCInstr
    261 258
                        -- Note [unboxed tuple bytecodes and tuple_BCO] in GHC.StgToByteCode
    
    262 259
     
    
    263 260
        -- Breakpoints
    
    264
    -   | BRK_FUN          (ForeignRef BreakArray)
    
    265
    -                      !InternalBreakpointId
    
    266
    -                      (RemotePtr CostCentre)
    
    261
    +   | BRK_FUN          !InternalBreakpointId
    
    267 262
     
    
    268 263
        -- An internal breakpoint for triggering a break on any case alternative
    
    269 264
        -- See Note [Debugger: BRK_ALTS]
    
    ... ... @@ -459,7 +454,7 @@ instance Outputable BCInstr where
    459 454
        ppr ENTER                 = text "ENTER"
    
    460 455
        ppr (RETURN pk)           = text "RETURN  " <+> ppr pk
    
    461 456
        ppr (RETURN_TUPLE)        = text "RETURN_TUPLE"
    
    462
    -   ppr (BRK_FUN _ (InternalBreakpointId info_mod infox) _)
    
    457
    +   ppr (BRK_FUN (InternalBreakpointId info_mod infox))
    
    463 458
                                  = text "BRK_FUN" <+> text "<breakarray>"
    
    464 459
                                    <+> ppr info_mod <+> ppr infox
    
    465 460
                                    <+> text "<cc>"
    

  • compiler/GHC/ByteCode/Linker.hs
    ... ... @@ -28,9 +28,11 @@ import GHCi.ResolvedBCO
    28 28
     import GHC.Builtin.PrimOps
    
    29 29
     import GHC.Builtin.PrimOps.Ids
    
    30 30
     
    
    31
    +import GHC.Unit.Module.Env
    
    31 32
     import GHC.Unit.Types
    
    32 33
     
    
    33 34
     import GHC.Data.FastString
    
    35
    +import GHC.Data.Maybe
    
    34 36
     import GHC.Data.SizedSeq
    
    35 37
     
    
    36 38
     import GHC.Linker.Types
    
    ... ... @@ -47,6 +49,7 @@ import GHC.Types.Unique.DFM
    47 49
     import Data.Array.Unboxed
    
    48 50
     import Foreign.Ptr
    
    49 51
     import GHC.Exts
    
    52
    +import GHC.HsToCore.Breakpoints (BreakpointId(..))
    
    50 53
     
    
    51 54
     {-
    
    52 55
       Linking interpretables into something we can run
    
    ... ... @@ -95,6 +98,14 @@ lookupLiteral interp pkgs_loaded le ptr = case ptr of
    95 98
       BCONPtrFFIInfo (FFIInfo {..}) -> do
    
    96 99
         RemotePtr p <- interpCmd interp $ PrepFFI ffiInfoArgs ffiInfoRet
    
    97 100
         pure $ fromIntegral p
    
    101
    +  BCONPtrCostCentre ibi
    
    102
    +    | interpreterProfiled interp -> do
    
    103
    +        (BreakpointId tick_mod tick_no) <- (error "todo") ibi
    
    104
    +        case expectJust (lookupModuleEnv (ccs_env le) tick_mod) ! tick_no of
    
    105
    +          RemotePtr p -> pure $ fromIntegral p
    
    106
    +    | otherwise ->
    
    107
    +        case toRemotePtr nullPtr of
    
    108
    +          RemotePtr p -> pure $ fromIntegral p
    
    98 109
     
    
    99 110
     lookupStaticPtr :: Interp -> FastString -> IO (Ptr ())
    
    100 111
     lookupStaticPtr interp addr_of_label_string = do
    
    ... ... @@ -175,8 +186,9 @@ resolvePtr interp pkgs_loaded le bco_ix ptr = case ptr of
    175 186
       BCOPtrBCO bco
    
    176 187
         -> ResolvedBCOPtrBCO <$> linkBCO interp pkgs_loaded le bco_ix bco
    
    177 188
     
    
    178
    -  BCOPtrBreakArray breakarray
    
    179
    -    -> withForeignRef breakarray $ \ba -> return (ResolvedBCOPtrBreakArray ba)
    
    189
    +  BCOPtrBreakArray tick_mod ->
    
    190
    +    withForeignRef (expectJust (lookupModuleEnv (breakarray_env le) tick_mod)) $
    
    191
    +      \ba -> pure $ ResolvedBCOPtrBreakArray ba
    
    180 192
     
    
    181 193
     -- | Look up the address of a Haskell symbol in the currently
    
    182 194
     -- loaded units.
    

  • compiler/GHC/ByteCode/Types.hs
    ... ... @@ -36,7 +36,6 @@ import GHC.Types.Name.Env
    36 36
     import GHC.Utils.Outputable
    
    37 37
     import GHC.Builtin.PrimOps
    
    38 38
     import GHC.Types.SptEntry
    
    39
    -import GHCi.BreakArray
    
    40 39
     import GHCi.Message
    
    41 40
     import GHCi.RemoteTypes
    
    42 41
     import GHCi.FFI
    
    ... ... @@ -48,6 +47,7 @@ import Data.ByteString (ByteString)
    48 47
     import qualified GHC.Exts.Heap as Heap
    
    49 48
     import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList )
    
    50 49
     import GHC.HsToCore.Breakpoints (ModBreaks)
    
    50
    +import GHC.Unit.Module
    
    51 51
     
    
    52 52
     -- -----------------------------------------------------------------------------
    
    53 53
     -- Compiled Byte Code
    
    ... ... @@ -63,11 +63,20 @@ data CompiledByteCode = CompiledByteCode
    63 63
         -- ^ top-level strings (heap allocated)
    
    64 64
     
    
    65 65
       , bc_breaks :: (Maybe (InternalModBreaks, ModBreaks))
    
    66
    -    -- ^ internal breakpoint info (no tick-level 'ModBreaks' if breakpoints are disabled)
    
    66
    +    -- ^ All (internal and tick-level) breakpoint information (no information
    
    67
    +    -- if breakpoints are disabled).
    
    67 68
         --
    
    69
    +    -- This information is used when loading a bytecode object: we will
    
    70
    +    -- construct the arrays to be used at runtime to trigger breakpoints then
    
    71
    +    -- from it (in 'allocateBreakArrays' and 'allocateCCS' in 'GHC.ByteCode.Loader').
    
    72
    +    --
    
    73
    +    -- Moreover, when a breakpoint is hit we will find the associated
    
    74
    +    -- breakpoint information indexed by the internal breakpoint id here (in
    
    75
    +    -- 'getModBreaks').
    
    76
    +
    
    68 77
         -- TODO: If ModBreaks is serialized and reconstructed as part of ModDetails
    
    69
    -    -- we don't need to keep it here as it can be fetched from the
    
    70
    -    -- 'HomeModInfo' directly.
    
    78
    +    -- we don't need to keep it in bc_breaks as it can be fetched from the
    
    79
    +    -- 'HomeModInfo' directly, right?
    
    71 80
     
    
    72 81
       , bc_spt_entries :: ![SptEntry]
    
    73 82
         -- ^ Static pointer table entries which should be loaded along with the
    
    ... ... @@ -258,8 +267,8 @@ data BCOPtr
    258 267
       = BCOPtrName   !Name
    
    259 268
       | BCOPtrPrimOp !PrimOp
    
    260 269
       | BCOPtrBCO    !UnlinkedBCO
    
    261
    -  | BCOPtrBreakArray (ForeignRef BreakArray)
    
    262
    -    -- ^ a pointer to a breakpoint's module's BreakArray in GHCi's memory
    
    270
    +  | BCOPtrBreakArray !Module
    
    271
    +    -- ^ Converted to the actual 'BreakArray' remote pointer at link-time
    
    263 272
     
    
    264 273
     instance NFData BCOPtr where
    
    265 274
       rnf (BCOPtrBCO bco) = rnf bco
    
    ... ... @@ -279,6 +288,8 @@ data BCONPtr
    279 288
       | BCONPtrFS    !FastString
    
    280 289
       -- | A libffi ffi_cif function prototype.
    
    281 290
       | BCONPtrFFIInfo !FFIInfo
    
    291
    +  -- | A 'CostCentre' remote pointer array's respective 'BreakpointId'
    
    292
    +  | BCONPtrCostCentre !InternalBreakpointId
    
    282 293
     
    
    283 294
     instance NFData BCONPtr where
    
    284 295
       rnf x = x `seq` ()
    

  • compiler/GHC/Driver/Main.hs
    ... ... @@ -304,6 +304,7 @@ import GHC.Cmm.Config (CmmConfig)
    304 304
     import Data.Bifunctor
    
    305 305
     import qualified GHC.Unit.Home.Graph as HUG
    
    306 306
     import GHC.Unit.Home.PackageTable
    
    307
    +import GHC.HsToCore.Breakpoints (ModBreaks)
    
    307 308
     
    
    308 309
     {- **********************************************************************
    
    309 310
     %*                                                                      *
    

  • compiler/GHC/Driver/Session/Inspect.hs
    ... ... @@ -17,6 +17,7 @@ import GHC.Driver.Session
    17 17
     import GHC.Rename.Names
    
    18 18
     import GHC.Runtime.Context
    
    19 19
     import GHC.Runtime.Interpreter
    
    20
    +import GHC.HsToCore.Breakpoints (ModBreaks)
    
    20 21
     import GHC.Types.Avail
    
    21 22
     import GHC.Types.Name
    
    22 23
     import GHC.Types.Name.Ppr
    
    ... ... @@ -91,7 +92,7 @@ data ModuleInfo = ModuleInfo {
    91 92
             minf_instances :: [ClsInst],
    
    92 93
             minf_iface     :: Maybe ModIface,
    
    93 94
             minf_safe      :: SafeHaskellMode,
    
    94
    -        minf_modBreaks :: Maybe ModBreaks
    
    95
    +        minf_modBreaks :: Maybe (InternalModBreaks, ModBreaks)
    
    95 96
       }
    
    96 97
             -- We don't want HomeModInfo here, because a ModuleInfo applies
    
    97 98
             -- to package modules too.
    
    ... ... @@ -196,6 +197,6 @@ modInfoIface = minf_iface
    196 197
     modInfoSafe :: ModuleInfo -> SafeHaskellMode
    
    197 198
     modInfoSafe = minf_safe
    
    198 199
     
    
    199
    -modInfoModBreaks :: ModuleInfo -> Maybe ModBreaks
    
    200
    +modInfoModBreaks :: ModuleInfo -> Maybe (InternalModBreaks, ModBreaks)
    
    200 201
     modInfoModBreaks = minf_modBreaks
    
    201 202
     

  • compiler/GHC/HsToCore.hs
    ... ... @@ -98,6 +98,7 @@ import GHC.Unit.Module.Deps
    98 98
     import Data.List (partition)
    
    99 99
     import Data.IORef
    
    100 100
     import GHC.Iface.Make (mkRecompUsageInfo)
    
    101
    +import GHC.Runtime.Interpreter (interpreterProfiled)
    
    101 102
     
    
    102 103
     {-
    
    103 104
     ************************************************************************
    
    ... ... @@ -164,7 +165,7 @@ deSugar hsc_env
    164 165
             ; let modBreaks
    
    165 166
                     | Just (_, specs) <- m_tickInfo
    
    166 167
                     , breakpointsAllowed dflags
    
    167
    -                = Just $ mkModBreaks mod specs
    
    168
    +                = Just $ mkModBreaks (interpreterProfiled $ hscInterp hsc_env) mod specs
    
    168 169
                     | otherwise
    
    169 170
                     = Nothing
    
    170 171
     
    

  • compiler/GHC/HsToCore/Breakpoints.hs
    1
    +{-# LANGUAGE RecordWildCards #-}
    
    2
    +
    
    1 3
     -- | Information attached to Breakpoints generated from Ticks
    
    2 4
     --
    
    3 5
     -- The breakpoint information stored in 'ModBreaks' is generated during
    
    ... ... @@ -13,10 +15,11 @@
    13 15
     -- See Note [ModBreaks vs InternalModBreaks] and Note [Breakpoint identifiers]
    
    14 16
     module GHC.HsToCore.Breakpoints
    
    15 17
       ( -- * ModBreaks
    
    16
    -    mkModBreaks, ModBreaks(modBreaks_locs, modBreaks_vars, modBreaks_decls)
    
    18
    +    mkModBreaks, ModBreaks(..)
    
    17 19
     
    
    18 20
         -- ** Queries
    
    19
    -  , getBreakLoc, getBreakVars, getBreakDecls
    
    21
    +    -- TODO: See where we could use these rather than using the arrays directly.
    
    22
    +  , getBreakLoc, getBreakVars, getBreakDecls, getBreakCCS
    
    20 23
     
    
    21 24
         -- ** Re-exports BreakpointId
    
    22 25
       , BreakpointId(..), BreakTickIndex
    
    ... ... @@ -33,6 +36,7 @@ import GHC.Types.Tickish (BreakTickIndex, BreakpointId(..))
    33 36
     import GHC.Unit.Module (Module)
    
    34 37
     import GHC.Utils.Outputable
    
    35 38
     import GHC.Utils.Panic
    
    39
    +import Data.List (intersperse)
    
    36 40
     
    
    37 41
     --------------------------------------------------------------------------------
    
    38 42
     -- ModBreaks
    
    ... ... @@ -51,16 +55,19 @@ import GHC.Utils.Panic
    51 55
     -- and 'modBreaks_decls'.
    
    52 56
     data ModBreaks
    
    53 57
        = ModBreaks
    
    54
    -   { modBreaks_locs :: !(Array BreakTickIndex SrcSpan)
    
    58
    +   { modBreaks_locs   :: !(Array BreakTickIndex SrcSpan)
    
    55 59
             -- ^ An array giving the source span of each breakpoint.
    
    56
    -   , modBreaks_vars :: !(Array BreakTickIndex [OccName])
    
    60
    +   , modBreaks_vars   :: !(Array BreakTickIndex [OccName])
    
    57 61
             -- ^ An array giving the names of the free variables at each breakpoint.
    
    58
    -   , modBreaks_decls :: !(Array BreakTickIndex [String])
    
    62
    +   , modBreaks_decls  :: !(Array BreakTickIndex [String])
    
    59 63
             -- ^ An array giving the names of the declarations enclosing each breakpoint.
    
    60 64
             -- See Note [Field modBreaks_decls]
    
    65
    +   , modBreaks_ccs    :: !(Array BreakTickIndex (String, String))
    
    66
    +        -- ^ Array pointing to cost centre info for each breakpoint;
    
    67
    +        -- actual 'CostCentre' allocation is done at link-time.
    
    61 68
        , modBreaks_module :: !Module
    
    62 69
             -- ^ The module to which this ModBreaks is associated.
    
    63
    -        -- We cache this here for internal sanity checks (don't export it!).
    
    70
    +        -- We also cache this here for internal sanity checks.
    
    64 71
        }
    
    65 72
     
    
    66 73
     -- | Initialize memory for breakpoint data that is shared between the bytecode
    
    ... ... @@ -70,34 +77,52 @@ data ModBreaks
    70 77
     -- generator needs to encode this information for each expression, the data is
    
    71 78
     -- allocated remotely in GHCi's address space and passed to the codegen as
    
    72 79
     -- foreign pointers.
    
    73
    -mkModBreaks :: Module -> SizedSeq Tick -> ModBreaks
    
    74
    -mkModBreaks modl extendedMixEntries
    
    80
    +mkModBreaks :: Bool {-^ Whether the interpreter is profiled and thus if we should include store a CCS array -}
    
    81
    +            -> Module -> SizedSeq Tick -> ModBreaks
    
    82
    +mkModBreaks interpreterProfiled modl extendedMixEntries
    
    75 83
       = let count = fromIntegral $ sizeSS extendedMixEntries
    
    76 84
             entries = ssElts extendedMixEntries
    
    77 85
             locsTicks  = listArray (0,count-1) [ tick_loc  t | t <- entries ]
    
    78 86
             varsTicks  = listArray (0,count-1) [ tick_ids  t | t <- entries ]
    
    79 87
             declsTicks = listArray (0,count-1) [ tick_path t | t <- entries ]
    
    88
    +        ccs
    
    89
    +          | interpreterProfiled =
    
    90
    +              listArray
    
    91
    +                (0, count - 1)
    
    92
    +                [ ( concat $ intersperse "." $ tick_path t,
    
    93
    +                    renderWithContext defaultSDocContext $ ppr $ tick_loc t
    
    94
    +                  )
    
    95
    +                | t <- entries
    
    96
    +                ]
    
    97
    +          | otherwise = listArray (0, -1) []
    
    80 98
          in ModBreaks
    
    81 99
           { modBreaks_locs   = locsTicks
    
    82 100
           , modBreaks_vars   = varsTicks
    
    83 101
           , modBreaks_decls  = declsTicks
    
    102
    +      , modBreaks_ccs    = ccs
    
    84 103
           , modBreaks_module = modl
    
    85 104
           }
    
    86 105
     
    
    87 106
     -- | Get the source span for this breakpoint
    
    88 107
     getBreakLoc  :: BreakpointId -> ModBreaks -> SrcSpan
    
    89
    -getBreakLoc (BreakpointId bid_mod ix) mbs =
    
    90
    -  assert_modules_match bid_mod (modBreaks_module mbs) $ modBreaks_locs mbs ! ix
    
    108
    +getBreakLoc = getBreakXXX modBreaks_locs
    
    91 109
     
    
    92 110
     -- | Get the vars for this breakpoint
    
    93 111
     getBreakVars  :: BreakpointId -> ModBreaks -> [OccName]
    
    94
    -getBreakVars (BreakpointId bid_mod ix) mbs =
    
    95
    -  assert_modules_match bid_mod (modBreaks_module mbs) $ modBreaks_vars mbs ! ix
    
    112
    +getBreakVars = getBreakXXX modBreaks_vars
    
    96 113
     
    
    97 114
     -- | Get the decls for this breakpoint
    
    98 115
     getBreakDecls :: BreakpointId -> ModBreaks -> [String]
    
    99
    -getBreakDecls (BreakpointId bid_mod ix) mbs =
    
    100
    -  assert_modules_match bid_mod (modBreaks_module mbs) $ modBreaks_decls mbs ! ix
    
    116
    +getBreakDecls = getBreakXXX modBreaks_decls
    
    117
    +
    
    118
    +-- | Get the decls for this breakpoint
    
    119
    +getBreakCCS :: BreakpointId -> ModBreaks -> (String, String)
    
    120
    +getBreakCCS = getBreakXXX modBreaks_ccs
    
    121
    +
    
    122
    +-- | Internal utility to access a ModBreaks field at a particular breakpoint index
    
    123
    +getBreakXXX :: (ModBreaks -> Array BreakTickIndex a) -> BreakpointId -> ModBreaks -> a
    
    124
    +getBreakXXX view (BreakpointId bid_mod ix) mbs =
    
    125
    +  assert_modules_match bid_mod (modBreaks_module mbs) $ view mbs ! ix
    
    101 126
     
    
    102 127
     -- | Assert that the module in the 'BreakpointId' and in 'ModBreaks' match.
    
    103 128
     assert_modules_match :: Module -> Module -> a -> a
    
    ... ... @@ -114,4 +139,3 @@ The breakpoint is in the function called "baz" that is declared in a `let`
    114 139
     or `where` clause of a declaration called "bar", which itself is declared
    
    115 140
     in a `let` or `where` clause of the top-level function called "foo".
    
    116 141
     -}
    117
    -

  • compiler/GHC/Linker/Loader.hs
    ... ... @@ -52,6 +52,7 @@ import GHC.Driver.Config.Finder
    52 52
     import GHC.Tc.Utils.Monad
    
    53 53
     
    
    54 54
     import GHC.Runtime.Interpreter
    
    55
    +import GHCi.BreakArray
    
    55 56
     import GHCi.RemoteTypes
    
    56 57
     import GHC.Iface.Load
    
    57 58
     import GHCi.Message (ConInfoTable(..), LoadedDLL)
    
    ... ... @@ -60,6 +61,7 @@ import GHC.ByteCode.Linker
    60 61
     import GHC.ByteCode.Asm
    
    61 62
     import GHC.ByteCode.Types
    
    62 63
     
    
    64
    +import GHC.Stack.CCS
    
    63 65
     import GHC.SysTools
    
    64 66
     
    
    65 67
     import GHC.Types.Basic
    
    ... ... @@ -95,6 +97,7 @@ import GHC.Linker.Types
    95 97
     -- Standard libraries
    
    96 98
     import Control.Monad
    
    97 99
     
    
    100
    +import Data.Array
    
    98 101
     import Data.ByteString (ByteString)
    
    99 102
     import qualified Data.Set as Set
    
    100 103
     import Data.Char (isSpace)
    
    ... ... @@ -119,6 +122,11 @@ import System.Win32.Info (getSystemDirectory)
    119 122
     import GHC.Utils.Exception
    
    120 123
     import GHC.Unit.Home.Graph (lookupHug, unitEnv_foldWithKey)
    
    121 124
     import GHC.Driver.Downsweep
    
    125
    +import GHC.HsToCore.Breakpoints
    
    126
    +import qualified Data.IntMap.Strict as IM
    
    127
    +import qualified GHC.Runtime.Interpreter as GHCi
    
    128
    +import GHC.Data.Maybe (expectJust)
    
    129
    +import Foreign.Ptr (nullPtr)
    
    122 130
     
    
    123 131
     
    
    124 132
     
    
    ... ... @@ -174,6 +182,8 @@ emptyLoaderState = LoaderState
    174 182
          { closure_env = emptyNameEnv
    
    175 183
          , itbl_env    = emptyNameEnv
    
    176 184
          , addr_env    = emptyNameEnv
    
    185
    +     , breakarray_env = emptyModuleEnv
    
    186
    +     , ccs_env        = emptyModuleEnv
    
    177 187
          }
    
    178 188
        , pkgs_loaded = init_pkgs
    
    179 189
        , bcos_loaded = emptyModuleEnv
    
    ... ... @@ -691,8 +701,20 @@ loadDecls interp hsc_env span linkable = do
    691 701
               let le  = linker_env pls
    
    692 702
               le2_itbl_env <- linkITbls interp (itbl_env le) (concat $ map bc_itbls cbcs)
    
    693 703
               le2_addr_env <- foldlM (\env cbc -> allocateTopStrings interp (bc_strs cbc) env) (addr_env le) cbcs
    
    704
    +          le2_breakarray_env <-
    
    705
    +            allocateBreakArrays
    
    706
    +              interp
    
    707
    +              (breakarray_env le)
    
    708
    +              (catMaybes $ map bc_breaks cbcs)
    
    709
    +          le2_ccs_env <-
    
    710
    +            allocateCCS
    
    711
    +              interp
    
    712
    +              (ccs_env le)
    
    713
    +              (catMaybes $ map bc_breaks cbcs)
    
    694 714
               let le2 = le { itbl_env = le2_itbl_env
    
    695
    -                       , addr_env = le2_addr_env }
    
    715
    +                       , addr_env = le2_addr_env
    
    716
    +                       , breakarray_env = le2_breakarray_env
    
    717
    +                       , ccs_env = le2_ccs_env }
    
    696 718
     
    
    697 719
               -- Link the necessary packages and linkables
    
    698 720
               new_bindings <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs
    
    ... ... @@ -916,7 +938,9 @@ dynLinkBCOs interp pls bcos = do
    916 938
                 le1 = linker_env pls
    
    917 939
             ie2 <- linkITbls interp (itbl_env le1) (concatMap bc_itbls cbcs)
    
    918 940
             ae2 <- foldlM (\env cbc -> allocateTopStrings interp (bc_strs cbc) env) (addr_env le1) cbcs
    
    919
    -        let le2 = le1 { itbl_env = ie2, addr_env = ae2 }
    
    941
    +        be2 <- allocateBreakArrays interp (breakarray_env le1) (catMaybes $ map bc_breaks cbcs)
    
    942
    +        ce2 <- allocateCCS         interp (ccs_env le1)        (catMaybes $ map bc_breaks cbcs)
    
    943
    +        let le2 = le1 { itbl_env = ie2, addr_env = ae2, breakarray_env = be2, ccs_env = ce2 }
    
    920 944
     
    
    921 945
             names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs
    
    922 946
     
    
    ... ... @@ -1632,3 +1656,71 @@ allocateTopStrings interp topStrings prev_env = do
    1632 1656
       evaluate $ extendNameEnvList prev_env (zipWith mk_entry bndrs ptrs)
    
    1633 1657
       where
    
    1634 1658
         mk_entry nm ptr = (nm, (nm, AddrPtr ptr))
    
    1659
    +
    
    1660
    +-- | Given a list of 'InternalModBreaks and 'ModBreaks' collected from a list of
    
    1661
    +-- 'CompiledByteCode', allocate the 'BreakArray' used to trigger breakpoints.
    
    1662
    +allocateBreakArrays ::
    
    1663
    +  Interp ->
    
    1664
    +  ModuleEnv (ForeignRef BreakArray) ->
    
    1665
    +  [(InternalModBreaks, ModBreaks)] ->
    
    1666
    +  IO (ModuleEnv (ForeignRef BreakArray))
    
    1667
    +allocateBreakArrays interp =
    
    1668
    +  foldlM
    
    1669
    +    ( \be0 (imbs, _mbs) -> do
    
    1670
    +        let bi = imodBreaks_breakInfo imbs
    
    1671
    +            (hi, _) = IM.findMax bi -- allocate as many slots as internal breakpoints
    
    1672
    +        breakArray <- GHCi.newBreakArray interp hi
    
    1673
    +        evaluate $ extendModuleEnv be0 (imodBreaks_module imbs) breakArray
    
    1674
    +    )
    
    1675
    +
    
    1676
    +-- | Given a list of 'InternalModBreaks' and 'ModBreaks' collected from a list
    
    1677
    +-- of 'CompiledByteCode', allocate the 'CostCentre' arrays when profiling is
    
    1678
    +-- enabled.
    
    1679
    +--
    
    1680
    +-- Note that the resulting CostCenter is indexed by the 'InternalBreakpointId',
    
    1681
    +-- not by 'BreakpointId'. At runtime, BRK_FUN instructions are annotated with
    
    1682
    +-- internal ids -- we'll look them up in the array and push the corresponding
    
    1683
    +-- cost center.
    
    1684
    +allocateCCS ::
    
    1685
    +  Interp ->
    
    1686
    +  ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre)) ->
    
    1687
    +  [(InternalModBreaks, ModBreaks)] ->
    
    1688
    +  IO (ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre)))
    
    1689
    +allocateCCS interp ce mbss
    
    1690
    +  | interpreterProfiled interp = do
    
    1691
    +      -- First construct the CCSs for each module, using the 'ModBreaks'
    
    1692
    +      ccs_map <- foldlM
    
    1693
    +        ( \(ccs_map :: ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre))) (_, mbs) -> do
    
    1694
    +          ccs <-
    
    1695
    +            mkCostCentres
    
    1696
    +              interp
    
    1697
    +              (moduleNameString $ moduleName $ modBreaks_module mbs)
    
    1698
    +              (elems $ modBreaks_ccs mbs)
    
    1699
    +          evaluate $
    
    1700
    +            extendModuleEnv ccs_map (modBreaks_module mbs) $
    
    1701
    +              listArray (0, length ccs - 1) ccs
    
    1702
    +        ) emptyModuleEnv mbss
    
    1703
    +      -- Now, construct an array indexed by an 'InternalBreakpointId' index by first
    
    1704
    +      -- finding the matching 'BreakpointId' and then looking it up in the ccs_map
    
    1705
    +      foldlM
    
    1706
    +        ( \ce0 (imbs, _) -> do
    
    1707
    +          let breakModl    = imodBreaks_module imbs
    
    1708
    +              breakInfoMap = imodBreaks_breakInfo imbs
    
    1709
    +              (hi, _)      = IM.findMax breakInfoMap -- as many slots as internal breaks
    
    1710
    +              ccss         = expectJust $ lookupModuleEnv ccs_map breakModl
    
    1711
    +          ccs_im <- foldlM
    
    1712
    +            (\(bids :: IM.IntMap (RemotePtr CostCentre)) cgi -> do
    
    1713
    +              let tickBreakId = bi_tick_index $ cgb_tick_id cgi
    
    1714
    +              pure $ IM.insert tickBreakId (ccss ! tickBreakId) bids
    
    1715
    +            ) mempty breakInfoMap
    
    1716
    +          evaluate $
    
    1717
    +            extendModuleEnv ce0 breakModl $
    
    1718
    +              listArray (0, hi-1) $
    
    1719
    +                map (\i -> case IM.lookup i ccs_im of
    
    1720
    +                      Nothing -> toRemotePtr nullPtr
    
    1721
    +                      Just ccs -> ccs
    
    1722
    +                    ) [0..hi-1]
    
    1723
    +        )
    
    1724
    +        ce
    
    1725
    +        mbss
    
    1726
    +  | otherwise = pure ce

  • compiler/GHC/Linker/Types.hs
    ... ... @@ -50,10 +50,12 @@ where
    50 50
     
    
    51 51
     import GHC.Prelude
    
    52 52
     import GHC.Unit                ( UnitId, Module )
    
    53
    -import GHC.ByteCode.Types      ( ItblEnv, AddrEnv, CompiledByteCode )
    
    54
    -import GHCi.RemoteTypes        ( ForeignHValue, RemotePtr )
    
    53
    +import GHC.ByteCode.Types
    
    54
    +import GHCi.BreakArray
    
    55
    +import GHCi.RemoteTypes
    
    55 56
     import GHCi.Message            ( LoadedDLL )
    
    56 57
     
    
    58
    +import GHC.Stack.CCS
    
    57 59
     import GHC.Types.Name.Env      ( NameEnv, emptyNameEnv, extendNameEnvList, filterNameEnv )
    
    58 60
     import GHC.Types.Name          ( Name )
    
    59 61
     import GHC.Types.SptEntry
    
    ... ... @@ -61,6 +63,7 @@ import GHC.Types.SptEntry
    61 63
     import GHC.Utils.Outputable
    
    62 64
     
    
    63 65
     import Control.Concurrent.MVar
    
    66
    +import Data.Array
    
    64 67
     import Data.Time               ( UTCTime )
    
    65 68
     import GHC.Unit.Module.Env
    
    66 69
     import GHC.Types.Unique.DSet
    
    ... ... @@ -69,6 +72,7 @@ import GHC.Unit.Module.WholeCoreBindings
    69 72
     import Data.Maybe (mapMaybe)
    
    70 73
     import Data.List.NonEmpty (NonEmpty, nonEmpty)
    
    71 74
     import qualified Data.List.NonEmpty as NE
    
    75
    +import GHC.HsToCore.Breakpoints (BreakTickIndex)
    
    72 76
     
    
    73 77
     
    
    74 78
     {- **********************************************************************
    
    ... ... @@ -181,10 +185,17 @@ data LinkerEnv = LinkerEnv
    181 185
       , addr_env    :: !AddrEnv
    
    182 186
           -- ^ Like 'closure_env' and 'itbl_env', but for top-level 'Addr#' literals,
    
    183 187
           -- see Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode.
    
    188
    +
    
    189
    +  , breakarray_env :: !(ModuleEnv (ForeignRef BreakArray))
    
    190
    +      -- ^ Each 'Module's remote pointer of 'BreakArray'.
    
    191
    +
    
    192
    +  , ccs_env :: !(ModuleEnv (Array BreakTickIndex (RemotePtr CostCentre)))
    
    193
    +      -- ^ Each 'Module's array of remote pointers of 'CostCentre'.
    
    194
    +      -- Untouched when not profiling.
    
    184 195
       }
    
    185 196
     
    
    186 197
     filterLinkerEnv :: (Name -> Bool) -> LinkerEnv -> LinkerEnv
    
    187
    -filterLinkerEnv f le = LinkerEnv
    
    198
    +filterLinkerEnv f le = le
    
    188 199
       { closure_env = filterNameEnv (f . fst) (closure_env le)
    
    189 200
       , itbl_env    = filterNameEnv (f . fst) (itbl_env le)
    
    190 201
       , addr_env    = filterNameEnv (f . fst) (addr_env le)
    

  • compiler/GHC/Runtime/Debugger/Breakpoints.hs
    ... ... @@ -16,7 +16,7 @@ import Data.Maybe
    16 16
     import qualified Data.List.NonEmpty as NE
    
    17 17
     import qualified Data.Semigroup as S
    
    18 18
     
    
    19
    -import GHC.ByteCode.Types
    
    19
    +import GHC.HsToCore.Breakpoints
    
    20 20
     import GHC.Driver.Env
    
    21 21
     import GHC.Driver.Monad
    
    22 22
     import GHC.Driver.Session.Inspect
    
    ... ... @@ -196,7 +196,7 @@ type TickArray = Array Int [(BreakTickIndex,RealSrcSpan)]
    196 196
     makeModuleLineMap :: GhcMonad m => Module -> m (Maybe TickArray)
    
    197 197
     makeModuleLineMap m = do
    
    198 198
       mi <- getModuleInfo m
    
    199
    -  return $ mkTickArray . assocs . modBreaks_locs <$> (modInfoModBreaks =<< mi)
    
    199
    +  return $ mkTickArray . assocs . modBreaks_locs <$> (fmap snd . modInfoModBreaks =<< mi)
    
    200 200
       where
    
    201 201
         mkTickArray :: [(BreakTickIndex, SrcSpan)] -> TickArray
    
    202 202
         mkTickArray ticks
    
    ... ... @@ -210,7 +210,7 @@ makeModuleLineMap m = do
    210 210
     getModBreak :: GhcMonad m => Module -> m (Maybe ModBreaks)
    
    211 211
     getModBreak m = do
    
    212 212
        mod_info <- fromMaybe (panic "getModBreak") <$> getModuleInfo m
    
    213
    -   pure $ modInfoModBreaks mod_info
    
    213
    +   pure $ snd <$> modInfoModBreaks mod_info
    
    214 214
     
    
    215 215
     --------------------------------------------------------------------------------
    
    216 216
     -- Getting current breakpoint information
    

  • compiler/GHC/Runtime/Eval.hs
    ... ... @@ -64,6 +64,7 @@ import GHCi.RemoteTypes
    64 64
     import GHC.ByteCode.Types
    
    65 65
     
    
    66 66
     import GHC.Linker.Loader as Loader
    
    67
    +import GHC.Linker.Types (LinkerEnv(..))
    
    67 68
     
    
    68 69
     import GHC.Hs
    
    69 70
     
    
    ... ... @@ -111,7 +112,6 @@ import GHC.Types.Unique
    111 112
     import GHC.Types.Unique.Supply
    
    112 113
     import GHC.Types.Unique.DSet
    
    113 114
     import GHC.Types.TyThing
    
    114
    -import GHC.Types.Breakpoint
    
    115 115
     import GHC.Types.Unique.Map
    
    116 116
     
    
    117 117
     import GHC.Types.Avail
    
    ... ... @@ -127,6 +127,8 @@ import GHC.Tc.Utils.Instantiate (instDFunType)
    127 127
     import GHC.Tc.Utils.Monad
    
    128 128
     
    
    129 129
     import GHC.IfaceToCore
    
    130
    +import GHC.HsToCore.Breakpoints
    
    131
    +import GHC.ByteCode.Breakpoints
    
    130 132
     
    
    131 133
     import Control.Monad
    
    132 134
     import Data.Array
    
    ... ... @@ -137,6 +139,7 @@ import Data.List (find,intercalate)
    137 139
     import Data.List.NonEmpty (NonEmpty)
    
    138 140
     import Unsafe.Coerce ( unsafeCoerce )
    
    139 141
     import qualified GHC.Unit.Home.Graph as HUG
    
    142
    +import GHCi.BreakArray (BreakArray)
    
    140 143
     
    
    141 144
     -- -----------------------------------------------------------------------------
    
    142 145
     -- running a statement interactively
    
    ... ... @@ -153,7 +156,7 @@ getHistoryModule = bi_tick_mod . historyBreakpointId
    153 156
     getHistorySpan :: HUG.HomeUnitGraph -> History -> IO SrcSpan
    
    154 157
     getHistorySpan hug hist = do
    
    155 158
       let bid = historyBreakpointId hist
    
    156
    -  brks <- readModBreaks hug (bi_tick_mod bid)
    
    159
    +  (_, brks) <- readModBreaks hug (bi_tick_mod bid)
    
    157 160
       return $ modBreaks_locs brks ! bi_tick_index bid
    
    158 161
     
    
    159 162
     {- | Finds the enclosing top level function name -}
    
    ... ... @@ -162,7 +165,7 @@ getHistorySpan hug hist = do
    162 165
     -- for each tick.
    
    163 166
     findEnclosingDecls :: HUG.HomeUnitGraph -> BreakpointId -> IO [String]
    
    164 167
     findEnclosingDecls hug bid = do
    
    165
    -  brks <- readModBreaks hug (bi_tick_mod bid)
    
    168
    +  (_, brks) <- readModBreaks hug (bi_tick_mod bid)
    
    166 169
       return $ modBreaks_decls brks ! bi_tick_index bid
    
    167 170
     
    
    168 171
     -- | Update fixity environment in the current interactive context.
    
    ... ... @@ -349,15 +352,17 @@ handleRunStatus step expr bindings final_ids status history0 = do
    349 352
         --  - or one of the stepping options in @EvalOpts@ caused us to stop at one
    
    350 353
         EvalBreak apStack_ref (Just eval_break) resume_ctxt ccs -> do
    
    351 354
           let hug = hsc_HUG hsc_env
    
    352
    -      let ibi = evalBreakpointToId eval_break
    
    353
    -      bid       <- liftIO $ internalBreakIdToBreakId hug ibi
    
    354
    -      tick_brks <- liftIO $ readModBreaks hug (bi_tick_mod bid)
    
    355
    +      let ibi@InternalBreakpointId{ibi_info_index}
    
    356
    +            = evalBreakpointToId eval_break
    
    357
    +      bid            <- liftIO $ internalBreakIdToBreakId hug ibi
    
    358
    +      (_, tick_brks) <- liftIO $ readModBreaks hug (bi_tick_mod bid)
    
    359
    +      breakArray     <- getBreakArray interp ibi
    
    355 360
           let
    
    356 361
             span      = modBreaks_locs tick_brks ! bi_tick_index bid
    
    357 362
             decl      = intercalate "." $ modBreaks_decls tick_brks ! bi_tick_index bid
    
    358 363
     
    
    359 364
           -- Was this breakpoint explicitly enabled (ie. in @BreakArray@)?
    
    360
    -      bactive <- liftIO $ breakpointStatus interp (modBreaks_flags tick_brks) (bi_tick_index bid)
    
    365
    +      bactive <- liftIO $ breakpointStatus interp breakArray ibi_info_index
    
    361 366
     
    
    362 367
           apStack_fhv <- liftIO $ mkFinalizedHValue interp apStack_ref
    
    363 368
           resume_ctxt_fhv   <- liftIO $ mkFinalizedHValue interp resume_ctxt
    
    ... ... @@ -445,8 +450,8 @@ resumeExec step mbCnt
    445 450
                     -- When the user specified a break ignore count, set it
    
    446 451
                     -- in the interpreter
    
    447 452
                     case (mb_brkpt, mbCnt) of
    
    448
    -                  (Just (bid, _ibi), Just cnt) ->
    
    449
    -                    setupBreakpoint hsc_env bid cnt
    
    453
    +                  (Just (bid, ibi), Just cnt) ->
    
    454
    +                    setupBreakpoint interp ibi cnt
    
    450 455
                       _ -> return ()
    
    451 456
     
    
    452 457
                     let eval_opts = initEvalOpts dflags (enableGhcStepMode step)
    
    ... ... @@ -462,14 +467,16 @@ resumeExec step mbCnt
    462 467
                              | otherwise -> pure prevHistoryLst
    
    463 468
                     handleRunStatus step expr bindings final_ids status =<< hist'
    
    464 469
     
    
    465
    -setupBreakpoint :: GhcMonad m => HscEnv -> BreakpointId -> Int -> m ()   -- #19157
    
    466
    -setupBreakpoint hsc_env bi cnt = do
    
    467
    -  let modl = bi_tick_mod bi
    
    468
    -  modBreaks <- liftIO $ readModBreaks (hsc_HUG hsc_env) modl
    
    469
    -  let breakarray = modBreaks_flags modBreaks
    
    470
    -      interp = hscInterp hsc_env
    
    471
    -  _ <- liftIO $ GHCi.storeBreakpoint interp breakarray (bi_tick_index bi) cnt
    
    472
    -  pure ()
    
    470
    +setupBreakpoint :: GhcMonad m => Interp -> InternalBreakpointId -> Int -> m ()   -- #19157
    
    471
    +setupBreakpoint interp ibi cnt = do
    
    472
    +  breakArray <- getBreakArray interp ibi
    
    473
    +  liftIO $ GHCi.storeBreakpoint interp breakArray (ibi_info_index ibi) cnt
    
    474
    +
    
    475
    +getBreakArray :: GhcMonad m => Interp -> InternalBreakpointId -> m (ForeignRef BreakArray)
    
    476
    +getBreakArray interp InternalBreakpointId{ibi_info_mod} = do
    
    477
    +  breakArrays <- liftIO $ breakarray_env . linker_env . expectJust
    
    478
    +                       <$> Loader.getLoaderState interp
    
    479
    +  return $ expectJust $ lookupModuleEnv breakArrays ibi_info_mod
    
    473 480
     
    
    474 481
     back :: GhcMonad m => Int -> m ([Name], Int, SrcSpan)
    
    475 482
     back n = moveHist (+n)
    
    ... ... @@ -498,8 +505,8 @@ moveHist fn = do
    498 505
                 span <- case mb_info of
    
    499 506
                           Nothing  -> return $ mkGeneralSrcSpan (fsLit "<unknown>")
    
    500 507
                           Just (bid, _ibi) -> liftIO $ do
    
    501
    -                        brks <- readModBreaks (hsc_HUG hsc_env) (bi_tick_mod bid)
    
    502
    -                        return $ modBreaks_locs brks ! bi_tick_index bid
    
    508
    +                        (_, brks) <- readModBreaks (hsc_HUG hsc_env) (bi_tick_mod bid)
    
    509
    +                        return $ modBreaks_locs brks ! bi_tick_index bid -- todo: getBreakLoc
    
    503 510
                 (hsc_env1, names) <-
    
    504 511
                   liftIO $ bindLocalsAtBreakpoint hsc_env apStack span (snd <$> mb_info)
    
    505 512
                 let ic = hsc_IC hsc_env1
    
    ... ... @@ -560,10 +567,10 @@ bindLocalsAtBreakpoint hsc_env apStack span Nothing = do
    560 567
     -- of the breakpoint and the free variables of the expression.
    
    561 568
     bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi) = do
    
    562 569
        let hug = hsc_HUG hsc_env
    
    563
    -   info_brks <- readModBreaks hug (ibi_info_mod ibi)
    
    570
    +   (info_brks, _) <- readModBreaks hug (ibi_info_mod ibi)
    
    564 571
        bid       <- internalBreakIdToBreakId hug ibi
    
    565
    -   tick_brks <- readModBreaks hug (bi_tick_mod bid)
    
    566
    -   let info   = expectJust $ IntMap.lookup (ibi_info_index ibi) (modBreaks_breakInfo info_brks)
    
    572
    +   (_, tick_brks) <- readModBreaks hug (bi_tick_mod bid)
    
    573
    +   let info   = expectJust $ IntMap.lookup (ibi_info_index ibi) (imodBreaks_breakInfo info_brks)
    
    567 574
            interp = hscInterp hsc_env
    
    568 575
            occs   = modBreaks_vars tick_brks ! bi_tick_index bid
    
    569 576
     
    

  • compiler/GHC/StgToByteCode.hs
    ... ... @@ -33,7 +33,6 @@ import GHC.Platform.Profile
    33 33
     
    
    34 34
     import GHC.Runtime.Interpreter
    
    35 35
     import GHCi.FFI
    
    36
    -import GHCi.RemoteTypes
    
    37 36
     import GHC.Types.Basic
    
    38 37
     import GHC.Utils.Outputable
    
    39 38
     import GHC.Types.Name
    
    ... ... @@ -81,17 +80,13 @@ import Control.Monad
    81 80
     import Data.Char
    
    82 81
     
    
    83 82
     import GHC.Unit.Module
    
    84
    -import qualified GHC.Unit.Home.Graph as HUG
    
    85 83
     
    
    86
    -import Data.Array
    
    87 84
     import Data.Coerce (coerce)
    
    88 85
     #if MIN_VERSION_rts(1,0,3)
    
    89 86
     import qualified Data.ByteString.Char8 as BS
    
    90 87
     #endif
    
    91 88
     import Data.Map (Map)
    
    92
    -import Data.IntMap (IntMap)
    
    93 89
     import qualified Data.Map as Map
    
    94
    -import qualified Data.IntMap as IntMap
    
    95 90
     import qualified GHC.Data.FiniteMap as Map
    
    96 91
     import Data.Ord
    
    97 92
     import Data.Either ( partitionEithers )
    
    ... ... @@ -101,8 +96,8 @@ import qualified Data.IntSet as IntSet
    101 96
     import GHC.CoreToIface
    
    102 97
     
    
    103 98
     import Control.Monad.IO.Class
    
    104
    -import Control.Monad.Trans.Reader (ReaderT)
    
    105
    -import Control.Monad.Trans.State  (StateT)
    
    99
    +import Control.Monad.Trans.Reader (ReaderT(..))
    
    100
    +import Control.Monad.Trans.State  (StateT(..))
    
    106 101
     
    
    107 102
     -- -----------------------------------------------------------------------------
    
    108 103
     -- Generating byte code for a complete module
    
    ... ... @@ -128,8 +123,8 @@ byteCodeGen hsc_env this_mod binds tycs mb_modBreaks spt_entries
    128 123
                 flattenBind (StgNonRec b e) = [(b,e)]
    
    129 124
                 flattenBind (StgRec bs)     = bs
    
    130 125
     
    
    131
    -        (BcM_State{..}, proto_bcos) <-
    
    132
    -           runBc hsc_env this_mod mb_modBreaks $ do
    
    126
    +        (proto_bcos, BcM_State{..}) <-
    
    127
    +           runBc hsc_env this_mod $ do
    
    133 128
                  let flattened_binds = concatMap flattenBind (reverse lifted_binds)
    
    134 129
                  FlatBag.fromList (fromIntegral $ length flattened_binds) <$> mapM schemeTopBind flattened_binds
    
    135 130
     
    
    ... ... @@ -138,15 +133,12 @@ byteCodeGen hsc_env this_mod binds tycs mb_modBreaks spt_entries
    138 133
                (vcat (intersperse (char ' ') (map ppr $ elemsFlatBag proto_bcos)))
    
    139 134
     
    
    140 135
             let all_mod_breaks = case mb_modBreaks of
    
    141
    -             Just modBreaks -> Just (modBreaks, internalBreaks)
    
    136
    +             Just modBreaks -> Just (internalBreaks, modBreaks)
    
    142 137
                  Nothing        -> Nothing
    
    143 138
                  -- no modBreaks, thus drop all
    
    144 139
                  -- internalBreaks? Will we ever want to have internal breakpoints in
    
    145 140
                  -- a module for which we're not doing breakpoints at all? probably
    
    146
    -             -- not?
    
    147
    -             -- TODO: Consider always returning InternalBreaks;
    
    148
    -             -- TODO: Consider making ModBreaks a SUM that can be empty instead of using Maybe.
    
    149
    -        cbc <- assembleBCOs profile proto_bcos tycs strings mod_breaks spt_entries
    
    141
    +        cbc <- assembleBCOs profile proto_bcos tycs strings all_mod_breaks spt_entries
    
    150 142
     
    
    151 143
             -- Squash space leaks in the CompiledByteCode.  This is really
    
    152 144
             -- important, because when loading a set of modules into GHCi
    
    ... ... @@ -409,7 +401,7 @@ schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_id fvs) rhs) = do
    409 401
       current_mod <- getCurrentModule
    
    410 402
       liftIO (readModBreaksMaybe (hsc_HUG hsc_env) current_mod) >>= \case
    
    411 403
         Nothing -> pure code
    
    412
    -    Just ModBreaks {modBreaks_flags = breaks, modBreaks_ccs = cc_arr} -> do
    
    404
    +    Just _ -> do
    
    413 405
           platform <- profilePlatform <$> getProfile
    
    414 406
           let idOffSets = getVarOffSets platform d p fvs
    
    415 407
               ty_vars   = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)
    
    ... ... @@ -417,20 +409,13 @@ schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_id fvs) rhs) = do
    417 409
               toWord = fmap (\(i, wo) -> (i, fromIntegral wo))
    
    418 410
               breakInfo  = dehydrateCgBreakInfo ty_vars (map toWord idOffSets) tick_ty tick_id
    
    419 411
     
    
    420
    -      let info_mod = current_mod
    
    421
    -      infox <- newBreakInfo breakInfo
    
    412
    +      ibi <- newBreakInfo breakInfo
    
    422 413
     
    
    423
    -      let cc | Just interp <- hsc_interp hsc_env
    
    424
    -             , interpreterProfiled interp
    
    425
    -             = cc_arr ! bi_tick_index tick_id
    
    426
    -             | otherwise = toRemotePtr nullPtr
    
    427
    -
    
    428
    -          breakInstr = BRK_FUN breaks (InternalBreakpointId info_mod infox) cc
    
    429
    -
    
    430
    -      return $ breakInstr `consOL` code
    
    414
    +      return $ BRK_FUN ibi `consOL` code
    
    431 415
     schemeER_wrk d p rhs = schemeE d 0 p rhs
    
    432 416
     
    
    433
    --- | Determine the GHCi-allocated 'BreakArray' and module pointer for the module
    
    417
    +-- TODO: WHERE TO PUT
    
    418
    +-- Determine the GHCi-allocated 'BreakArray' and module pointer for the module
    
    434 419
     -- from which the breakpoint originates.
    
    435 420
     -- These are stored in 'ModBreaks' as remote pointers in order to allow the BCOs
    
    436 421
     -- to refer to pointers in GHCi's address space.
    
    ... ... @@ -449,19 +434,6 @@ schemeER_wrk d p rhs = schemeE d 0 p rhs
    449 434
     -- If the breakpoint is inlined from another module, look it up in the HUG (home unit graph).
    
    450 435
     -- If the module doesn't exist there, or if the 'ModBreaks' value is
    
    451 436
     -- uninitialized, skip the instruction (i.e. return Nothing).
    
    452
    -break_info ::
    
    453
    -  HscEnv ->
    
    454
    -  Module ->
    
    455
    -  Module ->
    
    456
    -  Maybe ModBreaks ->
    
    457
    -  BcM (Maybe ModBreaks)
    
    458
    -break_info hsc_env mod current_mod current_mod_breaks
    
    459
    -  | mod == current_mod
    
    460
    -  = pure current_mod_breaks
    
    461
    -  | otherwise
    
    462
    -  = liftIO (HUG.lookupHugByModule mod (hsc_HUG hsc_env)) >>= \case
    
    463
    -      Just hp -> pure $ getModBreaks hp
    
    464
    -      Nothing -> pure Nothing
    
    465 437
     
    
    466 438
     getVarOffSets :: Platform -> StackDepth -> BCEnv -> [Id] -> [Maybe (Id, WordOff)]
    
    467 439
     getVarOffSets platform depth env = map getOffSet
    
    ... ... @@ -2642,34 +2614,31 @@ data BcM_Env
    2642 2614
        = BcM_Env
    
    2643 2615
             { bcm_hsc_env    :: HscEnv
    
    2644 2616
             , bcm_module     :: Module -- current module (for breakpoints)
    
    2645
    -        , bcm_mod_breaks :: Maybe ModBreaks -- this module's ModBreaks
    
    2646 2617
             }
    
    2647 2618
     
    
    2648 2619
     data BcM_State
    
    2649 2620
        = BcM_State
    
    2650 2621
             { nextlabel      :: !Word32 -- ^ For generating local labels
    
    2651 2622
             , breakInfoIdx   :: !Int    -- ^ Next index for breakInfo array
    
    2652
    -        , internalBreaks :: InternalModBreaks
    
    2623
    +        , internalBreaks :: !InternalModBreaks
    
    2653 2624
               -- ^ Info at breakpoints occurrences. Indexed with
    
    2654 2625
               -- 'InternalBreakpointId'. See Note [Breakpoint identifiers] in
    
    2655 2626
               -- GHC.ByteCode.Breakpoints.
    
    2656 2627
             }
    
    2657 2628
     
    
    2658
    -newtype BcM r = BcM (BcM_Env -> BcM_State -> IO (BcM_State, r))
    
    2629
    +newtype BcM r = BcM (BcM_Env -> BcM_State -> IO (r, BcM_State))
    
    2659 2630
       deriving (Functor, Applicative, Monad, MonadIO)
    
    2660 2631
         via (ReaderT BcM_Env (StateT BcM_State IO))
    
    2661 2632
     
    
    2662
    -runBc :: HscEnv -> Module -> Maybe ModBreaks
    
    2663
    -      -> BcM r
    
    2664
    -      -> IO (BcM_State, r)
    
    2665
    -runBc hsc_env this_mod modBreaks (BcM m)
    
    2666
    -   = m (BcM_Env hsc_env this_mod modBreaks) (BcM_State 0 0 (mkInternalModBreaks this_mod mempty))
    
    2633
    +runBc :: HscEnv -> Module -> BcM r -> IO (r, BcM_State)
    
    2634
    +runBc hsc_env this_mod (BcM m)
    
    2635
    +   = m (BcM_Env hsc_env this_mod) (BcM_State 0 0 (mkInternalModBreaks this_mod mempty))
    
    2667 2636
     
    
    2668 2637
     instance HasDynFlags BcM where
    
    2669 2638
         getDynFlags = hsc_dflags <$> getHscEnv
    
    2670 2639
     
    
    2671 2640
     getHscEnv :: BcM HscEnv
    
    2672
    -getHscEnv = BcM $ \env st -> return (st, bcm_hsc_env env)
    
    2641
    +getHscEnv = BcM $ \env st -> return (bcm_hsc_env env, st)
    
    2673 2642
     
    
    2674 2643
     getProfile :: BcM Profile
    
    2675 2644
     getProfile = targetProfile <$> getDynFlags
    
    ... ... @@ -2686,12 +2655,12 @@ getLabelBc = BcM $ \_ st ->
    2686 2655
       do let nl = nextlabel st
    
    2687 2656
          when (nl == maxBound) $
    
    2688 2657
              panic "getLabelBc: Ran out of labels"
    
    2689
    -     return (st{nextlabel = nl + 1}, LocalLabel nl)
    
    2658
    +     return (LocalLabel nl, st{nextlabel = nl + 1})
    
    2690 2659
     
    
    2691 2660
     getLabelsBc :: Word32 -> BcM [LocalLabel]
    
    2692 2661
     getLabelsBc n = BcM $ \_ st ->
    
    2693 2662
       let ctr = nextlabel st
    
    2694
    -   in return (st{nextlabel = ctr+n}, coerce [ctr .. ctr+n-1])
    
    2663
    +   in return (coerce [ctr .. ctr+n-1], st{nextlabel = ctr+n})
    
    2695 2664
     
    
    2696 2665
     newBreakInfo :: CgBreakInfo -> BcM InternalBreakpointId
    
    2697 2666
     newBreakInfo info = BcM $ \env st ->
    
    ... ... @@ -2701,10 +2670,10 @@ newBreakInfo info = BcM $ \env st ->
    2701 2670
             { internalBreaks = addInternalBreak ibi info (internalBreaks st)
    
    2702 2671
             , breakInfoIdx = ix + 1
    
    2703 2672
             }
    
    2704
    -  in return (st', ibi)
    
    2673
    +  in return (ibi, st')
    
    2705 2674
     
    
    2706 2675
     getCurrentModule :: BcM Module
    
    2707
    -getCurrentModule = BcM $ \env st -> return (st, thisModule env)
    
    2676
    +getCurrentModule = BcM $ \env st -> return (bcm_module env, st)
    
    2708 2677
     
    
    2709 2678
     tickFS :: FastString
    
    2710 2679
     tickFS = fsLit "ticked"