Rodrigo Mesquita pushed to branch wip/romes/step-out-11 at Glasgow Haskell Compiler / GHC
Commits:
-
5da18c23
by Rodrigo Mesquita at 2025-07-18T18:33:54+01:00
12 changed files:
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/StgToByteCode.hs
- ghc/GHCi/UI.hs
- rts/Disassembler.c
- rts/Interpreter.c
- testsuite/tests/ghci.debugger/scripts/all.T
Changes:
| ... | ... | @@ -841,7 +841,7 @@ assembleI platform i = case i of |
| 841 | 841 | W8 -> emit_ bci_OP_INDEX_ADDR_08 []
|
| 842 | 842 | _ -> unsupported_width
|
| 843 | 843 | |
| 844 | - BRK_FUN ibi@(InternalBreakpointId info_mod infox) byteOff -> do
|
|
| 844 | + BRK_FUN ibi@(InternalBreakpointId info_mod infox) -> do
|
|
| 845 | 845 | p1 <- ptr $ BCOPtrBreakArray info_mod
|
| 846 | 846 | let -- cast that checks that round-tripping through Word16 doesn't change the value
|
| 847 | 847 | toW16 x = let r = fromIntegral x :: Word16
|
| ... | ... | @@ -852,7 +852,7 @@ assembleI platform i = case i of |
| 852 | 852 | info_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS $ moduleUnitId info_mod
|
| 853 | 853 | np <- lit1 $ BCONPtrCostCentre ibi
|
| 854 | 854 | emit_ bci_BRK_FUN [ Op p1, Op info_addr, Op info_unitid_addr
|
| 855 | - , SmallOp (toW16 infox), SmallOp (toW16 byteOff), Op np ]
|
|
| 855 | + , SmallOp (toW16 infox), Op np ]
|
|
| 856 | 856 | |
| 857 | 857 | BRK_ALTS active -> emit_ bci_BRK_ALTS [SmallOp (if active then 1 else 0)]
|
| 858 | 858 |
| 1 | 1 | {-# LANGUAGE RecordWildCards #-}
|
| 2 | -{-# LANGUAGE DerivingStrategies #-}
|
|
| 3 | 2 | |
| 4 | 3 | -- | Breakpoint information constructed during ByteCode generation.
|
| 5 | 4 | --
|
| ... | ... | @@ -16,7 +15,6 @@ module GHC.ByteCode.Breakpoints |
| 16 | 15 | |
| 17 | 16 | -- ** Internal breakpoint identifier
|
| 18 | 17 | , InternalBreakpointId(..), BreakInfoIndex
|
| 19 | - , InternalBreakLoc(..)
|
|
| 20 | 18 | |
| 21 | 19 | -- * Operations
|
| 22 | 20 | |
| ... | ... | @@ -25,7 +23,7 @@ module GHC.ByteCode.Breakpoints |
| 25 | 23 | |
| 26 | 24 | -- ** Source-level information operations
|
| 27 | 25 | , getBreakLoc, getBreakVars, getBreakDecls, getBreakCCS
|
| 28 | - , getBreakSourceId, getBreakSourceMod
|
|
| 26 | + , getBreakSourceId
|
|
| 29 | 27 | |
| 30 | 28 | -- * Utils
|
| 31 | 29 | , seqInternalModBreaks
|
| ... | ... | @@ -167,7 +165,7 @@ data CgBreakInfo |
| 167 | 165 | { cgb_tyvars :: ![IfaceTvBndr] -- ^ Type variables in scope at the breakpoint
|
| 168 | 166 | , cgb_vars :: ![Maybe (IfaceIdBndr, Word)]
|
| 169 | 167 | , cgb_resty :: !IfaceType
|
| 170 | - , cgb_tick_id :: !(Either InternalBreakLoc BreakpointId)
|
|
| 168 | + , cgb_tick_id :: !BreakpointId
|
|
| 171 | 169 | -- ^ This field records the original breakpoint tick identifier for this
|
| 172 | 170 | -- internal breakpoint info. It is used to convert a breakpoint
|
| 173 | 171 | -- *occurrence* index ('InternalBreakpointId') into a *definition* index
|
| ... | ... | @@ -175,19 +173,9 @@ data CgBreakInfo |
| 175 | 173 | --
|
| 176 | 174 | -- The modules of breakpoint occurrence and breakpoint definition are not
|
| 177 | 175 | -- 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]
|
|
| 182 | 176 | }
|
| 183 | 177 | -- See Note [Syncing breakpoint info] in GHC.Runtime.Eval
|
| 184 | 178 | |
| 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 | - |
|
| 191 | 179 | -- | Get an internal breakpoint info by 'InternalBreakpointId'
|
| 192 | 180 | getInternalBreak :: InternalBreakpointId -> InternalModBreaks -> CgBreakInfo
|
| 193 | 181 | getInternalBreak (InternalBreakpointId mod ix) imbs =
|
| ... | ... | @@ -208,36 +196,27 @@ assert_modules_match ibi_mod imbs_mod = |
| 208 | 196 | |
| 209 | 197 | -- | Get the source module and tick index for this breakpoint
|
| 210 | 198 | -- (as opposed to the module where this breakpoint occurs, which is in 'InternalBreakpointId')
|
| 211 | -getBreakSourceId :: InternalBreakpointId -> InternalModBreaks -> Either InternalBreakLoc BreakpointId
|
|
| 199 | +getBreakSourceId :: InternalBreakpointId -> InternalModBreaks -> BreakpointId
|
|
| 212 | 200 | getBreakSourceId (InternalBreakpointId ibi_mod ibi_ix) imbs =
|
| 213 | 201 | assert_modules_match ibi_mod (imodBreaks_module imbs) $
|
| 214 | 202 | let cgb = imodBreaks_breakInfo imbs IM.! ibi_ix
|
| 215 | 203 | in cgb_tick_id cgb
|
| 216 | 204 | |
| 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 | - |
|
| 226 | 205 | -- | Get the source span for this breakpoint
|
| 227 | 206 | getBreakLoc :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO SrcSpan
|
| 228 | -getBreakLoc = getBreakXXX modBreaks_locs (\(InternalBreakLoc x) -> x)
|
|
| 207 | +getBreakLoc = getBreakXXX modBreaks_locs
|
|
| 229 | 208 | |
| 230 | 209 | -- | Get the vars for this breakpoint
|
| 231 | 210 | getBreakVars :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [OccName]
|
| 232 | -getBreakVars = getBreakXXX modBreaks_vars (const [])
|
|
| 211 | +getBreakVars = getBreakXXX modBreaks_vars
|
|
| 233 | 212 | |
| 234 | 213 | -- | Get the decls for this breakpoint
|
| 235 | 214 | getBreakDecls :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO [String]
|
| 236 | -getBreakDecls = getBreakXXX modBreaks_decls (const [])
|
|
| 215 | +getBreakDecls = getBreakXXX modBreaks_decls
|
|
| 237 | 216 | |
| 238 | 217 | -- | Get the decls for this breakpoint
|
| 239 | -getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO (Maybe (String, String))
|
|
| 240 | -getBreakCCS = getBreakXXX (fmap Just . modBreaks_ccs) (const Nothing)
|
|
| 218 | +getBreakCCS :: (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO (String, String)
|
|
| 219 | +getBreakCCS = getBreakXXX modBreaks_ccs
|
|
| 241 | 220 | |
| 242 | 221 | -- | Internal utility to access a ModBreaks field at a particular breakpoint index
|
| 243 | 222 | --
|
| ... | ... | @@ -249,17 +228,14 @@ getBreakCCS = getBreakXXX (fmap Just . modBreaks_ccs) (const Nothing) |
| 249 | 228 | -- 'ModBreaks'. When the tick module is different, we need to look up the
|
| 250 | 229 | -- 'ModBreaks' in the HUG for that other module.
|
| 251 | 230 | --
|
| 252 | --- When there is no tick module (the breakpoint was generated at codegen), use
|
|
| 253 | --- the function on internal mod breaks.
|
|
| 254 | ---
|
|
| 255 | 231 | -- To avoid cyclic dependencies, we instead receive a function that looks up
|
| 256 | 232 | -- 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 =
|
|
| 233 | +getBreakXXX :: (ModBreaks -> Array BreakTickIndex a) -> (Module -> IO ModBreaks) -> InternalBreakpointId -> InternalModBreaks -> IO a
|
|
| 234 | +getBreakXXX view lookupModule (InternalBreakpointId ibi_mod ibi_ix) imbs =
|
|
| 259 | 235 | assert_modules_match ibi_mod (imodBreaks_module imbs) $ do
|
| 260 | 236 | let cgb = imodBreaks_breakInfo imbs IM.! ibi_ix
|
| 261 | 237 | case cgb_tick_id cgb of
|
| 262 | - Right BreakpointId{bi_tick_mod, bi_tick_index}
|
|
| 238 | + BreakpointId{bi_tick_mod, bi_tick_index}
|
|
| 263 | 239 | | bi_tick_mod == ibi_mod
|
| 264 | 240 | -> do
|
| 265 | 241 | let these_mbs = imodBreaks_modBreaks imbs
|
| ... | ... | @@ -268,8 +244,6 @@ getBreakXXX view viewInternal lookupModule (InternalBreakpointId ibi_mod ibi_ix) |
| 268 | 244 | -> do
|
| 269 | 245 | other_mbs <- lookupModule bi_tick_mod
|
| 270 | 246 | return $ view other_mbs ! bi_tick_index
|
| 271 | - Left l ->
|
|
| 272 | - return $ viewInternal l
|
|
| 273 | 247 | |
| 274 | 248 | --------------------------------------------------------------------------------
|
| 275 | 249 | -- Instances
|
| ... | ... | @@ -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 !ByteOff
|
|
| 261 | + | BRK_FUN !InternalBreakpointId
|
|
| 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,9 @@ 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 info_mod infox) bo)
|
|
| 457 | + ppr (BRK_FUN (InternalBreakpointId info_mod infox))
|
|
| 458 | 458 | = text "BRK_FUN" <+> text "<breakarray>"
|
| 459 | 459 | <+> ppr info_mod <+> ppr infox
|
| 460 | - <+> ppr bo
|
|
| 461 | 460 | <+> text "<cc>"
|
| 462 | 461 | ppr (BRK_ALTS active) = text "BRK_ALTS" <+> ppr active
|
| 463 | 462 | #if MIN_VERSION_rts(1,0,3)
|
| ... | ... | @@ -50,6 +50,8 @@ import GHC.Prelude |
| 50 | 50 | |
| 51 | 51 | import GHC.StgToCmm.Types
|
| 52 | 52 | |
| 53 | +import GHC.ByteCode.Types
|
|
| 54 | + |
|
| 53 | 55 | import GHC.Core
|
| 54 | 56 | import GHC.Core.TyCon hiding ( pprPromotionQuote )
|
| 55 | 57 | import GHC.Core.Coercion.Axiom
|
| ... | ... | @@ -58,7 +58,6 @@ import GHCi.RemoteTypes |
| 58 | 58 | import GHC.Iface.Load
|
| 59 | 59 | import GHCi.Message (ConInfoTable(..), LoadedDLL)
|
| 60 | 60 | |
| 61 | -import GHC.ByteCode.Breakpoints
|
|
| 62 | 61 | import GHC.ByteCode.Linker
|
| 63 | 62 | import GHC.ByteCode.Asm
|
| 64 | 63 | import GHC.ByteCode.Types
|
| ... | ... | @@ -1712,10 +1711,8 @@ allocateCCS interp ce mbss |
| 1712 | 1711 | let count = 1 + (maybe 0 fst $ IM.lookupMax imodBreaks_breakInfo)
|
| 1713 | 1712 | let ccs = IM.map
|
| 1714 | 1713 | (\info ->
|
| 1715 | - case cgb_tick_id info of
|
|
| 1716 | - Right bi -> fromMaybe (toRemotePtr nullPtr)
|
|
| 1717 | - (M.lookup bi ccss)
|
|
| 1718 | - Left InternalBreakLoc{} -> toRemotePtr nullPtr
|
|
| 1714 | + fromMaybe (toRemotePtr nullPtr)
|
|
| 1715 | + (M.lookup (cgb_tick_id info) ccss)
|
|
| 1719 | 1716 | )
|
| 1720 | 1717 | imodBreaks_breakInfo
|
| 1721 | 1718 | assertPpr (count == length ccs)
|
| ... | ... | @@ -253,11 +253,8 @@ mkBreakpointOccurrences = do |
| 253 | 253 | let imod = modBreaks_module $ imodBreaks_modBreaks ibrks
|
| 254 | 254 | IntMap.foldrWithKey (\info_ix cgi bmp -> do
|
| 255 | 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
|
|
| 256 | + let BreakpointId tick_mod tick_ix = cgb_tick_id cgi
|
|
| 257 | + extendModuleEnvWith (IntMap.unionWith (S.<>)) bmp tick_mod (IntMap.singleton tick_ix [ibi])
|
|
| 261 | 258 | ) bmp0 (imodBreaks_breakInfo ibrks)
|
| 262 | 259 | |
| 263 | 260 | --------------------------------------------------------------------------------
|
| ... | ... | @@ -290,7 +287,7 @@ getCurrentBreakModule = do |
| 290 | 287 | Nothing -> pure Nothing
|
| 291 | 288 | Just ibi -> do
|
| 292 | 289 | brks <- readIModBreaks hug ibi
|
| 293 | - return $ Just $ getBreakSourceMod ibi brks
|
|
| 290 | + return $ Just $ bi_tick_mod $ getBreakSourceId ibi brks
|
|
| 294 | 291 | ix ->
|
| 295 | 292 | Just <$> getHistoryModule hug (resumeHistory r !! (ix-1))
|
| 296 | 293 |
| ... | ... | @@ -151,7 +151,7 @@ getHistoryModule :: HUG.HomeUnitGraph -> History -> IO Module |
| 151 | 151 | getHistoryModule hug hist = do
|
| 152 | 152 | let ibi = historyBreakpointId hist
|
| 153 | 153 | brks <- readIModBreaks hug ibi
|
| 154 | - return $ getBreakSourceMod ibi brks
|
|
| 154 | + return $ bi_tick_mod $ getBreakSourceId ibi brks
|
|
| 155 | 155 | |
| 156 | 156 | getHistorySpan :: HUG.HomeUnitGraph -> History -> IO SrcSpan
|
| 157 | 157 | getHistorySpan hug hist = do
|
| ... | ... | @@ -63,7 +63,7 @@ import GHC.StgToCmm.Closure ( NonVoid(..), fromNonVoid, idPrimRepU, |
| 63 | 63 | assertNonVoidIds, assertNonVoidStgArgs )
|
| 64 | 64 | import GHC.StgToCmm.Layout
|
| 65 | 65 | import GHC.Runtime.Heap.Layout hiding (WordOff, ByteOff, wordsToBytes)
|
| 66 | -import GHC.Runtime.Interpreter ( interpreterProfiled, readIModModBreaks )
|
|
| 66 | +import GHC.Runtime.Interpreter ( interpreterProfiled )
|
|
| 67 | 67 | import GHC.Data.Bitmap
|
| 68 | 68 | import GHC.Data.FlatBag as FlatBag
|
| 69 | 69 | import GHC.Data.OrdList
|
| ... | ... | @@ -99,7 +99,6 @@ import GHC.CoreToIface |
| 99 | 99 | import Control.Monad.IO.Class
|
| 100 | 100 | import Control.Monad.Trans.Reader (ReaderT(..))
|
| 101 | 101 | import Control.Monad.Trans.State (StateT(..))
|
| 102 | -import Data.Array ((!))
|
|
| 103 | 102 | |
| 104 | 103 | -- -----------------------------------------------------------------------------
|
| 105 | 104 | -- Generating byte code for a complete module
|
| ... | ... | @@ -394,30 +393,26 @@ schemeR_wrk fvs nm original_body (args, body) |
| 394 | 393 | -- | Introduce break instructions for ticked expressions.
|
| 395 | 394 | -- If no breakpoint information is available, the instruction is omitted.
|
| 396 | 395 | schemeER_wrk :: StackDepth -> BCEnv -> CgStgExpr -> BcM BCInstrList
|
| 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
|
|
| 396 | +schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_id fvs) rhs) = do
|
|
| 397 | + code <- schemeE d 0 p rhs
|
|
| 398 | + mb_current_mod_breaks <- getCurrentModBreaks
|
|
| 399 | + case mb_current_mod_breaks of
|
|
| 400 | + -- if we're not generating ModBreaks for this module for some reason, we
|
|
| 401 | + -- can't store breakpoint occurrence information.
|
|
| 402 | + Nothing -> pure code
|
|
| 403 | + Just current_mod_breaks -> do
|
|
| 404 | + platform <- profilePlatform <$> getProfile
|
|
| 405 | + let idOffSets = getVarOffSets platform d p fvs
|
|
| 406 | + ty_vars = tyCoVarsOfTypesWellScoped (tick_ty:map idType fvs)
|
|
| 407 | + toWord :: Maybe (Id, WordOff) -> Maybe (Id, Word)
|
|
| 408 | + toWord = fmap (\(i, wo) -> (i, fromIntegral wo))
|
|
| 409 | + breakInfo = dehydrateCgBreakInfo ty_vars (map toWord idOffSets) tick_ty tick_id
|
|
| 410 | + |
|
| 411 | + let info_mod = modBreaks_module current_mod_breaks
|
|
| 412 | + infox <- newBreakInfo breakInfo
|
|
| 420 | 413 | |
| 414 | + let breakInstr = BRK_FUN (InternalBreakpointId info_mod infox)
|
|
| 415 | + return $ breakInstr `consOL` code
|
|
| 421 | 416 | schemeER_wrk d p rhs = schemeE d 0 p rhs
|
| 422 | 417 | |
| 423 | 418 | getVarOffSets :: Platform -> StackDepth -> BCEnv -> [Id] -> [Maybe (Id, WordOff)]
|
| ... | ... | @@ -619,7 +614,7 @@ schemeE d s p (StgTick _ rhs) = schemeE d s p rhs |
| 619 | 614 | schemeE d s p (StgCase scrut _ _ []) = schemeE d s p scrut
|
| 620 | 615 | |
| 621 | 616 | schemeE d s p (StgCase scrut bndr _ alts)
|
| 622 | - = doCase d s p Nothing scrut bndr alts
|
|
| 617 | + = doCase d s p scrut bndr alts
|
|
| 623 | 618 | |
| 624 | 619 | |
| 625 | 620 | {-
|
| ... | ... | @@ -1111,15 +1106,11 @@ doCase |
| 1111 | 1106 | :: StackDepth
|
| 1112 | 1107 | -> Sequel
|
| 1113 | 1108 | -> 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]
|
|
| 1118 | 1109 | -> CgStgExpr
|
| 1119 | 1110 | -> Id
|
| 1120 | 1111 | -> [CgStgAlt]
|
| 1121 | 1112 | -> BcM BCInstrList
|
| 1122 | -doCase d s p m_bid scrut bndr alts
|
|
| 1113 | +doCase d s p scrut bndr alts
|
|
| 1123 | 1114 | = do
|
| 1124 | 1115 | profile <- getProfile
|
| 1125 | 1116 | hsc_env <- getHscEnv
|
| ... | ... | @@ -1336,28 +1327,11 @@ doCase d s p m_bid scrut bndr alts |
| 1336 | 1327 | let alt_final1
|
| 1337 | 1328 | | ubx_tuple_frame = SLIDE 0 2 `consOL` alt_final0
|
| 1338 | 1329 | | otherwise = alt_final0
|
| 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
|
|
| 1330 | + alt_final
|
|
| 1331 | + | gopt Opt_InsertBreakpoints (hsc_dflags hsc_env)
|
|
| 1332 | + -- See Note [Debugger: BRK_ALTS]
|
|
| 1333 | + = BRK_ALTS False `consOL` alt_final1
|
|
| 1334 | + | otherwise = alt_final1
|
|
| 1361 | 1335 | |
| 1362 | 1336 | add_bco_name <- shouldAddBcoName
|
| 1363 | 1337 | let
|
| ... | ... | @@ -1377,24 +1351,6 @@ doCase d s p m_bid scrut bndr alts |
| 1377 | 1351 | _ -> panic "schemeE(StgCase).push_alts"
|
| 1378 | 1352 | in return (PUSH_ALTS alt_bco scrut_rep `consOL` scrut_code)
|
| 1379 | 1353 | |
| 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 | - |
|
| 1398 | 1354 | {-
|
| 1399 | 1355 | Note [Debugger: BRK_ALTS]
|
| 1400 | 1356 | ~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -2715,19 +2671,14 @@ getLabelsBc n = BcM $ \_ st -> |
| 2715 | 2671 | let ctr = nextlabel st
|
| 2716 | 2672 | in return (coerce [ctr .. ctr+n-1], st{nextlabel = ctr+n})
|
| 2717 | 2673 | |
| 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')
|
|
| 2674 | +newBreakInfo :: CgBreakInfo -> BcM Int
|
|
| 2675 | +newBreakInfo info = BcM $ \_ st ->
|
|
| 2676 | + let ix = breakInfoIdx st
|
|
| 2677 | + st' = st
|
|
| 2678 | + { breakInfo = IntMap.insert ix info (breakInfo st)
|
|
| 2679 | + , breakInfoIdx = ix + 1
|
|
| 2680 | + }
|
|
| 2681 | + in return (ix, st')
|
|
| 2731 | 2682 | |
| 2732 | 2683 | getCurrentModule :: BcM Module
|
| 2733 | 2684 | getCurrentModule = BcM $ \env st -> return (bcm_module env, st)
|
| ... | ... | @@ -2740,7 +2691,7 @@ tickFS = fsLit "ticked" |
| 2740 | 2691 | |
| 2741 | 2692 | -- Dehydrating CgBreakInfo
|
| 2742 | 2693 | |
| 2743 | -dehydrateCgBreakInfo :: [TyVar] -> [Maybe (Id, Word)] -> Type -> Either InternalBreakLoc BreakpointId -> CgBreakInfo
|
|
| 2694 | +dehydrateCgBreakInfo :: [TyVar] -> [Maybe (Id, Word)] -> Type -> BreakpointId -> CgBreakInfo
|
|
| 2744 | 2695 | dehydrateCgBreakInfo ty_vars idOffSets tick_ty bid =
|
| 2745 | 2696 | CgBreakInfo
|
| 2746 | 2697 | { cgb_tyvars = map toIfaceTvBndr ty_vars
|
| ... | ... | @@ -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, InternalBreakpointId(..), getBreakSourceId, getBreakSourceMod)
|
|
| 48 | +import GHC.ByteCode.Breakpoints (imodBreaks_modBreaks, InternalBreakpointId(..), getBreakSourceId)
|
|
| 49 | 49 | import GHC.Runtime.Interpreter
|
| 50 | 50 | import GHCi.RemoteTypes
|
| 51 | 51 | import GHCi.BreakArray( breakOn, breakOff )
|
| ... | ... | @@ -1621,7 +1621,7 @@ toBreakIdAndLocation (Just inf) = do |
| 1621 | 1621 | brks <- liftIO $ readIModBreaks hug inf
|
| 1622 | 1622 | let bi = getBreakSourceId inf brks
|
| 1623 | 1623 | return $ listToMaybe [ id_loc | id_loc@(_,loc) <- IntMap.assocs (breaks st),
|
| 1624 | - Right (breakId loc) == bi ]
|
|
| 1624 | + breakId loc == bi ]
|
|
| 1625 | 1625 | |
| 1626 | 1626 | printStoppedAtBreakInfo :: GHC.GhcMonad m => Resume -> [Name] -> m ()
|
| 1627 | 1627 | printStoppedAtBreakInfo res names = do
|
| ... | ... | @@ -3825,7 +3825,7 @@ pprStopped res = do |
| 3825 | 3825 | hug <- hsc_HUG <$> GHC.getSession
|
| 3826 | 3826 | brks <- liftIO $ readIModBreaks hug ibi
|
| 3827 | 3827 | return $ Just $ moduleName $
|
| 3828 | - getBreakSourceMod ibi brks
|
|
| 3828 | + bi_tick_mod $ getBreakSourceId ibi brks
|
|
| 3829 | 3829 | return $
|
| 3830 | 3830 | text "Stopped in"
|
| 3831 | 3831 | <+> ((case mb_mod_name of
|
| ... | ... | @@ -85,18 +85,16 @@ disInstr ( StgBCO *bco, int pc ) |
| 85 | 85 | |
| 86 | 86 | switch (instr & 0xff) {
|
| 87 | 87 | case bci_BRK_FUN: {
|
| 88 | - W_ p1, info_mod, info_unit_id, info_wix, byte_off, np;
|
|
| 88 | + W_ p1, info_mod, info_unit_id, info_wix, np;
|
|
| 89 | 89 | p1 = BCO_GET_LARGE_ARG;
|
| 90 | 90 | info_mod = BCO_GET_LARGE_ARG;
|
| 91 | 91 | info_unit_id = BCO_GET_LARGE_ARG;
|
| 92 | 92 | info_wix = BCO_NEXT;
|
| 93 | - byte_off = BCO_NEXT;
|
|
| 94 | 93 | np = BCO_GET_LARGE_ARG;
|
| 95 | 94 | debugBelch ("BRK_FUN " ); printPtr( ptrs[p1] );
|
| 96 | 95 | debugBelch(" %" FMT_Word, literals[info_mod] );
|
| 97 | 96 | debugBelch(" %" FMT_Word, literals[info_unit_id] );
|
| 98 | 97 | debugBelch(" %" FMT_Word, info_wix );
|
| 99 | - debugBelch(" %" FMT_Word, byte_off );
|
|
| 100 | 98 | CostCentre* cc = (CostCentre*)literals[np];
|
| 101 | 99 | if (cc) {
|
| 102 | 100 | debugBelch(" %s", cc->label);
|
| ... | ... | @@ -747,7 +747,6 @@ interpretBCO (Capability* cap) |
| 747 | 747 | /* info_mod_name = */ BCO_GET_LARGE_ARG;
|
| 748 | 748 | /* info_mod_id = */ BCO_GET_LARGE_ARG;
|
| 749 | 749 | arg4_info_index = BCO_NEXT;
|
| 750 | - /* byte_off = BCO_NEXT; */
|
|
| 751 | 750 | |
| 752 | 751 | StgPtr* ptrs = (StgPtr*)(&bco->ptrs->payload[0]);
|
| 753 | 752 | StgArrBytes* breakPoints = (StgArrBytes *) BCO_PTR(arg1_brk_array);
|
| ... | ... | @@ -1573,9 +1572,9 @@ run_BCO: |
| 1573 | 1572 | /* check for a breakpoint on the beginning of a let binding */
|
| 1574 | 1573 | case bci_BRK_FUN:
|
| 1575 | 1574 | {
|
| 1576 | - W_ arg1_brk_array, arg2_info_mod_name, arg3_info_mod_id, arg4_info_index, arg5_byte_off;
|
|
| 1575 | + W_ arg1_brk_array, arg2_info_mod_name, arg3_info_mod_id, arg4_info_index;
|
|
| 1577 | 1576 | #if defined(PROFILING)
|
| 1578 | - W_ arg6_cc;
|
|
| 1577 | + W_ arg5_cc;
|
|
| 1579 | 1578 | #endif
|
| 1580 | 1579 | StgArrBytes *breakPoints;
|
| 1581 | 1580 | int returning_from_break, stop_next_breakpoint;
|
| ... | ... | @@ -1593,9 +1592,8 @@ run_BCO: |
| 1593 | 1592 | arg2_info_mod_name = BCO_GET_LARGE_ARG;
|
| 1594 | 1593 | arg3_info_mod_id = BCO_GET_LARGE_ARG;
|
| 1595 | 1594 | arg4_info_index = BCO_NEXT;
|
| 1596 | - arg5_byte_off = BCO_NEXT;
|
|
| 1597 | 1595 | #if defined(PROFILING)
|
| 1598 | - arg6_cc = BCO_GET_LARGE_ARG;
|
|
| 1596 | + arg5_cc = BCO_GET_LARGE_ARG;
|
|
| 1599 | 1597 | #else
|
| 1600 | 1598 | BCO_GET_LARGE_ARG;
|
| 1601 | 1599 | #endif
|
| ... | ... | @@ -1615,7 +1613,7 @@ run_BCO: |
| 1615 | 1613 | |
| 1616 | 1614 | #if defined(PROFILING)
|
| 1617 | 1615 | cap->r.rCCCS = pushCostCentre(cap->r.rCCCS,
|
| 1618 | - (CostCentre*)BCO_LIT(arg6_cc));
|
|
| 1616 | + (CostCentre*)BCO_LIT(arg5_cc));
|
|
| 1619 | 1617 | #endif
|
| 1620 | 1618 | |
| 1621 | 1619 | // if we are returning from a break then skip this section
|
| ... | ... | @@ -1655,12 +1653,7 @@ run_BCO: |
| 1655 | 1653 | // copy the contents of the top stack frame into the AP_STACK
|
| 1656 | 1654 | for (i = 2; i < size_words; i++)
|
| 1657 | 1655 | {
|
| 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);
|
|
| 1656 | + new_aps->payload[i] = (StgClosure *)ReadSpW(i-2);
|
|
| 1664 | 1657 | }
|
| 1665 | 1658 | |
| 1666 | 1659 | // No write barrier is needed here as this is a new allocation
|
| ... | ... | @@ -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', [extra_hc_opts('-O -fno-unoptimized-core-for-interpreter'), extra_files(['T26042c.hs'])], ghci_script, ['T26042c.script'])
|
|
| 150 | +test('T26042c', [expect_broken(26042),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
|