Note [Stack layout when entering run_BCO]
We have a bco (obj), and its arguments are all on the stack. We can start executing the byte codes. The stack is in one of two states. First, if this BCO is a function (in run_BCO_fun or run_BCO) | .... | +---------------+ | arg2 | +---------------+ | arg1 | +---------------+ Second, if this BCO is a case cont., as per Note [Case continuation BCOs] (only in run_BCO): | .... | +---------------+ | fv2 | +---------------+ | fv1 | +---------------+ | BCO | +---------------+ | stg_ctoi_ret_ | +---------------+ | retval | +---------------+ | stg_ret_..... | +---------------+ where retval is the value being returned to this continuation. In the event of a stack check, heap check, context switch, or breakpoint, we need to leave the stack in a sane state so the garbage collector can find all the pointers. (1) BCO is a function: the BCO's bitmap describes the pointerhood of the arguments. (2) BCO is a continuation: BCO's bitmap describes the pointerhood of the free variables. To reconstruct a valid stack state for yielding (such that when we return to the interpreter we end up in the same place from where we yielded), we need to differentiate the two cases again: (1) For function BCOs, the arguments are directly on top of the stack, so it suffices to add a `stg_apply_interp_info` frame header using the BCO that is being applied to these arguments (i.e. the `obj` being run) (2) For continuation BCOs, the stack is already consistent -- that's why we keep the ret and ctoi frame on top of the stack when we start executing it. We couldn't reconstruct a valid stack that resumes the case continuation execution just from the return and free vars values alone because we wouldn't know what kind of result it was (are we returning a pointer, non pointer int, a tuple? etc.); especially considering some frames have different sizes, notably unboxed tuple return frames (see Note [unboxed tuple bytecodes and tuple_BCO]). For consistency, the first instructions in a case continuation BCO, right after a possible BRK_FUN heading it, are two SLIDEs to remove the stg_ret_ and stg_ctoi_ frame headers, leaving only the return value followed by the free vars. Theses slides use statically known offsets computed in StgToByteCode.hs. Following the continuation BCO diagram above, SLIDING would result in: | .... | +---------------+ | fv2 | +---------------+ | fv1 | +---------------+ | retval | +---------------+
References 2
- Case continuation BCOs GHC.ByteCode.Types
- unboxed tuple bytecodes and tuple_BCO GHC.StgToByteCode
Referenced by 11
- rts/Interpreter.c call site ×8
- GHC.StgToByteCode call site ×3