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 +10/−0
- ghc-trace-events.cabal +3/−2
- src/Debug/Trace/Binary.hs +18/−6
- src/Debug/Trace/ByteString.hs +109/−53
- src/Debug/Trace/String.hs +35/−2
- src/Debug/Trace/Text.hs +60/−18
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)