packages feed

ghc-datasize 0.1.2 → 0.2.7

raw patch · 2 files changed

Files

ghc-datasize.cabal view
@@ -1,31 +1,32 @@ name:               ghc-datasize-version:            0.1.2+version:            0.2.7 license:            BSD3 license-file:       LICENSE category:           GHC, Debug, Development cabal-version:      >= 1.10-build-type:         Custom-author:             Dennis Felsing <dennis@felsin9.de>-maintainer:         Dennis Felsing <dennis@felsin9.de>-homepage:           http://felsin9.de/nnis/ghc-datasize-copyright:          Dennis Felsing 2012+build-type:         Simple+author:             Dennis Felsing <dennis@felsing.org>+maintainer:         Dennis Felsing <dennis@felsing.org>+homepage:           https://dennis.felsing.org/ghc-datasize+copyright:          Dennis Felsing 2012-2019 synopsis:           Determine the size of data structures in GHC's memory description:        ghc-datasize is a tool to determine the size of data                     structures in GHC's memory. Determining the size of                     recursive data structures is supported. All sizes are in                     Bytes. -tested-with: GHC == 7.4.2, GHC == 7.6.1, GHC == 7.8.3+tested-with: GHC == 8.6.5  Library   Exposed-modules: GHC.DataSize   Default-Language: Haskell2010-  Build-depends: base == 4.*,-                 --containers,-                 ghc-heap-view >= 0.5+  Build-depends: base >= 4.12 && < 5.0,+                 deepseq >= 1.3,+                 ghc-heap >= 8.0,+                 ghc-prim >= 0.5   Hs-source-dirs: src/   Ghc-options: -Wall  source-repository head     type:     git-    location: git://r0q.ath.cx/ghc-datasize+    location: https://github.com/def-/ghc-datasize.git
src/GHC/DataSize.hs view
@@ -1,42 +1,39 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}+ {- |    Module      : GHC.DataSize    Copyright   : (c) Dennis Felsing    License     : 3-Clause BSD-style-   Maintainer  : dennis@felsin9.de+   Maintainer  : dennis@felsing.org  -} module GHC.DataSize (   closureSize,-  recursiveSize-  --mSize+  recursiveSize,+  recursiveSizeNF   )   where -import GHC.HeapView hiding (size)+import Control.DeepSeq (NFData, ($!!)) +import GHC.Exts+import GHC.Exts.Heap hiding (size)+import GHC.Exts.Heap.Constants (wORD_SIZE)+ import Control.Monad  import System.Mem --- This used to be available via GHC.Constants-#include "MachDeps.h"-wORD_SIZE :: Int-wORD_SIZE = SIZEOF_HSWORD----import qualified Data.IntMap as IntMap----depth :: Int---depth = 10^10- -- Inspired by Simon Marlow: -- https://ghcmutterings.wordpress.com/2009/02/12/53/  -- | Calculate size of GHC objects in Bytes. Note that an object may not be --   evaluated yet and only the size of the initial closure is returned.-closureSize :: Num b => a -> IO b+closureSize :: a -> IO Word closureSize x = do-  (_,y,_) <- getClosureRaw x-  return . fromIntegral $ length y * wORD_SIZE+  rawWds <- getClosureRawWords x+  return . fromIntegral $ length rawWds * wORD_SIZE  -- | Calculate the recursive size of GHC objects in Bytes. Note that the actual --   size in memory is calculated, so shared values are only counted once.@@ -56,16 +53,42 @@ -- --   A garbage collection is performed before the size is calculated, because --   the garbage collector would make heap walks difficult.+--+--   This function works very quickly on small data structures, but can be slow+--   on large and complex ones. If speed is an issue it's probably possible to+--   get the exact size of a small portion of the data structure and then+--   estimate the total size from that. -recursiveSize :: Num b => a -> IO b+recursiveSize :: a -> IO Word recursiveSize x = do   performGC   liftM snd $ go ([], 0) $ asBox x-  where go (vs, acc) b@(Box y) = do+  where go (!vs, !acc) b@(Box y) = do           isElem <- liftM or $ mapM (areBoxesEqual b) vs           if isElem             then return (vs, acc)             else do              size    <- closureSize y              closure <- getClosureData y-             foldM go (b : vs, acc + size) $ allPtrs closure+             foldM go (b : vs, acc + size) $ allClosures closure++-- | Calculate the recursive size of GHC objects in Bytes after calling+-- Control.DeepSeq.force on the data structure to force it into Normal Form.+-- Using this function requires that the data structure has an `NFData`+-- typeclass instance.++recursiveSizeNF :: NFData a => a -> IO Word+recursiveSizeNF x = recursiveSize $!! x++-- | Adapted from 'GHC.Exts.Heap.getClosureRaw' which isn't exported.+--+-- This returns the raw words of the closure on the heap. Once back in the+-- Haskell world, the raw words that hold pointers may be outdated after a+-- garbage collector run.+getClosureRawWords :: a -> IO [Word]+getClosureRawWords x = do+    case unpackClosure# x of+        (# _iptr, dat, _pointers #) -> do+            let nelems = (I# (sizeofByteArray# dat)) `div` wORD_SIZE+                end = fromIntegral nelems - 1+            pure [W# (indexWordArray# dat i) | I# i <- [0.. end] ]