Cheng Shao pushed to branch wip/bytecode-serialize-pre at Glasgow Haskell Compiler / GHC
Commits:
-
55e22336
by Cheng Shao at 2025-05-14T01:17:16+00:00
-
739d2f38
by Cheng Shao at 2025-05-14T01:17:26+00:00
-
6a2710ff
by Cheng Shao at 2025-05-14T01:17:27+00:00
-
553c5fd5
by Cheng Shao at 2025-05-14T01:17:27+00:00
-
75ab80d0
by Cheng Shao at 2025-05-14T01:17:27+00:00
-
a9c42238
by Cheng Shao at 2025-05-14T01:17:27+00:00
-
bad310cb
by Cheng Shao at 2025-05-14T01:17:27+00:00
-
981efb4a
by Cheng Shao at 2025-05-14T01:17:27+00: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,11 +37,13 @@ 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
|
44 | 44 | |
45 | 45 | import GHC.Core.TyCon
|
46 | +import GHC.Data.FastString
|
|
46 | 47 | import GHC.Data.SizedSeq
|
47 | 48 | import GHC.Data.SmallArray
|
48 | 49 | |
... | ... | @@ -52,6 +53,7 @@ import GHC.Cmm.Reg ( GlobalArgRegs(..) ) |
52 | 53 | import GHC.Cmm.CallConv ( allArgRegsCover )
|
53 | 54 | import GHC.Platform
|
54 | 55 | import GHC.Platform.Profile
|
56 | +import Language.Haskell.Syntax.Module.Name
|
|
55 | 57 | |
56 | 58 | import Control.Monad
|
57 | 59 | import qualified Control.Monad.Trans.State.Strict as MTL
|
... | ... | @@ -65,6 +67,7 @@ import Data.Array.Base ( unsafeWrite ) |
65 | 67 | #endif
|
66 | 68 | |
67 | 69 | import Foreign hiding (shiftL, shiftR)
|
70 | +import Data.ByteString (ByteString)
|
|
68 | 71 | import Data.Char (ord)
|
69 | 72 | import Data.Maybe (fromMaybe)
|
70 | 73 | import GHC.Float (castFloatToWord32, castDoubleToWord64)
|
... | ... | @@ -104,24 +107,21 @@ bcoFreeNames bco |
104 | 107 | |
105 | 108 | -- Top level assembler fn.
|
106 | 109 | assembleBCOs
|
107 | - :: Interp
|
|
108 | - -> Profile
|
|
110 | + :: Profile
|
|
109 | 111 | -> FlatBag (ProtoBCO Name)
|
110 | 112 | -> [TyCon]
|
111 | - -> AddrEnv
|
|
113 | + -> [(Name, ByteString)]
|
|
112 | 114 | -> Maybe ModBreaks
|
113 | 115 | -> [SptEntry]
|
114 | 116 | -> IO CompiledByteCode
|
115 | -assembleBCOs interp profile proto_bcos tycons top_strs modbreaks spt_entries = do
|
|
117 | +assembleBCOs profile proto_bcos tycons top_strs modbreaks spt_entries = do
|
|
116 | 118 | -- TODO: the profile should be bundled with the interpreter: the rts ways are
|
117 | 119 | -- fixed for an interpreter
|
118 | - itblenv <- mkITbls interp profile tycons
|
|
120 | + let itbls = mkITbls profile tycons
|
|
119 | 121 | bcos <- mapM (assembleBCO (profilePlatform profile)) proto_bcos
|
120 | - bcos' <- mallocStrings interp bcos
|
|
121 | 122 | return CompiledByteCode
|
122 | - { bc_bcos = bcos'
|
|
123 | - , bc_itbls = itblenv
|
|
124 | - , bc_ffis = concatMap protoBCOFFIs proto_bcos
|
|
123 | + { bc_bcos = bcos
|
|
124 | + , bc_itbls = itbls
|
|
125 | 125 | , bc_strs = top_strs
|
126 | 126 | , bc_breaks = modbreaks
|
127 | 127 | , bc_spt_entries = spt_entries
|
... | ... | @@ -137,50 +137,17 @@ assembleBCOs interp profile proto_bcos tycons top_strs modbreaks spt_entries = d |
137 | 137 | -- memory for them, and bake the resulting addresses into the instruction stream
|
138 | 138 | -- in the form of BCONPtrWord arguments.
|
139 | 139 | --
|
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.
|
|
140 | +-- We used to allocate remote buffers for BCONPtrStr ByteStrings when
|
|
141 | +-- assembling, but this gets in the way of bytecode serialization: we
|
|
142 | +-- want the ability to serialize and reload assembled bytecode, so
|
|
143 | +-- it's better to preserve BCONPtrStr as-is, and only perform the
|
|
144 | +-- actual allocation at link-time.
|
|
144 | 145 | --
|
145 | 146 | -- Note that, as with top-level string literal bindings, this memory is never
|
146 | 147 | -- freed, so it just leaks if the BCO is unloaded. See Note [Generating code for
|
147 | 148 | -- top-level string literal bindings] in GHC.StgToByteCode for some discussion
|
148 | 149 | -- about why.
|
149 | 150 | --
|
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 | 151 | |
185 | 152 | data RunAsmReader = RunAsmReader { isn_array :: {-# UNPACK #-} !(Array.IOUArray Int Word16)
|
186 | 153 | , ptr_array :: {-# UNPACK #-} !(SmallMutableArrayIO BCOPtr)
|
... | ... | @@ -729,15 +696,15 @@ assembleI platform i = case i of |
729 | 696 | ENTER -> emit_ bci_ENTER []
|
730 | 697 | RETURN rep -> emit_ (return_non_tuple rep) []
|
731 | 698 | RETURN_TUPLE -> emit_ bci_RETURN_T []
|
732 | - CCALL off m_addr i -> do np <- addr m_addr
|
|
699 | + CCALL off ffi i -> do np <- lit1 $ BCONPtrFFIInfo ffi
|
|
733 | 700 | emit_ bci_CCALL [wOp off, Op np, SmallOp i]
|
734 | 701 | PRIMCALL -> emit_ bci_PRIMCALL []
|
735 | 702 | BRK_FUN arr tick_mod tick_mod_id tickx info_mod info_mod_id infox cc ->
|
736 | 703 | do p1 <- ptr (BCOPtrBreakArray arr)
|
737 | - tick_addr <- addr tick_mod
|
|
738 | - tick_unitid_addr <- addr tick_mod_id
|
|
739 | - info_addr <- addr info_mod
|
|
740 | - info_unitid_addr <- addr info_mod_id
|
|
704 | + tick_addr <- lit1 $ BCONPtrStr $ bytesFS $ moduleNameFS tick_mod
|
|
705 | + info_addr <- lit1 $ BCONPtrStr $ bytesFS $ moduleNameFS info_mod
|
|
706 | + tick_unitid_addr <- lit1 $ BCONPtrStr $ bytesFS $ unitIdFS tick_mod_id
|
|
707 | + info_unitid_addr <- lit1 $ BCONPtrStr $ bytesFS $ unitIdFS info_mod_id
|
|
741 | 708 | np <- addr cc
|
742 | 709 | emit_ bci_BRK_FUN [ Op p1
|
743 | 710 | , 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
|
... | ... | @@ -83,9 +84,12 @@ lookupLiteral interp pkgs_loaded le ptr = case ptr of |
83 | 84 | BCONPtrAddr nm -> do
|
84 | 85 | Ptr a# <- lookupAddr interp pkgs_loaded (addr_env le) nm
|
85 | 86 | return (W# (int2Word# (addr2Int# a#)))
|
86 | - BCONPtrStr _ ->
|
|
87 | - -- should be eliminated during assembleBCOs
|
|
88 | - panic "lookupLiteral: BCONPtrStr"
|
|
87 | + BCONPtrStr bs -> do
|
|
88 | + RemotePtr p <- fmap head $ interpCmd interp $ MallocStrings [bs]
|
|
89 | + pure $ fromIntegral p
|
|
90 | + BCONPtrFFIInfo (FFIInfo {..}) -> do
|
|
91 | + RemotePtr p <- interpCmd interp $ PrepFFI ffiInfoArgs ffiInfoRet
|
|
92 | + pure $ fromIntegral p
|
|
89 | 93 | |
90 | 94 | lookupStaticPtr :: Interp -> FastString -> IO (Ptr ())
|
91 | 95 | 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,11 @@ 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 | + -- | A libffi ffi_cif function prototype.
|
|
205 | + | BCONPtrFFIInfo !FFIInfo
|
|
207 | 206 | |
208 | 207 | instance NFData BCONPtr where
|
209 | 208 | rnf x = x `seq` ()
|
... | ... | @@ -263,9 +262,9 @@ data ModBreaks |
263 | 262 | -- ^ Array pointing to cost centre for each breakpoint
|
264 | 263 | , modBreaks_breakInfo :: IntMap CgBreakInfo
|
265 | 264 | -- ^ info about each breakpoint from the bytecode generator
|
266 | - , modBreaks_module :: RemotePtr ModuleName
|
|
265 | + , modBreaks_module :: !ModuleName
|
|
267 | 266 | -- ^ info about the module in which we are setting the breakpoint
|
268 | - , modBreaks_module_unitid :: RemotePtr UnitId
|
|
267 | + , modBreaks_module_unitid :: !UnitId
|
|
269 | 268 | -- ^ The 'UnitId' of the 'ModuleName'
|
270 | 269 | }
|
271 | 270 | |
... | ... | @@ -290,8 +289,8 @@ emptyModBreaks = ModBreaks |
290 | 289 | , modBreaks_decls = array (0,-1) []
|
291 | 290 | , modBreaks_ccs = array (0,-1) []
|
292 | 291 | , modBreaks_breakInfo = IntMap.empty
|
293 | - , modBreaks_module = toRemotePtr nullPtr
|
|
294 | - , modBreaks_module_unitid = toRemotePtr nullPtr
|
|
292 | + , modBreaks_module = mkModuleNameFS nilFS
|
|
293 | + , modBreaks_module_unitid = UnitId nilFS
|
|
295 | 294 | }
|
296 | 295 | |
297 | 296 | {-
|
... | ... | @@ -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
|