diff options
author | Adam Sandberg Ericsson <adam@sandbergericsson.se> | 2021-12-18 20:03:27 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-02-16 05:28:32 -0500 |
commit | 74bf9bb5b83e5ff335847fc2e1d3def413e7df90 (patch) | |
tree | 6b05224ba3e4c63eda1205c4e045a41795318239 /rts | |
parent | 2c28620d5ed09aaffa877b5e14b900a1ad789af1 (diff) | |
download | haskell-74bf9bb5b83e5ff335847fc2e1d3def413e7df90.tar.gz |
rts: document some closure types
Diffstat (limited to 'rts')
-rw-r--r-- | rts/ClosureFlags.c | 2 | ||||
-rw-r--r-- | rts/include/rts/storage/ClosureTypes.h | 4 | ||||
-rw-r--r-- | rts/include/rts/storage/Closures.h | 259 | ||||
-rw-r--r-- | rts/include/rts/storage/TSO.h | 1 |
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; |