module GHC.Runtime.Heap.Layout (
WordOff, ByteOff,
wordsToBytes, bytesToWordsRoundUp,
roundUpToWords, roundUpTo,
StgWord, fromStgWord, toStgWord,
StgHalfWord, fromStgHalfWord, toStgHalfWord,
halfWordSize, halfWordSizeInBits,
SMRep(..),
IsStatic,
ClosureTypeInfo(..), ArgDescr(..), Liveness,
ConstrDescription,
mkHeapRep, blackHoleRep, indStaticRep, mkStackRep, mkRTSRep, arrPtrsRep,
smallArrPtrsRep, arrWordsRep,
isStaticRep, isConRep, isThunkRep, isFunRep, isStaticNoCafCon,
isStackRep,
heapClosureSizeW,
fixedHdrSizeW, arrWordsHdrSize, arrWordsHdrSizeW, arrPtrsHdrSize,
arrPtrsHdrSizeW, profHdrSize, thunkHdrSize, nonHdrSize, nonHdrSizeW,
smallArrPtrsHdrSize, smallArrPtrsHdrSizeW, hdrSize, hdrSizeW,
fixedHdrSize,
rtsClosureType, rET_SMALL, rET_BIG,
aRG_GEN, aRG_GEN_BIG,
card, cardRoundUp, cardTableSizeB, cardTableSizeW
) where
import GHC.Prelude
import GHC.Types.Basic( ConTagZ )
import GHC.Driver.Session
import GHC.Utils.Outputable
import GHC.Platform
import GHC.Data.FastString
import GHC.StgToCmm.Types
import Data.Word
import Data.Bits
import Data.ByteString (ByteString)
type ByteOff = Int
roundUpToWords :: Platform -> ByteOff -> ByteOff
roundUpToWords platform n = roundUpTo n (platformWordSizeInBytes platform)
roundUpTo :: ByteOff -> ByteOff -> ByteOff
roundUpTo base size = (base + (size 1)) .&. (complement (size 1))
wordsToBytes :: Num a => Platform -> a -> a
wordsToBytes platform n = fromIntegral (platformWordSizeInBytes platform) * n
bytesToWordsRoundUp :: Platform -> ByteOff -> WordOff
bytesToWordsRoundUp platform n = (n + word_size 1) `quot` word_size
where word_size = platformWordSizeInBytes platform
newtype StgWord = StgWord Word64
deriving (Eq, Bits)
fromStgWord :: StgWord -> Integer
fromStgWord (StgWord i) = toInteger i
toStgWord :: Platform -> Integer -> StgWord
toStgWord platform i
= case platformWordSize platform of
PW4 -> StgWord (fromIntegral (fromInteger i :: Word32))
PW8 -> StgWord (fromInteger i)
instance Outputable StgWord where
ppr (StgWord i) = integer (toInteger i)
newtype StgHalfWord = StgHalfWord Word32
deriving Eq
fromStgHalfWord :: StgHalfWord -> Integer
fromStgHalfWord (StgHalfWord w) = toInteger w
toStgHalfWord :: Platform -> Integer -> StgHalfWord
toStgHalfWord platform i
= case platformWordSize platform of
PW4 -> StgHalfWord (fromIntegral (fromInteger i :: Word16))
PW8 -> StgHalfWord (fromInteger i :: Word32)
instance Outputable StgHalfWord where
ppr (StgHalfWord w) = integer (toInteger w)
halfWordSize :: Platform -> ByteOff
halfWordSize platform = platformWordSizeInBytes platform `div` 2
halfWordSizeInBits :: Platform -> Int
halfWordSizeInBits platform = platformWordSizeInBits platform `div` 2
data SMRep
= HeapRep
IsStatic
!WordOff
!WordOff
ClosureTypeInfo
| ArrayPtrsRep
!WordOff
!WordOff
| SmallArrayPtrsRep
!WordOff
| ArrayWordsRep
!WordOff
| StackRep
Liveness
| RTSRep
Int
SMRep
type IsStatic = Bool
data ClosureTypeInfo
= Constr ConTagZ ConstrDescription
| Fun FunArity ArgDescr
| Thunk
| ThunkSelector SelectorOffset
| BlackHole
| IndStatic
type ConstrDescription = ByteString
type FunArity = Int
type SelectorOffset = Int
mkHeapRep :: DynFlags -> IsStatic -> WordOff -> WordOff -> ClosureTypeInfo
-> SMRep
mkHeapRep dflags is_static ptr_wds nonptr_wds cl_type_info
= HeapRep is_static
ptr_wds
(nonptr_wds + slop_wds)
cl_type_info
where
slop_wds
| is_static = 0
| otherwise = max 0 (minClosureSize dflags (hdr_size + payload_size))
hdr_size = closureTypeHdrSize dflags cl_type_info
payload_size = ptr_wds + nonptr_wds
mkRTSRep :: Int -> SMRep -> SMRep
mkRTSRep = RTSRep
mkStackRep :: [Bool] -> SMRep
mkStackRep liveness = StackRep liveness
blackHoleRep :: SMRep
blackHoleRep = HeapRep False 0 0 BlackHole
indStaticRep :: SMRep
indStaticRep = HeapRep True 1 0 IndStatic
arrPtrsRep :: DynFlags -> WordOff -> SMRep
arrPtrsRep dflags elems = ArrayPtrsRep elems (cardTableSizeW dflags elems)
smallArrPtrsRep :: WordOff -> SMRep
smallArrPtrsRep elems = SmallArrayPtrsRep elems
arrWordsRep :: Platform -> ByteOff -> SMRep
arrWordsRep platform bytes = ArrayWordsRep (bytesToWordsRoundUp platform bytes)
isStaticRep :: SMRep -> IsStatic
isStaticRep (HeapRep is_static _ _ _) = is_static
isStaticRep (RTSRep _ rep) = isStaticRep rep
isStaticRep _ = False
isStackRep :: SMRep -> Bool
isStackRep StackRep{} = True
isStackRep (RTSRep _ rep) = isStackRep rep
isStackRep _ = False
isConRep :: SMRep -> Bool
isConRep (HeapRep _ _ _ Constr{}) = True
isConRep _ = False
isThunkRep :: SMRep -> Bool
isThunkRep (HeapRep _ _ _ Thunk) = True
isThunkRep (HeapRep _ _ _ ThunkSelector{}) = True
isThunkRep (HeapRep _ _ _ BlackHole) = True
isThunkRep (HeapRep _ _ _ IndStatic) = True
isThunkRep _ = False
isFunRep :: SMRep -> Bool
isFunRep (HeapRep _ _ _ Fun{}) = True
isFunRep _ = False
isStaticNoCafCon :: SMRep -> Bool
isStaticNoCafCon (HeapRep _ 0 _ Constr{}) = True
isStaticNoCafCon _ = False
fixedHdrSize :: DynFlags -> ByteOff
fixedHdrSize dflags = wordsToBytes (targetPlatform dflags) (fixedHdrSizeW dflags)
fixedHdrSizeW :: DynFlags -> WordOff
fixedHdrSizeW dflags = sTD_HDR_SIZE dflags + profHdrSize dflags
profHdrSize :: DynFlags -> WordOff
profHdrSize dflags
| sccProfilingEnabled dflags = pROF_HDR_SIZE dflags
| otherwise = 0
minClosureSize :: DynFlags -> WordOff
minClosureSize dflags = fixedHdrSizeW dflags + mIN_PAYLOAD_SIZE dflags
arrWordsHdrSize :: DynFlags -> ByteOff
arrWordsHdrSize dflags
= fixedHdrSize dflags + sIZEOF_StgArrBytes_NoHdr dflags
arrWordsHdrSizeW :: DynFlags -> WordOff
arrWordsHdrSizeW dflags =
fixedHdrSizeW dflags +
(sIZEOF_StgArrBytes_NoHdr dflags `quot`
platformWordSizeInBytes (targetPlatform dflags))
arrPtrsHdrSize :: DynFlags -> ByteOff
arrPtrsHdrSize dflags
= fixedHdrSize dflags + sIZEOF_StgMutArrPtrs_NoHdr dflags
arrPtrsHdrSizeW :: DynFlags -> WordOff
arrPtrsHdrSizeW dflags =
fixedHdrSizeW dflags +
(sIZEOF_StgMutArrPtrs_NoHdr dflags `quot`
platformWordSizeInBytes (targetPlatform dflags))
smallArrPtrsHdrSize :: DynFlags -> ByteOff
smallArrPtrsHdrSize dflags
= fixedHdrSize dflags + sIZEOF_StgSmallMutArrPtrs_NoHdr dflags
smallArrPtrsHdrSizeW :: DynFlags -> WordOff
smallArrPtrsHdrSizeW dflags =
fixedHdrSizeW dflags +
(sIZEOF_StgSmallMutArrPtrs_NoHdr dflags `quot`
platformWordSizeInBytes (targetPlatform dflags))
thunkHdrSize :: DynFlags -> WordOff
thunkHdrSize dflags = fixedHdrSizeW dflags + smp_hdr
where smp_hdr = sIZEOF_StgSMPThunkHeader dflags `quot`
platformWordSizeInBytes (targetPlatform dflags)
hdrSize :: DynFlags -> SMRep -> ByteOff
hdrSize dflags rep = wordsToBytes (targetPlatform dflags) (hdrSizeW dflags rep)
hdrSizeW :: DynFlags -> SMRep -> WordOff
hdrSizeW dflags (HeapRep _ _ _ ty) = closureTypeHdrSize dflags ty
hdrSizeW dflags (ArrayPtrsRep _ _) = arrPtrsHdrSizeW dflags
hdrSizeW dflags (SmallArrayPtrsRep _) = smallArrPtrsHdrSizeW dflags
hdrSizeW dflags (ArrayWordsRep _) = arrWordsHdrSizeW dflags
hdrSizeW _ _ = panic "SMRep.hdrSizeW"
nonHdrSize :: Platform -> SMRep -> ByteOff
nonHdrSize platform rep = wordsToBytes platform (nonHdrSizeW rep)
nonHdrSizeW :: SMRep -> WordOff
nonHdrSizeW (HeapRep _ p np _) = p + np
nonHdrSizeW (ArrayPtrsRep elems ct) = elems + ct
nonHdrSizeW (SmallArrayPtrsRep elems) = elems
nonHdrSizeW (ArrayWordsRep words) = words
nonHdrSizeW (StackRep bs) = length bs
nonHdrSizeW (RTSRep _ rep) = nonHdrSizeW rep
heapClosureSizeW :: DynFlags -> SMRep -> WordOff
heapClosureSizeW dflags (HeapRep _ p np ty)
= closureTypeHdrSize dflags ty + p + np
heapClosureSizeW dflags (ArrayPtrsRep elems ct)
= arrPtrsHdrSizeW dflags + elems + ct
heapClosureSizeW dflags (SmallArrayPtrsRep elems)
= smallArrPtrsHdrSizeW dflags + elems
heapClosureSizeW dflags (ArrayWordsRep words)
= arrWordsHdrSizeW dflags + words
heapClosureSizeW _ _ = panic "SMRep.heapClosureSize"
closureTypeHdrSize :: DynFlags -> ClosureTypeInfo -> WordOff
closureTypeHdrSize dflags ty = case ty of
Thunk -> thunkHdrSize dflags
ThunkSelector{} -> thunkHdrSize dflags
BlackHole -> thunkHdrSize dflags
IndStatic -> thunkHdrSize dflags
_ -> fixedHdrSizeW dflags
card :: DynFlags -> Int -> Int
card dflags i = i `shiftR` mUT_ARR_PTRS_CARD_BITS dflags
cardRoundUp :: DynFlags -> Int -> Int
cardRoundUp dflags i =
card dflags (i + ((1 `shiftL` mUT_ARR_PTRS_CARD_BITS dflags) 1))
cardTableSizeB :: DynFlags -> Int -> ByteOff
cardTableSizeB dflags elems = cardRoundUp dflags elems
cardTableSizeW :: DynFlags -> Int -> WordOff
cardTableSizeW dflags elems =
bytesToWordsRoundUp (targetPlatform dflags)
(cardTableSizeB dflags elems)
#include "../includes/rts/storage/ClosureTypes.h"
#include "../includes/rts/storage/FunTypes.h"
rtsClosureType :: SMRep -> Int
rtsClosureType rep
= case rep of
RTSRep ty _ -> ty
HeapRep _ 1 0 Constr{} -> CONSTR_1_0
HeapRep _ 0 1 Constr{} -> CONSTR_0_1
HeapRep _ 2 0 Constr{} -> CONSTR_2_0
HeapRep _ 1 1 Constr{} -> CONSTR_1_1
HeapRep _ 0 2 Constr{} -> CONSTR_0_2
HeapRep _ 0 _ Constr{} -> CONSTR_NOCAF
HeapRep _ _ _ Constr{} -> CONSTR
HeapRep False 1 0 Fun{} -> FUN_1_0
HeapRep False 0 1 Fun{} -> FUN_0_1
HeapRep False 2 0 Fun{} -> FUN_2_0
HeapRep False 1 1 Fun{} -> FUN_1_1
HeapRep False 0 2 Fun{} -> FUN_0_2
HeapRep False _ _ Fun{} -> FUN
HeapRep False 1 0 Thunk -> THUNK_1_0
HeapRep False 0 1 Thunk -> THUNK_0_1
HeapRep False 2 0 Thunk -> THUNK_2_0
HeapRep False 1 1 Thunk -> THUNK_1_1
HeapRep False 0 2 Thunk -> THUNK_0_2
HeapRep False _ _ Thunk -> THUNK
HeapRep False _ _ ThunkSelector{} -> THUNK_SELECTOR
HeapRep True _ _ Fun{} -> FUN_STATIC
HeapRep True _ _ Thunk -> THUNK_STATIC
HeapRep False _ _ BlackHole -> BLACKHOLE
HeapRep False _ _ IndStatic -> IND_STATIC
_ -> panic "rtsClosureType"
rET_SMALL, rET_BIG, aRG_GEN, aRG_GEN_BIG :: Int
rET_SMALL = RET_SMALL
rET_BIG = RET_BIG
aRG_GEN = ARG_GEN
aRG_GEN_BIG = ARG_GEN_BIG
instance Outputable ClosureTypeInfo where
ppr = pprTypeInfo
instance Outputable SMRep where
ppr (HeapRep static ps nps tyinfo)
= hang (header <+> lbrace) 2 (ppr tyinfo <+> rbrace)
where
header = text "HeapRep"
<+> if static then text "static" else empty
<+> pp_n "ptrs" ps <+> pp_n "nonptrs" nps
pp_n :: String -> Int -> SDoc
pp_n _ 0 = empty
pp_n s n = int n <+> text s
ppr (ArrayPtrsRep size _) = text "ArrayPtrsRep" <+> ppr size
ppr (SmallArrayPtrsRep size) = text "SmallArrayPtrsRep" <+> ppr size
ppr (ArrayWordsRep words) = text "ArrayWordsRep" <+> ppr words
ppr (StackRep bs) = text "StackRep" <+> ppr bs
ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep
pprTypeInfo :: ClosureTypeInfo -> SDoc
pprTypeInfo (Constr tag descr)
= text "Con" <+>
braces (sep [ text "tag:" <+> ppr tag
, text "descr:" <> text (show descr) ])
pprTypeInfo (Fun arity args)
= text "Fun" <+>
braces (sep [ text "arity:" <+> ppr arity
, ptext (sLit ("fun_type:")) <+> ppr args ])
pprTypeInfo (ThunkSelector offset)
= text "ThunkSel" <+> ppr offset
pprTypeInfo Thunk = text "Thunk"
pprTypeInfo BlackHole = text "BlackHole"
pprTypeInfo IndStatic = text "IndStatic"