Commit 74bf9bb5 authored by ase's avatar ase Committed by Marge Bot
Browse files

rts: document some closure types

parent 2c28620d
Pipeline #47676 canceled with stages
in 32 seconds
......@@ -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 */
......
......@@ -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
......
......@@ -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;
......
......@@ -261,6 +261,7 @@ typedef struct StgStack_ {
* See comment on "Invariants" below.
*/
StgPtr sp;
StgWord stack[];
} StgStack;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment