{-# LANGUAGE CPP,GeneralizedNewtypeDeriving #-}
module SMRep (
WordOff, ByteOff,
wordsToBytes, bytesToWordsRoundUp,
roundUpToWords, roundUpTo,
StgWord, fromStgWord, toStgWord,
StgHalfWord, fromStgHalfWord, toStgHalfWord,
hALF_WORD_SIZE, hALF_WORD_SIZE_IN_BITS,
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,
pprWord8String, stringToWord8s
) where
#include "../HsVersions.h"
#include "MachDeps.h"
import GhcPrelude
import BasicTypes( ConTagZ )
import DynFlags
import Outputable
import Platform
import FastString
import Data.Char( ord )
import Data.Word
import Data.Bits
type WordOff = Int
type ByteOff = Int
roundUpToWords :: DynFlags -> ByteOff -> ByteOff
roundUpToWords dflags n = roundUpTo n (wORD_SIZE dflags)
roundUpTo :: ByteOff -> ByteOff -> ByteOff
roundUpTo base size = (base + (size - 1)) .&. (complement (size - 1))
wordsToBytes :: Num a => DynFlags -> a -> a
wordsToBytes dflags n = fromIntegral (wORD_SIZE dflags) * n
{-# SPECIALIZE wordsToBytes :: DynFlags -> Int -> Int #-}
{-# SPECIALIZE wordsToBytes :: DynFlags -> Word -> Word #-}
{-# SPECIALIZE wordsToBytes :: DynFlags -> Integer -> Integer #-}
bytesToWordsRoundUp :: DynFlags -> ByteOff -> WordOff
bytesToWordsRoundUp dflags n = (n + word_size - 1) `quot` word_size
where word_size = wORD_SIZE dflags
newtype StgWord = StgWord Word64
deriving (Eq, Bits)
fromStgWord :: StgWord -> Integer
fromStgWord (StgWord i) = toInteger i
toStgWord :: DynFlags -> Integer -> StgWord
toStgWord dflags i
= case platformWordSize (targetPlatform dflags) of
4 -> StgWord (fromIntegral (fromInteger i :: Word32))
8 -> StgWord (fromInteger i :: Word64)
w -> panic ("toStgWord: Unknown platformWordSize: " ++ show w)
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 :: DynFlags -> Integer -> StgHalfWord
toStgHalfWord dflags i
= case platformWordSize (targetPlatform dflags) of
4 -> StgHalfWord (fromIntegral (fromInteger i :: Word16))
8 -> StgHalfWord (fromInteger i :: Word32)
w -> panic ("toStgHalfWord: Unknown platformWordSize: " ++ show w)
instance Outputable StgHalfWord where
ppr (StgHalfWord w) = integer (toInteger w)
hALF_WORD_SIZE :: DynFlags -> ByteOff
hALF_WORD_SIZE dflags = platformWordSize (targetPlatform dflags) `shiftR` 1
hALF_WORD_SIZE_IN_BITS :: DynFlags -> Int
hALF_WORD_SIZE_IN_BITS dflags = platformWordSize (targetPlatform dflags) `shiftL` 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 = [Word8]
type FunArity = Int
type SelectorOffset = Int
type Liveness = [Bool]
data ArgDescr
= ArgSpec
!Int
| ArgGen
Liveness
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 :: DynFlags -> ByteOff -> SMRep
arrWordsRep dflags bytes = ArrayWordsRep (bytesToWordsRoundUp dflags 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 dflags (fixedHdrSizeW dflags)
fixedHdrSizeW :: DynFlags -> WordOff
fixedHdrSizeW dflags = sTD_HDR_SIZE dflags + profHdrSize dflags
profHdrSize :: DynFlags -> WordOff
profHdrSize dflags
| gopt Opt_SccProfilingOn 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` wORD_SIZE dflags)
arrPtrsHdrSize :: DynFlags -> ByteOff
arrPtrsHdrSize dflags
= fixedHdrSize dflags + sIZEOF_StgMutArrPtrs_NoHdr dflags
arrPtrsHdrSizeW :: DynFlags -> WordOff
arrPtrsHdrSizeW dflags =
fixedHdrSizeW dflags +
(sIZEOF_StgMutArrPtrs_NoHdr dflags `quot` wORD_SIZE dflags)
smallArrPtrsHdrSize :: DynFlags -> ByteOff
smallArrPtrsHdrSize dflags
= fixedHdrSize dflags + sIZEOF_StgSmallMutArrPtrs_NoHdr dflags
smallArrPtrsHdrSizeW :: DynFlags -> WordOff
smallArrPtrsHdrSizeW dflags =
fixedHdrSizeW dflags +
(sIZEOF_StgSmallMutArrPtrs_NoHdr dflags `quot` wORD_SIZE dflags)
thunkHdrSize :: DynFlags -> WordOff
thunkHdrSize dflags = fixedHdrSizeW dflags + smp_hdr
where smp_hdr = sIZEOF_StgSMPThunkHeader dflags `quot` wORD_SIZE dflags
hdrSize :: DynFlags -> SMRep -> ByteOff
hdrSize dflags rep = wordsToBytes 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 :: DynFlags -> SMRep -> ByteOff
nonHdrSize dflags rep = wordsToBytes dflags (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 dflags (cardTableSizeB dflags elems)
#include "rts/storage/ClosureTypes.h"
#include "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
instance Outputable ArgDescr where
ppr (ArgSpec n) = text "ArgSpec" <+> ppr n
ppr (ArgGen ls) = text "ArgGen" <+> ppr ls
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"
stringToWord8s :: String -> [Word8]
stringToWord8s s = map (fromIntegral . ord) s
pprWord8String :: [Word8] -> SDoc
pprWord8String ws = text (show ws)