{-# LANGUAGE TupleSections #-} {-# LANGUAGE TemplateHaskell #-} -- | Calculate the size of GHC.Stats statically. module Weigh.GHCStats (ghcStatsSizeInBytes) where import GHC.Stats import GHC.Int import Language.Haskell.TH import Data.List -- | Get the size of a 'GHCStats' object in bytes. ghcStatsSizeInBytes :: Int64 ghcStatsSizeInBytes = $(do info <- reify ''GHC.Stats.GCStats case info of TyConI (DataD _ _ _ [RecC _ fields] _) -> do total <- fmap (foldl' (+) headerSize) (mapM fieldSize fields) litE (IntegerL (fromIntegral total)) where headerSize = 8 fieldSize :: (name,strict,Type) -> Q Int64 fieldSize (_,_,typ) = case typ of ConT typeName -> case lookup typeName knownTypes of Nothing -> fail ("Unknown size for type " ++ show typeName ++ ". Please report this as a bug, the codebase needs updating.") Just size -> return size _ -> fail ("Unexpected type shape: " ++ show typ ++ ". Please report this as a bug, the codebase needs updating.") knownTypes :: [(Name,Int64)] knownTypes = map (,8) [''Int64,''Int32,''Int8,''Int16,''Double] _ -> fail "Unexpected shape of GCStats data type. \ \Please report this as a bug, this function \ \needs to be updated to the newer GCStats type.")