Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
7147370b
by Cheng Shao at 2025-05-20T17:22:19-04:00
-
a67db612
by Cheng Shao at 2025-05-20T17:22:19-04:00
-
5faf34ef
by Cheng Shao at 2025-05-20T17:22:19-04:00
-
2abaf8c1
by Cheng Shao at 2025-05-20T17:22:19-04:00
-
adb9e4d2
by Cheng Shao at 2025-05-20T17:22:19-04:00
-
200f401b
by Cheng Shao at 2025-05-20T17:22:19-04:00
-
ddaadca6
by Cheng Shao at 2025-05-20T17:22:19-04:00
-
a0fde202
by Cheng Shao at 2025-05-20T17:22:19-04:00
-
68c8f140
by Cheng Shao at 2025-05-20T17:22:19-04:00
13 changed files:
- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/InfoTable.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Linker.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/StgToByteCode.hs
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/Run.hs
- testsuite/tests/bytecode/T22376/all.T
- testsuite/tests/perf/should_run/ByteCodeAsm.hs
Changes:
| ... | ... | @@ -29,7 +29,6 @@ import GHC.ByteCode.Instr |
| 29 | 29 | import GHC.ByteCode.InfoTable
|
| 30 | 30 | import GHC.ByteCode.Types
|
| 31 | 31 | import GHCi.RemoteTypes
|
| 32 | -import GHC.Runtime.Interpreter
|
|
| 33 | 32 | import GHC.Runtime.Heap.Layout ( fromStgWord, StgWord )
|
| 34 | 33 | |
| 35 | 34 | import GHC.Types.Name
|
| ... | ... | @@ -38,6 +37,7 @@ import GHC.Types.Literal |
| 38 | 37 | import GHC.Types.Unique.DSet
|
| 39 | 38 | import GHC.Types.SptEntry
|
| 40 | 39 | import GHC.Types.Unique.FM
|
| 40 | +import GHC.Unit.Types
|
|
| 41 | 41 | |
| 42 | 42 | import GHC.Utils.Outputable
|
| 43 | 43 | import GHC.Utils.Panic
|
| ... | ... | @@ -52,6 +52,7 @@ import GHC.Cmm.Reg ( GlobalArgRegs(..) ) |
| 52 | 52 | import GHC.Cmm.CallConv ( allArgRegsCover )
|
| 53 | 53 | import GHC.Platform
|
| 54 | 54 | import GHC.Platform.Profile
|
| 55 | +import Language.Haskell.Syntax.Module.Name
|
|
| 55 | 56 | |
| 56 | 57 | import Control.Monad
|
| 57 | 58 | import qualified Control.Monad.Trans.State.Strict as MTL
|
| ... | ... | @@ -65,6 +66,7 @@ import Data.Array.Base ( unsafeWrite ) |
| 65 | 66 | #endif
|
| 66 | 67 | |
| 67 | 68 | import Foreign hiding (shiftL, shiftR)
|
| 69 | +import Data.ByteString (ByteString)
|
|
| 68 | 70 | import Data.Char (ord)
|
| 69 | 71 | import Data.Maybe (fromMaybe)
|
| 70 | 72 | import GHC.Float (castFloatToWord32, castDoubleToWord64)
|
| ... | ... | @@ -104,24 +106,21 @@ bcoFreeNames bco |
| 104 | 106 | |
| 105 | 107 | -- Top level assembler fn.
|
| 106 | 108 | assembleBCOs
|
| 107 | - :: Interp
|
|
| 108 | - -> Profile
|
|
| 109 | + :: Profile
|
|
| 109 | 110 | -> FlatBag (ProtoBCO Name)
|
| 110 | 111 | -> [TyCon]
|
| 111 | - -> AddrEnv
|
|
| 112 | + -> [(Name, ByteString)]
|
|
| 112 | 113 | -> Maybe ModBreaks
|
| 113 | 114 | -> [SptEntry]
|
| 114 | 115 | -> IO CompiledByteCode
|
| 115 | -assembleBCOs interp profile proto_bcos tycons top_strs modbreaks spt_entries = do
|
|
| 116 | +assembleBCOs profile proto_bcos tycons top_strs modbreaks spt_entries = do
|
|
| 116 | 117 | -- TODO: the profile should be bundled with the interpreter: the rts ways are
|
| 117 | 118 | -- fixed for an interpreter
|
| 118 | - itblenv <- mkITbls interp profile tycons
|
|
| 119 | + let itbls = mkITbls profile tycons
|
|
| 119 | 120 | bcos <- mapM (assembleBCO (profilePlatform profile)) proto_bcos
|
| 120 | - bcos' <- mallocStrings interp bcos
|
|
| 121 | 121 | return CompiledByteCode
|
| 122 | - { bc_bcos = bcos'
|
|
| 123 | - , bc_itbls = itblenv
|
|
| 124 | - , bc_ffis = concatMap protoBCOFFIs proto_bcos
|
|
| 122 | + { bc_bcos = bcos
|
|
| 123 | + , bc_itbls = itbls
|
|
| 125 | 124 | , bc_strs = top_strs
|
| 126 | 125 | , bc_breaks = modbreaks
|
| 127 | 126 | , bc_spt_entries = spt_entries
|
| ... | ... | @@ -137,50 +136,17 @@ assembleBCOs interp profile proto_bcos tycons top_strs modbreaks spt_entries = d |
| 137 | 136 | -- memory for them, and bake the resulting addresses into the instruction stream
|
| 138 | 137 | -- in the form of BCONPtrWord arguments.
|
| 139 | 138 | --
|
| 140 | --- Since we do this when assembling, we only allocate the memory when we compile
|
|
| 141 | --- the module, not each time we relink it. However, we do want to take care to
|
|
| 142 | --- malloc the memory all in one go, since that is more efficient with
|
|
| 143 | --- -fexternal-interpreter, especially when compiling in parallel.
|
|
| 139 | +-- We used to allocate remote buffers for BCONPtrStr ByteStrings when
|
|
| 140 | +-- assembling, but this gets in the way of bytecode serialization: we
|
|
| 141 | +-- want the ability to serialize and reload assembled bytecode, so
|
|
| 142 | +-- it's better to preserve BCONPtrStr as-is, and only perform the
|
|
| 143 | +-- actual allocation at link-time.
|
|
| 144 | 144 | --
|
| 145 | 145 | -- Note that, as with top-level string literal bindings, this memory is never
|
| 146 | 146 | -- freed, so it just leaks if the BCO is unloaded. See Note [Generating code for
|
| 147 | 147 | -- top-level string literal bindings] in GHC.StgToByteCode for some discussion
|
| 148 | 148 | -- about why.
|
| 149 | 149 | --
|
| 150 | -mallocStrings :: Interp -> FlatBag UnlinkedBCO -> IO (FlatBag UnlinkedBCO)
|
|
| 151 | -mallocStrings interp ulbcos = do
|
|
| 152 | - let bytestrings = reverse (MTL.execState (mapM_ collect ulbcos) [])
|
|
| 153 | - ptrs <- interpCmd interp (MallocStrings bytestrings)
|
|
| 154 | - return (MTL.evalState (mapM splice ulbcos) ptrs)
|
|
| 155 | - where
|
|
| 156 | - splice bco@UnlinkedBCO{..} = do
|
|
| 157 | - lits <- mapM spliceLit unlinkedBCOLits
|
|
| 158 | - ptrs <- mapM splicePtr unlinkedBCOPtrs
|
|
| 159 | - return bco { unlinkedBCOLits = lits, unlinkedBCOPtrs = ptrs }
|
|
| 160 | - |
|
| 161 | - spliceLit (BCONPtrStr _) = do
|
|
| 162 | - rptrs <- MTL.get
|
|
| 163 | - case rptrs of
|
|
| 164 | - (RemotePtr p : rest) -> do
|
|
| 165 | - MTL.put rest
|
|
| 166 | - return (BCONPtrWord (fromIntegral p))
|
|
| 167 | - _ -> panic "mallocStrings:spliceLit"
|
|
| 168 | - spliceLit other = return other
|
|
| 169 | - |
|
| 170 | - splicePtr (BCOPtrBCO bco) = BCOPtrBCO <$> splice bco
|
|
| 171 | - splicePtr other = return other
|
|
| 172 | - |
|
| 173 | - collect UnlinkedBCO{..} = do
|
|
| 174 | - mapM_ collectLit unlinkedBCOLits
|
|
| 175 | - mapM_ collectPtr unlinkedBCOPtrs
|
|
| 176 | - |
|
| 177 | - collectLit (BCONPtrStr bs) = do
|
|
| 178 | - strs <- MTL.get
|
|
| 179 | - MTL.put (bs:strs)
|
|
| 180 | - collectLit _ = return ()
|
|
| 181 | - |
|
| 182 | - collectPtr (BCOPtrBCO bco) = collect bco
|
|
| 183 | - collectPtr _ = return ()
|
|
| 184 | 150 | |
| 185 | 151 | data RunAsmReader = RunAsmReader { isn_array :: {-# UNPACK #-} !(Array.IOUArray Int Word16)
|
| 186 | 152 | , ptr_array :: {-# UNPACK #-} !(SmallMutableArrayIO BCOPtr)
|
| ... | ... | @@ -736,15 +702,15 @@ assembleI platform i = case i of |
| 736 | 702 | ENTER -> emit_ bci_ENTER []
|
| 737 | 703 | RETURN rep -> emit_ (return_non_tuple rep) []
|
| 738 | 704 | RETURN_TUPLE -> emit_ bci_RETURN_T []
|
| 739 | - CCALL off m_addr i -> do np <- addr m_addr
|
|
| 705 | + CCALL off ffi i -> do np <- lit1 $ BCONPtrFFIInfo ffi
|
|
| 740 | 706 | emit_ bci_CCALL [wOp off, Op np, SmallOp i]
|
| 741 | 707 | PRIMCALL -> emit_ bci_PRIMCALL []
|
| 742 | 708 | BRK_FUN arr tick_mod tick_mod_id tickx info_mod info_mod_id infox cc ->
|
| 743 | 709 | do p1 <- ptr (BCOPtrBreakArray arr)
|
| 744 | - tick_addr <- addr tick_mod
|
|
| 745 | - tick_unitid_addr <- addr tick_mod_id
|
|
| 746 | - info_addr <- addr info_mod
|
|
| 747 | - info_unitid_addr <- addr info_mod_id
|
|
| 710 | + tick_addr <- lit1 $ BCONPtrFS $ moduleNameFS tick_mod
|
|
| 711 | + info_addr <- lit1 $ BCONPtrFS $ moduleNameFS info_mod
|
|
| 712 | + tick_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS tick_mod_id
|
|
| 713 | + info_unitid_addr <- lit1 $ BCONPtrFS $ unitIdFS info_mod_id
|
|
| 748 | 714 | np <- addr cc
|
| 749 | 715 | emit_ bci_BRK_FUN [ Op p1
|
| 750 | 716 | , Op tick_addr, Op info_addr
|
| ... | ... | @@ -13,11 +13,9 @@ import GHC.Prelude |
| 13 | 13 | import GHC.Platform
|
| 14 | 14 | import GHC.Platform.Profile
|
| 15 | 15 | |
| 16 | -import GHC.ByteCode.Types
|
|
| 17 | -import GHC.Runtime.Interpreter
|
|
| 16 | +import GHCi.Message
|
|
| 18 | 17 | |
| 19 | 18 | import GHC.Types.Name ( Name, getName )
|
| 20 | -import GHC.Types.Name.Env
|
|
| 21 | 19 | import GHC.Types.RepType
|
| 22 | 20 | |
| 23 | 21 | import GHC.Core.DataCon ( DataCon, dataConRepArgTys, dataConIdentity )
|
| ... | ... | @@ -35,33 +33,38 @@ import GHC.Utils.Panic |
| 35 | 33 | -}
|
| 36 | 34 | |
| 37 | 35 | -- Make info tables for the data decls in this module
|
| 38 | -mkITbls :: Interp -> Profile -> [TyCon] -> IO ItblEnv
|
|
| 39 | -mkITbls interp profile tcs =
|
|
| 40 | - foldr plusNameEnv emptyNameEnv <$>
|
|
| 41 | - mapM mkITbl (filter isDataTyCon tcs)
|
|
| 36 | +mkITbls :: Profile -> [TyCon] -> [(Name, ConInfoTable)]
|
|
| 37 | +mkITbls profile tcs = concatMap mkITbl (filter isDataTyCon tcs)
|
|
| 42 | 38 | where
|
| 43 | - mkITbl :: TyCon -> IO ItblEnv
|
|
| 39 | + mkITbl :: TyCon -> [(Name, ConInfoTable)]
|
|
| 44 | 40 | mkITbl tc
|
| 45 | 41 | | dcs `lengthIs` n -- paranoia; this is an assertion.
|
| 46 | - = make_constr_itbls interp profile dcs
|
|
| 42 | + = make_constr_itbls profile dcs
|
|
| 47 | 43 | where
|
| 48 | 44 | dcs = tyConDataCons tc
|
| 49 | 45 | n = tyConFamilySize tc
|
| 50 | 46 | mkITbl _ = panic "mkITbl"
|
| 51 | 47 | |
| 52 | -mkItblEnv :: [(Name,ItblPtr)] -> ItblEnv
|
|
| 53 | -mkItblEnv pairs = mkNameEnv [(n, (n,p)) | (n,p) <- pairs]
|
|
| 54 | - |
|
| 55 | 48 | -- Assumes constructors are numbered from zero, not one
|
| 56 | -make_constr_itbls :: Interp -> Profile -> [DataCon] -> IO ItblEnv
|
|
| 57 | -make_constr_itbls interp profile cons =
|
|
| 49 | +make_constr_itbls :: Profile -> [DataCon] -> [(Name, ConInfoTable)]
|
|
| 50 | +make_constr_itbls profile cons =
|
|
| 58 | 51 | -- TODO: the profile should be bundled with the interpreter: the rts ways are
|
| 59 | 52 | -- fixed for an interpreter
|
| 60 | - mkItblEnv <$> mapM (uncurry mk_itbl) (zip cons [0..])
|
|
| 61 | - where
|
|
| 62 | - mk_itbl :: DataCon -> Int -> IO (Name,ItblPtr)
|
|
| 63 | - mk_itbl dcon conNo = do
|
|
| 64 | - let rep_args = [ prim_rep
|
|
| 53 | + map (uncurry mk_itbl) (zip cons [0..])
|
|
| 54 | + where
|
|
| 55 | + mk_itbl :: DataCon -> Int -> (Name, ConInfoTable)
|
|
| 56 | + mk_itbl dcon conNo =
|
|
| 57 | + ( getName dcon,
|
|
| 58 | + ConInfoTable
|
|
| 59 | + tables_next_to_code
|
|
| 60 | + ptrs'
|
|
| 61 | + nptrs_really
|
|
| 62 | + conNo
|
|
| 63 | + (tagForCon platform dcon)
|
|
| 64 | + descr
|
|
| 65 | + )
|
|
| 66 | + where
|
|
| 67 | + rep_args = [ prim_rep
|
|
| 65 | 68 | | arg <- dataConRepArgTys dcon
|
| 66 | 69 | , prim_rep <- typePrimRep (scaledThing arg) ]
|
| 67 | 70 | |
| ... | ... | @@ -79,7 +82,3 @@ make_constr_itbls interp profile cons = |
| 79 | 82 | platform = profilePlatform profile
|
| 80 | 83 | constants = platformConstants platform
|
| 81 | 84 | tables_next_to_code = platformTablesNextToCode platform |
| 82 | - |
|
| 83 | - r <- interpCmd interp (MkConInfoTable tables_next_to_code ptrs' nptrs_really
|
|
| 84 | - conNo (tagForCon platform dcon) descr)
|
|
| 85 | - return (getName dcon, ItblPtr r) |
| ... | ... | @@ -15,7 +15,6 @@ import GHC.Prelude |
| 15 | 15 | |
| 16 | 16 | import GHC.ByteCode.Types
|
| 17 | 17 | import GHCi.RemoteTypes
|
| 18 | -import GHCi.FFI (C_ffi_cif)
|
|
| 19 | 18 | import GHC.StgToCmm.Layout ( ArgRep(..) )
|
| 20 | 19 | import GHC.Utils.Outputable
|
| 21 | 20 | import GHC.Types.Name
|
| ... | ... | @@ -51,9 +50,7 @@ data ProtoBCO a |
| 51 | 50 | protoBCOBitmapSize :: Word,
|
| 52 | 51 | protoBCOArity :: Int,
|
| 53 | 52 | -- what the BCO came from, for debugging only
|
| 54 | - protoBCOExpr :: Either [CgStgAlt] CgStgRhs,
|
|
| 55 | - -- malloc'd pointers
|
|
| 56 | - protoBCOFFIs :: [FFIInfo]
|
|
| 53 | + protoBCOExpr :: Either [CgStgAlt] CgStgRhs
|
|
| 57 | 54 | }
|
| 58 | 55 | |
| 59 | 56 | -- | A local block label (e.g. identifying a case alternative).
|
| ... | ... | @@ -209,7 +206,7 @@ data BCInstr |
| 209 | 206 | |
| 210 | 207 | -- For doing calls to C (via glue code generated by libffi)
|
| 211 | 208 | | CCALL !WordOff -- stack frame size
|
| 212 | - (RemotePtr C_ffi_cif) -- addr of the glue code
|
|
| 209 | + !FFIInfo -- libffi ffi_cif function prototype
|
|
| 213 | 210 | !Word16 -- flags.
|
| 214 | 211 | --
|
| 215 | 212 | -- 0x1: call is interruptible
|
| ... | ... | @@ -233,11 +230,11 @@ data BCInstr |
| 233 | 230 | |
| 234 | 231 | -- Breakpoints
|
| 235 | 232 | | BRK_FUN (ForeignRef BreakArray)
|
| 236 | - (RemotePtr ModuleName) -- breakpoint tick module
|
|
| 237 | - (RemotePtr UnitId) -- breakpoint tick module unit id
|
|
| 233 | + !ModuleName -- breakpoint tick module
|
|
| 234 | + !UnitId -- breakpoint tick module unit id
|
|
| 238 | 235 | !Word16 -- breakpoint tick index
|
| 239 | - (RemotePtr ModuleName) -- breakpoint info module
|
|
| 240 | - (RemotePtr UnitId) -- breakpoint info module unit id
|
|
| 236 | + !ModuleName -- breakpoint info module
|
|
| 237 | + !UnitId -- breakpoint info module unit id
|
|
| 241 | 238 | !Word16 -- breakpoint info index
|
| 242 | 239 | (RemotePtr CostCentre)
|
| 243 | 240 | |
| ... | ... | @@ -266,10 +263,9 @@ instance Outputable a => Outputable (ProtoBCO a) where |
| 266 | 263 | , protoBCOBitmap = bitmap
|
| 267 | 264 | , protoBCOBitmapSize = bsize
|
| 268 | 265 | , protoBCOArity = arity
|
| 269 | - , protoBCOExpr = origin
|
|
| 270 | - , protoBCOFFIs = ffis })
|
|
| 266 | + , protoBCOExpr = origin })
|
|
| 271 | 267 | = (text "ProtoBCO" <+> ppr name <> char '#' <> int arity
|
| 272 | - <+> text (show ffis) <> colon)
|
|
| 268 | + <> colon)
|
|
| 273 | 269 | $$ nest 3 (case origin of
|
| 274 | 270 | Left alts ->
|
| 275 | 271 | vcat (zipWith (<+>) (char '{' : repeat (char ';'))
|
| ... | ... | @@ -393,9 +389,9 @@ instance Outputable BCInstr where |
| 393 | 389 | ppr (TESTEQ_P i lab) = text "TESTEQ_P" <+> ppr i <+> text "__" <> ppr lab
|
| 394 | 390 | ppr CASEFAIL = text "CASEFAIL"
|
| 395 | 391 | ppr (JMP lab) = text "JMP" <+> ppr lab
|
| 396 | - ppr (CCALL off marshal_addr flags) = text "CCALL " <+> ppr off
|
|
| 392 | + ppr (CCALL off ffi flags) = text "CCALL " <+> ppr off
|
|
| 397 | 393 | <+> text "marshal code at"
|
| 398 | - <+> text (show marshal_addr)
|
|
| 394 | + <+> text (show ffi)
|
|
| 399 | 395 | <+> (case flags of
|
| 400 | 396 | 0x1 -> text "(interruptible)"
|
| 401 | 397 | 0x2 -> text "(unsafe)"
|
| ... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 | {-# LANGUAGE MultiParamTypeClasses #-}
|
| 4 | 4 | {-# LANGUAGE OverloadedStrings #-}
|
| 5 | 5 | {-# LANGUAGE DataKinds #-}
|
| 6 | +{-# LANGUAGE RecordWildCards #-}
|
|
| 6 | 7 | {-# OPTIONS_GHC -optc-DNON_POSIX_SOURCE #-}
|
| 7 | 8 | --
|
| 8 | 9 | -- (c) The University of Glasgow 2002-2006
|
| ... | ... | @@ -85,9 +86,15 @@ lookupLiteral interp pkgs_loaded le ptr = case ptr of |
| 85 | 86 | BCONPtrAddr nm -> do
|
| 86 | 87 | Ptr a# <- lookupAddr interp pkgs_loaded (addr_env le) nm
|
| 87 | 88 | return (W# (int2Word# (addr2Int# a#)))
|
| 88 | - BCONPtrStr _ ->
|
|
| 89 | - -- should be eliminated during assembleBCOs
|
|
| 90 | - panic "lookupLiteral: BCONPtrStr"
|
|
| 89 | + BCONPtrStr bs -> do
|
|
| 90 | + RemotePtr p <- fmap head $ interpCmd interp $ MallocStrings [bs]
|
|
| 91 | + pure $ fromIntegral p
|
|
| 92 | + BCONPtrFS fs -> do
|
|
| 93 | + RemotePtr p <- fmap head $ interpCmd interp $ MallocStrings [bytesFS fs]
|
|
| 94 | + pure $ fromIntegral p
|
|
| 95 | + BCONPtrFFIInfo (FFIInfo {..}) -> do
|
|
| 96 | + RemotePtr p <- interpCmd interp $ PrepFFI ffiInfoArgs ffiInfoRet
|
|
| 97 | + pure $ fromIntegral p
|
|
| 91 | 98 | |
| 92 | 99 | lookupStaticPtr :: Interp -> FastString -> IO (Ptr ())
|
| 93 | 100 | lookupStaticPtr interp addr_of_label_string = do
|
| ... | ... | @@ -35,6 +35,7 @@ import GHC.Builtin.PrimOps |
| 35 | 35 | import GHC.Types.SptEntry
|
| 36 | 36 | import GHC.Types.SrcLoc
|
| 37 | 37 | import GHCi.BreakArray
|
| 38 | +import GHCi.Message
|
|
| 38 | 39 | import GHCi.RemoteTypes
|
| 39 | 40 | import GHCi.FFI
|
| 40 | 41 | import Control.DeepSeq
|
| ... | ... | @@ -49,8 +50,8 @@ import qualified GHC.Exts.Heap as Heap |
| 49 | 50 | import GHC.Stack.CCS
|
| 50 | 51 | import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList )
|
| 51 | 52 | import GHC.Iface.Syntax
|
| 52 | -import Language.Haskell.Syntax.Module.Name (ModuleName)
|
|
| 53 | -import GHC.Unit.Types (UnitId)
|
|
| 53 | +import Language.Haskell.Syntax.Module.Name (ModuleName, mkModuleNameFS)
|
|
| 54 | +import GHC.Unit.Types (UnitId(..))
|
|
| 54 | 55 | |
| 55 | 56 | -- -----------------------------------------------------------------------------
|
| 56 | 57 | -- Compiled Byte Code
|
| ... | ... | @@ -59,13 +60,10 @@ data CompiledByteCode = CompiledByteCode |
| 59 | 60 | { bc_bcos :: FlatBag UnlinkedBCO
|
| 60 | 61 | -- ^ Bunch of interpretable bindings
|
| 61 | 62 | |
| 62 | - , bc_itbls :: ItblEnv
|
|
| 63 | + , bc_itbls :: [(Name, ConInfoTable)]
|
|
| 63 | 64 | -- ^ Mapping from DataCons to their info tables
|
| 64 | 65 | |
| 65 | - , bc_ffis :: [FFIInfo]
|
|
| 66 | - -- ^ ffi blocks we allocated
|
|
| 67 | - |
|
| 68 | - , bc_strs :: AddrEnv
|
|
| 66 | + , bc_strs :: [(Name, ByteString)]
|
|
| 69 | 67 | -- ^ top-level strings (heap allocated)
|
| 70 | 68 | |
| 71 | 69 | , bc_breaks :: Maybe ModBreaks
|
| ... | ... | @@ -76,9 +74,10 @@ data CompiledByteCode = CompiledByteCode |
| 76 | 74 | -- BCOs. See Note [Grand plan for static forms] in
|
| 77 | 75 | -- "GHC.Iface.Tidy.StaticPtrTable".
|
| 78 | 76 | }
|
| 79 | - -- ToDo: we're not tracking strings that we malloc'd
|
|
| 80 | -newtype FFIInfo = FFIInfo (RemotePtr C_ffi_cif)
|
|
| 81 | - deriving (Show, NFData)
|
|
| 77 | + |
|
| 78 | +-- | A libffi ffi_cif function prototype.
|
|
| 79 | +data FFIInfo = FFIInfo { ffiInfoArgs :: ![FFIType], ffiInfoRet :: !FFIType }
|
|
| 80 | + deriving (Show)
|
|
| 82 | 81 | |
| 83 | 82 | instance Outputable CompiledByteCode where
|
| 84 | 83 | ppr CompiledByteCode{..} = ppr $ elemsFlatBag bc_bcos
|
| ... | ... | @@ -88,9 +87,8 @@ instance Outputable CompiledByteCode where |
| 88 | 87 | seqCompiledByteCode :: CompiledByteCode -> ()
|
| 89 | 88 | seqCompiledByteCode CompiledByteCode{..} =
|
| 90 | 89 | rnf bc_bcos `seq`
|
| 91 | - seqEltsNameEnv rnf bc_itbls `seq`
|
|
| 92 | - rnf bc_ffis `seq`
|
|
| 93 | - seqEltsNameEnv rnf bc_strs `seq`
|
|
| 90 | + rnf bc_itbls `seq`
|
|
| 91 | + rnf bc_strs `seq`
|
|
| 94 | 92 | rnf (fmap seqModBreaks bc_breaks)
|
| 95 | 93 | |
| 96 | 94 | newtype ByteOff = ByteOff Int
|
| ... | ... | @@ -200,10 +198,13 @@ data BCONPtr |
| 200 | 198 | -- | A reference to a top-level string literal; see
|
| 201 | 199 | -- Note [Generating code for top-level string literal bindings] in GHC.StgToByteCode.
|
| 202 | 200 | | BCONPtrAddr !Name
|
| 203 | - -- | Only used internally in the assembler in an intermediate representation;
|
|
| 204 | - -- should never appear in a fully-assembled UnlinkedBCO.
|
|
| 201 | + -- | A top-level string literal.
|
|
| 205 | 202 | -- Also see Note [Allocating string literals] in GHC.ByteCode.Asm.
|
| 206 | 203 | | BCONPtrStr !ByteString
|
| 204 | + -- | Same as 'BCONPtrStr' but with benefits of 'FastString' interning logic.
|
|
| 205 | + | BCONPtrFS !FastString
|
|
| 206 | + -- | A libffi ffi_cif function prototype.
|
|
| 207 | + | BCONPtrFFIInfo !FFIInfo
|
|
| 207 | 208 | |
| 208 | 209 | instance NFData BCONPtr where
|
| 209 | 210 | rnf x = x `seq` ()
|
| ... | ... | @@ -263,9 +264,9 @@ data ModBreaks |
| 263 | 264 | -- ^ Array pointing to cost centre for each breakpoint
|
| 264 | 265 | , modBreaks_breakInfo :: IntMap CgBreakInfo
|
| 265 | 266 | -- ^ info about each breakpoint from the bytecode generator
|
| 266 | - , modBreaks_module :: RemotePtr ModuleName
|
|
| 267 | + , modBreaks_module :: !ModuleName
|
|
| 267 | 268 | -- ^ info about the module in which we are setting the breakpoint
|
| 268 | - , modBreaks_module_unitid :: RemotePtr UnitId
|
|
| 269 | + , modBreaks_module_unitid :: !UnitId
|
|
| 269 | 270 | -- ^ The 'UnitId' of the 'ModuleName'
|
| 270 | 271 | }
|
| 271 | 272 | |
| ... | ... | @@ -290,8 +291,8 @@ emptyModBreaks = ModBreaks |
| 290 | 291 | , modBreaks_decls = array (0,-1) []
|
| 291 | 292 | , modBreaks_ccs = array (0,-1) []
|
| 292 | 293 | , modBreaks_breakInfo = IntMap.empty
|
| 293 | - , modBreaks_module = toRemotePtr nullPtr
|
|
| 294 | - , modBreaks_module_unitid = toRemotePtr nullPtr
|
|
| 294 | + , modBreaks_module = mkModuleNameFS nilFS
|
|
| 295 | + , modBreaks_module_unitid = UnitId nilFS
|
|
| 295 | 296 | }
|
| 296 | 297 | |
| 297 | 298 | {-
|
| ... | ... | @@ -34,7 +34,6 @@ mkModBreaks interp mod extendedMixEntries |
| 34 | 34 | |
| 35 | 35 | breakArray <- GHCi.newBreakArray interp count
|
| 36 | 36 | ccs <- mkCCSArray interp mod count entries
|
| 37 | - (mod_ptr, mod_id_ptr) <- GHCi.newModule interp mod
|
|
| 38 | 37 | let
|
| 39 | 38 | locsTicks = listArray (0,count-1) [ tick_loc t | t <- entries ]
|
| 40 | 39 | varsTicks = listArray (0,count-1) [ tick_ids t | t <- entries ]
|
| ... | ... | @@ -45,8 +44,8 @@ mkModBreaks interp mod extendedMixEntries |
| 45 | 44 | , modBreaks_vars = varsTicks
|
| 46 | 45 | , modBreaks_decls = declsTicks
|
| 47 | 46 | , modBreaks_ccs = ccs
|
| 48 | - , modBreaks_module = mod_ptr
|
|
| 49 | - , modBreaks_module_unitid = mod_id_ptr
|
|
| 47 | + , modBreaks_module = moduleName mod
|
|
| 48 | + , modBreaks_module_unitid = toUnitId $ moduleUnit mod
|
|
| 50 | 49 | }
|
| 51 | 50 | |
| 52 | 51 | mkCCSArray
|
| ... | ... | @@ -54,7 +54,7 @@ import GHC.Tc.Utils.Monad |
| 54 | 54 | import GHC.Runtime.Interpreter
|
| 55 | 55 | import GHCi.RemoteTypes
|
| 56 | 56 | import GHC.Iface.Load
|
| 57 | -import GHCi.Message (LoadedDLL)
|
|
| 57 | +import GHCi.Message (ConInfoTable(..), LoadedDLL)
|
|
| 58 | 58 | |
| 59 | 59 | import GHC.ByteCode.Linker
|
| 60 | 60 | import GHC.ByteCode.Asm
|
| ... | ... | @@ -95,6 +95,7 @@ import GHC.Linker.Types |
| 95 | 95 | -- Standard libraries
|
| 96 | 96 | import Control.Monad
|
| 97 | 97 | |
| 98 | +import Data.ByteString (ByteString)
|
|
| 98 | 99 | import qualified Data.Set as Set
|
| 99 | 100 | import Data.Char (isSpace)
|
| 100 | 101 | import qualified Data.Foldable as Foldable
|
| ... | ... | @@ -688,8 +689,10 @@ loadDecls interp hsc_env span linkable = do |
| 688 | 689 | else do
|
| 689 | 690 | -- Link the expression itself
|
| 690 | 691 | let le = linker_env pls
|
| 691 | - le2 = le { itbl_env = foldl' (\acc cbc -> plusNameEnv acc (bc_itbls cbc)) (itbl_env le) cbcs
|
|
| 692 | - , addr_env = foldl' (\acc cbc -> plusNameEnv acc (bc_strs cbc)) (addr_env le) cbcs }
|
|
| 692 | + le2_itbl_env <- linkITbls interp (itbl_env le) (concat $ map bc_itbls cbcs)
|
|
| 693 | + le2_addr_env <- foldlM (\env cbc -> allocateTopStrings interp (bc_strs cbc) env) (addr_env le) cbcs
|
|
| 694 | + let le2 = le { itbl_env = le2_itbl_env
|
|
| 695 | + , addr_env = le2_addr_env }
|
|
| 693 | 696 | |
| 694 | 697 | -- Link the necessary packages and linkables
|
| 695 | 698 | new_bindings <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs
|
| ... | ... | @@ -911,9 +914,9 @@ dynLinkBCOs interp pls bcos = do |
| 911 | 914 | |
| 912 | 915 | |
| 913 | 916 | le1 = linker_env pls
|
| 914 | - ie2 = foldr plusNameEnv (itbl_env le1) (map bc_itbls cbcs)
|
|
| 915 | - ae2 = foldr plusNameEnv (addr_env le1) (map bc_strs cbcs)
|
|
| 916 | - le2 = le1 { itbl_env = ie2, addr_env = ae2 }
|
|
| 917 | + ie2 <- linkITbls interp (itbl_env le1) (concatMap bc_itbls cbcs)
|
|
| 918 | + ae2 <- foldlM (\env cbc -> allocateTopStrings interp (bc_strs cbc) env) (addr_env le1) cbcs
|
|
| 919 | + let le2 = le1 { itbl_env = ie2, addr_env = ae2 }
|
|
| 917 | 920 | |
| 918 | 921 | names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs
|
| 919 | 922 | |
| ... | ... | @@ -958,6 +961,11 @@ makeForeignNamedHValueRefs |
| 958 | 961 | makeForeignNamedHValueRefs interp bindings =
|
| 959 | 962 | mapM (\(n, hvref) -> (n,) <$> mkFinalizedHValue interp hvref) bindings
|
| 960 | 963 | |
| 964 | +linkITbls :: Interp -> ItblEnv -> [(Name, ConInfoTable)] -> IO ItblEnv
|
|
| 965 | +linkITbls interp = foldlM $ \env (nm, itbl) -> do
|
|
| 966 | + r <- interpCmd interp $ MkConInfoTable itbl
|
|
| 967 | + evaluate $ extendNameEnv env nm (nm, ItblPtr r)
|
|
| 968 | + |
|
| 961 | 969 | {- **********************************************************************
|
| 962 | 970 | |
| 963 | 971 | Unload some object modules
|
| ... | ... | @@ -1614,3 +1622,13 @@ maybePutStr logger s = maybePutSDoc logger (text s) |
| 1614 | 1622 | |
| 1615 | 1623 | maybePutStrLn :: Logger -> String -> IO ()
|
| 1616 | 1624 | maybePutStrLn logger s = maybePutSDoc logger (text s <> text "\n")
|
| 1625 | + |
|
| 1626 | +-- | see Note [Generating code for top-level string literal bindings]
|
|
| 1627 | +allocateTopStrings ::
|
|
| 1628 | + Interp -> [(Name, ByteString)] -> AddrEnv -> IO AddrEnv
|
|
| 1629 | +allocateTopStrings interp topStrings prev_env = do
|
|
| 1630 | + let (bndrs, strings) = unzip topStrings
|
|
| 1631 | + ptrs <- interpCmd interp $ MallocStrings strings
|
|
| 1632 | + evaluate $ extendNameEnvList prev_env (zipWith mk_entry bndrs ptrs)
|
|
| 1633 | + where
|
|
| 1634 | + mk_entry nm ptr = (nm, (nm, AddrPtr ptr)) |
| ... | ... | @@ -21,7 +21,6 @@ module GHC.Runtime.Interpreter |
| 21 | 21 | , mkCostCentres
|
| 22 | 22 | , costCentreStackInfo
|
| 23 | 23 | , newBreakArray
|
| 24 | - , newModule
|
|
| 25 | 24 | , storeBreakpoint
|
| 26 | 25 | , breakpointStatus
|
| 27 | 26 | , getBreakpointVar
|
| ... | ... | @@ -376,14 +375,6 @@ newBreakArray interp size = do |
| 376 | 375 | breakArray <- interpCmd interp (NewBreakArray size)
|
| 377 | 376 | mkFinalizedHValue interp breakArray
|
| 378 | 377 | |
| 379 | -newModule :: Interp -> Module -> IO (RemotePtr ModuleName, RemotePtr UnitId)
|
|
| 380 | -newModule interp mod = do
|
|
| 381 | - let
|
|
| 382 | - mod_name = moduleNameString $ moduleName mod
|
|
| 383 | - mod_id = fastStringToShortByteString $ unitIdFS $ toUnitId $ moduleUnit mod
|
|
| 384 | - (mod_ptr, mod_id_ptr) <- interpCmd interp (NewBreakModule mod_name mod_id)
|
|
| 385 | - pure (castRemotePtr mod_ptr, castRemotePtr mod_id_ptr)
|
|
| 386 | - |
|
| 387 | 378 | storeBreakpoint :: Interp -> ForeignRef BreakArray -> Int -> Int -> IO ()
|
| 388 | 379 | storeBreakpoint interp ref ix cnt = do -- #19157
|
| 389 | 380 | withForeignRef ref $ \breakarray ->
|
| ... | ... | @@ -67,7 +67,6 @@ import GHC.Data.Bitmap |
| 67 | 67 | import GHC.Data.FlatBag as FlatBag
|
| 68 | 68 | import GHC.Data.OrdList
|
| 69 | 69 | import GHC.Data.Maybe
|
| 70 | -import GHC.Types.Name.Env (mkNameEnv)
|
|
| 71 | 70 | import GHC.Types.Tickish
|
| 72 | 71 | import GHC.Types.SptEntry
|
| 73 | 72 | |
| ... | ... | @@ -82,7 +81,6 @@ import GHC.Unit.Home.PackageTable (lookupHpt) |
| 82 | 81 | |
| 83 | 82 | import Data.Array
|
| 84 | 83 | import Data.Coerce (coerce)
|
| 85 | -import Data.ByteString (ByteString)
|
|
| 86 | 84 | #if MIN_VERSION_rts(1,0,3)
|
| 87 | 85 | import qualified Data.ByteString.Char8 as BS
|
| 88 | 86 | #endif
|
| ... | ... | @@ -118,19 +116,15 @@ byteCodeGen hsc_env this_mod binds tycs mb_modBreaks spt_entries |
| 118 | 116 | bnd <- binds
|
| 119 | 117 | case bnd of
|
| 120 | 118 | StgTopLifted bnd -> [Right bnd]
|
| 121 | - StgTopStringLit b str -> [Left (b, str)]
|
|
| 119 | + StgTopStringLit b str -> [Left (getName b, str)]
|
|
| 122 | 120 | flattenBind (StgNonRec b e) = [(b,e)]
|
| 123 | 121 | flattenBind (StgRec bs) = bs
|
| 124 | - stringPtrs <- allocateTopStrings interp strings
|
|
| 125 | 122 | |
| 126 | 123 | (BcM_State{..}, proto_bcos) <-
|
| 127 | 124 | runBc hsc_env this_mod mb_modBreaks $ do
|
| 128 | 125 | let flattened_binds = concatMap flattenBind (reverse lifted_binds)
|
| 129 | 126 | FlatBag.fromList (fromIntegral $ length flattened_binds) <$> mapM schemeTopBind flattened_binds
|
| 130 | 127 | |
| 131 | - when (notNull ffis)
|
|
| 132 | - (panic "GHC.StgToByteCode.byteCodeGen: missing final emitBc?")
|
|
| 133 | - |
|
| 134 | 128 | putDumpFileMaybe logger Opt_D_dump_BCOs
|
| 135 | 129 | "Proto-BCOs" FormatByteCode
|
| 136 | 130 | (vcat (intersperse (char ' ') (map ppr $ elemsFlatBag proto_bcos)))
|
| ... | ... | @@ -138,7 +132,7 @@ byteCodeGen hsc_env this_mod binds tycs mb_modBreaks spt_entries |
| 138 | 132 | let mod_breaks = case modBreaks of
|
| 139 | 133 | Nothing -> Nothing
|
| 140 | 134 | Just mb -> Just mb{ modBreaks_breakInfo = breakInfo }
|
| 141 | - cbc <- assembleBCOs interp profile proto_bcos tycs stringPtrs mod_breaks spt_entries
|
|
| 135 | + cbc <- assembleBCOs profile proto_bcos tycs strings mod_breaks spt_entries
|
|
| 142 | 136 | |
| 143 | 137 | -- Squash space leaks in the CompiledByteCode. This is really
|
| 144 | 138 | -- important, because when loading a set of modules into GHCi
|
| ... | ... | @@ -152,22 +146,8 @@ byteCodeGen hsc_env this_mod binds tycs mb_modBreaks spt_entries |
| 152 | 146 | |
| 153 | 147 | where dflags = hsc_dflags hsc_env
|
| 154 | 148 | logger = hsc_logger hsc_env
|
| 155 | - interp = hscInterp hsc_env
|
|
| 156 | 149 | profile = targetProfile dflags
|
| 157 | 150 | |
| 158 | --- | see Note [Generating code for top-level string literal bindings]
|
|
| 159 | -allocateTopStrings
|
|
| 160 | - :: Interp
|
|
| 161 | - -> [(Id, ByteString)]
|
|
| 162 | - -> IO AddrEnv
|
|
| 163 | -allocateTopStrings interp topStrings = do
|
|
| 164 | - let !(bndrs, strings) = unzip topStrings
|
|
| 165 | - ptrs <- interpCmd interp $ MallocStrings strings
|
|
| 166 | - return $ mkNameEnv (zipWith mk_entry bndrs ptrs)
|
|
| 167 | - where
|
|
| 168 | - mk_entry bndr ptr = let nm = getName bndr
|
|
| 169 | - in (nm, (nm, AddrPtr ptr))
|
|
| 170 | - |
|
| 171 | 151 | {- Note [Generating code for top-level string literal bindings]
|
| 172 | 152 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 173 | 153 | As described in Note [Compilation plan for top-level string literals]
|
| ... | ... | @@ -178,9 +158,9 @@ the bytecode compiler: (1) compiling the bindings themselves, and |
| 178 | 158 | we deal with them:
|
| 179 | 159 | |
| 180 | 160 | 1. Top-level string literal bindings are separated from the rest of
|
| 181 | - the module. Memory for them is allocated immediately, via
|
|
| 182 | - interpCmd, in allocateTopStrings, and the resulting AddrEnv is
|
|
| 183 | - recorded in the bc_strs field of the CompiledByteCode result.
|
|
| 161 | + the module. Memory is not allocated until bytecode link-time, the
|
|
| 162 | + bc_strs field of the CompiledByteCode result records [(Name, ByteString)]
|
|
| 163 | + directly.
|
|
| 184 | 164 | |
| 185 | 165 | 2. When we encounter a reference to a top-level string literal, we
|
| 186 | 166 | generate a PUSH_ADDR pseudo-instruction, which is assembled to
|
| ... | ... | @@ -254,17 +234,15 @@ mkProtoBCO |
| 254 | 234 | -> WordOff -- ^ bitmap size
|
| 255 | 235 | -> [StgWord] -- ^ bitmap
|
| 256 | 236 | -> Bool -- ^ True <=> is a return point, rather than a function
|
| 257 | - -> [FFIInfo]
|
|
| 258 | 237 | -> ProtoBCO Name
|
| 259 | -mkProtoBCO platform _add_bco_name nm instrs_ordlist origin arity bitmap_size bitmap is_ret ffis
|
|
| 238 | +mkProtoBCO platform _add_bco_name nm instrs_ordlist origin arity bitmap_size bitmap is_ret
|
|
| 260 | 239 | = ProtoBCO {
|
| 261 | 240 | protoBCOName = nm,
|
| 262 | 241 | protoBCOInstrs = maybe_add_bco_name $ maybe_add_stack_check peep_d,
|
| 263 | 242 | protoBCOBitmap = bitmap,
|
| 264 | 243 | protoBCOBitmapSize = fromIntegral bitmap_size,
|
| 265 | 244 | protoBCOArity = arity,
|
| 266 | - protoBCOExpr = origin,
|
|
| 267 | - protoBCOFFIs = ffis
|
|
| 245 | + protoBCOExpr = origin
|
|
| 268 | 246 | }
|
| 269 | 247 | where
|
| 270 | 248 | #if MIN_VERSION_rts(1,0,3)
|
| ... | ... | @@ -334,7 +312,7 @@ schemeTopBind (id, rhs) |
| 334 | 312 | -- by just re-using the single top-level definition. So
|
| 335 | 313 | -- for the worker itself, we must allocate it directly.
|
| 336 | 314 | -- ioToBc (putStrLn $ "top level BCO")
|
| 337 | - emitBc (mkProtoBCO platform add_bco_name
|
|
| 315 | + pure (mkProtoBCO platform add_bco_name
|
|
| 338 | 316 | (getName id) (toOL [PACK data_con 0, RETURN P])
|
| 339 | 317 | (Right rhs) 0 0 [{-no bitmap-}] False{-not alts-})
|
| 340 | 318 | |
| ... | ... | @@ -399,7 +377,7 @@ schemeR_wrk fvs nm original_body (args, body) |
| 399 | 377 | bitmap = mkBitmap platform bits
|
| 400 | 378 | body_code <- schemeER_wrk sum_szsb_args p_init body
|
| 401 | 379 | |
| 402 | - emitBc (mkProtoBCO platform add_bco_name nm body_code (Right original_body)
|
|
| 380 | + pure (mkProtoBCO platform add_bco_name nm body_code (Right original_body)
|
|
| 403 | 381 | arity bitmap_size bitmap False{-not alts-})
|
| 404 | 382 | |
| 405 | 383 | -- | Introduce break instructions for ticked expressions.
|
| ... | ... | @@ -478,7 +456,7 @@ break_info hsc_env mod current_mod current_mod_breaks |
| 478 | 456 | where
|
| 479 | 457 | check_mod_ptr mb
|
| 480 | 458 | | mod_ptr <- modBreaks_module mb
|
| 481 | - , fromRemotePtr mod_ptr /= nullPtr
|
|
| 459 | + , not $ nullFS $ moduleNameFS mod_ptr
|
|
| 482 | 460 | = Just mb
|
| 483 | 461 | | otherwise
|
| 484 | 462 | = Nothing
|
| ... | ... | @@ -546,7 +524,7 @@ returnUnliftedReps d s szb reps = do |
| 546 | 524 | -- otherwise use RETURN_TUPLE with a tuple descriptor
|
| 547 | 525 | nv_reps -> do
|
| 548 | 526 | let (call_info, args_offsets) = layoutNativeCall profile NativeTupleReturn 0 id nv_reps
|
| 549 | - tuple_bco <- emitBc (tupleBCO platform call_info args_offsets)
|
|
| 527 | + tuple_bco = tupleBCO platform call_info args_offsets
|
|
| 550 | 528 | return $ PUSH_UBX (mkNativeCallInfoLit platform call_info) 1 `consOL`
|
| 551 | 529 | PUSH_BCO tuple_bco `consOL`
|
| 552 | 530 | unitOL RETURN_TUPLE
|
| ... | ... | @@ -1097,16 +1075,15 @@ doCase d s p scrut bndr alts |
| 1097 | 1075 | scrut_code <- schemeE (d + ret_frame_size_b + save_ccs_size_b)
|
| 1098 | 1076 | (d + ret_frame_size_b + save_ccs_size_b)
|
| 1099 | 1077 | p scrut
|
| 1100 | - alt_bco' <- emitBc alt_bco
|
|
| 1101 | 1078 | if ubx_tuple_frame
|
| 1102 | - then do tuple_bco <- emitBc (tupleBCO platform call_info args_offsets)
|
|
| 1103 | - return (PUSH_ALTS_TUPLE alt_bco' call_info tuple_bco
|
|
| 1079 | + then do let tuple_bco = tupleBCO platform call_info args_offsets
|
|
| 1080 | + return (PUSH_ALTS_TUPLE alt_bco call_info tuple_bco
|
|
| 1104 | 1081 | `consOL` scrut_code)
|
| 1105 | 1082 | else let scrut_rep = case non_void_arg_reps of
|
| 1106 | 1083 | [] -> V
|
| 1107 | 1084 | [rep] -> rep
|
| 1108 | 1085 | _ -> panic "schemeE(StgCase).push_alts"
|
| 1109 | - in return (PUSH_ALTS alt_bco' scrut_rep `consOL` scrut_code)
|
|
| 1086 | + in return (PUSH_ALTS alt_bco scrut_rep `consOL` scrut_code)
|
|
| 1110 | 1087 | |
| 1111 | 1088 | |
| 1112 | 1089 | -- -----------------------------------------------------------------------------
|
| ... | ... | @@ -1398,7 +1375,7 @@ Note [unboxed tuple bytecodes and tuple_BCO] |
| 1398 | 1375 | |
| 1399 | 1376 | -}
|
| 1400 | 1377 | |
| 1401 | -tupleBCO :: Platform -> NativeCallInfo -> [(PrimRep, ByteOff)] -> [FFIInfo] -> ProtoBCO Name
|
|
| 1378 | +tupleBCO :: Platform -> NativeCallInfo -> [(PrimRep, ByteOff)] -> ProtoBCO Name
|
|
| 1402 | 1379 | tupleBCO platform args_info args =
|
| 1403 | 1380 | mkProtoBCO platform Nothing invented_name body_code (Left [])
|
| 1404 | 1381 | 0{-no arity-} bitmap_size bitmap False{-is alts-}
|
| ... | ... | @@ -1419,7 +1396,7 @@ tupleBCO platform args_info args = |
| 1419 | 1396 | body_code = mkSlideW 0 1 -- pop frame header
|
| 1420 | 1397 | `snocOL` RETURN_TUPLE -- and add it again
|
| 1421 | 1398 | |
| 1422 | -primCallBCO :: Platform -> NativeCallInfo -> [(PrimRep, ByteOff)] -> [FFIInfo] -> ProtoBCO Name
|
|
| 1399 | +primCallBCO :: Platform -> NativeCallInfo -> [(PrimRep, ByteOff)] -> ProtoBCO Name
|
|
| 1423 | 1400 | primCallBCO platform args_info args =
|
| 1424 | 1401 | mkProtoBCO platform Nothing invented_name body_code (Left [])
|
| 1425 | 1402 | 0{-no arity-} bitmap_size bitmap False{-is alts-}
|
| ... | ... | @@ -1528,7 +1505,7 @@ generatePrimCall d s p target _mb_unit _result_ty args |
| 1528 | 1505 | massert (off == dd + szb)
|
| 1529 | 1506 | go (dd + szb) (push:pushes) cs
|
| 1530 | 1507 | push_args <- go d [] shifted_args_offsets
|
| 1531 | - args_bco <- emitBc (primCallBCO platform args_info prim_args_offsets)
|
|
| 1508 | + let args_bco = primCallBCO platform args_info prim_args_offsets
|
|
| 1532 | 1509 | return $ mconcat push_args `appOL`
|
| 1533 | 1510 | (push_target `consOL`
|
| 1534 | 1511 | push_info `consOL`
|
| ... | ... | @@ -1706,13 +1683,10 @@ generateCCall d0 s p (CCallSpec target _ safety) result_ty args |
| 1706 | 1683 | |
| 1707 | 1684 | let ffires = primRepToFFIType platform r_rep
|
| 1708 | 1685 | ffiargs = map (primRepToFFIType platform) a_reps
|
| 1709 | - interp <- hscInterp <$> getHscEnv
|
|
| 1710 | - token <- ioToBc $ interpCmd interp (PrepFFI ffiargs ffires)
|
|
| 1711 | - recordFFIBc token
|
|
| 1712 | 1686 | |
| 1713 | 1687 | let
|
| 1714 | 1688 | -- do the call
|
| 1715 | - do_call = unitOL (CCALL stk_offset token flags)
|
|
| 1689 | + do_call = unitOL (CCALL stk_offset (FFIInfo ffiargs ffires) flags)
|
|
| 1716 | 1690 | where flags = case safety of
|
| 1717 | 1691 | PlaySafe -> 0x0
|
| 1718 | 1692 | PlayInterruptible -> 0x1
|
| ... | ... | @@ -2311,8 +2285,6 @@ data BcM_State |
| 2311 | 2285 | { bcm_hsc_env :: HscEnv
|
| 2312 | 2286 | , thisModule :: Module -- current module (for breakpoints)
|
| 2313 | 2287 | , nextlabel :: Word32 -- for generating local labels
|
| 2314 | - , ffis :: [FFIInfo] -- ffi info blocks, to free later
|
|
| 2315 | - -- Should be free()d when it is GCd
|
|
| 2316 | 2288 | , modBreaks :: Maybe ModBreaks -- info about breakpoints
|
| 2317 | 2289 | |
| 2318 | 2290 | , breakInfo :: IntMap CgBreakInfo -- ^ Info at breakpoint occurrence.
|
| ... | ... | @@ -2333,7 +2305,7 @@ runBc :: HscEnv -> Module -> Maybe ModBreaks |
| 2333 | 2305 | -> BcM r
|
| 2334 | 2306 | -> IO (BcM_State, r)
|
| 2335 | 2307 | runBc hsc_env this_mod modBreaks (BcM m)
|
| 2336 | - = m (BcM_State hsc_env this_mod 0 [] modBreaks IntMap.empty 0)
|
|
| 2308 | + = m (BcM_State hsc_env this_mod 0 modBreaks IntMap.empty 0)
|
|
| 2337 | 2309 | |
| 2338 | 2310 | thenBc :: BcM a -> (a -> BcM b) -> BcM b
|
| 2339 | 2311 | thenBc (BcM expr) cont = BcM $ \st0 -> do
|
| ... | ... | @@ -2376,14 +2348,6 @@ shouldAddBcoName = do |
| 2376 | 2348 | then Just <$> getCurrentModule
|
| 2377 | 2349 | else return Nothing
|
| 2378 | 2350 | |
| 2379 | -emitBc :: ([FFIInfo] -> ProtoBCO Name) -> BcM (ProtoBCO Name)
|
|
| 2380 | -emitBc bco
|
|
| 2381 | - = BcM $ \st -> return (st{ffis=[]}, bco (ffis st))
|
|
| 2382 | - |
|
| 2383 | -recordFFIBc :: RemotePtr C_ffi_cif -> BcM ()
|
|
| 2384 | -recordFFIBc a
|
|
| 2385 | - = BcM $ \st -> return (st{ffis = FFIInfo a : ffis st}, ())
|
|
| 2386 | - |
|
| 2387 | 2351 | getLabelBc :: BcM LocalLabel
|
| 2388 | 2352 | getLabelBc
|
| 2389 | 2353 | = BcM $ \st -> do let nl = nextlabel st
|
| ... | ... | @@ -11,6 +11,7 @@ |
| 11 | 11 | --
|
| 12 | 12 | module GHCi.Message
|
| 13 | 13 | ( Message(..), Msg(..)
|
| 14 | + , ConInfoTable(..)
|
|
| 14 | 15 | , THMessage(..), THMsg(..)
|
| 15 | 16 | , QResult(..)
|
| 16 | 17 | , EvalStatus_(..), EvalStatus, EvalResult(..), EvalOpts(..), EvalExpr(..)
|
| ... | ... | @@ -41,6 +42,7 @@ import GHC.ForeignSrcLang |
| 41 | 42 | import GHC.Fingerprint
|
| 42 | 43 | import GHC.Conc (pseq, par)
|
| 43 | 44 | import Control.Concurrent
|
| 45 | +import Control.DeepSeq
|
|
| 44 | 46 | import Control.Exception
|
| 45 | 47 | #if MIN_VERSION_base(4,20,0)
|
| 46 | 48 | import Control.Exception.Context
|
| ... | ... | @@ -117,12 +119,7 @@ data Message a where |
| 117 | 119 | |
| 118 | 120 | -- | Create an info table for a constructor
|
| 119 | 121 | MkConInfoTable
|
| 120 | - :: Bool -- TABLES_NEXT_TO_CODE
|
|
| 121 | - -> Int -- ptr words
|
|
| 122 | - -> Int -- non-ptr words
|
|
| 123 | - -> Int -- constr tag
|
|
| 124 | - -> Int -- pointer tag
|
|
| 125 | - -> ByteString -- constructor desccription
|
|
| 122 | + :: !ConInfoTable
|
|
| 126 | 123 | -> Message (RemotePtr Heap.StgInfoTable)
|
| 127 | 124 | |
| 128 | 125 | -- | Evaluate a statement
|
| ... | ... | @@ -244,16 +241,23 @@ data Message a where |
| 244 | 241 | :: RemoteRef (ResumeContext ())
|
| 245 | 242 | -> Message (EvalStatus ())
|
| 246 | 243 | |
| 247 | - -- | Allocate a string for a breakpoint module name.
|
|
| 248 | - -- This uses an empty dummy type because @ModuleName@ isn't available here.
|
|
| 249 | - NewBreakModule
|
|
| 250 | - :: String -- ^ @ModuleName@
|
|
| 251 | - -> BS.ShortByteString -- ^ @UnitId@ for the given @ModuleName@
|
|
| 252 | - -> Message (RemotePtr BreakModule, RemotePtr BreakUnitId)
|
|
| 244 | +deriving instance Show (Message a)
|
|
| 253 | 245 | |
| 246 | +-- | Used to dynamically create a data constructor's info table at
|
|
| 247 | +-- run-time.
|
|
| 248 | +data ConInfoTable = ConInfoTable {
|
|
| 249 | + conItblTablesNextToCode :: !Bool, -- ^ TABLES_NEXT_TO_CODE
|
|
| 250 | + conItblPtrs :: !Int, -- ^ ptr words
|
|
| 251 | + conItblNPtrs :: !Int, -- ^ non-ptr words
|
|
| 252 | + conItblConTag :: !Int, -- ^ constr tag
|
|
| 253 | + conItblPtrTag :: !Int, -- ^ pointer tag
|
|
| 254 | + conItblDescr :: !ByteString -- ^ constructor desccription
|
|
| 255 | +}
|
|
| 256 | + deriving (Generic, Show)
|
|
| 254 | 257 | |
| 255 | -deriving instance Show (Message a)
|
|
| 258 | +instance Binary ConInfoTable
|
|
| 256 | 259 | |
| 260 | +instance NFData ConInfoTable
|
|
| 257 | 261 | |
| 258 | 262 | -- | Template Haskell return values
|
| 259 | 263 | data QResult a
|
| ... | ... | @@ -568,7 +572,7 @@ getMessage = do |
| 568 | 572 | 15 -> Msg <$> MallocStrings <$> get
|
| 569 | 573 | 16 -> Msg <$> (PrepFFI <$> get <*> get)
|
| 570 | 574 | 17 -> Msg <$> FreeFFI <$> get
|
| 571 | - 18 -> Msg <$> (MkConInfoTable <$> get <*> get <*> get <*> get <*> get <*> get)
|
|
| 575 | + 18 -> Msg <$> MkConInfoTable <$> get
|
|
| 572 | 576 | 19 -> Msg <$> (EvalStmt <$> get <*> get)
|
| 573 | 577 | 20 -> Msg <$> (ResumeStmt <$> get <*> get)
|
| 574 | 578 | 21 -> Msg <$> (AbandonStmt <$> get)
|
| ... | ... | @@ -589,9 +593,8 @@ getMessage = do |
| 589 | 593 | 36 -> Msg <$> (Seq <$> get)
|
| 590 | 594 | 37 -> Msg <$> return RtsRevertCAFs
|
| 591 | 595 | 38 -> Msg <$> (ResumeSeq <$> get)
|
| 592 | - 39 -> Msg <$> (NewBreakModule <$> get <*> get)
|
|
| 593 | - 40 -> Msg <$> (LookupSymbolInDLL <$> get <*> get)
|
|
| 594 | - 41 -> Msg <$> (WhereFrom <$> get)
|
|
| 596 | + 39 -> Msg <$> (LookupSymbolInDLL <$> get <*> get)
|
|
| 597 | + 40 -> Msg <$> (WhereFrom <$> get)
|
|
| 595 | 598 | _ -> error $ "Unknown Message code " ++ (show b)
|
| 596 | 599 | |
| 597 | 600 | putMessage :: Message a -> Put
|
| ... | ... | @@ -615,7 +618,7 @@ putMessage m = case m of |
| 615 | 618 | MallocStrings bss -> putWord8 15 >> put bss
|
| 616 | 619 | PrepFFI args res -> putWord8 16 >> put args >> put res
|
| 617 | 620 | FreeFFI p -> putWord8 17 >> put p
|
| 618 | - MkConInfoTable tc p n t pt d -> putWord8 18 >> put tc >> put p >> put n >> put t >> put pt >> put d
|
|
| 621 | + MkConInfoTable itbl -> putWord8 18 >> put itbl
|
|
| 619 | 622 | EvalStmt opts val -> putWord8 19 >> put opts >> put val
|
| 620 | 623 | ResumeStmt opts val -> putWord8 20 >> put opts >> put val
|
| 621 | 624 | AbandonStmt val -> putWord8 21 >> put val
|
| ... | ... | @@ -636,9 +639,8 @@ putMessage m = case m of |
| 636 | 639 | Seq a -> putWord8 36 >> put a
|
| 637 | 640 | RtsRevertCAFs -> putWord8 37
|
| 638 | 641 | ResumeSeq a -> putWord8 38 >> put a
|
| 639 | - NewBreakModule name unitid -> putWord8 39 >> put name >> put unitid
|
|
| 640 | - LookupSymbolInDLL dll str -> putWord8 40 >> put dll >> put str
|
|
| 641 | - WhereFrom a -> putWord8 41 >> put a
|
|
| 642 | + LookupSymbolInDLL dll str -> putWord8 39 >> put dll >> put str
|
|
| 643 | + WhereFrom a -> putWord8 40 >> put a
|
|
| 642 | 644 | |
| 643 | 645 | {-
|
| 644 | 646 | Note [Parallelize CreateBCOs serialization]
|
| ... | ... | @@ -74,7 +74,7 @@ run m = case m of |
| 74 | 74 | UnloadObj str -> unloadObj str
|
| 75 | 75 | AddLibrarySearchPath str -> toRemotePtr <$> addLibrarySearchPath str
|
| 76 | 76 | RemoveLibrarySearchPath ptr -> removeLibrarySearchPath (fromRemotePtr ptr)
|
| 77 | - MkConInfoTable tc ptrs nptrs tag ptrtag desc ->
|
|
| 77 | + MkConInfoTable (ConInfoTable tc ptrs nptrs tag ptrtag desc) ->
|
|
| 78 | 78 | toRemotePtr <$> mkConInfoTable tc ptrs nptrs tag ptrtag desc
|
| 79 | 79 | ResolveObjs -> resolveObjs
|
| 80 | 80 | FindSystemLibrary str -> findSystemLibrary str
|
| ... | ... | @@ -96,10 +96,6 @@ run m = case m of |
| 96 | 96 | MkCostCentres mod ccs -> mkCostCentres mod ccs
|
| 97 | 97 | CostCentreStackInfo ptr -> ccsToStrings (fromRemotePtr ptr)
|
| 98 | 98 | NewBreakArray sz -> mkRemoteRef =<< newBreakArray sz
|
| 99 | - NewBreakModule name unitid -> do
|
|
| 100 | - namePtr <- newModuleName name
|
|
| 101 | - uidPtr <- newUnitId unitid
|
|
| 102 | - pure (namePtr, uidPtr)
|
|
| 103 | 99 | SetupBreakpoint ref ix cnt -> do
|
| 104 | 100 | arr <- localRef ref;
|
| 105 | 101 | _ <- setupBreakpoint arr ix cnt
|
| ... | ... | @@ -440,13 +436,6 @@ mkString0 bs = B.unsafeUseAsCStringLen bs $ \(cstr,len) -> do |
| 440 | 436 | pokeElemOff (ptr :: Ptr CChar) len 0
|
| 441 | 437 | return (castRemotePtr (toRemotePtr ptr))
|
| 442 | 438 | |
| 443 | -mkShortByteString0 :: BS.ShortByteString -> IO (RemotePtr ())
|
|
| 444 | -mkShortByteString0 bs = BS.useAsCStringLen bs $ \(cstr,len) -> do
|
|
| 445 | - ptr <- mallocBytes (len+1)
|
|
| 446 | - copyBytes ptr cstr len
|
|
| 447 | - pokeElemOff (ptr :: Ptr CChar) len 0
|
|
| 448 | - return (castRemotePtr (toRemotePtr ptr))
|
|
| 449 | - |
|
| 450 | 439 | mkCostCentres :: String -> [(String,String)] -> IO [RemotePtr CostCentre]
|
| 451 | 440 | #if defined(PROFILING)
|
| 452 | 441 | mkCostCentres mod ccs = do
|
| ... | ... | @@ -464,14 +453,6 @@ foreign import ccall unsafe "mkCostCentre" |
| 464 | 453 | mkCostCentres _ _ = return []
|
| 465 | 454 | #endif
|
| 466 | 455 | |
| 467 | -newModuleName :: String -> IO (RemotePtr BreakModule)
|
|
| 468 | -newModuleName name =
|
|
| 469 | - castRemotePtr . toRemotePtr <$> newCString name
|
|
| 470 | - |
|
| 471 | -newUnitId :: BS.ShortByteString -> IO (RemotePtr BreakUnitId)
|
|
| 472 | -newUnitId name =
|
|
| 473 | - castRemotePtr <$> mkShortByteString0 name
|
|
| 474 | - |
|
| 475 | 456 | getIdValFromApStack :: HValue -> Int -> IO (Maybe HValue)
|
| 476 | 457 | getIdValFromApStack apStack (I# stackDepth) = do
|
| 477 | 458 | case getApStackVal# apStack stackDepth of
|
| 1 | -test('T22376', [req_interp, extra_files(['A.hs', 'B.hs'])], multimod_compile_and_run,
|
|
| 1 | +test('T22376', [extra_files(['A.hs', 'B.hs'])], multimod_compile_and_run,
|
|
| 2 | 2 | ['T22376', '-O1 -fwrite-if-simplified-core -fbyte-code-and-object-code -fprefer-byte-code']) |
| ... | ... | @@ -49,11 +49,11 @@ instrs = [ STKCHECK 1234 |
| 49 | 49 | ++ [ PUSH_G appAName | _ <- [0..100] ]
|
| 50 | 50 | ++ [ PUSH_BCO fake_proto2 ]
|
| 51 | 51 | |
| 52 | -fake_proto = ProtoBCO appAName instrs [] 0 0 (Left []) []
|
|
| 52 | +fake_proto = ProtoBCO appAName instrs [] 0 0 (Left [])
|
|
| 53 | 53 | |
| 54 | 54 | instrs2 = [ STKCHECK 77, UNPACK 4, SLIDE 0 4, ENTER ]
|
| 55 | 55 | |
| 56 | -fake_proto2 = ProtoBCO appAName instrs2 [] 0 0 (Left []) []
|
|
| 56 | +fake_proto2 = ProtoBCO appAName instrs2 [] 0 0 (Left [])
|
|
| 57 | 57 | |
| 58 | 58 | main :: IO ()
|
| 59 | 59 | main = do
|