diff options
author | Andy Wingo <wingo@pobox.com> | 2018-07-16 15:42:05 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2018-07-20 11:42:30 +0200 |
commit | 043432fd573648fe8591672aca7e2438b71e6774 (patch) | |
tree | 15e0f687c0bb1283b3fa066ed4ef23404e757a23 | |
parent | b1705bd0f0181a6496223b26cb5da68fa470ccaa (diff) | |
download | guile-043432fd573648fe8591672aca7e2438b71e6774.tar.gz |
Reserve frame word for machine return address
* libguile/frames.h: Add machine return address to diagram.
(SCM_FRAME_MACHINE_RETURN_ADDRESS):
(SCM_FRAME_SET_MACHINE_RETURN_ADDRESS): New macros.
(SCM_FRAME_PREVIOUS_SP):
(SCM_FRAME_DYNAMIC_LINK):
(SCM_FRAME_SET_DYNAMIC_LINK): Adapt for new frame size.
* libguile/vm-engine.c (halt): Set frame size to 3.
(call, call-label): Set mRA to 0.
* libguile/vm.c (push_interrupt_frame, reinstate_continuation_x):
(scm_call_n): Set frame size to 3. In push_interrupt_frame, init the
mRA of the frame.
(vm_builtin_call_with_values_code, vm_handle_interrupt_code): Allocate
larger frames.
* module/language/cps/slot-allocation.scm (allocate-slots): Frame size
is 3.
* module/system/vm/disassembler.scm (define-clobber-parser): Bump frame
size.
-rw-r--r-- | libguile/frames.h | 26 | ||||
-rw-r--r-- | libguile/vm-engine.c | 4 | ||||
-rw-r--r-- | libguile/vm.c | 23 | ||||
-rw-r--r-- | module/language/cps/slot-allocation.scm | 2 | ||||
-rw-r--r-- | module/system/vm/disassembler.scm | 2 |
5 files changed, 33 insertions, 24 deletions
diff --git a/libguile/frames.h b/libguile/frames.h index 85e36a5c2..99c5dff84 100644 --- a/libguile/frames.h +++ b/libguile/frames.h @@ -44,6 +44,8 @@ | Dynamic link | +------------------------------+ | Virtual return address (vRA) | + +------------------------------+ + | Machine return address (mRA) | +==============================+ <- fp | Local 0 | +------------------------------+ @@ -57,12 +59,12 @@ The stack grows down. The calling convention is that a caller prepares a stack frame - consisting of the saved FP and the saved virtual return address, - followed by the procedure and then the arguments to the call, in - order. Thus in the beginning of a call, the procedure being called - is in slot 0, the first argument is in slot 1, and the SP points to - the last argument. The number of arguments, including the procedure, - is thus FP - SP. + consisting of the saved FP, the saved virtual return addres, and the + saved machine return address of the calling function, followed by the + procedure and then the arguments to the call, in order. Thus in the + beginning of a call, the procedure being called is in slot 0, the + first argument is in slot 1, and the SP points to the last argument. + The number of arguments, including the procedure, is thus FP - SP. After ensuring that the correct number of arguments have been passed, a function will set the stack pointer to point to the last local @@ -103,11 +105,13 @@ union scm_vm_stack_element scm_t_bits as_bits; }; -#define SCM_FRAME_PREVIOUS_SP(fp) ((fp) + 2) -#define SCM_FRAME_VIRTUAL_RETURN_ADDRESS(fp) ((fp)[0].as_vcode) -#define SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS(fp, ra) ((fp)[0].as_vcode = (ra)) -#define SCM_FRAME_DYNAMIC_LINK(fp) ((fp) + (fp)[1].as_uint) -#define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) ((fp)[1].as_uint = ((dl) - (fp))) +#define SCM_FRAME_PREVIOUS_SP(fp) ((fp) + 3) +#define SCM_FRAME_MACHINE_RETURN_ADDRESS(fp) ((fp)[0].as_mcode) +#define SCM_FRAME_SET_MACHINE_RETURN_ADDRESS(fp, ra) ((fp)[0].as_mcode = (ra)) +#define SCM_FRAME_VIRTUAL_RETURN_ADDRESS(fp) ((fp)[1].as_vcode) +#define SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS(fp, ra) ((fp)[1].as_vcode = (ra)) +#define SCM_FRAME_DYNAMIC_LINK(fp) ((fp) + (fp)[2].as_uint) +#define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) ((fp)[2].as_uint = ((dl) - (fp))) #define SCM_FRAME_SLOT(fp,i) ((fp) - (i) - 1) #define SCM_FRAME_LOCAL(fp,i) (SCM_FRAME_SLOT (fp, i)->as_scm) #define SCM_FRAME_NUM_LOCALS(fp, sp) ((fp) - (sp)) diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c index cf4cab7ff..341a006fd 100644 --- a/libguile/vm-engine.c +++ b/libguile/vm-engine.c @@ -321,7 +321,7 @@ VM_NAME (scm_thread *thread) */ VM_DEFINE_OP (0, halt, "halt", OP1 (X32)) { - size_t frame_size = 2; + size_t frame_size = 3; /* Boot closure, then empty frame, then callee, then values. */ size_t first_value = 1 + frame_size + 1; uint32_t nvals = FRAME_LOCALS_COUNT_FROM (first_value); @@ -373,6 +373,7 @@ VM_NAME (scm_thread *thread) VP->fp = SCM_FRAME_SLOT (old_fp, proc - 1); SCM_FRAME_SET_DYNAMIC_LINK (VP->fp, old_fp); SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (VP->fp, ip + 2); + SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (VP->fp, 0); RESET_FRAME (nlocals); @@ -416,6 +417,7 @@ VM_NAME (scm_thread *thread) VP->fp = SCM_FRAME_SLOT (old_fp, proc - 1); SCM_FRAME_SET_DYNAMIC_LINK (VP->fp, old_fp); SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (VP->fp, ip + 3); + SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (VP->fp, 0); RESET_FRAME (nlocals); diff --git a/libguile/vm.c b/libguile/vm.c index cf7b13cac..1f2373acd 100644 --- a/libguile/vm.c +++ b/libguile/vm.c @@ -351,11 +351,11 @@ static const uint32_t vm_builtin_abort_to_prompt_code[] = { static const uint32_t vm_builtin_call_with_values_code[] = { SCM_PACK_OP_24 (assert_nargs_ee, 3), - SCM_PACK_OP_24 (alloc_frame, 7), - SCM_PACK_OP_12_12 (mov, 0, 5), - SCM_PACK_OP_24 (call, 6), SCM_PACK_OP_ARG_8_24 (0, 1), + SCM_PACK_OP_24 (alloc_frame, 8), + SCM_PACK_OP_12_12 (mov, 0, 6), + SCM_PACK_OP_24 (call, 7), SCM_PACK_OP_ARG_8_24 (0, 1), SCM_PACK_OP_24 (long_fmov, 0), SCM_PACK_OP_ARG_8_24 (0, 2), - SCM_PACK_OP_24 (tail_call_shuffle, 7) + SCM_PACK_OP_24 (tail_call_shuffle, 8) }; static const uint32_t vm_builtin_call_with_current_continuation_code[] = { @@ -364,9 +364,9 @@ static const uint32_t vm_builtin_call_with_current_continuation_code[] = { }; static const uint32_t vm_handle_interrupt_code[] = { - SCM_PACK_OP_24 (alloc_frame, 3), - SCM_PACK_OP_12_12 (mov, 0, 2), - SCM_PACK_OP_24 (call, 2), SCM_PACK_OP_ARG_8_24 (0, 1), + SCM_PACK_OP_24 (alloc_frame, 4), + SCM_PACK_OP_12_12 (mov, 0, 3), + SCM_PACK_OP_24 (call, 3), SCM_PACK_OP_ARG_8_24 (0, 1), SCM_PACK_OP_24 (return_from_interrupt, 0) }; @@ -1014,7 +1014,7 @@ static void push_interrupt_frame (scm_thread *thread, uint8_t *mra) { union scm_vm_stack_element *old_fp; - size_t frame_overhead = 2; + size_t frame_overhead = 3; size_t old_frame_size = frame_locals_count (thread); SCM proc = scm_i_async_pop (thread); @@ -1030,6 +1030,7 @@ push_interrupt_frame (scm_thread *thread, uint8_t *mra) /* Arrange to return to the same handle-interrupts opcode to handle any additional interrupts. */ SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (thread->vm.fp, thread->vm.ip); + SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (thread->vm.fp, mra); SCM_FRAME_LOCAL (thread->vm.fp, 0) = proc; } @@ -1070,7 +1071,7 @@ reinstate_continuation_x (scm_thread *thread, SCM cont) scm_t_contregs *continuation = scm_i_contregs (cont); struct scm_vm *vp = &thread->vm; struct scm_vm_cont *cp; - size_t n, i, frame_overhead = 2; + size_t n, i, frame_overhead = 3; union scm_vm_stack_element *argv; struct return_to_continuation_data data; @@ -1374,7 +1375,7 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs) elements and each element is at least 4 bytes, nargs will not be greater than INTMAX/2 and therefore we don't have to check for overflow here or below. */ - size_t return_nlocals = 1, call_nlocals = nargs + 1, frame_size = 2; + size_t return_nlocals = 1, call_nlocals = nargs + 1, frame_size = 3; ptrdiff_t stack_reserve_words; size_t i; @@ -1399,6 +1400,7 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs) return_fp = call_fp + frame_size + return_nlocals; SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (return_fp, vp->ip); + SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (return_fp, 0); SCM_FRAME_SET_DYNAMIC_LINK (return_fp, vp->fp); SCM_FRAME_LOCAL (return_fp, 0) = vm_boot_continuation; @@ -1406,6 +1408,7 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs) vp->fp = call_fp; SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (call_fp, vp->ip); + SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (call_fp, 0); SCM_FRAME_SET_DYNAMIC_LINK (call_fp, return_fp); SCM_FRAME_LOCAL (call_fp, 0) = proc; for (i = 0; i < nargs; i++) diff --git a/module/language/cps/slot-allocation.scm b/module/language/cps/slot-allocation.scm index 0febca59a..71c8b743e 100644 --- a/module/language/cps/slot-allocation.scm +++ b/module/language/cps/slot-allocation.scm @@ -807,7 +807,7 @@ are comparable with eqv?. A tmp slot may be used." needs-slot) empty-intset))) - (define frame-size 2) + (define frame-size 3) (define (empty-live-slots) #b0) diff --git a/module/system/vm/disassembler.scm b/module/system/vm/disassembler.scm index f0b1a1076..f46b160c6 100644 --- a/module/system/vm/disassembler.scm +++ b/module/system/vm/disassembler.scm @@ -615,7 +615,7 @@ address of that offset." (lambda () (disassemble-one code (/ pos 4))) (lambda (len elt) - (define frame-size 2) + (define frame-size 3) (match elt ((_ proc . _) (let lp ((slot (- proc frame-size))) |