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 -}