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
|