summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-02-08 13:10:18 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-02-08 13:10:18 +0000
commit76e3742711eb9eb2fed7654c56e602b54c517e87 (patch)
treef8b04d68405880bd921bfb2da958058cd8c038ae
parent3a4f9158d6d6688e591d505461d40e82c002c74c (diff)
downloadhaskell-76e3742711eb9eb2fed7654c56e602b54c517e87.tar.gz
add -dfaststring-stats to dump some stats about the FastString hash table
-rw-r--r--ghc/compiler/main/DynFlags.hs2
-rw-r--r--ghc/compiler/main/Main.hs41
-rw-r--r--ghc/compiler/utils/FastString.lhs25
3 files changed, 67 insertions, 1 deletions
diff --git a/ghc/compiler/main/DynFlags.hs b/ghc/compiler/main/DynFlags.hs
index 9d279d688e..82d3c37c1b 100644
--- a/ghc/compiler/main/DynFlags.hs
+++ b/ghc/compiler/main/DynFlags.hs
@@ -115,6 +115,7 @@ data DynFlag
| Opt_D_dump_hi
| Opt_D_dump_hi_diffs
| Opt_D_dump_minimal_imports
+ | Opt_D_faststring_stats
| Opt_DoCoreLinting
| Opt_DoStgLinting
| Opt_DoCmmLinting
@@ -899,6 +900,7 @@ dynamic_flags = [
, ( "dcmm-lint", NoArg (setDynFlag Opt_DoCmmLinting))
, ( "dshow-passes", NoArg (do unSetDynFlag Opt_RecompChecking
setVerbosity "2") )
+ , ( "dfaststring-stats", NoArg (setDynFlag Opt_D_faststring_stats))
------ Machine dependant (-m<blah>) stuff ---------------------------
diff --git a/ghc/compiler/main/Main.hs b/ghc/compiler/main/Main.hs
index 17eb526296..8d6e30a1af 100644
--- a/ghc/compiler/main/Main.hs
+++ b/ghc/compiler/main/Main.hs
@@ -14,7 +14,7 @@ module Main (main) where
-- The official GHC API
import qualified GHC
import GHC ( Session, DynFlags(..), GhcMode(..), HscTarget(..),
- LoadHowMuch(..) )
+ LoadHowMuch(..), dopt, DynFlag(..) )
import CmdLineParser
-- Implementations of the various modes (--show-iface, mkdependHS. etc.)
@@ -34,6 +34,9 @@ import DriverPhases ( Phase(..), isSourceFilename, anyHsc,
import StaticFlags ( staticFlags, v_Ld_inputs )
import DynFlags ( defaultDynFlags )
import BasicTypes ( failed )
+import ErrUtils ( Message, debugTraceMsg, putMsg )
+import FastString ( getFastStringTable, isZEncoded, hasZEncoding )
+import Outputable
import Util
import Panic
@@ -148,6 +151,7 @@ main =
DoInteractive -> interactiveUI session srcs Nothing
DoEval expr -> interactiveUI session srcs (Just expr)
+ dumpFinalStats dflags
exitWith ExitSuccess
#ifndef GHCI
@@ -430,6 +434,41 @@ showGhcUsage cli_mode = do
dump ('$':'$':s) = putStr progName >> dump s
dump (c:s) = putChar c >> dump s
+dumpFinalStats :: DynFlags -> IO ()
+dumpFinalStats dflags =
+ when (dopt Opt_D_faststring_stats dflags) $ dumpFastStringStats dflags
+
+dumpFastStringStats :: DynFlags -> IO ()
+dumpFastStringStats dflags = do
+ buckets <- getFastStringTable
+ let (entries, longest, is_z, has_z) = countFS 0 0 0 0 buckets
+ msg = text "FastString stats:" $$
+ nest 4 (vcat [text "size: " <+> int (length buckets),
+ text "entries: " <+> int entries,
+ text "longest chain: " <+> int longest,
+ text "z-encoded: " <+> (is_z `pcntOf` entries),
+ text "has z-encoding: " <+> (has_z `pcntOf` entries)
+ ])
+ -- we usually get more "has z-encoding" than "z-encoded", because
+ -- when we z-encode a string it might hash to the exact same string,
+ -- which will is not counted as "z-encoded". Only strings whose
+ -- Z-encoding is different from the original string are counted in
+ -- the "z-encoded" total.
+ putMsg dflags msg
+ where
+ x `pcntOf` y = int ((x * 100) `quot` y) <> char '%'
+
+countFS entries longest is_z has_z [] = (entries, longest, is_z, has_z)
+countFS entries longest is_z has_z (b:bs) =
+ let
+ len = length b
+ longest' = max len longest
+ entries' = entries + len
+ is_zs = length (filter isZEncoded b)
+ has_zs = length (filter hasZEncoding b)
+ in
+ countFS entries' longest' (is_z + is_zs) (has_z + has_zs) bs
+
-- -----------------------------------------------------------------------------
-- Util
diff --git a/ghc/compiler/utils/FastString.lhs b/ghc/compiler/utils/FastString.lhs
index 28aa6b0f31..4d432e6a75 100644
--- a/ghc/compiler/utils/FastString.lhs
+++ b/ghc/compiler/utils/FastString.lhs
@@ -51,6 +51,10 @@ module FastString
-- ** Outputing
hPutFS,
+ -- ** Internal
+ getFastStringTable,
+ hasZEncoding,
+
-- * LitStrings
LitString,
mkLitString#,
@@ -71,6 +75,7 @@ import System.IO.Unsafe ( unsafePerformIO )
import Control.Monad.ST ( stToIO )
import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
import System.IO ( hPutBuf )
+import Data.Maybe ( isJust )
import GHC.Arr ( STArray(..), newSTArray )
import GHC.IOBase ( IO(..) )
@@ -343,6 +348,17 @@ isZEncoded :: FastString -> Bool
isZEncoded fs | ZEncoded <- enc fs = True
| otherwise = False
+-- | Returns 'True' if this 'FastString' is not Z-encoded but already has
+-- a Z-encoding cached (used in producing stats).
+hasZEncoding :: FastString -> Bool
+hasZEncoding fs@(FastString uid n_bytes _ fp enc) =
+ case enc of
+ ZEncoded -> False
+ UTF8Encoded ref ->
+ inlinePerformIO $ do
+ m <- readIORef ref
+ return (isJust m)
+
-- | Returns 'True' if the 'FastString' is empty
nullFS :: FastString -> Bool
nullFS f = n_bytes f == 0
@@ -415,6 +431,15 @@ uniqueOfFS (FastString (I# u#) _ _ _ _) = u#
nilFS = mkFastString ""
-- -----------------------------------------------------------------------------
+-- Stats
+
+getFastStringTable :: IO [[FastString]]
+getFastStringTable = do
+ tbl <- readIORef string_table
+ buckets <- mapM (lookupTbl tbl) [0..hASH_TBL_SIZE]
+ return buckets
+
+-- -----------------------------------------------------------------------------
-- Outputting 'FastString's
-- |Outputs a 'FastString' with /no decoding at all/, that is, you