Copyright | (c) 2012 Joachim Breitner |
---|---|
License | BSD3 |
Maintainer | Joachim Breitner <mail@joachim-breitner.de> |
Safe Haskell | Ignore |
Language | GHC2021 |
With this module, you can investigate the heap representation of Haskell values, i.e. to investigate sharing and lazy evaluation.
Synopsis
- type Closure = GenClosure Box
- data GenClosure b
- = ConstrClosure { }
- | FunClosure {
- info :: !StgInfoTable
- ptrArgs :: ![b]
- dataArgs :: ![Word]
- | ThunkClosure {
- info :: !StgInfoTable
- ptrArgs :: ![b]
- dataArgs :: ![Word]
- | SelectorClosure {
- info :: !StgInfoTable
- selectee :: !b
- | PAPClosure { }
- | APClosure { }
- | APStackClosure {
- info :: !StgInfoTable
- fun :: !b
- payload :: ![b]
- | IndClosure {
- info :: !StgInfoTable
- indirectee :: !b
- | BCOClosure { }
- | BlackholeClosure {
- info :: !StgInfoTable
- indirectee :: !b
- | ArrWordsClosure { }
- | MutArrClosure {
- info :: !StgInfoTable
- mccPtrs :: !Word
- mccSize :: !Word
- mccPayload :: ![b]
- | SmallMutArrClosure {
- info :: !StgInfoTable
- mccPtrs :: !Word
- mccPayload :: ![b]
- | MVarClosure {
- info :: !StgInfoTable
- queueHead :: !b
- queueTail :: !b
- value :: !b
- | IOPortClosure {
- info :: !StgInfoTable
- queueHead :: !b
- queueTail :: !b
- value :: !b
- | MutVarClosure {
- info :: !StgInfoTable
- var :: !b
- | BlockingQueueClosure { }
- | WeakClosure {
- info :: !StgInfoTable
- cfinalizers :: !b
- key :: !b
- value :: !b
- finalizer :: !b
- weakLink :: !(Maybe b)
- | TSOClosure {
- info :: !StgInfoTable
- link :: !b
- global_link :: !b
- tsoStack :: !b
- trec :: !b
- blocked_exceptions :: !b
- bq :: !b
- thread_label :: !(Maybe b)
- what_next :: !WhatNext
- why_blocked :: !WhyBlocked
- flags :: ![TsoFlags]
- threadId :: !Word64
- saved_errno :: !Word32
- tso_dirty :: !Word32
- alloc_limit :: !Int64
- tot_stack_size :: !Word32
- prof :: !(Maybe StgTSOProfInfo)
- | StackClosure {
- info :: !StgInfoTable
- stack_size :: !Word32
- stack_dirty :: !Word8
- stack_marking :: !Word8
- | IntClosure { }
- | WordClosure { }
- | Int64Closure { }
- | Word64Closure { }
- | AddrClosure { }
- | FloatClosure { }
- | DoubleClosure { }
- | OtherClosure {
- info :: !StgInfoTable
- hvalues :: ![b]
- rawWords :: ![Word]
- | UnsupportedClosure {
- info :: !StgInfoTable
- | UnknownTypeWordSizedPrimitive { }
- data ClosureType
- = INVALID_OBJECT
- | CONSTR
- | CONSTR_1_0
- | CONSTR_0_1
- | CONSTR_2_0
- | CONSTR_1_1
- | CONSTR_0_2
- | CONSTR_NOCAF
- | FUN
- | FUN_1_0
- | FUN_0_1
- | FUN_2_0
- | FUN_1_1
- | FUN_0_2
- | FUN_STATIC
- | THUNK
- | THUNK_1_0
- | THUNK_0_1
- | THUNK_2_0
- | THUNK_1_1
- | THUNK_0_2
- | THUNK_STATIC
- | THUNK_SELECTOR
- | BCO
- | AP
- | PAP
- | AP_STACK
- | IND
- | IND_STATIC
- | RET_BCO
- | RET_SMALL
- | RET_BIG
- | RET_FUN
- | UPDATE_FRAME
- | CATCH_FRAME
- | UNDERFLOW_FRAME
- | STOP_FRAME
- | BLOCKING_QUEUE
- | BLACKHOLE
- | MVAR_CLEAN
- | MVAR_DIRTY
- | TVAR
- | ARR_WORDS
- | MUT_ARR_PTRS_CLEAN
- | MUT_ARR_PTRS_DIRTY
- | MUT_ARR_PTRS_FROZEN_DIRTY
- | MUT_ARR_PTRS_FROZEN_CLEAN
- | MUT_VAR_CLEAN
- | MUT_VAR_DIRTY
- | WEAK
- | PRIM
- | MUT_PRIM
- | TSO
- | STACK
- | TREC_CHUNK
- | ATOMICALLY_FRAME
- | CATCH_RETRY_FRAME
- | CATCH_STM_FRAME
- | WHITEHOLE
- | SMALL_MUT_ARR_PTRS_CLEAN
- | SMALL_MUT_ARR_PTRS_DIRTY
- | SMALL_MUT_ARR_PTRS_FROZEN_DIRTY
- | SMALL_MUT_ARR_PTRS_FROZEN_CLEAN
- | COMPACT_NFDATA
- | CONTINUATION
- | N_CLOSURE_TYPES
- data PrimType
- data WhatNext
- data WhyBlocked
- data TsoFlags
- class HasHeapRep (a :: TYPE rep) where
- getClosureData :: a -> IO Closure
- getClosureDataFromHeapRep :: ByteArray# -> Ptr StgInfoTable -> [b] -> IO (GenClosure b)
- getClosureDataFromHeapRepPrim :: IO (String, String, String) -> (Ptr a -> IO (Maybe CostCentreStack)) -> StgInfoTable -> ByteArray# -> [b] -> IO (GenClosure b)
- data StgInfoTable = StgInfoTable {}
- type EntryFunPtr = FunPtr (Ptr () -> IO (Ptr ()))
- type HalfWord = Word32
- type ItblCodes = Either [Word8] [Word32]
- itblSize :: Int
- peekItbl :: Ptr StgInfoTable -> IO StgInfoTable
- pokeItbl :: Ptr StgInfoTable -> StgInfoTable -> IO ()
- newtype StgTSOProfInfo = StgTSOProfInfo {}
- data IndexTable = IndexTable {}
- data CostCentre = CostCentre {}
- data CostCentreStack = CostCentreStack {
- ccs_ccsID :: Int
- ccs_cc :: CostCentre
- ccs_prevStack :: Maybe CostCentreStack
- ccs_indexTable :: Maybe IndexTable
- ccs_root :: Maybe CostCentreStack
- ccs_depth :: Word
- ccs_scc_count :: Word64
- ccs_selected :: Word
- ccs_time_ticks :: Word
- ccs_mem_alloc :: Word64
- ccs_inherited_alloc :: Word64
- ccs_inherited_ticks :: Word
- getBoxedClosureData :: Box -> IO Closure
- allClosures :: GenClosure b -> [b]
- data Box = Box Any
- asBox :: a -> Box
- areBoxesEqual :: Box -> Box -> IO Bool
Closure types
type Closure = GenClosure Box Source #
data GenClosure b Source #
This is the representation of a Haskell value on the heap. It reflects https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/storage/Closures.h
The data type is parametrized by b
: the type to store references in.
Usually this is a Box
with the type synonym Closure
.
All Heap objects have the same basic layout. A header containing a pointer to
the info table and a payload with various fields. The info
field below
always refers to the info table pointed to by the header. The remaining
fields are the payload.
See https://gitlab.haskell.org/ghc/ghc/wikis/commentary/rts/storage/heap-objects for more information.
ConstrClosure | A data constructor |
FunClosure | A function |
| |
ThunkClosure | A thunk, an expression not obviously in head normal form |
| |
SelectorClosure | A thunk which performs a simple selection operation |
| |
PAPClosure | An unsaturated function application |
| |
APClosure | A function application |
| |
APStackClosure | A suspended thunk evaluation |
| |
IndClosure | A pointer to another closure, introduced when a thunk is updated to point at its value |
| |
BCOClosure | A byte-code object (BCO) which can be interpreted by GHC's byte-code interpreter (e.g. as used by GHCi) |
| |
BlackholeClosure | A thunk under evaluation by another thread |
| |
ArrWordsClosure | A |
MutArrClosure | A |
| |
SmallMutArrClosure | A Since: 8.10.1 |
| |
MVarClosure | An |
| |
IOPortClosure | An |
| |
MutVarClosure | A |
| |
BlockingQueueClosure | An STM blocking queue. |
WeakClosure | |
| |
TSOClosure | Representation of StgTSO: A Thread State Object. The values for
|
| |
StackClosure | Representation of StgStack: The 'tsoStack ' of a |
| |
IntClosure | Primitive Int |
WordClosure | Primitive Word |
Int64Closure | Primitive Int64 |
Word64Closure | Primitive Word64 |
AddrClosure | Primitive Addr |
FloatClosure | Primitive Float |
DoubleClosure | Primitive Double |
OtherClosure | Another kind of closure |
| |
UnsupportedClosure | |
| |
UnknownTypeWordSizedPrimitive | A primitive word from a bitmap encoded stack frame payload The type itself cannot be restored (i.e. it might represent a Word8# or an Int#). |
Instances
data ClosureType Source #
Instances
Instances
Generic PrimType Source # | |
Show PrimType Source # | |
Binary PrimType Source # | |
Eq PrimType Source # | |
Ord PrimType Source # | |
Defined in GHC.Exts.Heap.Closures | |
type Rep PrimType Source # | |
Defined in GHC.Exts.Heap.Closures type Rep PrimType = D1 ('MetaData "PrimType" "GHC.Exts.Heap.Closures" "ghc-lib-parser-9.10.1.20240511-FCOK3MWDKkc1AE2Ll0xWIs" 'False) ((C1 ('MetaCons "PInt" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "PWord" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "PInt64" 'PrefixI 'False) (U1 :: Type -> Type))) :+: ((C1 ('MetaCons "PWord64" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "PAddr" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "PFloat" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "PDouble" 'PrefixI 'False) (U1 :: Type -> Type)))) |
ThreadRunGHC | |
ThreadInterpret | |
ThreadKilled | |
ThreadComplete | |
WhatNextUnknownValue Word16 | Please report this as a bug |
Instances
Generic WhatNext Source # | |
Show WhatNext Source # | |
Binary WhatNext Source # | |
Eq WhatNext Source # | |
Ord WhatNext Source # | |
Defined in GHC.Exts.Heap.Closures | |
type Rep WhatNext Source # | |
Defined in GHC.Exts.Heap.Closures type Rep WhatNext = D1 ('MetaData "WhatNext" "GHC.Exts.Heap.Closures" "ghc-lib-parser-9.10.1.20240511-FCOK3MWDKkc1AE2Ll0xWIs" 'False) ((C1 ('MetaCons "ThreadRunGHC" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "ThreadInterpret" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "ThreadKilled" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "ThreadComplete" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "WhatNextUnknownValue" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Word16))))) |
data WhyBlocked Source #
Instances
TsoLocked | |
TsoBlockx | |
TsoInterruptible | |
TsoStoppedOnBreakpoint | |
TsoMarked | |
TsoSqueezed | |
TsoAllocLimit | |
TsoFlagsUnknownValue Word32 | Please report this as a bug |
Instances
class HasHeapRep (a :: TYPE rep) where Source #
Decode a closure to it's heap representation (GenClosure
).
Instances
getClosureDataFromHeapRep :: ByteArray# -> Ptr StgInfoTable -> [b] -> IO (GenClosure b) Source #
Convert an unpacked heap object, to a `GenClosure b`. The inputs to this
function can be generated from a heap object using unpackClosure#
.
getClosureDataFromHeapRepPrim Source #
:: IO (String, String, String) | A continuation used to decode the constructor description field, in ghc-debug this code can lead to segfaults because dataConNames will dereference a random part of memory. |
-> (Ptr a -> IO (Maybe CostCentreStack)) | A continuation which is used to decode a cost centre stack
In ghc-debug, this code will need to call back into the debuggee to
fetch the representation of the CCS before decoding it. Using
|
-> StgInfoTable | The |
-> ByteArray# | Heap representation of the closure as returned by |
-> [b] | Pointers in the payload of the closure, extracted from the heap
representation as returned by `collect_pointers()` in |
-> IO (GenClosure b) | Heap representation of the closure. |
Info Table types
data StgInfoTable Source #
This is a somewhat faithful representation of an info table. See https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/storage/InfoTables.h for more details on this data structure.
Instances
peekItbl :: Ptr StgInfoTable -> IO StgInfoTable Source #
Read an InfoTable from the heap into a haskell type. WARNING: This code assumes it is passed a pointer to a "standard" info table. If tables_next_to_code is enabled, it will look 1 byte before the start for the entry field.
pokeItbl :: Ptr StgInfoTable -> StgInfoTable -> IO () Source #
Cost Centre (profiling) types
newtype StgTSOProfInfo Source #
This is a somewhat faithful representation of StgTSOProfInfo. See https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/storage/TSO.h for more details on this data structure.
Instances
data IndexTable Source #
This is a somewhat faithful representation of IndexTable. See https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/prof/CCS.h for more details on this data structure.
IndexTable | |
|
Instances
data CostCentre Source #
This is a somewhat faithful representation of CostCentre. See https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/prof/CCS.h for more details on this data structure.
Instances
data CostCentreStack Source #
This is a somewhat faithful representation of CostCentreStack. See https://gitlab.haskell.org/ghc/ghc/blob/master/rts/include/rts/prof/CCS.h for more details on this data structure.
Instances
Closure inspection
getBoxedClosureData :: Box -> IO Closure Source #
Like getClosureData
, but taking a Box
, so it is easier to work with.
allClosures :: GenClosure b -> [b] Source #
For generic code, this function returns all referenced closures.
Boxes
An arbitrary Haskell value in a safe Box. The point is that even
unevaluated thunks can safely be moved around inside the Box, and when
required, e.g. in getBoxedClosureData
, the function knows how far it has
to evaluate the argument.
This takes an arbitrary value and puts it into a box. Note that calls like
asBox (head list)
will put the thunk "head list" into the box, not the element at the head of the list. For that, use careful case expressions:
case list of x:_ -> asBox x