packages feed

ghc-trace-events 0.1.0.1 → 0.1.2

raw patch · 6 files changed

+235/−81 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,15 @@ # Revision history for ghc-trace-events +## v0.1.2 - 2020-06-09++* Revert "Use unsafeUseAsCString in place of useAsCString in Debug.Trace.Text" because it's unsafe+* Minimize the scope of NOINLINE to get better performance when user tracing is disabled++## v0.1.1 - 2020-06-07 (abondoned)++* Remove redundant checks of userTracingEnabled+* Optimize Debug.Trace.Text+ ## v0.1.0.1 - 2020-04-06  * Support GHC 8.10.1
ghc-trace-events.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: ghc-trace-events-version: 0.1.0.1+version: 0.1.2 synopsis: Faster traceEvent and traceMarker, and binary object logging for   eventlog description: ghc-trace-events provides faster traceEvent and traceMarker as well@@ -30,7 +30,7 @@ license-file: LICENSE author: Mitsutoshi Aoe maintainer: Mitsutoshi Aoe <me@maoe.name>-copyright: Copyright (C) 2018-2019 Mitsutoshi Aoe+copyright: Copyright (C) 2018-2020 Mitsutoshi Aoe category: Development, GHC, Trace build-type: Simple extra-source-files:@@ -55,6 +55,7 @@       base     , bytestring     , text+  ghc-options: -Wall   exposed-modules:     Debug.Trace.ByteString     Debug.Trace.Flags
src/Debug/Trace/Binary.hs view
@@ -1,7 +1,13 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-}+{-|+Arbitary binary object logging available for GHC 8.8 or later. Unlike the other+tracing functions 'traceBinaryEvent' takes an arbitrary 'B.ByteString' object as+opposed to a UTF-8 encoded string.+-} module Debug.Trace.Binary-  ( traceBinaryEvent+  ( -- * Binary eventlog tracing+     traceBinaryEvent   , traceBinaryEventIO   ) where import Control.Monad (when)@@ -32,12 +38,15 @@ -- generates a broken eventlog. traceBinaryEvent :: B.ByteString -> a -> a traceBinaryEvent bytes a-  | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do-    traceBinaryEventIO bytes-    return a+  | userTracingEnabled = traceBinaryEvent' bytes a   | otherwise = a-{-# NOINLINE traceBinaryEvent #-} +traceBinaryEvent' :: B.ByteString -> a -> a+traceBinaryEvent' bytes a = Unsafe.unsafeDupablePerformIO $ do+  traceBinaryEventIO' bytes+  return a+{-# NOINLINE traceBinaryEvent' #-}+ -- | The 'traceBinaryEventIO' function emits a binary message to the eventlog, -- if eventlog profiling is available and enabled at runtime. --@@ -50,7 +59,10 @@ -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. traceBinaryEventIO :: B.ByteString -> IO ()-traceBinaryEventIO bytes = when userTracingEnabled $+traceBinaryEventIO bytes = when userTracingEnabled $ traceBinaryEventIO' bytes++traceBinaryEventIO' :: B.ByteString -> IO ()+traceBinaryEventIO' bytes =   BU.unsafeUseAsCStringLen bytes $ \(Ptr p, I# n) -> IO $ \s ->     case traceBinaryEvent# p n s of       s' -> (# s', () #)
src/Debug/Trace/ByteString.hs view
@@ -5,22 +5,25 @@ 'B.ByteString' variant of the tracing functions in "Debug.Trace". -} module Debug.Trace.ByteString-  ( traceEvent+  ( -- * Eventlog tracing+    -- $eventlog_tracing+    traceEvent   , traceEventIO -  , traceMarker-  , traceMarkerIO-   , unsafeTraceEvent   , unsafeTraceEventIO +  -- * Execution phase markers+  -- $markers+  , traceMarker+  , traceMarkerIO+   , unsafeTraceMarker   , unsafeTraceMarkerIO   ) where import Control.Monad (when) import GHC.Exts (Ptr(..), traceEvent#, traceMarker#) import GHC.IO (IO(..))-import qualified GHC.RTS.Flags as Flags import qualified System.IO.Unsafe as Unsafe  import qualified Data.ByteString as B@@ -28,6 +31,17 @@  import Debug.Trace.Flags (userTracingEnabled) +-- $eventlog_tracing+--+-- Eventlog tracing is a performance profiling system. These functions emit+-- extra events into the eventlog. In combination with eventlog profiling+-- tools these functions can be used for monitoring execution and+-- investigating performance problems.+--+-- Currently only GHC provides eventlog profiling, see the GHC user guide for+-- details on how to use it. These function exists for other Haskell+-- implementations but no events are emitted.+ -- | 'B.ByteString' variant of 'Debug.Trace.traceEvent'. -- -- \(O(n)\) This function copies the 'B.ByteString' to convert it to a@@ -40,12 +54,15 @@ -- generates a broken eventlog. traceEvent :: B.ByteString -> a -> a traceEvent message a-  | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do-    traceEventIO message-    return a+  | userTracingEnabled = traceEvent' message a   | otherwise = a-{-# NOINLINE traceEvent #-} +traceEvent' :: B.ByteString -> a -> a+traceEvent' message a = Unsafe.unsafeDupablePerformIO $ do+  traceEventIO' message+  return a+{-# NOINLINE traceEvent' #-}+ -- | 'B.ByteString' variant of 'Debug.Trace.traceEventIO'. -- -- \(O(n)\) This function copies the 'B.ByteString' to convert it to a@@ -57,81 +74,113 @@ -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. traceEventIO :: B.ByteString -> IO ()-traceEventIO message = when userTracingEnabled $-  B.useAsCString message $ \(Ptr p) -> IO $ \s ->-    case traceEvent# p s of-      s' -> (# s', () #)+traceEventIO message = when userTracingEnabled $ traceEventIO' message --- | 'B.ByteString' variant of 'Debug.Trace.traceMarker'.+traceEventIO' :: B.ByteString -> IO ()+traceEventIO' message = B.useAsCString message $ \(Ptr p) -> IO $ \s ->+  case traceEvent# p s of+    s' -> (# s', () #)++-- | 'B.ByteString' variant of 'Debug.Trace.traceEvent'. ----- \(O(n)\) This function copies the 'B.ByteString' to convert it to a--- null-terminated 'Foreign.C.Types.CString'.+-- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input+-- string to be null-terminated. It is user's responsibility to null-terminate+-- the input. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog.-traceMarker :: B.ByteString -> a -> a-traceMarker message a-  | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do-    traceMarkerIO message-    return a+unsafeTraceEvent :: B.ByteString -> a -> a+unsafeTraceEvent message a+  | userTracingEnabled = unsafeTraceEvent' message a   | otherwise = a-{-# NOINLINE traceMarker #-} --- | 'B.ByteString' variant of 'Debug.Trace.traceMarkerIO'.+unsafeTraceEvent' :: B.ByteString -> a -> a+unsafeTraceEvent' message a = Unsafe.unsafeDupablePerformIO $ do+  unsafeTraceEventIO' message+  return a+{-# NOINLINE unsafeTraceEvent' #-}++-- | 'B.ByteString' variant of 'Debug.Trace.traceEventIO'. ----- \(O(n)\) This function copies the 'B.ByteString' to convert it to a--- null-terminated 'Foreign.C.Types.CString'.+-- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input+-- string to be null-terminated. It is user's responsibility to null-terminate+-- the input. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog.-traceMarkerIO :: B.ByteString -> IO ()-traceMarkerIO message = when userTracingEnabled $-  B.useAsCString message $ \(Ptr p) -> IO $ \s ->-    case traceMarker# p s of+unsafeTraceEventIO :: B.ByteString -> IO ()+unsafeTraceEventIO message =+  when userTracingEnabled $ unsafeTraceEventIO' message++unsafeTraceEventIO' :: B.ByteString -> IO ()+unsafeTraceEventIO' message =+  BU.unsafeUseAsCString message $ \(Ptr p) -> IO $ \s ->+    case traceEvent# p s of       s' -> (# s', () #) --- | 'B.ByteString' variant of 'Debug.Trace.traceEvent'.+-- $markers ----- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input--- string to be null-terminated. It is user's responsibility to null-terminate--- the input.+-- When looking at a profile for the execution of a program we often want to+-- be able to mark certain points or phases in the execution and see that+-- visually in the profile. --+-- For example, a program might have several distinct phases with different+-- performance or resource behaviour in each phase. To properly interpret the+-- profile graph we really want to see when each phase starts and ends.+--+-- Markers let us do this: we can annotate the program to emit a marker at+-- an appropriate point during execution and then see that in a profile.+--+-- Currently this feature is only supported in GHC by the eventlog tracing+-- system, but in future it may also be supported by the heap profiling or+-- other profiling tools. These function exists for other Haskell+-- implementations but they have no effect.++-- | 'B.ByteString' variant of 'Debug.Trace.traceMarker'.+--+-- \(O(n)\) This function copies the 'B.ByteString' to convert it to a+-- null-terminated 'Foreign.C.Types.CString'.+-- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog.-unsafeTraceEvent :: B.ByteString -> a -> a-unsafeTraceEvent message a-  | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do-    unsafeTraceEventIO message-    return a+traceMarker :: B.ByteString -> a -> a+traceMarker message a+  | userTracingEnabled = traceMarker' message a   | otherwise = a-{-# NOINLINE unsafeTraceEvent #-} --- | 'B.ByteString' variant of 'Debug.Trace.traceEventIO'.+traceMarker' :: B.ByteString -> a -> a+traceMarker' message a = Unsafe.unsafeDupablePerformIO $ do+  traceMarkerIO' message+  return a+{-# NOINLINE traceMarker' #-}++-- | 'B.ByteString' variant of 'Debug.Trace.traceMarkerIO'. ----- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input--- string to be null-terminated. It is user's responsibility to null-terminate--- the input.+-- \(O(n)\) This function copies the 'B.ByteString' to convert it to a+-- null-terminated 'Foreign.C.Types.CString'. -- -- Note that this function doesn't evaluate the 'B.ByteString' if user tracing -- in eventlog is disabled. -- -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog.-unsafeTraceEventIO :: B.ByteString -> IO ()-unsafeTraceEventIO message = when userTracingEnabled $-  BU.unsafeUseAsCString message $ \(Ptr p) -> IO $ \s ->-    case traceEvent# p s of-      s' -> (# s', () #)+traceMarkerIO :: B.ByteString -> IO ()+traceMarkerIO message = when userTracingEnabled $ traceMarkerIO' message +traceMarkerIO' :: B.ByteString -> IO ()+traceMarkerIO' message = B.useAsCString message $ \(Ptr p) -> IO $ \s ->+  case traceMarker# p s of+    s' -> (# s', () #)+ -- | 'B.ByteString' variant of 'Debug.Trace.traceMarker'. -- -- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input@@ -145,12 +194,15 @@ -- generates a broken eventlog. unsafeTraceMarker :: B.ByteString -> a -> a unsafeTraceMarker message a-  | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do-    unsafeTraceEventIO message-    return a+  | userTracingEnabled = unsafeTraceMarker' message a   | otherwise = a-{-# NOINLINE unsafeTraceMarker #-} +unsafeTraceMarker' :: B.ByteString -> a -> a+unsafeTraceMarker' message a = Unsafe.unsafeDupablePerformIO $ do+  unsafeTraceMarkerIO' message+  return a+{-# NOINLINE unsafeTraceMarker' #-}+ -- | 'B.ByteString' variant of 'Debug.Trace.traceMarkerIO'. -- -- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input@@ -163,7 +215,11 @@ -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. unsafeTraceMarkerIO :: B.ByteString -> IO ()-unsafeTraceMarkerIO message = when userTracingEnabled $+unsafeTraceMarkerIO message =+  when userTracingEnabled $ unsafeTraceMarkerIO' message++unsafeTraceMarkerIO' :: B.ByteString -> IO ()+unsafeTraceMarkerIO' message =   BU.unsafeUseAsCString message $ \(Ptr p) -> IO $ \s ->     case traceMarker# p s of       s' -> (# s', () #)
src/Debug/Trace/String.hs view
@@ -1,11 +1,15 @@ {-|-Drop-in replacements for the event tracing functions in "Debug.Trace" but are+Drop-in replacement for the event tracing functions in "Debug.Trace" but are faster when user tracing is disabled. -} module Debug.Trace.String-  ( traceEvent+  ( -- * Eventlog tracing+    -- $eventlog_tracing+    traceEvent   , traceEventIO +  -- * Execution phase markers+  -- $markers   , traceMarker   , traceMarkerIO   ) where@@ -14,6 +18,17 @@  import Debug.Trace.Flags (userTracingEnabled) +-- $eventlog_tracing+--+-- Eventlog tracing is a performance profiling system. These functions emit+-- extra events into the eventlog. In combination with eventlog profiling+-- tools these functions can be used for monitoring execution and+-- investigating performance problems.+--+-- Currently only GHC provides eventlog profiling, see the GHC user guide for+-- details on how to use it. These function exists for other Haskell+-- implementations but no events are emitted.+ -- | Drop-in replacement for 'Debug.Trace.traceEvent' but is more efficient -- if user tracing in eventlog is disabled. --@@ -37,6 +52,24 @@ -- generates a broken eventlog. traceEventIO :: String -> IO () traceEventIO message = when userTracingEnabled $ Base.traceEventIO message++-- $markers+--+-- When looking at a profile for the execution of a program we often want to+-- be able to mark certain points or phases in the execution and see that+-- visually in the profile.+--+-- For example, a program might have several distinct phases with different+-- performance or resource behaviour in each phase. To properly interpret the+-- profile graph we really want to see when each phase starts and ends.+--+-- Markers let us do this: we can annotate the program to emit a marker at+-- an appropriate point during execution and then see that in a profile.+--+-- Currently this feature is only supported in GHC by the eventlog tracing+-- system, but in future it may also be supported by the heap profiling or+-- other profiling tools. These function exists for other Haskell+-- implementations but they have no effect.  -- | Drop-in replacement for 'Debug.Trace.traceMarker' but is more efficient -- if user tracing in eventlog is disabled.
src/Debug/Trace/Text.hs view
@@ -4,9 +4,13 @@ 'T.Text' variant of the tracing functions in "Debug.Trace". -} module Debug.Trace.Text-  ( traceEvent+  ( -- * Eventlog tracing+  -- $eventlog_tracing+    traceEvent   , traceEventIO +  -- * Execution phase markers+  -- $markers   , traceMarker   , traceMarkerIO   ) where@@ -14,7 +18,6 @@ import Foreign.C.String (CString) import GHC.Exts (Ptr(..), traceEvent#, traceMarker#) import GHC.IO (IO(..))-import qualified GHC.RTS.Flags as Flags import qualified System.IO.Unsafe as Unsafe  import qualified Data.ByteString as B@@ -23,6 +26,17 @@  import Debug.Trace.Flags (userTracingEnabled) +-- $eventlog_tracing+--+-- Eventlog tracing is a performance profiling system. These functions emit+-- extra events into the eventlog. In combination with eventlog profiling+-- tools these functions can be used for monitoring execution and+-- investigating performance problems.+--+-- Currently only GHC provides eventlog profiling, see the GHC user guide for+-- details on how to use it. These function exists for other Haskell+-- implementations but no events are emitted.+ -- | 'T.Text' variant of 'Debug.Trace.traceEvent'. -- -- \(O(n)\) This function marshals the 'T.Text' into a 'B.ByteString' and@@ -35,12 +49,15 @@ -- generates a broken eventlog. traceEvent :: T.Text -> a -> a traceEvent message a-  | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do-    traceEventIO message-    return a+  | userTracingEnabled = traceEvent' message a   | otherwise = a-{-# NOINLINE traceEvent #-} +traceEvent' :: T.Text -> a -> a+traceEvent' message a = Unsafe.unsafeDupablePerformIO $ do+  traceEventIO' message+  return a+{-# NOINLINE traceEvent' #-}+ -- | 'T.Text' variant of 'Debug.Trace.traceEventIO'. -- -- \(O(n)\) This function marshals the 'T.Text' into a 'B.ByteString' and@@ -52,11 +69,31 @@ -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. traceEventIO :: T.Text -> IO ()-traceEventIO message = when userTracingEnabled $-  withCString message $ \(Ptr p) -> IO $ \s ->-    case traceEvent# p s of-      s' -> (# s', () #)+traceEventIO message = when userTracingEnabled $ traceEventIO' message +traceEventIO' :: T.Text -> IO ()+traceEventIO' message = withCString message $ \(Ptr p) -> IO $ \s ->+  case traceEvent# p s of+    s' -> (# s', () #)++-- $markers+--+-- When looking at a profile for the execution of a program we often want to+-- be able to mark certain points or phases in the execution and see that+-- visually in the profile.+--+-- For example, a program might have several distinct phases with different+-- performance or resource behaviour in each phase. To properly interpret the+-- profile graph we really want to see when each phase starts and ends.+--+-- Markers let us do this: we can annotate the program to emit a marker at+-- an appropriate point during execution and then see that in a profile.+--+-- Currently this feature is only supported in GHC by the eventlog tracing+-- system, but in future it may also be supported by the heap profiling or+-- other profiling tools. These function exists for other Haskell+-- implementations but they have no effect.+ -- | 'T.Text' variant of 'Debug.Trace.traceMarker'. -- -- \(O(n)\) This function marshals the 'T.Text' into a 'B.ByteString' and@@ -69,12 +106,15 @@ -- generates a broken eventlog. traceMarker :: T.Text -> a -> a traceMarker message a-  | userTracingEnabled = Unsafe.unsafeDupablePerformIO $ do-    traceMarkerIO message-    return a+  | userTracingEnabled = traceMarker' message a   | otherwise = a-{-# NOINLINE traceMarker #-} +traceMarker' :: T.Text -> a -> a+traceMarker' message a = Unsafe.unsafeDupablePerformIO $ do+  traceMarkerIO' message+  return a+{-# NOINLINE traceMarker' #-}+ -- | 'T.Text' variant of 'Debug.Trace.traceMarkerIO'. -- -- \(O(n)\) This function marshals the 'T.Text' into a 'B.ByteString' and@@ -86,10 +126,12 @@ -- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS -- generates a broken eventlog. traceMarkerIO :: T.Text -> IO ()-traceMarkerIO message = when userTracingEnabled $-  withCString message $ \(Ptr p) -> IO $ \s ->-    case traceMarker# p s of-      s' -> (# s', () #)+traceMarkerIO message = when userTracingEnabled $ traceMarkerIO' message++traceMarkerIO' :: T.Text -> IO ()+traceMarkerIO' message = withCString message $ \(Ptr p) -> IO $ \s ->+  case traceMarker# p s of+    s' -> (# s', () #)  withCString :: T.Text -> (CString -> IO a) -> IO a withCString text = B.useAsCString (TE.encodeUtf8 text)