Rodrigo Mesquita pushed to branch wip/romes/step-out-9 at Glasgow Haskell Compiler / GHC
Commits:
-
e610933e
by Rodrigo Mesquita at 2025-06-30T20:10:58+01:00
-
ba684e79
by Rodrigo Mesquita at 2025-06-30T20:10:58+01:00
-
2764f1f6
by Rodrigo Mesquita at 2025-06-30T20:10:58+01:00
-
8c302392
by Rodrigo Mesquita at 2025-06-30T20:10:58+01:00
-
affa8dbc
by Rodrigo Mesquita at 2025-06-30T20:10:58+01:00
-
819bb93f
by Rodrigo Mesquita at 2025-06-30T20:10:58+01:00
27 changed files:
- compiler/GHC.hs
- compiler/GHC/Core/FVs.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Map/Expr.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/Subst.hs
- compiler/GHC/Core/Tidy.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToIface.hs
- compiler/GHC/CoreToStg.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- compiler/GHC/Stg/BcPrep.hs
- compiler/GHC/Stg/FVs.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Types/Breakpoint.hs
- compiler/GHC/Types/Tickish.hs
- ghc/GHCi/UI.hs
Changes:
| ... | ... | @@ -1899,7 +1899,7 @@ getGHCiMonad :: GhcMonad m => m Name |
| 1899 | 1899 | getGHCiMonad = fmap (ic_monad . hsc_IC) getSession
|
| 1900 | 1900 | |
| 1901 | 1901 | getHistorySpan :: GhcMonad m => History -> m SrcSpan
|
| 1902 | -getHistorySpan h = withSession $ \hsc_env -> liftIO $ GHC.Runtime.Eval.getHistorySpan hsc_env h
|
|
| 1902 | +getHistorySpan h = withSession $ \hsc_env -> liftIO $ GHC.Runtime.Eval.getHistorySpan (hsc_HUG hsc_env) h
|
|
| 1903 | 1903 | |
| 1904 | 1904 | obtainTermFromVal :: GhcMonad m => Int -> Bool -> Type -> a -> m Term
|
| 1905 | 1905 | obtainTermFromVal bound force ty a = withSession $ \hsc_env ->
|
| ... | ... | @@ -287,7 +287,7 @@ exprs_fvs :: [CoreExpr] -> FV |
| 287 | 287 | exprs_fvs exprs = mapUnionFV expr_fvs exprs
|
| 288 | 288 | |
| 289 | 289 | tickish_fvs :: CoreTickish -> FV
|
| 290 | -tickish_fvs (Breakpoint _ _ ids _) = FV.mkFVs ids
|
|
| 290 | +tickish_fvs (Breakpoint _ _ ids) = FV.mkFVs ids
|
|
| 291 | 291 | tickish_fvs _ = emptyFV
|
| 292 | 292 | |
| 293 | 293 | {- **********************************************************************
|
| ... | ... | @@ -759,8 +759,8 @@ freeVars = go |
| 759 | 759 | , AnnTick tickish expr2 )
|
| 760 | 760 | where
|
| 761 | 761 | expr2 = go expr
|
| 762 | - tickishFVs (Breakpoint _ _ ids _) = mkDVarSet ids
|
|
| 763 | - tickishFVs _ = emptyDVarSet
|
|
| 762 | + tickishFVs (Breakpoint _ _ ids) = mkDVarSet ids
|
|
| 763 | + tickishFVs _ = emptyDVarSet
|
|
| 764 | 764 | |
| 765 | 765 | go (Type ty) = (tyCoVarsOfTypeDSet ty, AnnType ty)
|
| 766 | 766 | go (Coercion co) = (tyCoVarsOfCoDSet co, AnnCoercion co) |
| ... | ... | @@ -897,8 +897,8 @@ lintCoreExpr (Cast expr co) |
| 897 | 897 | |
| 898 | 898 | lintCoreExpr (Tick tickish expr)
|
| 899 | 899 | = do { case tickish of
|
| 900 | - Breakpoint _ _ ids _ -> forM_ ids $ \id -> lintIdOcc id 0
|
|
| 901 | - _ -> return ()
|
|
| 900 | + Breakpoint _ _ ids -> forM_ ids $ \id -> lintIdOcc id 0
|
|
| 901 | + _ -> return ()
|
|
| 902 | 902 | ; markAllJoinsBadIf block_joins $ lintCoreExpr expr }
|
| 903 | 903 | where
|
| 904 | 904 | block_joins = not (tickish `tickishScopesLike` SoftScope)
|
| ... | ... | @@ -198,11 +198,10 @@ eqDeBruijnExpr (D env1 e1) (D env2 e2) = go e1 e2 where |
| 198 | 198 | |
| 199 | 199 | eqDeBruijnTickish :: DeBruijn CoreTickish -> DeBruijn CoreTickish -> Bool
|
| 200 | 200 | eqDeBruijnTickish (D env1 t1) (D env2 t2) = go t1 t2 where
|
| 201 | - go (Breakpoint lext lid lids lmod) (Breakpoint rext rid rids rmod)
|
|
| 201 | + go (Breakpoint lext lid lids) (Breakpoint rext rid rids)
|
|
| 202 | 202 | = lid == rid
|
| 203 | 203 | && D env1 lids == D env2 rids
|
| 204 | 204 | && lext == rext
|
| 205 | - && lmod == rmod
|
|
| 206 | 205 | go l r = l == r
|
| 207 | 206 | |
| 208 | 207 | -- Compares for equality, modulo alpha
|
| ... | ... | @@ -2501,7 +2501,7 @@ occAnal env (Tick tickish body) |
| 2501 | 2501 | -- For a non-soft tick scope, we can inline lambdas only, so we
|
| 2502 | 2502 | -- abandon tail calls, and do markAllInsideLam too: usage_lam
|
| 2503 | 2503 | |
| 2504 | - | Breakpoint _ _ ids _ <- tickish
|
|
| 2504 | + | Breakpoint _ _ ids <- tickish
|
|
| 2505 | 2505 | = -- Never substitute for any of the Ids in a Breakpoint
|
| 2506 | 2506 | addManyOccs usage_lam (mkVarSet ids)
|
| 2507 | 2507 |
| ... | ... | @@ -1461,8 +1461,8 @@ simplTick env tickish expr cont |
| 1461 | 1461 | |
| 1462 | 1462 | |
| 1463 | 1463 | simplTickish env tickish
|
| 1464 | - | Breakpoint ext n ids modl <- tickish
|
|
| 1465 | - = Breakpoint ext n (mapMaybe (getDoneId . substId env) ids) modl
|
|
| 1464 | + | Breakpoint ext bid ids <- tickish
|
|
| 1465 | + = Breakpoint ext bid (mapMaybe (getDoneId . substId env) ids)
|
|
| 1466 | 1466 | | otherwise = tickish
|
| 1467 | 1467 | |
| 1468 | 1468 | -- Push type application and coercion inside a tick
|
| ... | ... | @@ -31,6 +31,7 @@ import GHC.Prelude |
| 31 | 31 | |
| 32 | 32 | import GHC.Core
|
| 33 | 33 | import GHC.Core.Stats (exprStats)
|
| 34 | +import GHC.Types.Breakpoint
|
|
| 34 | 35 | import GHC.Types.Fixity (LexicalFixity(..))
|
| 35 | 36 | import GHC.Types.Literal( pprLiteral )
|
| 36 | 37 | import GHC.Types.Name( pprInfixName, pprPrefixName )
|
| ... | ... | @@ -694,10 +695,10 @@ instance Outputable (XTickishId pass) => Outputable (GenTickish pass) where |
| 694 | 695 | ppr modl, comma,
|
| 695 | 696 | ppr ix,
|
| 696 | 697 | text ">"]
|
| 697 | - ppr (Breakpoint _ext ix vars modl) =
|
|
| 698 | + ppr (Breakpoint _ext bid vars) =
|
|
| 698 | 699 | hcat [text "break<",
|
| 699 | - ppr modl, comma,
|
|
| 700 | - ppr ix,
|
|
| 700 | + ppr (bi_tick_mod bid), comma,
|
|
| 701 | + ppr (bi_tick_index bid),
|
|
| 701 | 702 | text ">",
|
| 702 | 703 | parens (hcat (punctuate comma (map ppr vars)))]
|
| 703 | 704 | ppr (ProfNote { profNoteCC = cc,
|
| ... | ... | @@ -602,8 +602,8 @@ substDVarSet subst@(Subst _ _ tv_env cv_env) fvs |
| 602 | 602 | ------------------
|
| 603 | 603 | -- | Drop free vars from the breakpoint if they have a non-variable substitution.
|
| 604 | 604 | substTickish :: Subst -> CoreTickish -> CoreTickish
|
| 605 | -substTickish subst (Breakpoint ext n ids modl)
|
|
| 606 | - = Breakpoint ext n (mapMaybe do_one ids) modl
|
|
| 605 | +substTickish subst (Breakpoint ext bid ids)
|
|
| 606 | + = Breakpoint ext bid (mapMaybe do_one ids)
|
|
| 607 | 607 | where
|
| 608 | 608 | do_one = getIdFromTrivialExpr_maybe . lookupIdSubst subst
|
| 609 | 609 |
| ... | ... | @@ -235,8 +235,8 @@ tidyAlt env (Alt con vs rhs) |
| 235 | 235 | |
| 236 | 236 | ------------ Tickish --------------
|
| 237 | 237 | tidyTickish :: TidyEnv -> CoreTickish -> CoreTickish
|
| 238 | -tidyTickish env (Breakpoint ext ix ids modl)
|
|
| 239 | - = Breakpoint ext ix (map (tidyVarOcc env) ids) modl
|
|
| 238 | +tidyTickish env (Breakpoint ext bid ids)
|
|
| 239 | + = Breakpoint ext bid (map (tidyVarOcc env) ids)
|
|
| 240 | 240 | tidyTickish _ other_tickish = other_tickish
|
| 241 | 241 | |
| 242 | 242 | ------------ Rules --------------
|
| ... | ... | @@ -2492,11 +2492,10 @@ cheapEqExpr' ignoreTick e1 e2 |
| 2492 | 2492 | |
| 2493 | 2493 | -- Used by diffBinds, which is itself only used in GHC.Core.Lint.lintAnnots
|
| 2494 | 2494 | eqTickish :: RnEnv2 -> CoreTickish -> CoreTickish -> Bool
|
| 2495 | -eqTickish env (Breakpoint lext lid lids lmod) (Breakpoint rext rid rids rmod)
|
|
| 2495 | +eqTickish env (Breakpoint lext lid lids) (Breakpoint rext rid rids)
|
|
| 2496 | 2496 | = lid == rid &&
|
| 2497 | 2497 | map (rnOccL env) lids == map (rnOccR env) rids &&
|
| 2498 | - lext == rext &&
|
|
| 2499 | - lmod == rmod
|
|
| 2498 | + lext == rext
|
|
| 2500 | 2499 | eqTickish _ l r = l == r
|
| 2501 | 2500 | |
| 2502 | 2501 | -- | Finds differences between core bindings, see @diffExpr@.
|
| ... | ... | @@ -586,8 +586,8 @@ toIfaceTickish (ProfNote cc tick push) = IfaceSCC cc tick push |
| 586 | 586 | toIfaceTickish (HpcTick modl ix) = IfaceHpcTick modl ix
|
| 587 | 587 | toIfaceTickish (SourceNote src (LexicalFastString names)) =
|
| 588 | 588 | IfaceSource src names
|
| 589 | -toIfaceTickish (Breakpoint _ ix fv m) =
|
|
| 590 | - IfaceBreakpoint ix (toIfaceVar <$> fv) m
|
|
| 589 | +toIfaceTickish (Breakpoint _ ix fv) =
|
|
| 590 | + IfaceBreakpoint ix (toIfaceVar <$> fv)
|
|
| 591 | 591 | |
| 592 | 592 | ---------------------
|
| 593 | 593 | toIfaceBind :: Bind Id -> IfaceBinding IfaceLetBndr
|
| ... | ... | @@ -643,10 +643,10 @@ coreToStgArgs (arg : args) = do -- Non-type argument |
| 643 | 643 | coreToStgTick :: Type -- type of the ticked expression
|
| 644 | 644 | -> CoreTickish
|
| 645 | 645 | -> StgTickish
|
| 646 | -coreToStgTick _ty (HpcTick m i) = HpcTick m i
|
|
| 647 | -coreToStgTick _ty (SourceNote span nm) = SourceNote span nm
|
|
| 648 | -coreToStgTick _ty (ProfNote cc cnt scope) = ProfNote cc cnt scope
|
|
| 649 | -coreToStgTick !ty (Breakpoint _ bid fvs modl) = Breakpoint ty bid fvs modl
|
|
| 646 | +coreToStgTick _ty (HpcTick m i) = HpcTick m i
|
|
| 647 | +coreToStgTick _ty (SourceNote span nm) = SourceNote span nm
|
|
| 648 | +coreToStgTick _ty (ProfNote cc cnt scope) = ProfNote cc cnt scope
|
|
| 649 | +coreToStgTick !ty (Breakpoint _ bid fvs) = Breakpoint ty bid fvs
|
|
| 650 | 650 | |
| 651 | 651 | -- ---------------------------------------------------------------------------
|
| 652 | 652 | -- The magic for lets:
|
| ... | ... | @@ -842,9 +842,9 @@ cpeRhsE env (Tick tickish expr) |
| 842 | 842 | = do { body <- cpeBodyNF env expr
|
| 843 | 843 | ; return (emptyFloats, mkTick tickish' body) }
|
| 844 | 844 | where
|
| 845 | - tickish' | Breakpoint ext n fvs modl <- tickish
|
|
| 845 | + tickish' | Breakpoint ext bid fvs <- tickish
|
|
| 846 | 846 | -- See also 'substTickish'
|
| 847 | - = Breakpoint ext n (map (getIdFromTrivialExpr . lookupCorePrepEnv env) fvs) modl
|
|
| 847 | + = Breakpoint ext bid (map (getIdFromTrivialExpr . lookupCorePrepEnv env) fvs)
|
|
| 848 | 848 | | otherwise
|
| 849 | 849 | = tickish
|
| 850 | 850 |
| ... | ... | @@ -35,6 +35,7 @@ import GHC.Driver.Flags (DumpFlag(..)) |
| 35 | 35 | import GHC.Utils.Outputable as Outputable
|
| 36 | 36 | import GHC.Utils.Panic
|
| 37 | 37 | import GHC.Utils.Logger
|
| 38 | +import GHC.Types.Breakpoint
|
|
| 38 | 39 | import GHC.Types.SrcLoc
|
| 39 | 40 | import GHC.Types.Basic
|
| 40 | 41 | import GHC.Types.Id
|
| ... | ... | @@ -1235,7 +1236,7 @@ mkTickish boxLabel countEntries topOnly pos fvs decl_path = do |
| 1235 | 1236 | |
| 1236 | 1237 | Breakpoints -> do
|
| 1237 | 1238 | i <- addMixEntry me
|
| 1238 | - pure (Breakpoint noExtField i ids (this_mod env))
|
|
| 1239 | + pure (Breakpoint noExtField (BreakpointId (this_mod env) i) ids)
|
|
| 1239 | 1240 | |
| 1240 | 1241 | SourceNotes | RealSrcSpan pos' _ <- pos ->
|
| 1241 | 1242 | return $ SourceNote pos' $ LexicalFastString cc_name
|
| ... | ... | @@ -56,6 +56,7 @@ import GHC.Data.BooleanFormula (pprBooleanFormula, isTrue) |
| 56 | 56 | |
| 57 | 57 | import GHC.Builtin.Names ( unrestrictedFunTyConKey, liftedTypeKindTyConKey,
|
| 58 | 58 | constraintKindTyConKey )
|
| 59 | +import GHC.Types.Breakpoint
|
|
| 59 | 60 | import GHC.Types.Unique ( hasKey )
|
| 60 | 61 | import GHC.Iface.Type
|
| 61 | 62 | import GHC.Iface.Recomp.Binary
|
| ... | ... | @@ -699,7 +700,7 @@ data IfaceTickish |
| 699 | 700 | = IfaceHpcTick Module Int -- from HpcTick x
|
| 700 | 701 | | IfaceSCC CostCentre Bool Bool -- from ProfNote
|
| 701 | 702 | | IfaceSource RealSrcSpan FastString -- from SourceNote
|
| 702 | - | IfaceBreakpoint Int [IfaceExpr] Module -- from Breakpoint
|
|
| 703 | + | IfaceBreakpoint BreakpointId [IfaceExpr] -- from Breakpoint
|
|
| 703 | 704 | |
| 704 | 705 | data IfaceAlt = IfaceAlt IfaceConAlt [IfLclName] IfaceExpr
|
| 705 | 706 | -- Note: IfLclName, not IfaceBndr (and same with the case binder)
|
| ... | ... | @@ -1848,7 +1849,7 @@ pprIfaceTickish (IfaceSCC cc tick scope) |
| 1848 | 1849 | = braces (pprCostCentreCore cc <+> ppr tick <+> ppr scope)
|
| 1849 | 1850 | pprIfaceTickish (IfaceSource src _names)
|
| 1850 | 1851 | = braces (pprUserRealSpan True src)
|
| 1851 | -pprIfaceTickish (IfaceBreakpoint m ix fvs)
|
|
| 1852 | +pprIfaceTickish (IfaceBreakpoint (BreakpointId m ix) fvs)
|
|
| 1852 | 1853 | = braces (text "break" <+> ppr m <+> ppr ix <+> ppr fvs)
|
| 1853 | 1854 | |
| 1854 | 1855 | ------------------
|
| ... | ... | @@ -2198,7 +2199,7 @@ freeNamesIfaceTyConParent (IfDataInstance ax tc tys) |
| 2198 | 2199 | = unitNameSet ax &&& freeNamesIfTc tc &&& freeNamesIfAppArgs tys
|
| 2199 | 2200 | |
| 2200 | 2201 | freeNamesIfTickish :: IfaceTickish -> NameSet
|
| 2201 | -freeNamesIfTickish (IfaceBreakpoint _ fvs _) =
|
|
| 2202 | +freeNamesIfTickish (IfaceBreakpoint _ fvs) =
|
|
| 2202 | 2203 | fnList freeNamesIfExpr fvs
|
| 2203 | 2204 | freeNamesIfTickish _ = emptyNameSet
|
| 2204 | 2205 | |
| ... | ... | @@ -2919,7 +2920,7 @@ instance Binary IfaceTickish where |
| 2919 | 2920 | put_ bh (srcSpanEndLine src)
|
| 2920 | 2921 | put_ bh (srcSpanEndCol src)
|
| 2921 | 2922 | put_ bh name
|
| 2922 | - put_ bh (IfaceBreakpoint m ix fvs) = do
|
|
| 2923 | + put_ bh (IfaceBreakpoint (BreakpointId m ix) fvs) = do
|
|
| 2923 | 2924 | putByte bh 3
|
| 2924 | 2925 | put_ bh m
|
| 2925 | 2926 | put_ bh ix
|
| ... | ... | @@ -2947,7 +2948,7 @@ instance Binary IfaceTickish where |
| 2947 | 2948 | 3 -> do m <- get bh
|
| 2948 | 2949 | ix <- get bh
|
| 2949 | 2950 | fvs <- get bh
|
| 2950 | - return (IfaceBreakpoint m ix fvs)
|
|
| 2951 | + return (IfaceBreakpoint (BreakpointId m ix) fvs)
|
|
| 2951 | 2952 | _ -> panic ("get IfaceTickish " ++ show h)
|
| 2952 | 2953 | |
| 2953 | 2954 | instance Binary IfaceConAlt where
|
| ... | ... | @@ -3206,7 +3207,7 @@ instance NFData IfaceTickish where |
| 3206 | 3207 | IfaceHpcTick m i -> rnf m `seq` rnf i
|
| 3207 | 3208 | IfaceSCC cc b1 b2 -> rnf cc `seq` rnf b1 `seq` rnf b2
|
| 3208 | 3209 | IfaceSource src str -> rnf src `seq` rnf str
|
| 3209 | - IfaceBreakpoint m i fvs -> rnf m `seq` rnf i `seq` rnf fvs
|
|
| 3210 | + IfaceBreakpoint i fvs -> rnf i `seq` rnf fvs
|
|
| 3210 | 3211 | |
| 3211 | 3212 | instance NFData IfaceConAlt where
|
| 3212 | 3213 | rnf = \case
|
| ... | ... | @@ -955,7 +955,7 @@ dffvExpr :: CoreExpr -> DFFV () |
| 955 | 955 | dffvExpr (Var v) = insert v
|
| 956 | 956 | dffvExpr (App e1 e2) = dffvExpr e1 >> dffvExpr e2
|
| 957 | 957 | dffvExpr (Lam v e) = extendScope v (dffvExpr e)
|
| 958 | -dffvExpr (Tick (Breakpoint _ _ ids _) e) = mapM_ insert ids >> dffvExpr e
|
|
| 958 | +dffvExpr (Tick (Breakpoint _ _ ids) e) = mapM_ insert ids >> dffvExpr e
|
|
| 959 | 959 | dffvExpr (Tick _other e) = dffvExpr e
|
| 960 | 960 | dffvExpr (Cast e _) = dffvExpr e
|
| 961 | 961 | dffvExpr (Let (NonRec x r) e) = dffvBind (x,r) >> extendScope x (dffvExpr e)
|
| ... | ... | @@ -1732,9 +1732,9 @@ tcIfaceTickish :: IfaceTickish -> IfL CoreTickish |
| 1732 | 1732 | tcIfaceTickish (IfaceHpcTick modl ix) = return (HpcTick modl ix)
|
| 1733 | 1733 | tcIfaceTickish (IfaceSCC cc tick push) = return (ProfNote cc tick push)
|
| 1734 | 1734 | tcIfaceTickish (IfaceSource src name) = return (SourceNote src (LexicalFastString name))
|
| 1735 | -tcIfaceTickish (IfaceBreakpoint ix fvs modl) = do
|
|
| 1735 | +tcIfaceTickish (IfaceBreakpoint bid fvs) = do
|
|
| 1736 | 1736 | fvs' <- mapM tcIfaceExpr fvs
|
| 1737 | - return (Breakpoint NoExtField ix [f | Var f <- fvs'] modl)
|
|
| 1737 | + return (Breakpoint NoExtField bid [f | Var f <- fvs'])
|
|
| 1738 | 1738 | |
| 1739 | 1739 | -------------------------
|
| 1740 | 1740 | tcIfaceLit :: Literal -> IfL Literal
|
| 1 | + |
|
| 1 | 2 | -- | GHC API debugger module for finding and setting breakpoints.
|
| 2 | 3 | --
|
| 3 | 4 | -- This module is user facing and is at least used by `GHCi` and `ghc-debugger`
|
| 4 | 5 | -- to find and set breakpoints.
|
| 5 | 6 | module GHC.Runtime.Debugger.Breakpoints where
|
| 6 | 7 | |
| 8 | +import GHC.Prelude
|
|
| 9 | + |
|
| 7 | 10 | import Control.Monad.Catch
|
| 8 | 11 | import Control.Monad
|
| 9 | 12 | import Data.Array
|
| ... | ... | @@ -13,10 +16,18 @@ import Data.Maybe |
| 13 | 16 | import qualified Data.List.NonEmpty as NE
|
| 14 | 17 | import qualified Data.Semigroup as S
|
| 15 | 18 | |
| 16 | -import GHC
|
|
| 17 | -import GHC.Prelude
|
|
| 19 | +import GHC.ByteCode.Types (BreakIndex, ModBreaks(..))
|
|
| 20 | +import GHC.Driver.Env
|
|
| 21 | +import GHC.Driver.Monad
|
|
| 22 | +import GHC.Driver.Session.Inspect
|
|
| 23 | +import GHC.Runtime.Eval
|
|
| 18 | 24 | import GHC.Runtime.Eval.Utils
|
| 25 | +import GHC.Types.Name
|
|
| 19 | 26 | import GHC.Types.SrcLoc
|
| 27 | +import GHC.Types.Breakpoint
|
|
| 28 | +import GHC.Unit.Module
|
|
| 29 | +import GHC.Unit.Module.Graph
|
|
| 30 | +import GHC.Unit.Module.ModSummary
|
|
| 20 | 31 | import GHC.Utils.Outputable
|
| 21 | 32 | import GHC.Utils.Panic
|
| 22 | 33 | import qualified GHC.Data.Strict as Strict
|
| ... | ... | @@ -44,10 +55,10 @@ findBreakByLine line arr |
| 44 | 55 | ticks = arr ! line
|
| 45 | 56 | |
| 46 | 57 | starts_here = [ (ix,pan) | (ix, pan) <- ticks,
|
| 47 | - GHC.srcSpanStartLine pan == line ]
|
|
| 58 | + srcSpanStartLine pan == line ]
|
|
| 48 | 59 | |
| 49 | 60 | (comp, incomp) = partition ends_here starts_here
|
| 50 | - where ends_here (_,pan) = GHC.srcSpanEndLine pan == line
|
|
| 61 | + where ends_here (_,pan) = srcSpanEndLine pan == line
|
|
| 51 | 62 | |
| 52 | 63 | -- | Find a breakpoint in the 'TickArray' of a module, given a line number and a column coordinate.
|
| 53 | 64 | findBreakByCoord :: (Int, Int) -> TickArray -> Maybe (BreakIndex, RealSrcSpan)
|
| ... | ... | @@ -63,8 +74,8 @@ findBreakByCoord (line, col) arr |
| 63 | 74 | contains = [ tick | tick@(_,pan) <- ticks, RealSrcSpan pan Strict.Nothing `spans` (line,col) ]
|
| 64 | 75 | |
| 65 | 76 | after_here = [ tick | tick@(_,pan) <- ticks,
|
| 66 | - GHC.srcSpanStartLine pan == line,
|
|
| 67 | - GHC.srcSpanStartCol pan >= col ]
|
|
| 77 | + srcSpanStartLine pan == line,
|
|
| 78 | + srcSpanStartCol pan >= col ]
|
|
| 68 | 79 | |
| 69 | 80 | leftmostLargestRealSrcSpan :: RealSrcSpan -> RealSrcSpan -> Ordering
|
| 70 | 81 | leftmostLargestRealSrcSpan = on compare realSrcSpanStart S.<> on (flip compare) realSrcSpanEnd
|
| ... | ... | @@ -112,7 +123,7 @@ resolveFunctionBreakpoint inp = do |
| 112 | 123 | Nothing -> do
|
| 113 | 124 | -- No errors found, go and return the module info
|
| 114 | 125 | let mod = fromMaybe (panic "resolveFunctionBreakpoint") mb_mod
|
| 115 | - mb_mod_info <- GHC.getModuleInfo mod
|
|
| 126 | + mb_mod_info <- getModuleInfo mod
|
|
| 116 | 127 | case mb_mod_info of
|
| 117 | 128 | Nothing -> pure . Left $
|
| 118 | 129 | text "Could not find ModuleInfo of " <> ppr mod
|
| ... | ... | @@ -120,16 +131,16 @@ resolveFunctionBreakpoint inp = do |
| 120 | 131 | where
|
| 121 | 132 | -- Try to lookup the module for an identifier that is in scope.
|
| 122 | 133 | -- `parseName` throws an exception, if the identifier is not in scope
|
| 123 | - lookupModuleInscope :: GHC.GhcMonad m => String -> m (Maybe Module)
|
|
| 134 | + lookupModuleInscope :: GhcMonad m => String -> m (Maybe Module)
|
|
| 124 | 135 | lookupModuleInscope mod_top_lvl = do
|
| 125 | - names <- GHC.parseName mod_top_lvl
|
|
| 126 | - pure $ Just $ NE.head $ GHC.nameModule <$> names
|
|
| 136 | + names <- parseName mod_top_lvl
|
|
| 137 | + pure $ Just $ NE.head $ nameModule <$> names
|
|
| 127 | 138 | |
| 128 | 139 | -- Lookup the Module of a module name in the module graph
|
| 129 | - lookupModuleInGraph :: GHC.GhcMonad m => String -> m (Maybe Module)
|
|
| 140 | + lookupModuleInGraph :: GhcMonad m => String -> m (Maybe Module)
|
|
| 130 | 141 | lookupModuleInGraph mod_str = do
|
| 131 | - graph <- GHC.getModuleGraph
|
|
| 132 | - let hmods = ms_mod <$> GHC.mgModSummaries graph
|
|
| 142 | + graph <- getModuleGraph
|
|
| 143 | + let hmods = ms_mod <$> mgModSummaries graph
|
|
| 133 | 144 | pure $ find ((== mod_str) . moduleNameString . moduleName) hmods
|
| 134 | 145 | |
| 135 | 146 | -- Check validity of an identifier to set a breakpoint:
|
| ... | ... | @@ -137,21 +148,21 @@ resolveFunctionBreakpoint inp = do |
| 137 | 148 | -- 2. the identifier must be in an interpreted module
|
| 138 | 149 | -- 3. the ModBreaks array for module `mod` must have an entry
|
| 139 | 150 | -- for the function
|
| 140 | - validateBP :: GHC.GhcMonad m => String -> String -> Maybe Module
|
|
| 151 | + validateBP :: GhcMonad m => String -> String -> Maybe Module
|
|
| 141 | 152 | -> m (Maybe SDoc)
|
| 142 | 153 | validateBP mod_str fun_str Nothing = pure $ Just $ quotes (text
|
| 143 | 154 | (combineModIdent mod_str (takeWhile (/= '.') fun_str)))
|
| 144 | 155 | <+> text "not in scope"
|
| 145 | 156 | validateBP _ "" (Just _) = pure $ Just $ text "Function name is missing"
|
| 146 | 157 | validateBP _ fun_str (Just modl) = do
|
| 147 | - isInterpr <- GHC.moduleIsInterpreted modl
|
|
| 158 | + isInterpr <- moduleIsInterpreted modl
|
|
| 148 | 159 | mb_err_msg <- case isInterpr of
|
| 149 | 160 | False -> pure $ Just $ text "Module" <+> quotes (ppr modl) <+> text "is not interpreted"
|
| 150 | 161 | True -> do
|
| 151 | 162 | mb_modbreaks <- getModBreak modl
|
| 152 | 163 | let found = case mb_modbreaks of
|
| 153 | 164 | Nothing -> False
|
| 154 | - Just mb -> fun_str `elem` (intercalate "." <$> elems (GHC.modBreaks_decls mb))
|
|
| 165 | + Just mb -> fun_str `elem` (intercalate "." <$> elems (modBreaks_decls mb))
|
|
| 155 | 166 | if found
|
| 156 | 167 | then pure Nothing
|
| 157 | 168 | else pure $ Just $ text "No breakpoint found for" <+> quotes (text fun_str)
|
| ... | ... | @@ -163,13 +174,13 @@ resolveFunctionBreakpoint inp = do |
| 163 | 174 | -- for
|
| 164 | 175 | -- (a) this binder only (it maybe a top-level or a nested declaration)
|
| 165 | 176 | -- (b) that do not have an enclosing breakpoint
|
| 166 | -findBreakForBind :: String {-^ Name of bind to break at -} -> GHC.ModBreaks -> [(BreakIndex, RealSrcSpan)]
|
|
| 177 | +findBreakForBind :: String {-^ Name of bind to break at -} -> ModBreaks -> [(BreakIndex, RealSrcSpan)]
|
|
| 167 | 178 | findBreakForBind str_name modbreaks = filter (not . enclosed) ticks
|
| 168 | 179 | where
|
| 169 | 180 | ticks = [ (index, span)
|
| 170 | - | (index, decls) <- assocs (GHC.modBreaks_decls modbreaks),
|
|
| 181 | + | (index, decls) <- assocs (modBreaks_decls modbreaks),
|
|
| 171 | 182 | str_name == intercalate "." decls,
|
| 172 | - RealSrcSpan span _ <- [GHC.modBreaks_locs modbreaks ! index] ]
|
|
| 183 | + RealSrcSpan span _ <- [modBreaks_locs modbreaks ! index] ]
|
|
| 173 | 184 | enclosed (_,sp0) = any subspan ticks
|
| 174 | 185 | where subspan (_,sp) = sp /= sp0 &&
|
| 175 | 186 | realSrcSpanStart sp <= realSrcSpanStart sp0 &&
|
| ... | ... | @@ -180,53 +191,53 @@ findBreakForBind str_name modbreaks = filter (not . enclosed) ticks |
| 180 | 191 | --------------------------------------------------------------------------------
|
| 181 | 192 | |
| 182 | 193 | -- | Maps line numbers to the breakpoint ticks existing at that line for a module.
|
| 183 | -type TickArray = Array Int [(GHC.BreakIndex,RealSrcSpan)]
|
|
| 194 | +type TickArray = Array Int [(BreakIndex,RealSrcSpan)]
|
|
| 184 | 195 | |
| 185 | 196 | -- | Construct the 'TickArray' for the given module.
|
| 186 | 197 | makeModuleLineMap :: GhcMonad m => Module -> m (Maybe TickArray)
|
| 187 | 198 | makeModuleLineMap m = do
|
| 188 | - mi <- GHC.getModuleInfo m
|
|
| 189 | - return $ mkTickArray . assocs . GHC.modBreaks_locs <$> (GHC.modInfoModBreaks =<< mi)
|
|
| 199 | + mi <- getModuleInfo m
|
|
| 200 | + return $ mkTickArray . assocs . modBreaks_locs <$> (modInfoModBreaks =<< mi)
|
|
| 190 | 201 | where
|
| 191 | 202 | mkTickArray :: [(BreakIndex, SrcSpan)] -> TickArray
|
| 192 | 203 | mkTickArray ticks
|
| 193 | 204 | = accumArray (flip (:)) [] (1, max_line)
|
| 194 | 205 | [ (line, (nm,pan)) | (nm,RealSrcSpan pan _) <- ticks, line <- srcSpanLines pan ]
|
| 195 | 206 | where
|
| 196 | - max_line = foldr max 0 [ GHC.srcSpanEndLine sp | (_, RealSrcSpan sp _) <- ticks ]
|
|
| 197 | - srcSpanLines pan = [ GHC.srcSpanStartLine pan .. GHC.srcSpanEndLine pan ]
|
|
| 207 | + max_line = foldr max 0 [ srcSpanEndLine sp | (_, RealSrcSpan sp _) <- ticks ]
|
|
| 208 | + srcSpanLines pan = [ srcSpanStartLine pan .. srcSpanEndLine pan ]
|
|
| 198 | 209 | |
| 199 | 210 | -- | Get the 'ModBreaks' of the given 'Module' when available
|
| 200 | -getModBreak :: GHC.GhcMonad m
|
|
| 201 | - => Module -> m (Maybe ModBreaks)
|
|
| 211 | +getModBreak :: GhcMonad m => Module -> m (Maybe ModBreaks)
|
|
| 202 | 212 | getModBreak m = do
|
| 203 | - mod_info <- fromMaybe (panic "getModBreak") <$> GHC.getModuleInfo m
|
|
| 204 | - pure $ GHC.modInfoModBreaks mod_info
|
|
| 213 | + mod_info <- fromMaybe (panic "getModBreak") <$> getModuleInfo m
|
|
| 214 | + pure $ modInfoModBreaks mod_info
|
|
| 205 | 215 | |
| 206 | 216 | --------------------------------------------------------------------------------
|
| 207 | 217 | -- Getting current breakpoint information
|
| 208 | 218 | --------------------------------------------------------------------------------
|
| 209 | 219 | |
| 210 | -getCurrentBreakSpan :: GHC.GhcMonad m => m (Maybe SrcSpan)
|
|
| 220 | +getCurrentBreakSpan :: GhcMonad m => m (Maybe SrcSpan)
|
|
| 211 | 221 | getCurrentBreakSpan = do
|
| 212 | - resumes <- GHC.getResumeContext
|
|
| 222 | + hug <- hsc_HUG <$> getSession
|
|
| 223 | + resumes <- getResumeContext
|
|
| 213 | 224 | case resumes of
|
| 214 | 225 | [] -> return Nothing
|
| 215 | 226 | (r:_) -> do
|
| 216 | - let ix = GHC.resumeHistoryIx r
|
|
| 227 | + let ix = resumeHistoryIx r
|
|
| 217 | 228 | if ix == 0
|
| 218 | - then return (Just (GHC.resumeSpan r))
|
|
| 229 | + then return (Just (resumeSpan r))
|
|
| 219 | 230 | else do
|
| 220 | - let hist = GHC.resumeHistory r !! (ix-1)
|
|
| 221 | - pan <- GHC.getHistorySpan hist
|
|
| 231 | + let hist = resumeHistory r !! (ix-1)
|
|
| 232 | + pan <- liftIO $ getHistorySpan hug hist
|
|
| 222 | 233 | return (Just pan)
|
| 223 | 234 | |
| 224 | -getCurrentBreakModule :: GHC.GhcMonad m => m (Maybe Module)
|
|
| 235 | +getCurrentBreakModule :: GhcMonad m => m (Maybe Module)
|
|
| 225 | 236 | getCurrentBreakModule = do
|
| 226 | - resumes <- GHC.getResumeContext
|
|
| 237 | + resumes <- getResumeContext
|
|
| 227 | 238 | return $ case resumes of
|
| 228 | 239 | [] -> Nothing
|
| 229 | - (r:_) -> case GHC.resumeHistoryIx r of
|
|
| 230 | - 0 -> ibi_tick_mod <$> GHC.resumeBreakpointId r
|
|
| 231 | - ix -> Just $ GHC.getHistoryModule $ GHC.resumeHistory r !! (ix-1)
|
|
| 240 | + (r:_) -> case resumeHistoryIx r of
|
|
| 241 | + 0 -> ibi_tick_mod <$> resumeBreakpointId r
|
|
| 242 | + ix -> Just $ getHistoryModule $ resumeHistory r !! (ix-1)
|
|
| 232 | 243 |
| ... | ... | @@ -144,25 +144,25 @@ import qualified GHC.Unit.Home.Graph as HUG |
| 144 | 144 | getResumeContext :: GhcMonad m => m [Resume]
|
| 145 | 145 | getResumeContext = withSession (return . ic_resume . hsc_IC)
|
| 146 | 146 | |
| 147 | -mkHistory :: HscEnv -> ForeignHValue -> InternalBreakpointId -> IO History
|
|
| 148 | -mkHistory hsc_env hval ibi = History hval ibi <$> findEnclosingDecls hsc_env ibi
|
|
| 147 | +mkHistory :: HUG.HomeUnitGraph -> ForeignHValue -> InternalBreakpointId -> IO History
|
|
| 148 | +mkHistory hug hval ibi = History hval ibi <$> findEnclosingDecls hug ibi
|
|
| 149 | 149 | |
| 150 | 150 | getHistoryModule :: History -> Module
|
| 151 | 151 | getHistoryModule = ibi_tick_mod . historyBreakpointId
|
| 152 | 152 | |
| 153 | -getHistorySpan :: HscEnv -> History -> IO SrcSpan
|
|
| 154 | -getHistorySpan hsc_env hist = do
|
|
| 153 | +getHistorySpan :: HUG.HomeUnitGraph -> History -> IO SrcSpan
|
|
| 154 | +getHistorySpan hug hist = do
|
|
| 155 | 155 | let ibi = historyBreakpointId hist
|
| 156 | - brks <- readModBreaks hsc_env (ibi_tick_mod ibi)
|
|
| 156 | + brks <- readModBreaks hug (ibi_tick_mod ibi)
|
|
| 157 | 157 | return $ modBreaks_locs brks ! ibi_tick_index ibi
|
| 158 | 158 | |
| 159 | 159 | {- | Finds the enclosing top level function name -}
|
| 160 | 160 | -- ToDo: a better way to do this would be to keep hold of the decl_path computed
|
| 161 | 161 | -- by the coverage pass, which gives the list of lexically-enclosing bindings
|
| 162 | 162 | -- for each tick.
|
| 163 | -findEnclosingDecls :: HscEnv -> InternalBreakpointId -> IO [String]
|
|
| 164 | -findEnclosingDecls hsc_env ibi = do
|
|
| 165 | - brks <- readModBreaks hsc_env (ibi_tick_mod ibi)
|
|
| 163 | +findEnclosingDecls :: HUG.HomeUnitGraph -> InternalBreakpointId -> IO [String]
|
|
| 164 | +findEnclosingDecls hug ibi = do
|
|
| 165 | + brks <- readModBreaks hug (ibi_tick_mod ibi)
|
|
| 166 | 166 | return $ modBreaks_decls brks ! ibi_tick_index ibi
|
| 167 | 167 | |
| 168 | 168 | -- | Update fixity environment in the current interactive context.
|
| ... | ... | @@ -349,7 +349,8 @@ handleRunStatus step expr bindings final_ids status history0 = do |
| 349 | 349 | -- - or one of the stepping options in @EvalOpts@ caused us to stop at one
|
| 350 | 350 | EvalBreak apStack_ref (Just eval_break) resume_ctxt ccs -> do
|
| 351 | 351 | let ibi = evalBreakpointToId eval_break
|
| 352 | - tick_brks <- liftIO $ readModBreaks hsc_env (ibi_tick_mod ibi)
|
|
| 352 | + let hug = hsc_HUG hsc_env
|
|
| 353 | + tick_brks <- liftIO $ readModBreaks hug (ibi_tick_mod ibi)
|
|
| 353 | 354 | let
|
| 354 | 355 | span = modBreaks_locs tick_brks ! ibi_tick_index ibi
|
| 355 | 356 | decl = intercalate "." $ modBreaks_decls tick_brks ! ibi_tick_index ibi
|
| ... | ... | @@ -390,7 +391,7 @@ handleRunStatus step expr bindings final_ids status history0 = do |
| 390 | 391 | let eval_opts = initEvalOpts dflags (enableGhcStepMode step)
|
| 391 | 392 | status <- liftIO $ GHCi.resumeStmt interp eval_opts resume_ctxt_fhv
|
| 392 | 393 | history <- if not tracing then pure history0 else do
|
| 393 | - history1 <- liftIO $ mkHistory hsc_env apStack_fhv ibi
|
|
| 394 | + history1 <- liftIO $ mkHistory hug apStack_fhv ibi
|
|
| 394 | 395 | let !history' = history1 `consBL` history0
|
| 395 | 396 | -- history is strict, otherwise our BoundedList is pointless.
|
| 396 | 397 | return history'
|
| ... | ... | @@ -443,27 +444,27 @@ resumeExec step mbCnt |
| 443 | 444 | -- When the user specified a break ignore count, set it
|
| 444 | 445 | -- in the interpreter
|
| 445 | 446 | case (mb_brkpt, mbCnt) of
|
| 446 | - (Just brkpt, Just cnt) -> setupBreakpoint hsc_env (toBreakpointId brkpt) cnt
|
|
| 447 | + (Just brkpt, Just cnt) -> setupBreakpoint interp (toBreakpointId brkpt) cnt
|
|
| 447 | 448 | _ -> return ()
|
| 448 | 449 | |
| 449 | 450 | let eval_opts = initEvalOpts dflags (enableGhcStepMode step)
|
| 450 | 451 | status <- liftIO $ GHCi.resumeStmt interp eval_opts fhv
|
| 451 | 452 | let prevHistoryLst = fromListBL 50 hist
|
| 453 | + hug = hsc_HUG hsc_env
|
|
| 452 | 454 | hist' = case mb_brkpt of
|
| 453 | 455 | Nothing -> pure prevHistoryLst
|
| 454 | 456 | Just bi
|
| 455 | 457 | | breakHere False step span -> do
|
| 456 | - hist1 <- liftIO (mkHistory hsc_env apStack bi)
|
|
| 458 | + hist1 <- liftIO (mkHistory hug apStack bi)
|
|
| 457 | 459 | return $ hist1 `consBL` fromListBL 50 hist
|
| 458 | 460 | | otherwise -> pure prevHistoryLst
|
| 459 | 461 | handleRunStatus step expr bindings final_ids status =<< hist'
|
| 460 | 462 | |
| 461 | -setupBreakpoint :: GhcMonad m => HscEnv -> BreakpointId -> Int -> m () -- #19157
|
|
| 462 | -setupBreakpoint hsc_env bi cnt = do
|
|
| 463 | - let modl = bi_tick_mod bi
|
|
| 464 | - modBreaks <- liftIO $ readModBreaks hsc_env modl
|
|
| 463 | +setupBreakpoint :: GhcMonad m => Interp -> BreakpointId -> Int -> m () -- #19157
|
|
| 464 | +setupBreakpoint interp bi cnt = do
|
|
| 465 | + hug <- hsc_HUG <$> getSession
|
|
| 466 | + modBreaks <- liftIO $ readModBreaks hug (bi_tick_mod bi)
|
|
| 465 | 467 | let breakarray = modBreaks_flags modBreaks
|
| 466 | - interp = hscInterp hsc_env
|
|
| 467 | 468 | _ <- liftIO $ GHCi.storeBreakpoint interp breakarray (bi_tick_index bi) cnt
|
| 468 | 469 | pure ()
|
| 469 | 470 | |
| ... | ... | @@ -494,7 +495,7 @@ moveHist fn = do |
| 494 | 495 | span <- case mb_info of
|
| 495 | 496 | Nothing -> return $ mkGeneralSrcSpan (fsLit "<unknown>")
|
| 496 | 497 | Just ibi -> liftIO $ do
|
| 497 | - brks <- readModBreaks hsc_env (ibi_tick_mod ibi)
|
|
| 498 | + brks <- readModBreaks (hsc_HUG hsc_env) (ibi_tick_mod ibi)
|
|
| 498 | 499 | return $ modBreaks_locs brks ! ibi_tick_index ibi
|
| 499 | 500 | (hsc_env1, names) <-
|
| 500 | 501 | liftIO $ bindLocalsAtBreakpoint hsc_env apStack span mb_info
|
| ... | ... | @@ -525,11 +526,6 @@ moveHist fn = do |
| 525 | 526 | result_fs :: FastString
|
| 526 | 527 | result_fs = fsLit "_result"
|
| 527 | 528 | |
| 528 | --- | Read the 'ModBreaks' of the given home 'Module' from the 'HomeUnitGraph'.
|
|
| 529 | -readModBreaks :: HscEnv -> Module -> IO ModBreaks
|
|
| 530 | -readModBreaks hsc_env mod = expectJust . getModBreaks . expectJust <$> HUG.lookupHugByModule mod (hsc_HUG hsc_env)
|
|
| 531 | - |
|
| 532 | - |
|
| 533 | 529 | bindLocalsAtBreakpoint
|
| 534 | 530 | :: HscEnv
|
| 535 | 531 | -> ForeignHValue
|
| ... | ... | @@ -560,8 +556,9 @@ bindLocalsAtBreakpoint hsc_env apStack span Nothing = do |
| 560 | 556 | -- Just case: we stopped at a breakpoint, we have information about the location
|
| 561 | 557 | -- of the breakpoint and the free variables of the expression.
|
| 562 | 558 | bindLocalsAtBreakpoint hsc_env apStack_fhv span (Just ibi) = do
|
| 563 | - info_brks <- readModBreaks hsc_env (ibi_info_mod ibi)
|
|
| 564 | - tick_brks <- readModBreaks hsc_env (ibi_tick_mod ibi)
|
|
| 559 | + let hug = hsc_HUG hsc_env
|
|
| 560 | + info_brks <- readModBreaks hug (ibi_info_mod ibi)
|
|
| 561 | + tick_brks <- readModBreaks hug (ibi_tick_mod ibi)
|
|
| 565 | 562 | let info = expectJust $ IntMap.lookup (ibi_info_index ibi) (modBreaks_breakInfo info_brks)
|
| 566 | 563 | interp = hscInterp hsc_env
|
| 567 | 564 | occs = modBreaks_vars tick_brks ! ibi_tick_index ibi
|
| ... | ... | @@ -27,10 +27,9 @@ module GHC.Runtime.Interpreter |
| 27 | 27 | , getClosure
|
| 28 | 28 | , whereFrom
|
| 29 | 29 | , getModBreaks
|
| 30 | + , readModBreaks
|
|
| 30 | 31 | , seqHValue
|
| 31 | 32 | , evalBreakpointToId
|
| 32 | - , interpreterDynamic
|
|
| 33 | - , interpreterProfiled
|
|
| 34 | 33 | |
| 35 | 34 | -- * The object-code linker
|
| 36 | 35 | , initObjLinker
|
| ... | ... | @@ -98,7 +97,6 @@ import GHC.Unit.Env |
| 98 | 97 | |
| 99 | 98 | #if defined(HAVE_INTERNAL_INTERPRETER)
|
| 100 | 99 | import GHCi.Run
|
| 101 | -import GHC.Platform.Ways
|
|
| 102 | 100 | #endif
|
| 103 | 101 | |
| 104 | 102 | import Control.Concurrent
|
| ... | ... | @@ -117,6 +115,7 @@ import qualified GHC.InfoProv as InfoProv |
| 117 | 115 | |
| 118 | 116 | import GHC.Builtin.Names
|
| 119 | 117 | import GHC.Types.Name
|
| 118 | +import qualified GHC.Unit.Home.Graph as HUG
|
|
| 120 | 119 | |
| 121 | 120 | -- Standard libraries
|
| 122 | 121 | import GHC.Exts
|
| ... | ... | @@ -732,13 +731,12 @@ wormholeRef interp _r = case interpInstance interp of |
| 732 | 731 | ExternalInterp {}
|
| 733 | 732 | -> throwIO (InstallationError "this operation requires -fno-external-interpreter")
|
| 734 | 733 | |
| 735 | --- -----------------------------------------------------------------------------
|
|
| 736 | --- Misc utils
|
|
| 737 | - |
|
| 738 | -fromEvalResult :: EvalResult a -> IO a
|
|
| 739 | -fromEvalResult (EvalException e) = throwIO (fromSerializableException e)
|
|
| 740 | -fromEvalResult (EvalSuccess a) = return a
|
|
| 734 | +--------------------------------------------------------------------------------
|
|
| 735 | +-- * Finding breakpoint information
|
|
| 736 | +--------------------------------------------------------------------------------
|
|
| 741 | 737 | |
| 738 | +-- | Get the breakpoint information from the ByteCode object associated to this
|
|
| 739 | +-- 'HomeModInfo'.
|
|
| 742 | 740 | getModBreaks :: HomeModInfo -> Maybe ModBreaks
|
| 743 | 741 | getModBreaks hmi
|
| 744 | 742 | | Just linkable <- homeModInfoByteCode hmi,
|
| ... | ... | @@ -748,24 +746,15 @@ getModBreaks hmi |
| 748 | 746 | | otherwise
|
| 749 | 747 | = Nothing -- probably object code
|
| 750 | 748 | |
| 751 | --- | Interpreter uses Profiling way
|
|
| 752 | -interpreterProfiled :: Interp -> Bool
|
|
| 753 | -interpreterProfiled interp = case interpInstance interp of
|
|
| 754 | -#if defined(HAVE_INTERNAL_INTERPRETER)
|
|
| 755 | - InternalInterp -> hostIsProfiled
|
|
| 756 | -#endif
|
|
| 757 | - ExternalInterp ext -> case ext of
|
|
| 758 | - ExtIServ i -> iservConfProfiled (interpConfig i)
|
|
| 759 | - ExtJS {} -> False -- we don't support profiling yet in the JS backend
|
|
| 760 | - ExtWasm i -> wasmInterpProfiled $ interpConfig i
|
|
| 761 | - |
|
| 762 | --- | Interpreter uses Dynamic way
|
|
| 763 | -interpreterDynamic :: Interp -> Bool
|
|
| 764 | -interpreterDynamic interp = case interpInstance interp of
|
|
| 765 | -#if defined(HAVE_INTERNAL_INTERPRETER)
|
|
| 766 | - InternalInterp -> hostIsDynamic
|
|
| 767 | -#endif
|
|
| 768 | - ExternalInterp ext -> case ext of
|
|
| 769 | - ExtIServ i -> iservConfDynamic (interpConfig i)
|
|
| 770 | - ExtJS {} -> False -- dynamic doesn't make sense for JS
|
|
| 771 | - ExtWasm {} -> True -- wasm dyld can only load dynamic code |
|
| 749 | +-- | Read the 'InternalModBreaks' and 'ModBreaks' of the given home 'Module'
|
|
| 750 | +-- from the 'HomeUnitGraph'.
|
|
| 751 | +readModBreaks :: HomeUnitGraph -> Module -> IO ModBreaks
|
|
| 752 | +readModBreaks hug modl = expectJust . getModBreaks . expectJust <$> HUG.lookupHugByModule modl hug
|
|
| 753 | + |
|
| 754 | +-- -----------------------------------------------------------------------------
|
|
| 755 | +-- Misc utils
|
|
| 756 | + |
|
| 757 | +fromEvalResult :: EvalResult a -> IO a
|
|
| 758 | +fromEvalResult (EvalException e) = throwIO (fromSerializableException e)
|
|
| 759 | +fromEvalResult (EvalSuccess a) = return a
|
|
| 760 | + |
| ... | ... | @@ -24,7 +24,8 @@ module GHC.Runtime.Interpreter.Types |
| 24 | 24 | , interpSymbolSuffix
|
| 25 | 25 | , eliminateInterpSymbol
|
| 26 | 26 | , interpretedInterpSymbol
|
| 27 | - |
|
| 27 | + , interpreterProfiled
|
|
| 28 | + , interpreterDynamic
|
|
| 28 | 29 | |
| 29 | 30 | -- * IServ
|
| 30 | 31 | , IServ
|
| ... | ... | @@ -48,6 +49,9 @@ import GHCi.RemoteTypes |
| 48 | 49 | import GHCi.Message ( Pipe )
|
| 49 | 50 | |
| 50 | 51 | import GHC.Platform
|
| 52 | +#if defined(HAVE_INTERNAL_INTERPRETER)
|
|
| 53 | +import GHC.Platform.Ways
|
|
| 54 | +#endif
|
|
| 51 | 55 | import GHC.Utils.TmpFs
|
| 52 | 56 | import GHC.Utils.Logger
|
| 53 | 57 | import GHC.Unit.Env
|
| ... | ... | @@ -136,6 +140,28 @@ data ExtInterpInstance c = ExtInterpInstance |
| 136 | 140 | -- ^ Instance specific extra fields
|
| 137 | 141 | }
|
| 138 | 142 | |
| 143 | +-- | Interpreter uses Profiling way
|
|
| 144 | +interpreterProfiled :: Interp -> Bool
|
|
| 145 | +interpreterProfiled interp = case interpInstance interp of
|
|
| 146 | +#if defined(HAVE_INTERNAL_INTERPRETER)
|
|
| 147 | + InternalInterp -> hostIsProfiled
|
|
| 148 | +#endif
|
|
| 149 | + ExternalInterp ext -> case ext of
|
|
| 150 | + ExtIServ i -> iservConfProfiled (interpConfig i)
|
|
| 151 | + ExtJS {} -> False -- we don't support profiling yet in the JS backend
|
|
| 152 | + ExtWasm i -> wasmInterpProfiled $ interpConfig i
|
|
| 153 | + |
|
| 154 | +-- | Interpreter uses Dynamic way
|
|
| 155 | +interpreterDynamic :: Interp -> Bool
|
|
| 156 | +interpreterDynamic interp = case interpInstance interp of
|
|
| 157 | +#if defined(HAVE_INTERNAL_INTERPRETER)
|
|
| 158 | + InternalInterp -> hostIsDynamic
|
|
| 159 | +#endif
|
|
| 160 | + ExternalInterp ext -> case ext of
|
|
| 161 | + ExtIServ i -> iservConfDynamic (interpConfig i)
|
|
| 162 | + ExtJS {} -> False -- dynamic doesn't make sense for JS
|
|
| 163 | + ExtWasm {} -> True -- wasm dyld can only load dynamic code
|
|
| 164 | + |
|
| 139 | 165 | ------------------------
|
| 140 | 166 | -- JS Stuff
|
| 141 | 167 | ------------------------
|
| ... | ... | @@ -49,7 +49,7 @@ bcPrepRHS con@StgRhsCon{} = pure con |
| 49 | 49 | |
| 50 | 50 | bcPrepExpr :: StgExpr -> BcPrepM StgExpr
|
| 51 | 51 | -- explicitly match all constructors so we get a warning if we miss any
|
| 52 | -bcPrepExpr (StgTick bp@(Breakpoint tick_ty _ _ _) rhs)
|
|
| 52 | +bcPrepExpr (StgTick bp@(Breakpoint tick_ty _ _) rhs)
|
|
| 53 | 53 | | isLiftedTypeKind (typeKind tick_ty) = do
|
| 54 | 54 | id <- newId tick_ty
|
| 55 | 55 | rhs' <- bcPrepExpr rhs
|
| ... | ... | @@ -257,8 +257,8 @@ exprFVs env = go |
| 257 | 257 | , let lcl_fvs' = unionDVarSet (tickish tick) lcl_fvs
|
| 258 | 258 | = (StgTick tick e', imp_fvs, top_fvs, lcl_fvs')
|
| 259 | 259 | where
|
| 260 | - tickish (Breakpoint _ _ ids _) = mkDVarSet ids
|
|
| 261 | - tickish _ = emptyDVarSet
|
|
| 260 | + tickish (Breakpoint _ _ ids) = mkDVarSet ids
|
|
| 261 | + tickish _ = emptyDVarSet
|
|
| 262 | 262 | |
| 263 | 263 | go_bind dc bind body = (dc bind' body', imp_fvs, top_fvs, lcl_fvs)
|
| 264 | 264 | where
|
| ... | ... | @@ -4,13 +4,14 @@ |
| 4 | 4 | {-# LANGUAGE LambdaCase #-}
|
| 5 | 5 | {-# LANGUAGE RecordWildCards #-}
|
| 6 | 6 | {-# LANGUAGE FlexibleContexts #-}
|
| 7 | +{-# LANGUAGE DerivingVia #-}
|
|
| 7 | 8 | |
| 8 | 9 | --
|
| 9 | 10 | -- (c) The University of Glasgow 2002-2006
|
| 10 | 11 | --
|
| 11 | 12 | |
| 12 | 13 | -- | GHC.StgToByteCode: Generate bytecode from STG
|
| 13 | -module GHC.StgToByteCode ( UnlinkedBCO, byteCodeGen) where
|
|
| 14 | +module GHC.StgToByteCode ( UnlinkedBCO, byteCodeGen ) where
|
|
| 14 | 15 | |
| 15 | 16 | import GHC.Prelude
|
| 16 | 17 | |
| ... | ... | @@ -33,6 +34,7 @@ import GHC.Platform.Profile |
| 33 | 34 | import GHC.Runtime.Interpreter
|
| 34 | 35 | import GHCi.FFI
|
| 35 | 36 | import GHC.Types.Basic
|
| 37 | +import GHC.Types.Breakpoint
|
|
| 36 | 38 | import GHC.Utils.Outputable
|
| 37 | 39 | import GHC.Types.Name
|
| 38 | 40 | import GHC.Types.Id
|
| ... | ... | @@ -95,6 +97,10 @@ import GHC.Stg.Syntax |
| 95 | 97 | import qualified Data.IntSet as IntSet
|
| 96 | 98 | import GHC.CoreToIface
|
| 97 | 99 | |
| 100 | +import Control.Monad.IO.Class
|
|
| 101 | +import Control.Monad.Trans.Reader (ReaderT(..))
|
|
| 102 | +import Control.Monad.Trans.State (StateT(..))
|
|
| 103 | + |
|
| 98 | 104 | -- -----------------------------------------------------------------------------
|
| 99 | 105 | -- Generating byte code for a complete module
|
| 100 | 106 | |
| ... | ... | @@ -119,7 +125,7 @@ byteCodeGen hsc_env this_mod binds tycs mb_modBreaks spt_entries |
| 119 | 125 | flattenBind (StgNonRec b e) = [(b,e)]
|
| 120 | 126 | flattenBind (StgRec bs) = bs
|
| 121 | 127 | |
| 122 | - (BcM_State{..}, proto_bcos) <-
|
|
| 128 | + (proto_bcos, BcM_State{..}) <-
|
|
| 123 | 129 | runBc hsc_env this_mod mb_modBreaks $ do
|
| 124 | 130 | let flattened_binds = concatMap flattenBind (reverse lifted_binds)
|
| 125 | 131 | FlatBag.fromList (fromIntegral $ length flattened_binds) <$> mapM schemeTopBind flattened_binds
|
| ... | ... | @@ -311,7 +317,7 @@ schemeTopBind (id, rhs) |
| 311 | 317 | -- because mkConAppCode treats nullary constructor applications
|
| 312 | 318 | -- by just re-using the single top-level definition. So
|
| 313 | 319 | -- for the worker itself, we must allocate it directly.
|
| 314 | - -- ioToBc (putStrLn $ "top level BCO")
|
|
| 320 | + -- liftIO (putStrLn $ "top level BCO")
|
|
| 315 | 321 | pure (mkProtoBCO platform add_bco_name
|
| 316 | 322 | (getName id) (toOL [PACK data_con 0, RETURN P])
|
| 317 | 323 | (Right rhs) 0 0 [{-no bitmap-}] False{-not alts-})
|
| ... | ... | @@ -388,7 +394,7 @@ schemeR_wrk fvs nm original_body (args, body) |
| 388 | 394 | -- | Introduce break instructions for ticked expressions.
|
| 389 | 395 | -- If no breakpoint information is available, the instruction is omitted.
|
| 390 | 396 | schemeER_wrk :: StackDepth -> BCEnv -> CgStgExpr -> BcM BCInstrList
|
| 391 | -schemeER_wrk d p (StgTick (Breakpoint tick_ty tick_no fvs tick_mod) rhs) = do
|
|
| 397 | +schemeER_wrk d p (StgTick (Breakpoint tick_ty (BreakpointId tick_mod tick_no) fvs) rhs) = do
|
|
| 392 | 398 | code <- schemeE d 0 p rhs
|
| 393 | 399 | hsc_env <- getHscEnv
|
| 394 | 400 | current_mod <- getCurrentModule
|
| ... | ... | @@ -448,7 +454,7 @@ break_info hsc_env mod current_mod current_mod_breaks |
| 448 | 454 | | mod == current_mod
|
| 449 | 455 | = pure current_mod_breaks
|
| 450 | 456 | | otherwise
|
| 451 | - = ioToBc (HUG.lookupHugByModule mod (hsc_HUG hsc_env)) >>= \case
|
|
| 457 | + = liftIO (HUG.lookupHugByModule mod (hsc_HUG hsc_env)) >>= \case
|
|
| 452 | 458 | Just hp -> pure $ getModBreaks hp
|
| 453 | 459 | Nothing -> pure Nothing
|
| 454 | 460 | |
| ... | ... | @@ -640,10 +646,9 @@ schemeE d s p (StgLet _ext binds body) = do |
| 640 | 646 | thunk_codes <- sequence compile_binds
|
| 641 | 647 | return (alloc_code `appOL` concatOL thunk_codes `appOL` body_code)
|
| 642 | 648 | |
| 643 | -schemeE _d _s _p (StgTick (Breakpoint _ bp_id _ _) _rhs)
|
|
| 644 | - = panic ("schemeE: Breakpoint without let binding: " ++
|
|
| 645 | - show bp_id ++
|
|
| 646 | - " forgot to run bcPrep?")
|
|
| 649 | +schemeE _d _s _p (StgTick (Breakpoint _ bp_id _) _rhs)
|
|
| 650 | + = pprPanic "schemeE: Breakpoint without let binding:"
|
|
| 651 | + (ppr bp_id <+> text "forgot to run bcPrep?")
|
|
| 647 | 652 | |
| 648 | 653 | -- ignore other kinds of tick
|
| 649 | 654 | schemeE d s p (StgTick _ rhs) = schemeE d s p rhs
|
| ... | ... | @@ -2627,63 +2632,38 @@ typeArgReps platform = map (toArgRep platform) . typePrimRep |
| 2627 | 2632 | -- -----------------------------------------------------------------------------
|
| 2628 | 2633 | -- The bytecode generator's monad
|
| 2629 | 2634 | |
| 2635 | +-- | Read only environment for generating ByteCode
|
|
| 2636 | +data BcM_Env
|
|
| 2637 | + = BcM_Env
|
|
| 2638 | + { bcm_hsc_env :: HscEnv
|
|
| 2639 | + , bcm_module :: Module -- current module (for breakpoints)
|
|
| 2640 | + }
|
|
| 2641 | + |
|
| 2630 | 2642 | data BcM_State
|
| 2631 | 2643 | = BcM_State
|
| 2632 | - { bcm_hsc_env :: HscEnv
|
|
| 2633 | - , thisModule :: Module -- current module (for breakpoints)
|
|
| 2634 | - , nextlabel :: Word32 -- for generating local labels
|
|
| 2635 | - , modBreaks :: Maybe ModBreaks -- info about breakpoints
|
|
| 2636 | - |
|
| 2637 | - , breakInfo :: IntMap CgBreakInfo -- ^ Info at breakpoint occurrence.
|
|
| 2638 | - -- Indexed with breakpoint *info* index.
|
|
| 2639 | - -- See Note [Breakpoint identifiers]
|
|
| 2640 | - -- in GHC.Types.Breakpoint
|
|
| 2641 | - , breakInfoIdx :: !Int -- ^ Next index for breakInfo array
|
|
| 2644 | + { nextlabel :: !Word32 -- ^ For generating local labels
|
|
| 2645 | + , breakInfoIdx :: !Int -- ^ Next index for breakInfo array
|
|
| 2646 | + , modBreaks :: Maybe ModBreaks -- info about breakpoints
|
|
| 2647 | + |
|
| 2648 | + , breakInfo :: IntMap CgBreakInfo -- ^ Info at breakpoint occurrence.
|
|
| 2649 | + -- Indexed with breakpoint *info* index.
|
|
| 2650 | + -- See Note [Breakpoint identifiers]
|
|
| 2651 | + -- in GHC.Types.Breakpoint
|
|
| 2642 | 2652 | }
|
| 2643 | 2653 | |
| 2644 | -newtype BcM r = BcM (BcM_State -> IO (BcM_State, r)) deriving (Functor)
|
|
| 2645 | - |
|
| 2646 | -ioToBc :: IO a -> BcM a
|
|
| 2647 | -ioToBc io = BcM $ \st -> do
|
|
| 2648 | - x <- io
|
|
| 2649 | - return (st, x)
|
|
| 2650 | - |
|
| 2651 | -runBc :: HscEnv -> Module -> Maybe ModBreaks
|
|
| 2652 | - -> BcM r
|
|
| 2653 | - -> IO (BcM_State, r)
|
|
| 2654 | -runBc hsc_env this_mod modBreaks (BcM m)
|
|
| 2655 | - = m (BcM_State hsc_env this_mod 0 modBreaks IntMap.empty 0)
|
|
| 2654 | +newtype BcM r = BcM (BcM_Env -> BcM_State -> IO (r, BcM_State))
|
|
| 2655 | + deriving (Functor, Applicative, Monad, MonadIO)
|
|
| 2656 | + via (ReaderT BcM_Env (StateT BcM_State IO))
|
|
| 2656 | 2657 | |
| 2657 | -thenBc :: BcM a -> (a -> BcM b) -> BcM b
|
|
| 2658 | -thenBc (BcM expr) cont = BcM $ \st0 -> do
|
|
| 2659 | - (st1, q) <- expr st0
|
|
| 2660 | - let BcM k = cont q
|
|
| 2661 | - (st2, r) <- k st1
|
|
| 2662 | - return (st2, r)
|
|
| 2663 | - |
|
| 2664 | -thenBc_ :: BcM a -> BcM b -> BcM b
|
|
| 2665 | -thenBc_ (BcM expr) (BcM cont) = BcM $ \st0 -> do
|
|
| 2666 | - (st1, _) <- expr st0
|
|
| 2667 | - (st2, r) <- cont st1
|
|
| 2668 | - return (st2, r)
|
|
| 2669 | - |
|
| 2670 | -returnBc :: a -> BcM a
|
|
| 2671 | -returnBc result = BcM $ \st -> (return (st, result))
|
|
| 2672 | - |
|
| 2673 | -instance Applicative BcM where
|
|
| 2674 | - pure = returnBc
|
|
| 2675 | - (<*>) = ap
|
|
| 2676 | - (*>) = thenBc_
|
|
| 2677 | - |
|
| 2678 | -instance Monad BcM where
|
|
| 2679 | - (>>=) = thenBc
|
|
| 2680 | - (>>) = (*>)
|
|
| 2658 | +runBc :: HscEnv -> Module -> Maybe ModBreaks -> BcM r -> IO (r, BcM_State)
|
|
| 2659 | +runBc hsc_env this_mod mbs (BcM m)
|
|
| 2660 | + = m (BcM_Env hsc_env this_mod) (BcM_State 0 0 mbs IntMap.empty)
|
|
| 2681 | 2661 | |
| 2682 | 2662 | instance HasDynFlags BcM where
|
| 2683 | - getDynFlags = BcM $ \st -> return (st, hsc_dflags (bcm_hsc_env st))
|
|
| 2663 | + getDynFlags = hsc_dflags <$> getHscEnv
|
|
| 2684 | 2664 | |
| 2685 | 2665 | getHscEnv :: BcM HscEnv
|
| 2686 | -getHscEnv = BcM $ \st -> return (st, bcm_hsc_env st)
|
|
| 2666 | +getHscEnv = BcM $ \env st -> return (bcm_hsc_env env, st)
|
|
| 2687 | 2667 | |
| 2688 | 2668 | getProfile :: BcM Profile
|
| 2689 | 2669 | getProfile = targetProfile <$> getDynFlags
|
| ... | ... | @@ -2696,31 +2676,31 @@ shouldAddBcoName = do |
| 2696 | 2676 | else return Nothing
|
| 2697 | 2677 | |
| 2698 | 2678 | getLabelBc :: BcM LocalLabel
|
| 2699 | -getLabelBc
|
|
| 2700 | - = BcM $ \st -> do let nl = nextlabel st
|
|
| 2701 | - when (nl == maxBound) $
|
|
| 2702 | - panic "getLabelBc: Ran out of labels"
|
|
| 2703 | - return (st{nextlabel = nl + 1}, LocalLabel nl)
|
|
| 2679 | +getLabelBc = BcM $ \_ st ->
|
|
| 2680 | + do let nl = nextlabel st
|
|
| 2681 | + when (nl == maxBound) $
|
|
| 2682 | + panic "getLabelBc: Ran out of labels"
|
|
| 2683 | + return (LocalLabel nl, st{nextlabel = nl + 1})
|
|
| 2704 | 2684 | |
| 2705 | 2685 | getLabelsBc :: Word32 -> BcM [LocalLabel]
|
| 2706 | -getLabelsBc n
|
|
| 2707 | - = BcM $ \st -> let ctr = nextlabel st
|
|
| 2708 | - in return (st{nextlabel = ctr+n}, coerce [ctr .. ctr+n-1])
|
|
| 2686 | +getLabelsBc n = BcM $ \_ st ->
|
|
| 2687 | + let ctr = nextlabel st
|
|
| 2688 | + in return (coerce [ctr .. ctr+n-1], st{nextlabel = ctr+n})
|
|
| 2709 | 2689 | |
| 2710 | 2690 | newBreakInfo :: CgBreakInfo -> BcM Int
|
| 2711 | -newBreakInfo info = BcM $ \st ->
|
|
| 2691 | +newBreakInfo info = BcM $ \_ st ->
|
|
| 2712 | 2692 | let ix = breakInfoIdx st
|
| 2713 | 2693 | st' = st
|
| 2714 | - { breakInfo = IntMap.insert ix info (breakInfo st)
|
|
| 2715 | - , breakInfoIdx = ix + 1
|
|
| 2716 | - }
|
|
| 2717 | - in return (st', ix)
|
|
| 2694 | + { breakInfo = IntMap.insert ix info (breakInfo st)
|
|
| 2695 | + , breakInfoIdx = ix + 1
|
|
| 2696 | + }
|
|
| 2697 | + in return (ix, st')
|
|
| 2718 | 2698 | |
| 2719 | 2699 | getCurrentModule :: BcM Module
|
| 2720 | -getCurrentModule = BcM $ \st -> return (st, thisModule st)
|
|
| 2700 | +getCurrentModule = BcM $ \env st -> return (bcm_module env, st)
|
|
| 2721 | 2701 | |
| 2722 | 2702 | getCurrentModBreaks :: BcM (Maybe ModBreaks)
|
| 2723 | -getCurrentModBreaks = BcM $ \st -> return (st, modBreaks st)
|
|
| 2703 | +getCurrentModBreaks = BcM $ \_env st -> return (modBreaks st, st)
|
|
| 2724 | 2704 | |
| 2725 | 2705 | tickFS :: FastString
|
| 2726 | 2706 | tickFS = fsLit "ticked" |
| ... | ... | @@ -8,6 +8,9 @@ where |
| 8 | 8 | |
| 9 | 9 | import GHC.Prelude
|
| 10 | 10 | import GHC.Unit.Module
|
| 11 | +import GHC.Utils.Outputable
|
|
| 12 | +import Control.DeepSeq
|
|
| 13 | +import Data.Data (Data)
|
|
| 11 | 14 | |
| 12 | 15 | -- | Breakpoint identifier.
|
| 13 | 16 | --
|
| ... | ... | @@ -16,7 +19,7 @@ data BreakpointId = BreakpointId |
| 16 | 19 | { bi_tick_mod :: !Module -- ^ Breakpoint tick module
|
| 17 | 20 | , bi_tick_index :: !Int -- ^ Breakpoint tick index
|
| 18 | 21 | }
|
| 19 | - deriving (Eq, Ord)
|
|
| 22 | + deriving (Eq, Ord, Data)
|
|
| 20 | 23 | |
| 21 | 24 | -- | Internal breakpoint identifier
|
| 22 | 25 | --
|
| ... | ... | @@ -53,3 +56,11 @@ toBreakpointId ibi = BreakpointId |
| 53 | 56 | -- So every breakpoint occurrence gets assigned a module-unique *info index* and
|
| 54 | 57 | -- we store it alongside the occurrence module (*info module*) in the
|
| 55 | 58 | -- InternalBreakpointId datatype.
|
| 59 | + |
|
| 60 | +instance Outputable BreakpointId where
|
|
| 61 | + ppr BreakpointId{bi_tick_mod, bi_tick_index} =
|
|
| 62 | + text "BreakpointId" <+> ppr bi_tick_mod <+> ppr bi_tick_index
|
|
| 63 | + |
|
| 64 | +instance NFData BreakpointId where
|
|
| 65 | + rnf BreakpointId{bi_tick_mod, bi_tick_index} =
|
|
| 66 | + rnf bi_tick_mod `seq` rnf bi_tick_index |
| ... | ... | @@ -31,6 +31,7 @@ import GHC.Core.Type |
| 31 | 31 | |
| 32 | 32 | import GHC.Unit.Module
|
| 33 | 33 | |
| 34 | +import GHC.Types.Breakpoint
|
|
| 34 | 35 | import GHC.Types.CostCentre
|
| 35 | 36 | import GHC.Types.SrcLoc ( RealSrcSpan, containsSpan )
|
| 36 | 37 | import GHC.Types.Var
|
| ... | ... | @@ -128,7 +129,7 @@ data GenTickish pass = |
| 128 | 129 | -- and (b) substituting (don't substitute for them)
|
| 129 | 130 | | Breakpoint
|
| 130 | 131 | { breakpointExt :: XBreakpoint pass
|
| 131 | - , breakpointId :: !Int
|
|
| 132 | + , breakpointId :: !BreakpointId
|
|
| 132 | 133 | , breakpointFVs :: [XTickishId pass]
|
| 133 | 134 | -- ^ the order of this list is important:
|
| 134 | 135 | -- it matches the order of the lists in the
|
| ... | ... | @@ -136,7 +137,6 @@ data GenTickish pass = |
| 136 | 137 | --
|
| 137 | 138 | -- Careful about substitution! See
|
| 138 | 139 | -- Note [substTickish] in "GHC.Core.Subst".
|
| 139 | - , breakpointModule :: Module
|
|
| 140 | 140 | }
|
| 141 | 141 | |
| 142 | 142 | -- | A source note.
|
| ... | ... | @@ -4371,7 +4371,7 @@ getIgnoreCount str = |
| 4371 | 4371 | setupBreakpoint :: GhciMonad m => GHC.BreakpointId -> Int -> m()
|
| 4372 | 4372 | setupBreakpoint loc count = do
|
| 4373 | 4373 | hsc_env <- GHC.getSession
|
| 4374 | - GHC.setupBreakpoint hsc_env loc count
|
|
| 4374 | + GHC.setupBreakpoint (hscInterp hsc_env) loc count
|
|
| 4375 | 4375 | |
| 4376 | 4376 | backCmd :: GhciMonad m => String -> m ()
|
| 4377 | 4377 | backCmd arg
|