[Git][ghc/ghc][wip/keepAlive-the-return-of-the-primop] 9 commits: Sized

Ben Gamari gitlab at gitlab.haskell.org
Tue Dec 1 03:02:14 UTC 2020



Ben Gamari pushed to branch wip/keepAlive-the-return-of-the-primop at Glasgow Haskell Compiler / GHC


Commits:
5e5f48e8 by Ben Gamari at 2020-11-30T18:54:39-05:00
Sized

- - - - -
5b1d2a82 by Ben Gamari at 2020-11-30T22:00:28-05:00
genprimopcode: Add a second levity-polymorphic tyvar

This will be needed shortly.

- - - - -
970e078a by GHC GitLab CI at 2020-11-30T22:00:28-05:00
Introduce keepAlive primop

- - - - -
b4739d60 by Ben Gamari at 2020-11-30T22:00:28-05:00
base: Use keepAlive# in withForeignPtr

- - - - -
78ce842a by Ben Gamari at 2020-11-30T22:00:28-05:00
Implement withByteArrayContents in terms of keepAlive#

- - - - -
f9051eb0 by Ben Gamari at 2020-11-30T22:01:07-05:00
base: Implement GHC.ForeignPtr.Ops in terms of keepAlive#

- - - - -
d3336c83 by Ben Gamari at 2020-11-30T22:01:08-05:00
base: Use keepAlive# in Foreign.Marshal.Alloc

- - - - -
a095280e by Ben Gamari at 2020-11-30T22:01:08-05:00
ghc-compact: Use keepAlive# in GHC.Compact.Serialized

- - - - -
9e1a58a4 by Ben Gamari at 2020-11-30T22:01:55-05:00
iFix it

- - - - -


10 changed files:

- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Data/ByteArray.hs
- compiler/GHC/StgToCmm/Prim.hs
- libraries/base/Foreign/Marshal/Alloc.hs
- libraries/base/GHC/ForeignPtr.hs
- libraries/base/GHC/ForeignPtr/Ops.hs
- libraries/ghc-compact/GHC/Compact/Serialized.hs
- utils/genprimopcode/Main.hs


Changes:

=====================================
compiler/GHC/Builtin/primops.txt.pp
=====================================
@@ -2983,6 +2983,20 @@ primop NumSparks "numSparks#" GenPrimOp
    has_side_effects = True
    out_of_line = True
 
+
+------------------------------------------------------------------------
+section "Controlling object lifetime"
+        {Ensuring that objects don't die a premature death.}
+------------------------------------------------------------------------
+
+-- See Note [keepAlive# magic] in GHC.CoreToStg.Prep.
+primop KeepAliveOp "keepAlive#" GenPrimOp
+   o -> State# RealWorld -> (State# RealWorld -> p) -> p
+   { TODO. }
+   with
+   strictness = { \ _arity -> mkClosedStrictSig [topDmd, topDmd, strictOnceApply1Dmd] topDiv }
+
+
 ------------------------------------------------------------------------
 section "Tag to enum stuff"
         {Convert back and forth between values of enumerated types


=====================================
compiler/GHC/Core/Utils.hs
=====================================
@@ -1642,6 +1642,8 @@ app_ok primop_ok fun args
         -> False       --     for the special cases for SeqOp and DataToTagOp
         | DataToTagOp <- op
         -> False
+        | KeepAliveOp <- op
+        -> False
 
         | otherwise
         -> primop_ok op  -- Check the primop itself


=====================================
compiler/GHC/CoreToStg/Prep.hs
=====================================
@@ -32,7 +32,10 @@ import GHC.Tc.Utils.Env
 import GHC.Unit
 
 import GHC.Builtin.Names
+import GHC.Builtin.PrimOps
 import GHC.Builtin.Types
+import GHC.Builtin.Types.Prim ( realWorldStatePrimTy )
+import GHC.Types.Id.Make ( realWorldPrimId, mkPrimOpId )
 
 import GHC.Core.Utils
 import GHC.Core.Opt.Arity
@@ -47,6 +50,7 @@ import GHC.Core.TyCon
 import GHC.Core.DataCon
 import GHC.Core.Opt.OccurAnal
 
+
 import GHC.Data.Maybe
 import GHC.Data.OrdList
 import GHC.Data.FastString
@@ -63,7 +67,6 @@ import GHC.Types.Var.Set
 import GHC.Types.Var.Env
 import GHC.Types.Id
 import GHC.Types.Id.Info
-import GHC.Types.Id.Make ( realWorldPrimId )
 import GHC.Types.Basic
 import GHC.Types.Name   ( NamedThing(..), nameSrcSpan, isInternalName )
 import GHC.Types.SrcLoc ( SrcSpan(..), realSrcLocSpan, mkRealSrcLoc )
@@ -784,6 +787,38 @@ cpeApp top_env expr
         -- rather than the far superior "f x y".  Test case is par01.
         = let (terminal, args', depth') = collect_args arg
           in cpe_app env terminal (args' ++ args) (depth + depth' - 1)
+
+    cpe_app env
+            (Var f)
+            args
+            n
+        | Just KeepAliveOp <- isPrimOpId_maybe f
+        , CpeApp (Type arg_rep)
+          : CpeApp (Type arg_ty)
+          : CpeApp (Type _result_rep)
+          : CpeApp (Type result_ty)
+          : CpeApp arg
+          : CpeApp s0
+          : CpeApp k
+          : rest <- pprTrace "cpe_app keepAlive#" (ppr args) args
+        = do { pprTraceM "cpe_app(keepAlive#)" (ppr n)
+             ; y <- newVar result_ty
+             ; s2 <- newVar realWorldStatePrimTy
+             ; -- beta reduce if possible
+             ; (floats, k') <- case k of
+                  Lam s body -> cpe_app (extendCorePrepEnvExpr env s s0) body rest (n-2)
+                  _          -> cpe_app env k (CpeApp s0 : rest) (n-1)
+             ; let touchId = mkPrimOpId TouchOp
+                   expr = Case k' y result_ty [(DEFAULT, [], rhs)]
+                   rhs = let scrut = mkApps (Var touchId) [Type arg_rep, Type arg_ty, arg, Var realWorldPrimId]
+                         in Case scrut s2 result_ty [(DEFAULT, [], Var y)]
+             ; pprTraceM "cpe_app(keepAlive)" (ppr expr)
+             ; (floats', expr') <- cpeBody env expr
+             ; return (floats `appendFloats` floats', expr')
+             }
+        | Just KeepAliveOp <- isPrimOpId_maybe f
+        = panic "invalid keepAlive# application"
+
     cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) n
         | f `hasKey` runRWKey
         -- N.B. While it may appear that n == 1 in the case of runRW#


=====================================
compiler/GHC/Data/ByteArray.hs
=====================================
@@ -77,10 +77,15 @@ unsafeMutableByteArrayContents :: MutableByteArray -> Ptr a
 unsafeMutableByteArrayContents = unsafeByteArrayContents . unsafeCoerce
 
 withByteArrayContents :: ByteArray -> (Ptr a -> IO b) -> IO b
+#if MIN_VERSION_base(4,15,0)
+withByteArrayContents (ByteArray ba) f =
+  IO $ \s -> keepAlive# ba s (unIO (f (Ptr (byteArrayContents# ba))))
+#else
 withByteArrayContents (ByteArray ba) f = do
   r <- f $ Ptr (byteArrayContents# ba)
   IO $ \s -> case touch# ba s of s' -> (# s', () #)
   return r
+#endif
 
 newMutableByteArray :: Int -> IO MutableByteArray
 newMutableByteArray (I# size) = IO $ \s ->


=====================================
compiler/GHC/StgToCmm/Prim.hs
=====================================
@@ -1551,6 +1551,8 @@ emitPrimOp dflags primop = case primop of
   TraceMarkerOp -> alwaysExternal
   SetThreadAllocationCounter -> alwaysExternal
 
+  KeepAliveOp -> panic "keepAlive# should have been eliminated in CorePrep"
+
  where
   profile = targetProfile dflags
   platform = profilePlatform profile


=====================================
libraries/base/Foreign/Marshal/Alloc.hs
=====================================
@@ -116,19 +116,6 @@ alloca :: forall a b . Storable a => (Ptr a -> IO b) -> IO b
 alloca  =
   allocaBytesAligned (sizeOf (undefined :: a)) (alignment (undefined :: a))
 
--- Note [NOINLINE for touch#]
--- ~~~~~~~~~~~~~~~~~~~~~~~~~~
--- Both allocaBytes and allocaBytesAligned use the touch#, which is notoriously
--- fragile in the presence of simplification (see #14346). In particular, the
--- simplifier may drop the continuation containing the touch# if it can prove
--- that the action passed to allocaBytes will not return. The hack introduced to
--- fix this for 8.2.2 is to mark allocaBytes as NOINLINE, ensuring that the
--- simplifier can't see the divergence.
---
--- These can be removed once #14375 is fixed, which suggests that we instead do
--- away with touch# in favor of a primitive that will capture the scoping left
--- implicit in the case of touch#.
-
 -- |@'allocaBytes' n f@ executes the computation @f@, passing as argument
 -- a pointer to a temporarily allocated block of memory of @n@ bytes.
 -- The block of memory is sufficiently aligned for any of the basic
@@ -143,12 +130,8 @@ allocaBytes (I# size) action = IO $ \ s0 ->
      case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr#  #) ->
      let addr = Ptr (byteArrayContents# barr#) in
      case action addr     of { IO action' ->
-     case action' s2      of { (# s3, r #) ->
-     case touch# barr# s3 of { s4 ->
-     (# s4, r #)
-  }}}}}
--- See Note [NOINLINE for touch#]
-{-# NOINLINE allocaBytes #-}
+     keepAlive# barr# s2 action'
+  }}}
 
 allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b
 allocaBytesAligned (I# size) (I# align) action = IO $ \ s0 ->
@@ -156,12 +139,8 @@ allocaBytesAligned (I# size) (I# align) action = IO $ \ s0 ->
      case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr#  #) ->
      let addr = Ptr (byteArrayContents# barr#) in
      case action addr     of { IO action' ->
-     case action' s2      of { (# s3, r #) ->
-     case touch# barr# s3 of { s4 ->
-     (# s4, r #)
-  }}}}}
--- See Note [NOINLINE for touch#]
-{-# NOINLINE allocaBytesAligned #-}
+     keepAlive# barr# s2 action'
+  }}}
 
 -- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes'
 -- to the size needed to store values of type @b at .  The returned pointer


=====================================
libraries/base/GHC/ForeignPtr.hs
=====================================
@@ -526,7 +526,9 @@ withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
 -- or from the object pointed to by the
 -- 'ForeignPtr', using the operations from the
 -- 'Storable' class.
-withForeignPtr = unsafeWithForeignPtr
+withForeignPtr fo@(ForeignPtr _ r) f = IO $ \s ->
+  case f (unsafeForeignPtrToPtr fo) of
+    IO action# -> keepAlive# r s action#
 
 -- | This is similar to 'withForeignPtr' but comes with an important caveat:
 -- the user must guarantee that the continuation does not diverge (e.g. loop or


=====================================
libraries/base/GHC/ForeignPtr/Ops.hs
=====================================
@@ -51,121 +51,114 @@ import GHC.Word
 import GHC.Int
 import GHC.Base
 import GHC.ForeignPtr
-import GHC.Ptr
-
-withFP :: ForeignPtr a
-       -> (Addr# -> State# RealWorld -> (# State# RealWorld, b #))
-       -> IO b
-withFP fp f =
-  withForeignPtr fp (\(Ptr addr) -> IO (f addr))
 
 peekWord8ForeignPtr :: ForeignPtr ty -> Int -> IO Word8
-peekWord8ForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readWord8OffAddr# addr d s0 of
-      (# s1, r #) -> (# s1, W8# r #)
+peekWord8ForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readWord8OffAddr# addr d) of
+      (# s1, r #) -> (# s1, W8# (narrowWord8# r) #)
 
 peekWord16ForeignPtr :: ForeignPtr ty -> Int -> IO Word16
-peekWord16ForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readWord16OffAddr# addr d s0 of
-      (# s1, r #) -> (# s1, W16# r #)
+peekWord16ForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readWord16OffAddr# addr d) of
+      (# s1, r #) -> (# s1, W16# (narrowWord16# r) #)
 
 peekWord32ForeignPtr :: ForeignPtr ty -> Int -> IO Word32
-peekWord32ForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readWord32OffAddr# addr d s0 of
-      (# s1, r #) -> (# s1, W32# r #)
+peekWord32ForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readWord32OffAddr# addr d) of
+      (# s1, r #) -> (# s1, W32# (narrowWord32# r) #)
 
 peekWord64ForeignPtr :: ForeignPtr ty -> Int -> IO Word64
-peekWord64ForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readWord64OffAddr# addr d s0 of
+peekWord64ForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readWord64OffAddr# addr d) of
       (# s1, r #) -> (# s1, W64# r #)
 
 peekWordForeignPtr :: ForeignPtr ty -> Int -> IO Word
-peekWordForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readWordOffAddr# addr d s0 of
+peekWordForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readWordOffAddr# addr d) of
       (# s1, r #) -> (# s1, W# r #)
 
 peekInt8ForeignPtr :: ForeignPtr ty -> Int -> IO Int8
-peekInt8ForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readInt8OffAddr# addr d s0 of
-      (# s1, r #) -> (# s1, I8# r #)
+peekInt8ForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readInt8OffAddr# addr d) of
+      (# s1, r #) -> (# s1, I8# (narrowInt8# r) #)
 
 peekInt16ForeignPtr :: ForeignPtr ty -> Int -> IO Int16
-peekInt16ForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readInt16OffAddr# addr d s0 of
-      (# s1, r #) -> (# s1, I16# r #)
+peekInt16ForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readInt16OffAddr# addr d) of
+      (# s1, r #) -> (# s1, I16# (narrowInt16# r) #)
 
 peekInt32ForeignPtr :: ForeignPtr ty -> Int -> IO Int32
-peekInt32ForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readInt32OffAddr# addr d s0 of
-      (# s1, r #) -> (# s1, I32# r #)
+peekInt32ForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readInt32OffAddr# addr d) of
+      (# s1, r #) -> (# s1, I32# (narrowInt32# r) #)
 
 peekInt64ForeignPtr :: ForeignPtr ty -> Int -> IO Int64
-peekInt64ForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readInt64OffAddr# addr d s0 of
+peekInt64ForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readInt64OffAddr# addr d) of
       (# s1, r #) -> (# s1, I64# r #)
 
 peekIntForeignPtr :: ForeignPtr ty -> Int -> IO Int
-peekIntForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readIntOffAddr# addr d s0 of
+peekIntForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readIntOffAddr# addr d) of
       (# s1, r #) -> (# s1, I# r #)
 
 peekCharForeignPtr :: ForeignPtr ty -> Int -> IO Char
-peekCharForeignPtr fp (I# d) = withFP fp $ \addr s0 ->
-    case readCharOffAddr# addr d s0 of
+peekCharForeignPtr (ForeignPtr addr c) (I# d) = IO $ \s0 ->
+    case keepAlive# c s0 (readCharOffAddr# addr d) of
       (# s1, r #) -> (# s1, C# r #)
 
 pokeWord8ForeignPtr :: ForeignPtr ty -> Int -> Word8 -> IO ()
-pokeWord8ForeignPtr fp (I# d) (W8# n) = withFP fp $ \addr s0 ->
-    case writeWord8OffAddr# addr d n s0 of
+pokeWord8ForeignPtr (ForeignPtr addr c) (I# d) (W8# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeWord8OffAddr# addr d (extendWord8# n)) of
       s1 -> (# s1, () #)
 
 pokeWord16ForeignPtr :: ForeignPtr ty -> Int -> Word16 -> IO ()
-pokeWord16ForeignPtr fp (I# d) (W16# n) = withFP fp $ \addr s0 ->
-    case writeWord16OffAddr# addr d n s0 of
+pokeWord16ForeignPtr (ForeignPtr addr c) (I# d) (W16# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeWord16OffAddr# addr d (extendWord16# n)) of
       s1 -> (# s1, () #)
 
 pokeWord32ForeignPtr :: ForeignPtr ty -> Int -> Word32 -> IO ()
-pokeWord32ForeignPtr fp (I# d) (W32# n) = withFP fp $ \addr s0 ->
-    case writeWord32OffAddr# addr d n s0 of
+pokeWord32ForeignPtr (ForeignPtr addr c) (I# d) (W32# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeWord32OffAddr# addr d (extendWord32# n)) of
       s1 -> (# s1, () #)
 
 pokeWord64ForeignPtr :: ForeignPtr ty -> Int -> Word64 -> IO ()
-pokeWord64ForeignPtr fp (I# d) (W64# n) = withFP fp $ \addr s0 ->
-    case writeWord64OffAddr# addr d n s0 of
+pokeWord64ForeignPtr (ForeignPtr addr c) (I# d) (W64# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeWord64OffAddr# addr d n) of
       s1 -> (# s1, () #)
 
 pokeWordForeignPtr :: ForeignPtr ty -> Int -> Word -> IO ()
-pokeWordForeignPtr fp (I# d) (W# n) = withFP fp $ \addr s0 ->
-    case writeWord64OffAddr# addr d n s0 of
+pokeWordForeignPtr (ForeignPtr addr c) (I# d) (W# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeWordOffAddr# addr d n) of
       s1 -> (# s1, () #)
 
 pokeInt8ForeignPtr :: ForeignPtr ty -> Int -> Int8 -> IO ()
-pokeInt8ForeignPtr fp (I# d) (I8# n) = withFP fp $ \addr s0 ->
-    case writeInt8OffAddr# addr d n s0 of
+pokeInt8ForeignPtr (ForeignPtr addr c) (I# d) (I8# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeInt8OffAddr# addr d (extendInt8# n)) of
       s1 -> (# s1, () #)
 
 pokeInt16ForeignPtr :: ForeignPtr ty -> Int -> Int16 -> IO ()
-pokeInt16ForeignPtr fp (I# d) (I16# n) = withFP fp $ \addr s0 ->
-    case writeInt16OffAddr# addr d n s0 of
+pokeInt16ForeignPtr (ForeignPtr addr c) (I# d) (I16# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeInt16OffAddr# addr d (extendInt16# n)) of
       s1 -> (# s1, () #)
 
 pokeInt32ForeignPtr :: ForeignPtr ty -> Int -> Int32 -> IO ()
-pokeInt32ForeignPtr fp (I# d) (I32# n) = withFP fp $ \addr s0 ->
-    case writeInt32OffAddr# addr d n s0 of
+pokeInt32ForeignPtr (ForeignPtr addr c) (I# d) (I32# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeInt32OffAddr# addr d (extendInt32# n)) of
       s1 -> (# s1, () #)
 
 pokeInt64ForeignPtr :: ForeignPtr ty -> Int -> Int64 -> IO ()
-pokeInt64ForeignPtr fp (I# d) (I64# n) = withFP fp $ \addr s0 ->
-    case writeInt64OffAddr# addr d n s0 of
+pokeInt64ForeignPtr (ForeignPtr addr c) (I# d) (I64# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeInt64OffAddr# addr d n) of
       s1 -> (# s1, () #)
 
 pokeIntForeignPtr :: ForeignPtr ty -> Int -> Int -> IO ()
-pokeIntForeignPtr fp (I# d) (I# n) = withFP fp $ \addr s0 ->
-    case writeIntOffAddr# addr d n s0 of
+pokeIntForeignPtr (ForeignPtr addr c) (I# d) (I# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeIntOffAddr# addr d n) of
       s1 -> (# s1, () #)
 
 pokeCharForeignPtr :: ForeignPtr ty -> Int -> Char -> IO ()
-pokeCharForeignPtr fp (I# d) (C# n) = withFP fp $ \addr s0 ->
-    case writeCharOffAddr# addr d n s0 of
+pokeCharForeignPtr (ForeignPtr addr c) (I# d) (C# n) = IO $ \s0 ->
+    case keepAlive# c s0 (writeCharOffAddr# addr d n) of
       s1 -> (# s1, () #)
 


=====================================
libraries/ghc-compact/GHC/Compact/Serialized.hs
=====================================
@@ -29,6 +29,7 @@ module GHC.Compact.Serialized(
 import GHC.Prim
 import GHC.Types
 import GHC.Word (Word8)
+import GHC.IO (unIO)
 
 import GHC.Ptr (Ptr(..), plusPtr)
 
@@ -74,12 +75,6 @@ mkBlockList buffer = compactGetFirstBlock buffer >>= go
       rest <- go next
       return $ item : rest
 
--- We MUST mark withSerializedCompact as NOINLINE
--- Otherwise the compiler will eliminate the call to touch#
--- causing the Compact# to be potentially GCed too eagerly,
--- before func had a chance to copy everything into its own
--- buffers/sockets/whatever
-
 -- | Serialize the 'Compact', and call the provided function with
 -- with the 'Compact' serialized representation.  It is not safe
 -- to return the pointer from the action and use it after
@@ -89,7 +84,6 @@ mkBlockList buffer = compactGetFirstBlock buffer >>= go
 -- unsound to use 'unsafeInterleaveIO' to lazily construct
 -- a lazy bytestring from the 'Ptr'.
 --
-{-# NOINLINE withSerializedCompact #-}
 withSerializedCompact :: Compact a ->
                          (SerializedCompact a -> IO c) -> IO c
 withSerializedCompact (Compact buffer root lock) func = withMVar lock $ \_ -> do
@@ -97,9 +91,7 @@ withSerializedCompact (Compact buffer root lock) func = withMVar lock $ \_ -> do
                     (# s', rootAddr #) -> (# s', Ptr rootAddr #) )
   blockList <- mkBlockList buffer
   let serialized = SerializedCompact blockList rootPtr
-  r <- func serialized
-  IO (\s -> case touch# buffer s of
-         s' -> (# s', r #) )
+  IO $ \s -> keepAlive# buffer s (unIO $ func serialized)
 
 fixupPointers :: Addr# -> Addr# -> State# RealWorld ->
                  (# State# RealWorld, Maybe (Compact a) #)


=====================================
utils/genprimopcode/Main.hs
=====================================
@@ -503,6 +503,7 @@ gen_latex_doc (Info defaults entries)
                    tvars = tvars_of typ
                    tbinds [] = ". "
                    tbinds ("o":tbs) = "(o::?) " ++ (tbinds tbs)
+                   tbinds ("p":tbs) = "(p::?) " ++ (tbinds tbs)
                    tbinds (tv:tbs) = tv ++ " " ++ (tbinds tbs)
            tvars_of (TyF t1 t2) = tvars_of t1 `union` tvars_of t2
            tvars_of (TyC t1 t2) = tvars_of t1 `union` tvars_of t2
@@ -852,6 +853,7 @@ ppTyVar "b" = "betaTyVar"
 ppTyVar "c" = "gammaTyVar"
 ppTyVar "s" = "deltaTyVar"
 ppTyVar "o" = "runtimeRep1TyVar, openAlphaTyVar"
+ppTyVar "p" = "runtimeRep2TyVar, openBetaTyVar"
 ppTyVar _   = error "Unknown type var"
 
 ppType :: Ty -> String
@@ -885,6 +887,7 @@ ppType (TyVar "b")                      = "betaTy"
 ppType (TyVar "c")                      = "gammaTy"
 ppType (TyVar "s")                      = "deltaTy"
 ppType (TyVar "o")                      = "openAlphaTy"
+ppType (TyVar "p")                      = "openBetaTy"
 
 ppType (TyApp (TyCon "State#") [x])             = "mkStatePrimTy " ++ ppType x
 ppType (TyApp (TyCon "MutVar#") [x,y])          = "mkMutVarPrimTy " ++ ppType x



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e88f492b462149616ca4a157f3b871247a575a07...9e1a58a469f3f64a667b3e3aeb8218a26f36077d

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e88f492b462149616ca4a157f3b871247a575a07...9e1a58a469f3f64a667b3e3aeb8218a26f36077d
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20201130/05c9aa81/attachment-0001.html>


More information about the ghc-commits mailing list