mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 19:50:24 +02:00
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.
This commit is contained in:
parent
b1705bd0f0
commit
043432fd57
5 changed files with 33 additions and 24 deletions
|
@ -44,6 +44,8 @@
|
||||||
| Dynamic link |
|
| Dynamic link |
|
||||||
+------------------------------+
|
+------------------------------+
|
||||||
| Virtual return address (vRA) |
|
| Virtual return address (vRA) |
|
||||||
|
+------------------------------+
|
||||||
|
| Machine return address (mRA) |
|
||||||
+==============================+ <- fp
|
+==============================+ <- fp
|
||||||
| Local 0 |
|
| Local 0 |
|
||||||
+------------------------------+
|
+------------------------------+
|
||||||
|
@ -57,12 +59,12 @@
|
||||||
The stack grows down.
|
The stack grows down.
|
||||||
|
|
||||||
The calling convention is that a caller prepares a stack frame
|
The calling convention is that a caller prepares a stack frame
|
||||||
consisting of the saved FP and the saved virtual return address,
|
consisting of the saved FP, the saved virtual return addres, and the
|
||||||
followed by the procedure and then the arguments to the call, in
|
saved machine return address of the calling function, followed by the
|
||||||
order. Thus in the beginning of a call, the procedure being called
|
procedure and then the arguments to the call, in order. Thus in the
|
||||||
is in slot 0, the first argument is in slot 1, and the SP points to
|
beginning of a call, the procedure being called is in slot 0, the
|
||||||
the last argument. The number of arguments, including the procedure,
|
first argument is in slot 1, and the SP points to the last argument.
|
||||||
is thus FP - SP.
|
The number of arguments, including the procedure, is thus FP - SP.
|
||||||
|
|
||||||
After ensuring that the correct number of arguments have been passed,
|
After ensuring that the correct number of arguments have been passed,
|
||||||
a function will set the stack pointer to point to the last local
|
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;
|
scm_t_bits as_bits;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCM_FRAME_PREVIOUS_SP(fp) ((fp) + 2)
|
#define SCM_FRAME_PREVIOUS_SP(fp) ((fp) + 3)
|
||||||
#define SCM_FRAME_VIRTUAL_RETURN_ADDRESS(fp) ((fp)[0].as_vcode)
|
#define SCM_FRAME_MACHINE_RETURN_ADDRESS(fp) ((fp)[0].as_mcode)
|
||||||
#define SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS(fp, ra) ((fp)[0].as_vcode = (ra))
|
#define SCM_FRAME_SET_MACHINE_RETURN_ADDRESS(fp, ra) ((fp)[0].as_mcode = (ra))
|
||||||
#define SCM_FRAME_DYNAMIC_LINK(fp) ((fp) + (fp)[1].as_uint)
|
#define SCM_FRAME_VIRTUAL_RETURN_ADDRESS(fp) ((fp)[1].as_vcode)
|
||||||
#define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) ((fp)[1].as_uint = ((dl) - (fp)))
|
#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_SLOT(fp,i) ((fp) - (i) - 1)
|
||||||
#define SCM_FRAME_LOCAL(fp,i) (SCM_FRAME_SLOT (fp, i)->as_scm)
|
#define SCM_FRAME_LOCAL(fp,i) (SCM_FRAME_SLOT (fp, i)->as_scm)
|
||||||
#define SCM_FRAME_NUM_LOCALS(fp, sp) ((fp) - (sp))
|
#define SCM_FRAME_NUM_LOCALS(fp, sp) ((fp) - (sp))
|
||||||
|
|
|
@ -321,7 +321,7 @@ VM_NAME (scm_thread *thread)
|
||||||
*/
|
*/
|
||||||
VM_DEFINE_OP (0, halt, "halt", OP1 (X32))
|
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. */
|
/* Boot closure, then empty frame, then callee, then values. */
|
||||||
size_t first_value = 1 + frame_size + 1;
|
size_t first_value = 1 + frame_size + 1;
|
||||||
uint32_t nvals = FRAME_LOCALS_COUNT_FROM (first_value);
|
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);
|
VP->fp = SCM_FRAME_SLOT (old_fp, proc - 1);
|
||||||
SCM_FRAME_SET_DYNAMIC_LINK (VP->fp, old_fp);
|
SCM_FRAME_SET_DYNAMIC_LINK (VP->fp, old_fp);
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (VP->fp, ip + 2);
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (VP->fp, ip + 2);
|
||||||
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (VP->fp, 0);
|
||||||
|
|
||||||
RESET_FRAME (nlocals);
|
RESET_FRAME (nlocals);
|
||||||
|
|
||||||
|
@ -416,6 +417,7 @@ VM_NAME (scm_thread *thread)
|
||||||
VP->fp = SCM_FRAME_SLOT (old_fp, proc - 1);
|
VP->fp = SCM_FRAME_SLOT (old_fp, proc - 1);
|
||||||
SCM_FRAME_SET_DYNAMIC_LINK (VP->fp, old_fp);
|
SCM_FRAME_SET_DYNAMIC_LINK (VP->fp, old_fp);
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (VP->fp, ip + 3);
|
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (VP->fp, ip + 3);
|
||||||
|
SCM_FRAME_SET_MACHINE_RETURN_ADDRESS (VP->fp, 0);
|
||||||
|
|
||||||
RESET_FRAME (nlocals);
|
RESET_FRAME (nlocals);
|
||||||
|
|
||||||
|
|
|
@ -351,11 +351,11 @@ static const uint32_t vm_builtin_abort_to_prompt_code[] = {
|
||||||
|
|
||||||
static const uint32_t vm_builtin_call_with_values_code[] = {
|
static const uint32_t vm_builtin_call_with_values_code[] = {
|
||||||
SCM_PACK_OP_24 (assert_nargs_ee, 3),
|
SCM_PACK_OP_24 (assert_nargs_ee, 3),
|
||||||
SCM_PACK_OP_24 (alloc_frame, 7),
|
SCM_PACK_OP_24 (alloc_frame, 8),
|
||||||
SCM_PACK_OP_12_12 (mov, 0, 5),
|
SCM_PACK_OP_12_12 (mov, 0, 6),
|
||||||
SCM_PACK_OP_24 (call, 6), SCM_PACK_OP_ARG_8_24 (0, 1),
|
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 (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[] = {
|
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[] = {
|
static const uint32_t vm_handle_interrupt_code[] = {
|
||||||
SCM_PACK_OP_24 (alloc_frame, 3),
|
SCM_PACK_OP_24 (alloc_frame, 4),
|
||||||
SCM_PACK_OP_12_12 (mov, 0, 2),
|
SCM_PACK_OP_12_12 (mov, 0, 3),
|
||||||
SCM_PACK_OP_24 (call, 2), SCM_PACK_OP_ARG_8_24 (0, 1),
|
SCM_PACK_OP_24 (call, 3), SCM_PACK_OP_ARG_8_24 (0, 1),
|
||||||
SCM_PACK_OP_24 (return_from_interrupt, 0)
|
SCM_PACK_OP_24 (return_from_interrupt, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1014,7 +1014,7 @@ static void
|
||||||
push_interrupt_frame (scm_thread *thread, uint8_t *mra)
|
push_interrupt_frame (scm_thread *thread, uint8_t *mra)
|
||||||
{
|
{
|
||||||
union scm_vm_stack_element *old_fp;
|
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);
|
size_t old_frame_size = frame_locals_count (thread);
|
||||||
SCM proc = scm_i_async_pop (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
|
/* Arrange to return to the same handle-interrupts opcode to handle
|
||||||
any additional interrupts. */
|
any additional interrupts. */
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (thread->vm.fp, thread->vm.ip);
|
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;
|
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);
|
scm_t_contregs *continuation = scm_i_contregs (cont);
|
||||||
struct scm_vm *vp = &thread->vm;
|
struct scm_vm *vp = &thread->vm;
|
||||||
struct scm_vm_cont *cp;
|
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;
|
union scm_vm_stack_element *argv;
|
||||||
struct return_to_continuation_data data;
|
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
|
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
|
greater than INTMAX/2 and therefore we don't have to check for
|
||||||
overflow here or below. */
|
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;
|
ptrdiff_t stack_reserve_words;
|
||||||
size_t i;
|
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;
|
return_fp = call_fp + frame_size + return_nlocals;
|
||||||
|
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (return_fp, vp->ip);
|
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_SET_DYNAMIC_LINK (return_fp, vp->fp);
|
||||||
SCM_FRAME_LOCAL (return_fp, 0) = vm_boot_continuation;
|
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;
|
vp->fp = call_fp;
|
||||||
|
|
||||||
SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS (call_fp, vp->ip);
|
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_SET_DYNAMIC_LINK (call_fp, return_fp);
|
||||||
SCM_FRAME_LOCAL (call_fp, 0) = proc;
|
SCM_FRAME_LOCAL (call_fp, 0) = proc;
|
||||||
for (i = 0; i < nargs; i++)
|
for (i = 0; i < nargs; i++)
|
||||||
|
|
|
@ -807,7 +807,7 @@ are comparable with eqv?. A tmp slot may be used."
|
||||||
needs-slot)
|
needs-slot)
|
||||||
empty-intset)))
|
empty-intset)))
|
||||||
|
|
||||||
(define frame-size 2)
|
(define frame-size 3)
|
||||||
|
|
||||||
(define (empty-live-slots)
|
(define (empty-live-slots)
|
||||||
#b0)
|
#b0)
|
||||||
|
|
|
@ -615,7 +615,7 @@ address of that offset."
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(disassemble-one code (/ pos 4)))
|
(disassemble-one code (/ pos 4)))
|
||||||
(lambda (len elt)
|
(lambda (len elt)
|
||||||
(define frame-size 2)
|
(define frame-size 3)
|
||||||
(match elt
|
(match elt
|
||||||
((_ proc . _)
|
((_ proc . _)
|
||||||
(let lp ((slot (- proc frame-size)))
|
(let lp ((slot (- proc frame-size)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue