Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Glasgow Haskell Compiler
GHC
Commits
74bf9bb5
Commit
74bf9bb5
authored
Dec 18, 2021
by
ase
Committed by
Marge Bot
Feb 16, 2022
Browse files
rts: document some closure types
parent
2c28620d
Pipeline
#47676
canceled with stages
in 32 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
rts/ClosureFlags.c
View file @
74bf9bb5
...
...
@@ -18,6 +18,8 @@ StgWord16 closure_flags[] = {
* to thunks.)
*/
/* See InfoTables.h for the meaning of these flags */
/* 0 1 2 4 5 6 7 8 */
/* HNF BTM NS THU MUT UPT SRT IND */
...
...
rts/include/rts/storage/ClosureTypes.h
View file @
74bf9bb5
...
...
@@ -18,6 +18,10 @@
* - the closure_type_names list in rts/Printer.c
*/
/* CONSTR/THUNK/FUN_$A_$B mean they have $A pointers followed by $B
* non-pointers in their payloads.
*/
/* Object tag 0 raises an internal error */
#define INVALID_OBJECT 0
#define CONSTR 1
...
...
rts/include/rts/storage/Closures.h
View file @
74bf9bb5
...
...
@@ -60,6 +60,7 @@ typedef struct {
// start of the info table. See
// https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/rts/storage/heap-objects#tables_next_to_code.
const
StgInfoTable
*
info
;
#if defined(PROFILING)
StgProfHeader
prof
;
#endif
...
...
@@ -78,62 +79,93 @@ typedef struct {
/* -----------------------------------------------------------------------------
Closure Types
For any given closure type (defined in InfoTables.h), there is a
corresponding structure defined below. The name of the structure
is obtained by concatenating the closure type with '_closure'
For any given closure type (defined in ClosureTypes.h), there is a
corresponding structure defined below.
-------------------------------------------------------------------------- */
/* All closures follow the generic format */
// Generic closure layout, all closures follow this format consisting of a
// header field and some payload
typedef
struct
StgClosure_
{
StgHeader
header
;
struct
StgClosure_
*
payload
[];
}
*
StgClosurePtr
;
// StgClosure defined in rts/Types.h
// Thunk closure, an unevaluated value
//
// Closure types: THUNK, THUNK_<X>_<Y>
typedef
struct
StgThunk_
{
StgThunkHeader
header
;
struct
StgClosure_
*
payload
[];
}
StgThunk
;
// A selector thunk, this represent an unevaluated applied record field
// selector, ie `fst pair`. The field offset is stored in the header.
//
// Closure types: THUNK_SELECTOR
typedef
struct
{
StgThunkHeader
header
;
StgClosure
*
selectee
;
}
StgSelector
;
/*
PAP payload contains pointers and non-pointers interleaved and we only have
one info table for PAPs (stg_PAP_info). To visit pointers in a PAP payload we
use the `fun`s bitmap. For a PAP with n_args arguments the first n_args bits
in the fun's bitmap tell us which payload locations contain pointers.
*/
// PAP, partially applied function
//
// PAP payload contains pointers and non-pointers interleaved and we only have
// one info table for PAPs (stg_PAP_info). To visit pointers in a PAP payload we
// use the `fun`s bitmap. For a PAP with n_args arguments the first n_args bits
// in the fun's bitmap tell us which payload locations contain pointers.
//
// Closure types: PAP
typedef
struct
{
StgHeader
header
;
StgHalfWord
arity
;
/*
zero
if it
is an AP
*/
StgHalfWord
n_args
;
StgClosure
*
fun
;
/* really
point
s
to a
fun */
StgHalfWord
arity
;
// number of arguments left to apply, if
zero
this
is an AP
closure
StgHalfWord
n_args
;
// number of applied arguments
StgClosure
*
fun
;
// guaranteed to
point to a
FUN closure
StgClosure
*
payload
[];
}
StgPAP
;
// AP, applied function
//
// Closure types: AP
typedef
struct
{
StgThunkHeader
header
;
StgHalfWord
arity
;
/* zero if it is an AP */
StgHalfWord
n_args
;
StgClosure
*
fun
;
/* really
point
s
to a
fun */
StgHalfWord
arity
;
// number of arguments left to apply, 0 for an AP closure
StgHalfWord
n_args
;
// number of arguments applied
StgClosure
*
fun
;
// guaranteed to
point to a
FUN closure
StgClosure
*
payload
[];
}
StgAP
;
// Paused evaluation, created
// - when async exceptions are thrown
// - when we have to abort thunk evaluation in threadPaused
//
// Closure types: AP_STACK
typedef
struct
{
StgThunkHeader
header
;
StgWord
size
;
/*
number of words in payload
*/
StgThunkHeader
header
;
StgWord
size
;
//
number of words in payload
StgClosure
*
fun
;
StgClosure
*
payload
[];
/
*
contains a chunk of *stack*
*/
StgClosure
*
payload
[];
/
/
contains a chunk of *stack*
}
StgAP_STACK
;
// Indirection to some other closure on the heap
//
// Closure types: IND
typedef
struct
{
StgHeader
header
;
StgClosure
*
indirectee
;
}
StgInd
;
// Static indirection, indirection to a statically allocated closure? or a the
// statically allocated thing itself?
//
// Closure types: IND_STATIC
typedef
struct
{
StgHeader
header
;
StgClosure
*
indirectee
;
...
...
@@ -143,6 +175,10 @@ typedef struct {
// see `newCAF` and Note [CAF lists] in rts/sm/Storage.h.
}
StgIndStatic
;
// A queue for blocking on things
//
// Closure types: BLOCKING_QUEUE
typedef
struct
StgBlockingQueue_
{
StgHeader
header
;
struct
StgBlockingQueue_
*
link
;
...
...
@@ -154,12 +190,22 @@ typedef struct StgBlockingQueue_ {
// holds TSOs blocked on `bh`
}
StgBlockingQueue
;
// An array of bytes, ie ByteArray# and MutableByteArray#
//
// Closure types: ARR_WORDS
typedef
struct
{
StgHeader
header
;
StgWord
bytes
;
StgWord
bytes
;
// number of bytes in payload
StgWord
payload
[];
}
StgArrBytes
;
// An array of heap objects, ie Array# v and MutableArray# v
//
// Closure types: MUT_ARR_PTRS_CLEAN, MUT_ARR_PTRS_DIRTY,
// MUT_ARR_PTRS_FROZEN_DIRTY, MUT_ARR_PTRS_FROZEN_CLEAN, MUT_VAR_CLEAN,
// MUT_VAR_DIRTY
typedef
struct
{
StgHeader
header
;
StgWord
ptrs
;
...
...
@@ -168,94 +214,175 @@ typedef struct {
// see also: StgMutArrPtrs macros in ClosureMacros.h
}
StgMutArrPtrs
;
// A small array of head objects, ie SmallArray# and MutableSmallArray#
//
// Closure types: SMALL_MUT_ARR_PTRS_CLEAN, SMALL_MUT_ARR_PTRS_DIRTY,
// SMALL_MUT_ARR_PTRS_FROZEN_DIRTY, SMALL_MUT_ARR_PTRS_FROZEN_CLEAN,
typedef
struct
{
StgHeader
header
;
StgWord
ptrs
;
StgClosure
*
payload
[];
}
StgSmallMutArrPtrs
;
// A mutable reference, ie MutVar#
//
// Closure types: MUT_VAR_CLEAN, MUT_VAR_DIRTY
typedef
struct
{
StgHeader
header
;
StgClosure
*
var
;
}
StgMutVar
;
// Stack frames
// ============
//
// See also StgStack in TSO.h
//
// These do not appear alone on the heap but always inside an StgStack or a
// StgAP_STACK.
// Stack frame
//
// Closure types: UPDATE_FRAME
typedef
struct
_StgUpdateFrame
{
StgHeader
header
;
StgClosure
*
updatee
;
}
StgUpdateFrame
;
// Stack frame, when we call catch one of these will be put on the stack so we
// know to handle exceptions with the supplied handler
//
// Closure types: CATCH_FRAME
typedef
struct
{
StgHeader
header
;
StgWord
exceptions_blocked
;
StgClosure
*
handler
;
}
StgCatchFrame
;
// Stack underflow frame, placed on the bottom of a stack chunk and links to
// the next chunk
//
// Closure types: UNDERFLOW_FRAME
typedef
struct
{
const
StgInfoTable
*
info
;
struct
StgStack_
*
next_chunk
;
}
StgUnderflowFrame
;
// Stack end frame, placed on the bottom of a stack chunk signifying the very
// bottom of the stack
//
// Closure types: STOP_FRAME
typedef
struct
{
StgHeader
header
;
}
StgStopFrame
;
// A function return stack frame: used when saving the state for a
// garbage collection at a function entry point. The function
// arguments are on the stack, and we also save the function (its
// info table describes the pointerhood of the arguments).
//
// The stack frame size is also cached in the frame for convenience.
//
// The only RET_FUN is stg_gc_fun, which is created by __stg_gc_fun,
// both in HeapStackCheck.cmm.
//
// Closure types: RET_FUN
typedef
struct
{
const
StgInfoTable
*
info
;
StgWord
size
;
StgClosure
*
fun
;
StgClosure
*
payload
[];
}
StgRetFun
;
// Int or charlike things, these are statically allocated in StgMiscClosures.h
//
// Closure type: CONSTR_0_1
typedef
struct
{
StgHeader
header
;
StgWord
data
;
}
StgIntCharlikeClosure
;
// Stable name, StableName# v
typedef
struct
_StgStableName
{
StgHeader
header
;
StgWord
sn
;
}
StgStableName
;
typedef
struct
_StgWeak
{
/* Weak v */
// A weak reference, Weak#
//
// Closure types: WEAK
typedef
struct
_StgWeak
{
StgHeader
header
;
StgClosure
*
cfinalizers
;
StgClosure
*
key
;
StgClosure
*
value
;
/* v */
StgClosure
*
value
;
// the actual value
StgClosure
*
finalizer
;
struct
_StgWeak
*
link
;
}
StgWeak
;
// Linked list of c function pointer finalisers for a weak reference
//
// See the addCFinalizerToWeak# primop where these are constructed.
//
// Closure type: CONSTR
typedef
struct
_StgCFinalizerList
{
StgHeader
header
;
StgClosure
*
link
;
StgClosure
*
link
;
// the next finaliser
// function to call
//
// Actual type is `void (*)(void* ptr)` or `void (*)(void* eptr, void* ptr)`
// depending on the flag field.
void
(
*
fptr
)(
void
);
void
*
ptr
;
void
*
eptr
;
StgWord
flag
;
/* has environment (0 or 1) */
void
*
ptr
;
// pointer to data
void
*
eptr
;
// pointer to environment
StgWord
flag
;
// has environment, 0: no environment, 1: yes environment
}
StgCFinalizerList
;
/* Byte code objects. These are fixed size objects with pointers to
* four arrays, designed so that a BCO can be easily "re-linked" to
* other BCOs, to facilitate GHC's intelligent recompilation. The
* array of instructions is static and not re-generated when the BCO
* is re-linked, but the other 3 arrays will be regenerated.
*
* A BCO represents either a function or a stack frame. In each case,
* it needs a bitmap to describe to the garbage collector the
* pointerhood of its arguments/free variables respectively, and in
* the case of a function it also needs an arity. These are stored
* directly in the BCO, rather than in the instrs array, for two
* reasons:
* (a) speed: we need to get at the bitmap info quickly when
* the GC is examining APs and PAPs that point to this BCO
* (b) a subtle interaction with the compacting GC. In compacting
* GC, the info that describes the size/layout of a closure
* cannot be in an object more than one level of indirection
* away from the current object, because of the order in
* which pointers are updated to point to their new locations.
*/
// Byte code objects. These are fixed size objects with pointers to
// four arrays, designed so that a BCO can be easily "re-linked" to
// other BCOs, to facilitate GHC's intelligent recompilation. The
// array of instructions is static and not re-generated when the BCO
// is re-linked, but the other 3 arrays will be regenerated.
//
// A BCO represents either a function or a stack frame. In each case,
// it needs a bitmap to describe to the garbage collector the
// pointerhood of its arguments/free variables respectively, and in
// the case of a function it also needs an arity. These are stored
// directly in the BCO, rather than in the instrs array, for two
// reasons:
// (a) speed: we need to get at the bitmap info quickly when
// the GC is examining APs and PAPs that point to this BCO
// (b) a subtle interaction with the compacting GC. In compacting
// GC, the info that describes the size/layout of a closure
// cannot be in an object more than one level of indirection
// away from the current object, because of the order in
// which pointers are updated to point to their new locations.
//
// Closure types: BCO
typedef
struct
{
StgHeader
header
;
StgArrBytes
*
instrs
;
/* a pointer to an ArrWords */
StgArrBytes
*
literals
;
/* a pointer to an ArrWords */
StgMutArrPtrs
*
ptrs
;
/* a pointer to a MutArrPtrs */
StgHalfWord
arity
;
/*
arity of this BCO
*/
StgHalfWord
size
;
/*
size of th
is BCO (in words) */
StgWord
bitmap
[];
/*
an StgLargeBitmap
*/
StgArrBytes
*
instrs
;
// the code
StgArrBytes
*
literals
;
// literals used by the instructions
StgMutArrPtrs
*
ptrs
;
// free variables
StgHalfWord
arity
;
//
arity of this BCO
StgHalfWord
size
;
//
size of th
e bitmap
StgWord
bitmap
[];
//
an StgLargeBitmap
}
StgBCO
;
#define BCO_BITMAP(bco) ((StgLargeBitmap *)((StgBCO *)(bco))->bitmap)
...
...
@@ -264,35 +391,31 @@ typedef struct {
#define BCO_BITMAP_SIZEW(bco) ((BCO_BITMAP_SIZE(bco) + BITS_IN(StgWord) - 1) \
/ BITS_IN(StgWord))
/* A function return stack frame: used when saving the state for a
* garbage collection at a function entry point. The function
* arguments are on the stack, and we also save the function (its
* info table describes the pointerhood of the arguments).
*
* The stack frame size is also cached in the frame for convenience.
*
* The only RET_FUN is stg_gc_fun, which is created by __stg_gc_fun,
* both in HeapStackCheck.cmm.
*/
typedef
struct
{
const
StgInfoTable
*
info
;
StgWord
size
;
StgClosure
*
fun
;
StgClosure
*
payload
[];
}
StgRetFun
;
/* Concurrent communication objects */
// Queue for threads waiting on an MVar
//
// Closure types:
typedef
struct
StgMVarTSOQueue_
{
StgHeader
header
;
struct
StgMVarTSOQueue_
*
link
;
struct
StgTSO_
*
tso
;
}
StgMVarTSOQueue
;
// An MVar#
//
// Closure types: MVAR_CLEAN, MVAR_DIRTY
typedef
struct
{
StgHeader
header
;
// threads that are waiting on this MVar
struct
StgMVarTSOQueue_
*
head
;
struct
StgMVarTSOQueue_
*
tail
;
// The value in the MVar if filled
StgClosure
*
value
;
}
StgMVar
;
...
...
rts/include/rts/storage/TSO.h
View file @
74bf9bb5
...
...
@@ -261,6 +261,7 @@ typedef struct StgStack_ {
* See comment on "Invariants" below.
*/
StgPtr
sp
;
StgWord
stack
[];
}
StgStack
;
...
...
Marge Bot
💬
@marge-bot
mentioned in merge request
!7212 (closed)
·
Feb 16, 2022
mentioned in merge request
!7212 (closed)
mentioned in merge request !7212
Toggle commit list
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment