never executed always true always false
1 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
2 {-# LANGUAGE RecordWildCards #-}
3 --
4 -- (c) The University of Glasgow 2002-2006
5 --
6
7 -- | Bytecode assembler types
8 module GHC.ByteCode.Types
9 ( CompiledByteCode(..), seqCompiledByteCode
10 , FFIInfo(..)
11 , RegBitmap(..)
12 , TupleInfo(..), voidTupleInfo
13 , ByteOff(..), WordOff(..)
14 , UnlinkedBCO(..), BCOPtr(..), BCONPtr(..)
15 , ItblEnv, ItblPtr(..)
16 , CgBreakInfo(..)
17 , ModBreaks (..), BreakIndex, emptyModBreaks
18 , CCostCentre
19 ) where
20
21 import GHC.Prelude
22
23 import GHC.Data.FastString
24 import GHC.Data.SizedSeq
25 import GHC.Types.Id
26 import GHC.Types.Name
27 import GHC.Types.Name.Env
28 import GHC.Utils.Outputable
29 import GHC.Builtin.PrimOps
30 import GHC.Core.Type
31 import GHC.Types.SrcLoc
32 import GHCi.BreakArray
33 import GHCi.RemoteTypes
34 import GHCi.FFI
35 import Control.DeepSeq
36
37 import Foreign
38 import Data.Array
39 import Data.Array.Base ( UArray(..) )
40 import Data.ByteString (ByteString)
41 import Data.IntMap (IntMap)
42 import qualified Data.IntMap as IntMap
43 import Data.Maybe (catMaybes)
44 import qualified GHC.Exts.Heap as Heap
45 import GHC.Stack.CCS
46 import GHC.Cmm.Expr ( GlobalRegSet, emptyRegSet, regSetToList )
47
48 -- -----------------------------------------------------------------------------
49 -- Compiled Byte Code
50
51 data CompiledByteCode = CompiledByteCode
52 { bc_bcos :: [UnlinkedBCO] -- Bunch of interpretable bindings
53 , bc_itbls :: ItblEnv -- A mapping from DataCons to their itbls
54 , bc_ffis :: [FFIInfo] -- ffi blocks we allocated
55 , bc_strs :: [RemotePtr ()] -- malloc'd strings
56 , bc_breaks :: Maybe ModBreaks -- breakpoint info (Nothing if we're not
57 -- creating breakpoints, for some reason)
58 }
59 -- ToDo: we're not tracking strings that we malloc'd
60 newtype FFIInfo = FFIInfo (RemotePtr C_ffi_cif)
61 deriving (Show, NFData)
62
63 instance Outputable CompiledByteCode where
64 ppr CompiledByteCode{..} = ppr bc_bcos
65
66 -- Not a real NFData instance, because ModBreaks contains some things
67 -- we can't rnf
68 seqCompiledByteCode :: CompiledByteCode -> ()
69 seqCompiledByteCode CompiledByteCode{..} =
70 rnf bc_bcos `seq`
71 seqEltsNameEnv rnf bc_itbls `seq`
72 rnf bc_ffis `seq`
73 rnf bc_strs `seq`
74 rnf (fmap seqModBreaks bc_breaks)
75
76 newtype ByteOff = ByteOff Int
77 deriving (Enum, Eq, Show, Integral, Num, Ord, Real, Outputable)
78
79 newtype WordOff = WordOff Int
80 deriving (Enum, Eq, Show, Integral, Num, Ord, Real, Outputable)
81
82 newtype RegBitmap = RegBitmap { unRegBitmap :: Word32 }
83 deriving (Enum, Eq, Show, Integral, Num, Ord, Real, Bits, FiniteBits, Outputable)
84
85 {- Note [GHCi TupleInfo]
86 ~~~~~~~~~~~~~~~~~~~~~~~~
87
88 This contains the data we need for passing unboxed tuples between
89 bytecode and native code
90
91 In general we closely follow the native calling convention that
92 GHC uses for unboxed tuples, but we don't use any registers in
93 bytecode. All tuple elements are expanded to use a full register
94 or a full word on the stack.
95
96 The position of tuple elements that are returned on the stack in
97 the native calling convention is unchanged when returning the same
98 tuple in bytecode.
99
100 The order of the remaining elements is determined by the register in
101 which they would have been returned, rather than by their position in
102 the tuple in the Haskell source code. This makes jumping between bytecode
103 and native code easier: A map of live registers is enough to convert the
104 tuple.
105
106 See GHC.StgToByteCode.layoutTuple for more details.
107 -}
108 data TupleInfo = TupleInfo
109 { tupleSize :: !WordOff -- total size of tuple in words
110 , tupleRegs :: !GlobalRegSet
111 , tupleNativeStackSize :: !WordOff {- words spilled on the stack by
112 GHCs native calling convention -}
113 } deriving (Show)
114
115 instance Outputable TupleInfo where
116 ppr TupleInfo{..} = text "<size" <+> ppr tupleSize <+>
117 text "stack" <+> ppr tupleNativeStackSize <+>
118 text "regs" <+>
119 ppr (map (text.show) $ regSetToList tupleRegs) <>
120 char '>'
121
122 voidTupleInfo :: TupleInfo
123 voidTupleInfo = TupleInfo 0 emptyRegSet 0
124
125 type ItblEnv = NameEnv (Name, ItblPtr)
126 -- We need the Name in the range so we know which
127 -- elements to filter out when unloading a module
128
129 newtype ItblPtr = ItblPtr (RemotePtr Heap.StgInfoTable)
130 deriving (Show, NFData)
131
132 data UnlinkedBCO
133 = UnlinkedBCO {
134 unlinkedBCOName :: !Name,
135 unlinkedBCOArity :: {-# UNPACK #-} !Int,
136 unlinkedBCOInstrs :: !(UArray Int Word16), -- insns
137 unlinkedBCOBitmap :: !(UArray Int Word64), -- bitmap
138 unlinkedBCOLits :: !(SizedSeq BCONPtr), -- non-ptrs
139 unlinkedBCOPtrs :: !(SizedSeq BCOPtr) -- ptrs
140 }
141
142 instance NFData UnlinkedBCO where
143 rnf UnlinkedBCO{..} =
144 rnf unlinkedBCOLits `seq`
145 rnf unlinkedBCOPtrs
146
147 data BCOPtr
148 = BCOPtrName !Name
149 | BCOPtrPrimOp !PrimOp
150 | BCOPtrBCO !UnlinkedBCO
151 | BCOPtrBreakArray -- a pointer to this module's BreakArray
152
153 instance NFData BCOPtr where
154 rnf (BCOPtrBCO bco) = rnf bco
155 rnf x = x `seq` ()
156
157 data BCONPtr
158 = BCONPtrWord {-# UNPACK #-} !Word
159 | BCONPtrLbl !FastString
160 | BCONPtrItbl !Name
161 | BCONPtrStr !ByteString
162
163 instance NFData BCONPtr where
164 rnf x = x `seq` ()
165
166 -- | Information about a breakpoint that we know at code-generation time
167 data CgBreakInfo
168 = CgBreakInfo
169 { cgb_vars :: [Maybe (Id,Word16)]
170 , cgb_resty :: Type
171 }
172 -- See Note [Syncing breakpoint info] in GHC.Runtime.Eval
173
174 -- Not a real NFData instance because we can't rnf Id or Type
175 seqCgBreakInfo :: CgBreakInfo -> ()
176 seqCgBreakInfo CgBreakInfo{..} =
177 rnf (map snd (catMaybes (cgb_vars))) `seq`
178 seqType cgb_resty
179
180 instance Outputable UnlinkedBCO where
181 ppr (UnlinkedBCO nm _arity _insns _bitmap lits ptrs)
182 = sep [text "BCO", ppr nm, text "with",
183 ppr (sizeSS lits), text "lits",
184 ppr (sizeSS ptrs), text "ptrs" ]
185
186 instance Outputable CgBreakInfo where
187 ppr info = text "CgBreakInfo" <+>
188 parens (ppr (cgb_vars info) <+>
189 ppr (cgb_resty info))
190
191 -- -----------------------------------------------------------------------------
192 -- Breakpoints
193
194 -- | Breakpoint index
195 type BreakIndex = Int
196
197 -- | C CostCentre type
198 data CCostCentre
199
200 -- | All the information about the breakpoints for a module
201 data ModBreaks
202 = ModBreaks
203 { modBreaks_flags :: ForeignRef BreakArray
204 -- ^ The array of flags, one per breakpoint,
205 -- indicating which breakpoints are enabled.
206 , modBreaks_locs :: !(Array BreakIndex SrcSpan)
207 -- ^ An array giving the source span of each breakpoint.
208 , modBreaks_vars :: !(Array BreakIndex [OccName])
209 -- ^ An array giving the names of the free variables at each breakpoint.
210 , modBreaks_decls :: !(Array BreakIndex [String])
211 -- ^ An array giving the names of the declarations enclosing each breakpoint.
212 -- See Note [Field modBreaks_decls]
213 , modBreaks_ccs :: !(Array BreakIndex (RemotePtr CostCentre))
214 -- ^ Array pointing to cost centre for each breakpoint
215 , modBreaks_breakInfo :: IntMap CgBreakInfo
216 -- ^ info about each breakpoint from the bytecode generator
217 }
218
219 seqModBreaks :: ModBreaks -> ()
220 seqModBreaks ModBreaks{..} =
221 rnf modBreaks_flags `seq`
222 rnf modBreaks_locs `seq`
223 rnf modBreaks_vars `seq`
224 rnf modBreaks_decls `seq`
225 rnf modBreaks_ccs `seq`
226 rnf (fmap seqCgBreakInfo modBreaks_breakInfo)
227
228 -- | Construct an empty ModBreaks
229 emptyModBreaks :: ModBreaks
230 emptyModBreaks = ModBreaks
231 { modBreaks_flags = error "ModBreaks.modBreaks_array not initialised"
232 -- ToDo: can we avoid this?
233 , modBreaks_locs = array (0,-1) []
234 , modBreaks_vars = array (0,-1) []
235 , modBreaks_decls = array (0,-1) []
236 , modBreaks_ccs = array (0,-1) []
237 , modBreaks_breakInfo = IntMap.empty
238 }
239
240 {-
241 Note [Field modBreaks_decls]
242 ~~~~~~~~~~~~~~~~~~~~~~
243 A value of eg ["foo", "bar", "baz"] in a `modBreaks_decls` field means:
244 The breakpoint is in the function called "baz" that is declared in a `let`
245 or `where` clause of a declaration called "bar", which itself is declared
246 in a `let` or `where` clause of the top-level function called "foo".
247 -}