summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorAdam Sandberg Ericsson <adam@sandbergericsson.se>2021-12-18 20:03:27 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-02-16 05:28:32 -0500
commit74bf9bb5b83e5ff335847fc2e1d3def413e7df90 (patch)
tree6b05224ba3e4c63eda1205c4e045a41795318239 /rts
parent2c28620d5ed09aaffa877b5e14b900a1ad789af1 (diff)
downloadhaskell-74bf9bb5b83e5ff335847fc2e1d3def413e7df90.tar.gz
rts: document some closure types
Diffstat (limited to 'rts')
-rw-r--r--rts/ClosureFlags.c2
-rw-r--r--rts/include/rts/storage/ClosureTypes.h4
-rw-r--r--rts/include/rts/storage/Closures.h259
-rw-r--r--rts/include/rts/storage/TSO.h1
4 files changed, 198 insertions, 68 deletions
diff --git a/rts/ClosureFlags.c b/rts/ClosureFlags.c
index da66b34d9a..390e11900b 100644
--- a/rts/ClosureFlags.c
+++ b/rts/ClosureFlags.c
@@ -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 */
diff --git a/rts/include/rts/storage/ClosureTypes.h b/rts/include/rts/storage/ClosureTypes.h
index 85dc1a0ce4..31e75cc617 100644
--- a/rts/include/rts/storage/ClosureTypes.h
+++ b/rts/include/rts/storage/ClosureTypes.h
@@ -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
diff --git a/rts/include/rts/storage/Closures.h b/rts/include/rts/storage/Closures.h
index c821073516..41861abac9 100644
--- a/rts/include/rts/storage/Closures.h
+++ b/rts/include/rts/storage/Closures.h
@@ -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 points 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 points 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 this 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 the 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;
diff --git a/rts/include/rts/storage/TSO.h b/rts/include/rts/storage/TSO.h
index d21cd7a645..db56a8128b 100644
--- a/rts/include/rts/storage/TSO.h
+++ b/rts/include/rts/storage/TSO.h
@@ -261,6 +261,7 @@ typedef struct StgStack_ {
* See comment on "Invariants" below.
*/
StgPtr sp;
+
StgWord stack[];
} StgStack;