-
Notifications
You must be signed in to change notification settings - Fork 1
GHCi architecture
Description of how breakpoints mechanism is implemented in GHCi. Useful when working with GHCi source code.
data BreakInfo
= BreakInfo
{ breakInfo_module :: Module
, breakInfo_number :: {-# UNPACK #-} !Int
, breakInfo_vars :: [(Id,Word16)]
, breakInfo_resty :: Type
}
data Resume
= Resume {
resumeStmt :: String, -- the original statement
resumeThreadId :: ThreadId, -- thread running the computation
resumeBreakMVar :: MVar (),
resumeStatMVar :: MVar Status,
resumeBindings :: ([TyThing], GlobalRdrEnv),
resumeFinalIds :: [Id], -- [Id] to bind on completion
resumeApStack :: HValue, -- The object from which we can get
-- value of the free variables.
resumeBreakInfo :: Maybe BreakInfo,
-- the breakpoint we stopped at
-- (Nothing <=> exception)
resumeSpan :: SrcSpan, -- just a cache, otherwise it's a pain
-- to fetch the ModDetails & ModBreaks
-- to get this.
resumeHistory :: [History],
resumeHistoryIx :: Int -- 0 <==> at the top of the history
}
data History
= History {
historyApStack :: HValue,
historyBreakInfo :: BreakInfo,
resumeApStack сontaints new_aps from code below.
Intepreter.c
size_words = BCO_BITMAP_SIZE(obj) + 2;
new_aps = (StgAP_STACK *) allocate(cap, AP_STACK_sizeW(size_words));
SET_HDR(new_aps,&stg_AP_STACK_info,CCS_SYSTEM);
new_aps->size = size_words;
new_aps->fun = &stg_dummy_ret_closure;
// fill in the payload of the AP_STACK
new_aps->payload[0] = (StgClosure *)&stg_apply_interp_info;
new_aps->payload[1] = (StgClosure *)obj;
// copy the contents of the top stack frame into the AP_STACK
for (i = 2; i < size_words; i++)
{
new_aps->payload[i] = (StgClosure *)Sp[i-2];
}
Very good description of these things is given in GHC commentary for RTS in section Storage/HeapObjects.
Structures under consideration are actually defined in the file ghc/includes/rts/storage/Closures.h, comments there may be useful.
Some useful information about what Entry Code, Info Table and Closures are is given in description of STG machine in the section "Important concepts in the machine".
- StgClosure
Defined in ghc/includes/rts/Types.h as follows:
typedef struct StgClosure_ StgClosure;
So it it just a typedef. Actual definition is in ghc/includes/rts/storage/Closures.h:
typedef struct StgClosure_ {
StgHeader header;
struct StgClosure_ *payload[FLEXIBLE_ARRAY];
} *StgClosurePtr; // StgClosure defined in rts/Types.h
This structure represents heap object. Heap objects are closures, if I've got the idea right. All heap objects have header and payload.
Main part of the header is pointer to InfoTable. InfoTable contains different information, for example, closure type and layout of payload (payload's structure, how objects located there). This info is used by Garbage Collector (GC) in particular. Another important thing stored in InfoTable is entry code. It is used to evaluate the closure.
Payload contains different information about closure depending on it's type. For example, payload of Function Closures stores free variables of the function.
- StgThunkHeader
As it was mentioned above, closures have headers. It seems like Thunks (closure type that represents an expression that is not obviously in head normal form, see Storage/HeapObjects for more info) has this kind of headers. Source code in ghc/includes/rts/storage/Closures.h:
/* -----------------------------------------------------------------------------
The SMP header
A thunk has a padding word to take the updated value. This is so
that the update doesn't overwrite the payload, so we can avoid
needing to lock the thunk during entry and update.
Note: this doesn't apply to THUNK_STATICs, which have no payload.
Note: we leave this padding word in all ways, rather than just SMP,
so that we don't have to recompile all our libraries for SMP.
-------------------------------------------------------------------------- */
typedef struct {
StgWord pad;
} StgSMPThunkHeader;
/* -----------------------------------------------------------------------------
The full fixed-size closure header
The size of the fixed header is the sum of the optional parts plus a single
word for the entry code pointer.
-------------------------------------------------------------------------- */
typedef struct {
const StgInfoTable* info;
#ifdef PROFILING
StgProfHeader prof;
#endif
} StgHeader;
typedef struct {
const StgInfoTable* info;
#ifdef PROFILING
StgProfHeader prof;
#endif
StgSMPThunkHeader smp;
} StgThunkHeader;
All this makes me think that it is usual header but with additional information for SMP ([info] (http://www.haskell.org/ghc/docs/6.6/html/users_guide/sec-using-smp.html)). So we may assume that it is just a header as it is described above.
- StgAP_STACK
Represents closure type for Stack Application. See corresponding section in Storage/HeapObjects. Source code in ghc/includes/rts/storage/Closures.h:
typedef struct {
StgThunkHeader header;
StgWord size; /* number of words in payload */
StgClosure *fun;
StgClosure *payload[FLEXIBLE_ARRAY]; /* contains a chunk of *stack* */
} StgAP_STACK;