Next: machinery call arguments, Previous: machinery continuations, Up: machinery [Index]
Let’s recall how the Scheme stack segment looks, machinery stack overflow. Function call frames are put on the stack starting from high memory addresses, stack usage grows towards low memory addresses; at some point the stack runs out of space.
high memory | | |----------------------| | | <- pcb->frame_base |----------------------| -- | ik_underflow_handler | . |----------------------| . . . . . . . |----------------------| . | | <- pcb->frame_redline . stack |----------------------| . segment . . size . . . . |----------------------| . | | <- pcb->stack_base . |----------------------| -- | | low memory
To detect stack usage approaching the end of available stack space: the PCB contains a field referencing a machine word 2 memory chunks (4096 bytes each) above the lower boundary; whenever stack usage crosses this “red line”: a new stack segment needs to be allocated and call frames must be put on the new stack; machinery stack overflow.
high memory | | <- pcb->frame_base |----------------------| | ik_underflow_handler | |----------------------| . . . |----------------------| -- | local value | . |----------------------| . | local value | <- pcb->frame_redline . |----------------------| . framesize | local value | . |----------------------| . | return address | <- FPR . |----------------------| -- | function argument | |----------------------| | function argument | |----------------------| . . . |----------------------| | | <- pcb->stack_base |----------------------| | | low memory
Scheme functions can be partitioned in: those that may use more stack space, those that do not; Vicare recognises this partition and inserts a stack overflow check at the beginning of each of the former. The pseudo–Assembly performing the check is as follows:
(label function_entry_point) (cmpl FPR pcb->frame_redline) (jb L0) (label L1) ... the function body ... (ret) (label L0) (forcall "ik_stack_overflow") (jmp L1)
When stack overflow happens the C function ik_stack_overflow()
is
called through the forcall
primitive instruction and the Assembly
subroutine ik_foreign_call
; forcall
creates a new stack
frame and then calls ik_foreign_call
which in turn calls the C
function, machinery stack overflow.
high memory | | |----------------------| -- | local value | . |----------------------| . | local value | <- pcb->frame_redline . |----------------------| . framesize | local value | . |----------------------| . | return address | . |----------------------| -- | function argument | . |----------------------| . frame of | function argument | . forcall |----------------------| . | return address | <- FPR . |----------------------| -- | | low memory
ik_stack_overflow()
does the following:
Upon returning to the caller ik_foreign_call
performs a
ret
Assembly instruction with the FPR referencing the
underflow handler; so returning from a stack reallocation is exactly
like returning to the next PCB continuation.
Next: machinery call arguments, Previous: machinery continuations, Up: machinery [Index]