HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Modulebasement-0.0.16Haskell2010

Basement.Block.Mutable

A block of memory that contains elements of a type, very similar to an unboxed array but with the key difference:

  • It doesn't have slicing capability (no cheap take or drop)

  • It consume less memory: 1 Offset, 1 CountOf, 1 Pinning status trimmed

  • It's unpackable in any constructor

  • It uses unpinned memory by default

It should be rarely needed in high level API, but in lowlevel API or some data structure containing lots of unboxed array that will benefit from optimisation.

Because it's unpinned, the blocks are compactable / movable, at the expense of making them less friendly to interop with the C layer as address.

Note that sadly the bytearray primitive type automatically create a pinned bytearray if the size is bigger than a certain threshold

GHC Documentation associated:

includesrtsstorage/Block.h * LARGE_OBJECT_THRESHOLD ((uint32_t)(BLOCK_SIZE * 8 / 10)) * BLOCK_SIZE (1<<BLOCK_SHIFT)

includesrtsConstant.h * BLOCK_SHIFT 12

  • 2 types
  • 24 values
  • Packagebasement-0.0.16
  • Exports26
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceMutable.hs
datadata Block ty
#

A block of memory containing unpacked bytes representing values of type ty

Constructors

Instances17IsList, Eq, Data, Ord, Show, Semigroup, …
valuewithMutablePtr
  1. :: PrimMonad prim
  2. => MutableBlock ty (PrimState prim)
  3. -> Ptr ty -> prim a
  4. -> prim a
#

Create a pointer on the beginning of the MutableBlock and call a function f.

The mutable block can be mutated by the f function and the change will be reflected in the mutable block

If the mutable block is unpinned, a trampoline buffer is created and the data is only copied when f return.

it is all-in-all highly inefficient as this cause 2 copies

valuewithMutablePtrHint
  1. :: PrimMonad prim
  2. => Bool

    hint that the buffer doesn't need to have the same value as the mutable block when calling f

  3. -> Bool

    hint that the buffer is not supposed to be modified by call of f

  4. -> MutableBlock ty (PrimState prim)
  5. -> (Ptr ty -> prim a)
  6. -> prim a
#

Same as withMutablePtr but allow to specify 2 optimisations which is only useful when the MutableBlock is unpinned and need a pinned trampoline to be called safely.

If skipCopy is True, then the first copy which happen before the call to f, is skipped. The Ptr is now effectively pointing to uninitialized data in a new mutable Block.

If skipCopyBack is True, then the second copy which happen after the call to f, is skipped. Then effectively in the case of a trampoline being used the memory changed by f will not be reflected in the original Mutable Block.

If using the wrong parameters, it will lead to difficult to debug issue of corrupted buffer which only present themselves with certain Mutable Block that happened to have been allocated unpinned.

If unsure use withMutablePtr, which default to *not* skip any copy.

valuenew
  1. :: (PrimMonad prim, PrimType ty)
  2. => CountOf ty
  3. -> prim (MutableBlock ty (PrimState prim))
#

Create a new unpinned mutable block of a specific N size of ty elements

If the size exceeds a GHC-defined threshold, then the memory will be pinned. To be certain about pinning status with small size, use newPinned

valueunsafeWrite
  1. :: (PrimMonad prim, PrimType ty)
  2. => MutableBlock ty (PrimState prim)
  3. -> Offset ty
  4. -> ty
  5. -> prim ()
#

write to a cell in a mutable block without bounds checking.

Writing with invalid bounds will corrupt memory and your program will become unreliable. use write if unsure.

valueunsafeFreeze
  1. :: PrimMonad prim
  2. => MutableBlock ty (PrimState prim)
  3. -> prim (Block ty)
#

Freeze a mutable block into a block.

If the mutable block is still use after freeze, then the modification will be reflected in an unexpected way in the Block.

Foreign

2 declarations
valuecopyFromPtr
  1. :: (PrimMonad prim, PrimType ty)
  2. => Ptr ty

    Source Ptr of ty to start of memory

  3. -> MutableBlock ty (PrimState prim)

    Destination mutable block

  4. -> Offset ty

    Start offset in the destination mutable block

  5. -> CountOf ty

    Number of ty elements

  6. -> prim ()
#

Copy from a pointer, count elements, into the Mutable Block at a starting offset ofs

if the source pointer is invalid (size or bad allocation), bad things will happen

valuecopyToPtr
  1. :: (PrimType ty, PrimMonad prim)
  2. => MutableBlock ty (PrimState prim)

    The source mutable block to copy

  3. -> Offset ty

    The source offset in the mutable block

  4. -> Ptr ty

    The destination address where the copy is going to start

  5. -> CountOf ty

    The number of bytes

  6. -> prim ()
#

Copy all the block content to the memory starting at the destination address

If the destination pointer is invalid (size or bad allocation), bad things will happen