[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Bump bytestring submodule to 0.11.5.1
Marge Bot (@marge-bot)
gitlab at gitlab.haskell.org
Sat Aug 5 02:25:38 UTC 2023
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
43c2911f by Matthew Craven at 2023-08-04T22:25:24-04:00
Bump bytestring submodule to 0.11.5.1
- - - - -
1c71b502 by Ben Gamari at 2023-08-04T22:25:25-04:00
Initial commit of Note [Thunks, blackholes, and indirections]
This Note attempts to summarize the treatment of thunks, thunk update,
and indirections.
This fell out of work on #23185.
- - - - -
d5e564eb by sheaf at 2023-08-04T22:25:30-04:00
Remove zonk in tcVTA
This removes the zonk in GHC.Tc.Gen.App.tc_inst_forall_arg and its
accompanying Note [Visible type application zonk]. Indeed, this zonk
is no longer necessary, as we no longer maintain the invariant that
types are well-kinded without zonking; only that typeKind does not
crash; see Note [The Purely Kinded Type Invariant (PKTI)].
This commit removes this zonking step (as well as a secondary zonk),
and replaces the aforementioned Note with the explanatory
Note [Type application substitution], which justifies why the
substitution performed in tc_inst_forall_arg remains valid without
this zonking step.
Fixes #23661
- - - - -
51596290 by Ben Gamari at 2023-08-04T22:25:31-04:00
Bump nofib submodule
Ensuring that nofib can be build using the same range of bootstrap
compilers as GHC itself.
- - - - -
9 changed files:
- .gitlab-ci.yml
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Utils/Binary.hs
- hadrian/src/Settings/Warnings.hs
- libraries/bytestring
- nofib
- rts/Updates.h
- testsuite/tests/ghci/scripts/T9881.stdout
- testsuite/tests/ghci/scripts/ghci025.stdout
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -401,7 +401,7 @@ hadrian-multi:
# workaround for docker permissions
- sudo chown ghc:ghc -R .
variables:
- GHC_FLAGS: -Werror
+ GHC_FLAGS: "-Werror -Wwarn=deprecations"
CONFIGURE_ARGS: --enable-bootstrap-with-devel-snapshot
tags:
- x86_64-linux
=====================================
compiler/GHC/Tc/Gen/App.hs
=====================================
@@ -840,19 +840,14 @@ tc_inst_forall_arg conc_tvs (tvb, inner_ty) hs_ty
-- Example: user wrote e.g. (#,#) @(F Bool) for a type family F.
-- Emit [W] F Bool ~ kappa[conc] and pretend the user wrote (#,#) @kappa.
do { mco <- unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0
- ; let ty_arg = case mco of { MRefl -> ty_arg0; MCo co -> coercionRKind co }
- ; liftZonkM $ zonkTcType ty_arg }
- -- (zonk here to match the zonk below, because unifyConcrete can
- -- perform unification)
-
- ; inner_ty <- liftZonkM $ zonkTcType inner_ty
- -- See Note [Visible type application zonk]
+ ; return $ case mco of { MRefl -> ty_arg0; MCo co -> coercionRKind co } }
; let fun_ty = mkForAllTy tvb inner_ty
in_scope = mkInScopeSet (tyCoVarsOfTypes [fun_ty, ty_arg])
insted_ty = substTyWithInScope in_scope [tv] [ty_arg] inner_ty
- -- NB: tv and ty_arg have the same kind, so this
- -- substitution is kind-respecting
+ -- This substitution is well-kinded even when inner_ty
+ -- is not fully zonked, because ty_arg is fully zonked.
+ -- See Note [Type application substitution].
; traceTc "tc_inst_forall_arg (VTA/VDQ)" (
vcat [ text "fun_ty" <+> ppr fun_ty
@@ -1141,35 +1136,39 @@ Downside: the typechecked term has lost its visible type arguments; we
don't even kind-check them. But let's jump that bridge if we come to
it. Meanwhile, let's not crash!
-
-Note [Visible type application zonk]
+Note [Type application substitution]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* Substitutions should be kind-preserving, so we need kind(tv) = kind(ty_arg).
-
-* tcHsTypeApp only guarantees that
- - ty_arg is zonked
- - kind(zonk(tv)) = kind(ty_arg)
- (checkExpectedKind zonks as it goes).
-
-So we must zonk inner_ty as well, to guarantee consistency between zonk(tv)
-and inner_ty. Otherwise we can build an ill-kinded type. An example was #14158,
-where we had:
- id :: forall k. forall (cat :: k -> k -> *). forall (a :: k). cat a a
-and we had the visible type application
- id @(->)
-
-* We instantiated k := kappa, yielding
- forall (cat :: kappa -> kappa -> *). forall (a :: kappa). cat a a
-* Then we called tcHsTypeApp (->) with expected kind (kappa -> kappa -> *).
-* That instantiated (->) as ((->) q1 q1), and unified kappa := q1,
- Here q1 :: RuntimeRep
-* Now we substitute
- cat :-> (->) q1 q1 :: TYPE q1 -> TYPE q1 -> *
- but we must first zonk the inner_ty to get
- forall (a :: TYPE q1). cat a a
- so that the result of substitution is well-kinded
- Failing to do so led to #14158.
-
+In `tc_inst_forall_arg`, suppose we are checking a visible type
+application `f @hs_ty`, where `f :: forall (a :: k). body`. We will:
+ * Compute `ty <- tcHsTypeApp hs_ty k`
+ * Then substitute `a :-> ty` in `body`.
+Now, you might worry that `a` might not have the same kind as `ty`, so that the
+substitution isn't kind-preserving. How can that happen? The kinds will
+definitely be the same after zonking, and `ty` will be zonked (as this is
+a postcondition of `tcHsTypeApp`). But the function type `forall a. body`
+might not be fully zonked (hence the worry).
+
+But it's OK! During type checking, we don't require types to be well-kinded (without
+zonking); we only require them to satsisfy the Purely Kinded Type Invariant (PKTI).
+See Note [The Purely Kinded Type Invariant (PKTI)] in GHC.Tc.Gen.HsType.
+
+In the case of a type application:
+ * `forall a. body` satisfies the PKTI
+ * `ty` is zonked
+ * If we substitute a fully-zonked thing into an un-zonked Type that
+ satisfies the PKTI, the result still satisfies the PKTI.
+
+This last statement isn't obvious, but read
+Note [The Purely Kinded Type Invariant (PKTI)] in GHC.Tc.Gen.HsType.
+The tricky case is when `body` contains an application of the form `a b1 ... bn`,
+and we substitute `a :-> ty` where `ty` has fewer arrows in its kind than `a` does.
+That can't happen: the call `tcHsTypeApp hs_ty k` would have rejected the
+type application as ill-kinded.
+
+Historical remark: we used to require a stronger invariant than the PKTI,
+namely that all types are well-kinded prior to zonking. In that context, we did
+need to zonk `body` before performing the substitution above. See test case
+#14158, as well as the discussion in #23661.
-}
{- *********************************************************************
=====================================
compiler/GHC/Utils/Binary.hs
=====================================
@@ -1240,13 +1240,13 @@ putBS :: BinHandle -> ByteString -> IO ()
putBS bh bs =
BS.unsafeUseAsCStringLen bs $ \(ptr, l) -> do
put_ bh l
- putPrim bh l (\op -> BS.memcpy op (castPtr ptr) l)
+ putPrim bh l (\op -> copyBytes op (castPtr ptr) l)
getBS :: BinHandle -> IO ByteString
getBS bh = do
l <- get bh :: IO Int
BS.create l $ \dest -> do
- getPrim bh l (\src -> BS.memcpy dest src l)
+ getPrim bh l (\src -> copyBytes dest src l)
instance Binary ByteString where
put_ bh f = putBS bh f
=====================================
hadrian/src/Settings/Warnings.hs
=====================================
@@ -53,10 +53,12 @@ ghcWarningsArgs = do
, package primitive ? pure [ "-Wno-unused-imports"
, "-Wno-deprecations" ]
, package rts ? pure [ "-Wcpp-undef" ]
+ , package text ? pure [ "-Wno-deprecations" ]
, package terminfo ? pure [ "-Wno-unused-imports" ]
, package transformers ? pure [ "-Wno-unused-matches"
, "-Wno-unused-imports"
, "-Wno-redundant-constraints"
, "-Wno-orphans" ]
+ , package unix ? pure [ "-Wno-deprecations" ]
, package win32 ? pure [ "-Wno-trustworthy-safe" ]
, package xhtml ? pure [ "-Wno-unused-imports" ] ] ]
=====================================
libraries/bytestring
=====================================
@@ -1 +1 @@
-Subproject commit 9cab76dc861f651c3940e873ce921d9e09733cc8
+Subproject commit 602fd2f3470f180d64cb8baadf63e94baec66b60
=====================================
nofib
=====================================
@@ -1 +1 @@
-Subproject commit 2cee92861c43ac74154bbd155a83f9f4ad0b9f2f
+Subproject commit 274cc3f7479431e3a52c78840b3daee887e0414f
=====================================
rts/Updates.h
=====================================
@@ -12,6 +12,347 @@
#include "BeginPrivate.h"
#endif
+/* Note [Thunks, blackholes, and indirections]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Consider the following STG binding:
+ *
+ * thnk = {fv_0, fv_1} \u [] g x y;
+ *
+ * This binding is a updatable thunk carrying free variables `fv_0` and `fv_1`.
+ * Over its lifetime, this closure may transition through three states:
+ *
+ * 1. it starts life as a thunk, which carries with it free variables
+ * 2. if a thread enters it, it may turn into a blackhole
+ * 3. if evaluation finishes, it will be "updated", turning it into an
+ * indirection pointing to the result of the evaluation
+ *
+ * On the heap, state (1) is represented as a closure with the following layout
+ * (embodied in the C runtime by the `StgThunk` struct):
+ *
+ * thnk
+ * ┌───────────────────────┐ ╮
+ * │ blah_info │ │
+ * ├────────────┬──────────┤ │ StgThunkHeader
+ * │ indirectee │ NULL │ │
+ * ├────────────┼──────────┤ ╯
+ * │ payload[0] │ fv_0 │
+ * ├────────────┼──────────┤
+ * │ payload[1] │ fv_1 │
+ * └────────────┴──────────┘
+ *
+ * Here `blah_info` is a pointer to the thunk's info table, which will be of
+ * type THUNK. The `indirectee` field (also known as the "SMP header") is
+ * initially NULL and is unused while the closure remains a thunk. However, as
+ * we will see, it will eventually point to the result of the thunk's
+ * evaluation.
+ *
+ *
+ * Entry
+ * -----
+ * As usual, to enter `thnk` (step (2) of the lifetime) a mutator thread
+ * `tso_0` will jump to its entry code (which is recorded in or next to its
+ * info table, depending upon whether tables-next-to-code is enabled). This
+ * entry code will push an "update frame" (namely, either `stg_upd_frame` or
+ * `stg_bh_upd_frame`) to `tso_0`'s stack and begin the evaluation of the
+ * thunk's RHS.
+ *
+ * However, before commencing evaluation, the entry code may also mark the
+ * thunk as being under evaluation; this process is known a "blackholing".
+ * Whether this happens depends upon which of GHC's two blackholing strategies
+ * which was selected during the compilation of the defining module. We will
+ * discuss the simpler "eager blackholing" case first and later introduce the
+ * more-efficient "lazy blackholing" strategy.
+ *
+ *
+ * Eager blackholing
+ * -----------------
+ * Under the eager blackholing strategy (which is enabled via the
+ * `-feager-blackholing` flag), a thunk's entry code (generated by
+ * `GHC.StgToCmm.Bind.emitBlackHoleCode`) will immediately turn the thunk into
+ * a blackhole, indicating that the thunk is under evaluation. Additionally,
+ * the indirectee field will be updated to point to the thread performing the
+ * evaluation, `tso_0`. Since we know statically that the thunk is now a
+ * `BLACKHOLE`, the thunk entry code will push an `stg_bh_upd_frame` to the
+ * stack in this case (in contrast to the lazy strategy, as we will see later).
+ *
+ * After this, `thnk` will look like,
+ *
+ * thnk
+ * ┌───────────────────────┐
+ * │ EAGER_BLACKHOLE_info │
+ * ├────────────┬──────────┤ tso_0
+ * │ indirectee │ tso_0 │─────────►┌──────┐
+ * ├────────────┼──────────┤ │ ... │
+ * │ payload[0] │ fv_0 │ └──────┘
+ * ├────────────┼──────────┤
+ * │ payload[1] │ fv_1 │
+ * └────────────┴──────────┘
+ *
+ * Note that blackholing in this way does not guarantee mutual exclusion: two
+ * threads may indeed race to enter `thnk`. This will result in both threads
+ * performing evaluation and, in some cases, the blackhole being updated
+ * multiple times.
+ *
+ *
+ * Updating a thunk
+ * ----------------
+ * When `tso_0` finishes the evaluation of `thnk`, it will return to the entry
+ * code of the update frame pushed when the thunk was entered (e.g.
+ * `stg_bh_upd_frame`). This code first checks whether the blackhole
+ * has already been updated by another thread; if it has then `tso_0` will
+ * throw out its result and reuse that which the earlier thread recorded in the
+ * blackhole's `indirectee` field.
+ *
+ * If the blackhole has not yet been updated then `tso_0` will:
+ *
+ * 2A. set `thnk`'s `indirectee` field to point to the result of its
+ * evaluation, and
+ * 2B. set its info table to `BLACKHOLE_info`
+ *
+ * N.B. You might notice that step (2B) here appears to be redundant as we
+ * already set the info table pointer to `EAGER_BLACKHOLE_info` above. However,
+ * as we will see below, this may not be the case when lazy blackholing is in
+ * use.
+ *
+ * After these updates, we will have the following:
+ *
+ * thnk
+ * ┌───────────────────────┐
+ * │ BLACKHOLE_info │
+ * ├────────────┬──────────┤ result
+ * │ indirectee │ result │─────────►┌────────┐
+ * ├────────────┼──────────┤ │ ... │
+ * │ payload[0] │ fv_0 │ └────────┘
+ * ├────────────┼──────────┤
+ * │ payload[1] │ fv_1 │
+ * └────────────┴──────────┘
+ *
+ * In addition, the code will check the blocking queues that were added to the
+ * blackhole (recorded in the `indirectee` field, as we will see below) and
+ * wake them up (see `Threads.c:updateThunk`).
+ *
+ * Note that we are using `BLACKHOLE_info` to represent two distinct states of
+ * a thunk:
+ *
+ * - if the indirectee points to a `TSO` or `BLOCKING_QUEUE`, then the
+ * `BLACKHOLE` represents a thunk currently being evaluated
+ *
+ * - otherwise `BLACKHOLE` is merely representing an evaluated thunk and
+ * serves as an indirection to the final result.
+ *
+ * This overloading may seem odd given that we also have `stg_IND_info`, which
+ * also represents an indirection. However, the overloading serves a purpose:
+ * it means that safely updating a blackhole (step (3) of the lifetime above)
+ * requires only a single store (namely the store to the `indirectee` field).
+ *
+ * If we were to instead use `stg_IND` to represent the updated thunk, we would
+ * require two stores and consequently have an awkward period where the info
+ * table and indirectee fields are inconsistent:
+ *
+ * - if we were to update the info table first, there would be a period where
+ * the `indirectee` field pointed to the TSO which did the evaluation and
+ * not the result as one would expect.
+ *
+ * - if we were to update the indirectee first, there would be a period where
+ * the closure is still a `BLACKHOLE_info` yet the indirectee points to the
+ * evaluation result.
+ *
+ * For this reason, it is simpler to use `BLACKHOLE` to represent both states
+ * (2) and (3), distinguishing them using the identity of the indirectee. The
+ * uses of `stg_IND` are few and will be discussed below.
+ *
+ *
+ * Lazy blackholing
+ * ----------------
+ * While the strict blackholing strategy described above is simple and is
+ * faithful to the semantics of the STG machine, it is fairly costly on modern
+ * hardware. Specifically, thunk entry can be extremely common and in a
+ * parallel program blackholing may induce considerable pressure on the
+ * machine's memory subsystem.
+ *
+ * To mitigate this, GHC uses a lazy blackholing strategy by default. Here we
+ * take advantage of the fact that redundant evaluation of a thunk is
+ * acceptable, and defer blackholing until the thread returns to the scheduler.
+ * This is an optimisation, because we will often finish evaluation *before*
+ * yielding; in this case we avoid incurring the memory writes necessary to
+ * blackhole the thunk (step (2)), and rather update the thunk straight to an
+ * indirection.
+ *
+ * When entering a thunk compiled with lazy blackholing, we push an
+ * `stg_upd_frame` (not `stg_upd_bh_frame`) frame to the stack and do not
+ * modify the thunk closure itself.
+ *
+ * If the thread yields before finishing evaluation, the thunk will be turned
+ * into a `BLACKHOLE` in `ThreadPaused.c:threadPaused`. This function traverses
+ * the stack of the yielding thread looking for update frames; when such a
+ * frame is encountered, it checks the info table of the updatee and:
+ *
+ * - if it is `BLACKHOLE`, then the thunk has already been claimed for evaluation
+ * by another thread, and the yielding thread is instead added to the
+ * `BLACKHOLE`'s blocking queue (see Note [suspend duplicate work] in
+ * `ThreadPaused.c`).
+ *
+ * - if not, then it blackholes the thunk as done in eager blackholing (but
+ * using the `BLACKHOLE_info` info table instead of `EAGER_BLACKHOLE_info`).
+ *
+ * Update frames processed in this manner are rewritten to become
+ * `stg_marked_upd_frame`s. The stack traversal continues until a
+ * `stg_marked_upd_frame_info` frame is encountered, at which point we know
+ * that all subsequent frames have already been processed in a previous yield.
+ *
+ * The entry code of `stg_upd_frame` is considerably simpler than that of
+ * `stg_bh_upd_frame` since we know that the thunk has not accumulated any
+ * `BLOCKING_QUEUE`s in need of waking (since it was never blackhole'd). This
+ * is itself a small optimisation for the common case of uncontended thunk
+ * update. By contrast, the entry code of `stg_marked_upd_frame` is identical
+ * to that of `stg_bh_upd_frame` and must deal with waking of blocked threads.
+ *
+ * See `Note [suspend duplicate work]` in `ThreadPaused.c` for a subtle case
+ * involving the interaction between lazy and eager blackholing.
+ *
+ * See `Note [upd-black-hole]` in `Scav.c` for another subtle case.
+ *
+ *
+ * Blocking on a blackhole'd thunk
+ * -------------------------------
+ * If another thread `tso_1` enters `thnk` while it is blackholed by `tso_0`,
+ * the entry code of `BLACKHOLE` will allocate a `MSG_BLACKHOLE` object
+ * `msg_bh_0`. This message will be sent to the capability where the thread
+ * owning the thunk resides (see `Messages.c:messageBlackHole`). This
+ * capability will allocate a `BLOCKING_QUEUE` object `bq_0` recording the fact
+ * that `tso_1` is waiting for the result of `thnk`'s evaluation, and link it to
+ * `thnk` as follows:
+ *
+ * thnk
+ * ┌─►┌───────────────────────┐
+ * │ │ EAGER_BLACKHOLE_info │
+ * │ ├────────────┬──────────┤
+ * │ │ indirectee │ bq_0 ├──────┐
+ * │ ├────────────┼──────────┤ │
+ * │ │ payload[0] │ fv_0 │ │
+ * │ ├────────────┼──────────┤ │
+ * │ │ payload[1] │ fv_1 │ │
+ * │ └────────────┴──────────┘ │
+ * │ │ msg_bh_0
+ * │ ┌───────────────────────────┘ ┌──►┌───────────────────────────┐
+ * │ │ │ │ MSG_BLACKHOLE_info │
+ * │ │ │ ├───────────┬───────────────┤
+ * │ │ bq_0 │ │ link │ END_TSO_QUEUE │
+ * │ └─►┌──────────────────────┐ │ ├───────────┼───────────────┤
+ * │ │ BLOCKING_QUEUE_info │ │ │ result │ NULL │
+ * │ ├───────────┬──────────┤ │ ├───────────┼───────────────┤ tso_1
+ * │ │ link │ NULL │ │ │ tso │ tso_1 ├────►┌──────┐
+ * │ ├───────────┼──────────┤ │ └───────────┴───────────────┘ │ ... │
+ * │ │ queue │ msg_bh_0 ├────┘ └──────┘
+ * │ ├───────────┼──────────┤ tso_0
+ * │ │ owner │ tso_0 ├───────►┌──────┐
+ * │ ├───────────┼──────────┤ │ ... │
+ * │ │ bh │ thnk ├────┐ └──────┘
+ * │ └───────────┴──────────┘ │
+ * │ │
+ * └────────────────────────────────────┘
+ *
+ * Additionally, the `BLOCKING_QUEUE` is added to the `bq` list of the owning
+ * TSO, which collects all blocking queue objects which are blocked on thunks
+ * owned by the thread.
+ *
+ * In addition to this book-keeping, the `MSG_BLACKHOLE` message results in
+ * `tso_0` being promoted in its capability's run queue in the hope that
+ * `tso_1` and other blocked threads may be unblocked more quickly.
+ *
+ *
+ * Exception handling
+ * ------------------
+ * When an exception is thrown to a thread which is evaluating a thunk, it is
+ * important that we put things back into a state in which evaluation can
+ * be resumed by another thread. This is done by
+ * `RaiseAsync.c:raiseAsync` which walks the stack looking for update
+ * frames and rewrites the updatees into indirections pointing to an
+ * `AP_STACK` closure recording the aborted execution state.
+ * See `RaiseAsync.c:raiseAsync` for details.
+ *
+ *
+ * CAFs
+ * ----
+ * Top-level thunks (CAFs) reuse much of this machinery. The only differences
+ * are:
+ *
+ * - CAF entry ensures mutual exclusion (see `Note [atomic CAF entry]`
+ * in `Storage.c` for why)
+ *
+ * - we have a distinct blackhole type, `stg_CAF_BLACKHOLE_info`; it is not
+ * clear that maintaining this distinction from `stg_EAGER_BLACKHOLE_info`
+ * is strictly necessary.
+ *
+ * See `Note [CAF management]` in `Storage.c` .
+ *
+ *
+ * Memory ordering
+ * ---------------
+ * The memory orderings necessary for safe concurrent thunk evaluation
+ * are rather subtle and described in Note [Heap memory barriers] in `SMP.h`.
+ *
+ *
+ * The uses of `stg_IND`
+ * ---------------------
+ * As noted above, `stg_IND_info` is not used for thunk evaluation. Instead, it
+ * merely serves as a general-purpose indirection in a few miscellaneous cases:
+ *
+ * * it is used to "short-out" `BLOCKING_QUEUE`s and `MVAR_TSO_QUEUES` that have
+ * already been woken-up. See Note [BLACKHOLE pointing to IND] in `Evac.c`.
+ *
+ * * It is used to perform indirection of selector thunks (see
+ * `Evac.c:unchain_thunk_selectors`).
+ *
+ *
+ * Indirection shortcutting
+ * ------------------------
+ * Note that the garbage collector can "shortcut" both `IND` and
+ * `BLACKHOLE` indirections. That is, the heap:
+ *
+ * ref
+ * ┌──────────┐ evald_thunk
+ * │ ├────────►┌───────────────┬──────┐
+ * └──────────┘ │ stg_IND_info │ │
+ * ├───────────────┼──────┤ x
+ * │ indirectee │ ├────────►┌──────────────┐
+ * └───────────────┴──────┘ │ ... │
+ * │ │
+ * └──────────────┘
+ * Can be rewritten to:
+ *
+ * ref ┌────────────────────────────────────┐
+ * ┌──────────┐ │ evald_thunk │
+ * │ ├────┘ ┌───────────────┬──────┐ │
+ * └──────────┘ │ stg_IND_info │ │ │
+ * ├───────────────┼──────┤ ▼ x
+ * │ indirectee │ ├────────►┌──────────────┐
+ * └───────────────┴──────┘ │ ... │
+ * │ │
+ * └──────────────┘
+ *
+ *
+ * Selector optimisation
+ * ---------------------
+ * In addition to shortcutting indirections, the garbage collector can do a
+ * limited form of evaluation known as the "selector optimisation"
+ * [Wadler1987]. Specifically, the GC knows to rewrite a certain class of thunk
+ * (so-called "selector thunks", which are applications of selector functions
+ * like `fst`) into their result. For instance, given
+ *
+ * x = (a,b)
+ * y = fst x
+ *
+ * the GC can rewrite `y` into an indirection to `a`. References to `y` can
+ * then be further shortcutted via indirection shortcutting as described above.
+ *
+ *
+ * [Wadler1987]:
+ * Wadler, P. (1987), Fixing some space leaks with a garbage collector.
+ * Softw: Pract. Exper., 17: 595-608. https://doi.org/10.1002/spe.4380170904
+ */
+
+
/* -----------------------------------------------------------------------------
Updates
-------------------------------------------------------------------------- */
=====================================
testsuite/tests/ghci/scripts/T9881.stdout
=====================================
@@ -19,19 +19,19 @@ instance Ord Data.ByteString.Lazy.ByteString
type Data.ByteString.ByteString :: *
data Data.ByteString.ByteString
- = bytestring-0.11.4.0:Data.ByteString.Internal.Type.BS {-# UNPACK #-}(GHC.ForeignPtr.ForeignPtr
+ = bytestring-0.11.5.1:Data.ByteString.Internal.Type.BS {-# UNPACK #-}(GHC.ForeignPtr.ForeignPtr
GHC.Word.Word8)
{-# UNPACK #-}Int
- -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’
+ -- Defined in ‘bytestring-0.11.5.1:Data.ByteString.Internal.Type’
instance Monoid Data.ByteString.ByteString
- -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’
+ -- Defined in ‘bytestring-0.11.5.1:Data.ByteString.Internal.Type’
instance Read Data.ByteString.ByteString
- -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’
+ -- Defined in ‘bytestring-0.11.5.1:Data.ByteString.Internal.Type’
instance Semigroup Data.ByteString.ByteString
- -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’
+ -- Defined in ‘bytestring-0.11.5.1:Data.ByteString.Internal.Type’
instance Show Data.ByteString.ByteString
- -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’
+ -- Defined in ‘bytestring-0.11.5.1:Data.ByteString.Internal.Type’
instance Eq Data.ByteString.ByteString
- -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’
+ -- Defined in ‘bytestring-0.11.5.1:Data.ByteString.Internal.Type’
instance Ord Data.ByteString.ByteString
- -- Defined in ‘bytestring-0.11.4.0:Data.ByteString.Internal.Type’
+ -- Defined in ‘bytestring-0.11.5.1:Data.ByteString.Internal.Type’
=====================================
testsuite/tests/ghci/scripts/ghci025.stdout
=====================================
@@ -54,7 +54,7 @@ Prelude.length :: Data.Foldable.Foldable t => t a -> GHC.Types.Int
type T.Integer :: *
data T.Integer = ...
T.length ::
- bytestring-0.11.4.0:Data.ByteString.Internal.Type.ByteString
+ bytestring-0.11.5.1:Data.ByteString.Internal.Type.ByteString
-> GHC.Types.Int
:browse! T
-- defined locally
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/641762b16dabbd35b26847560a47c88542dfd8b9...515962908307547e47fc9c94f7f776c6e8ecd259
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/641762b16dabbd35b26847560a47c88542dfd8b9...515962908307547e47fc9c94f7f776c6e8ecd259
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/20230804/cd9dda5c/attachment-0001.html>
More information about the ghc-commits
mailing list