eventlog2html-0.10.0: src/Eventlog/Types.hs
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module Eventlog.Types(module Eventlog.Types, HeapProfBreakdown(..), ClosureType) where
import Data.Text (Text)
import Data.Map (Map)
import Data.Aeson
import Data.Hashable
import Data.Word
import GHC.RTS.Events (HeapProfBreakdown(..))
import GHC.Exts.Heap.ClosureTypes
import Numeric
import qualified Data.Text as T
import qualified Data.Map as Map
data Header =
Header
{ hJob :: Text
, hDate :: Text
, hHeapProfileType :: Maybe HeapProfBreakdown
, hSamplingRate :: Text
, hSampleUnit :: Text
, hValueUnit :: Text
, hCount :: Int
, hProgPath :: Maybe FilePath
} deriving Show
-- The bucket is a key to uniquely identify a band
newtype Bucket = Bucket Text
deriving (Show, Ord, Eq)
deriving newtype (ToJSON, Hashable)
data BucketInfo = BucketInfo { shortDescription :: Text -- For the legend and hover
, longDescription :: Maybe [Word32]
, bucketTotal :: Double
, bucketStddev :: Double
, bucketGradient :: !(Maybe (Double, Double, Double))
} deriving Show
data CostCentre = CC { cid :: Word32
, label :: Text
, modul :: Text
, loc :: Text } deriving Show
data Sample = Sample Bucket Double deriving Show
data HeapSample = HeapSample Double Word64 deriving Show
data Frame = Frame Double [Sample] deriving Show
-- | A trace we also want to show on the graph
data Trace = Trace Double Text deriving Show
data HeapInfo = HeapInfo { heapSizeSamples :: [HeapSample]
, blocksSizeSamples :: [HeapSample]
, liveBytesSamples :: [HeapSample]
} deriving Show
data ProfData = ProfData { profHeader :: Header
, profTotals :: Map Bucket BucketInfo
, profCCMap :: Map Word32 CostCentre
, profFrames :: [Frame]
, profTraces :: [Trace]
, profHeap :: HeapInfo
, profItl :: Map InfoTablePtr InfoTableLoc
, profTickyCounters :: Map TickyCounterId TickyCounter
, profTickySamples :: [TickySample]
, profTotalAllocations :: Word64
} deriving Show
newtype TickyCounterId = TickyCounterId Word64 deriving (Ord, Eq, Show)
data TickyCounterArgs = TickyCounterArgs { tickyCounterType :: Text
, tickyCounterFVs :: [Char]
, tickyCounterArgs :: [Char]
} deriving Show
instance FromJSON TickyCounterArgs where
parseJSON = withObject "TickyCounterArgs" $ \v -> TickyCounterArgs
<$> v .: "type"
<*> (T.unpack <$> v .: "fvs")
<*> (T.unpack <$> v .: "args")
data TickyCounter = TickyCounter { tickyCtrId :: Word64, tickyCtrArity :: Word16, tickyCtrArgs :: TickyCounterArgs , tickyCtrName :: Text, tickyCtrInfo :: InfoTablePtr }
deriving Show
data TickySample = TickySample { tickyCtrSampleId, tickyCtrEntries, tickyCtrAllocs, tickyCtrAllocd :: Word64, tickySampleTime :: Double }
deriving Show
data InfoTableLoc = InfoTableLoc { itlName :: !Text
, itlClosureDesc :: !ClosureType
, itlTyDesc :: !Text
, itlLbl :: !Text
, itlModule :: !Text
, itlSrcLoc :: !Text } deriving Show
data InfoTablePtr = InfoTablePtr Word64 deriving (Eq, Ord)
instance Show InfoTablePtr where
show (InfoTablePtr p) = "0x" ++ showHex p ""
toItblPointer :: Bucket -> InfoTablePtr
toItblPointer (Bucket t) =
let s = drop 2 (T.unpack t)
w64 = case readHex s of
((n, ""):_) -> n
_ -> error (show t)
in InfoTablePtr w64
data InfoTableLocStatus = None -- None of the entries have InfoTableLoc
| Missing -- This one is just missing
| Here InfoTableLoc -- Here is is
mkMissing :: Maybe InfoTableLoc -> InfoTableLocStatus
mkMissing = maybe Missing Here
mkClosureInfo :: (k -> a -> InfoTablePtr)
-> Map.Map k a
-> Map.Map InfoTablePtr InfoTableLoc
-> Map.Map k (InfoTableLocStatus, a)
mkClosureInfo f b ipes =
Map.mapWithKey (\k v -> (mkMissing $ Map.lookup (f k v) ipes, v)) b