mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
Remove MVRA from VM frames
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump for frame layout change. * libguile/frames.c: Update some static checks. (scm_frame_num_locals, scm_frame_local_ref, scm_frame_local_set_x): Update to not skip over uninitialized frames, as that's not a thing any more. * libguile/frames.h: Update to remove MVRA. Woo! * libguile/vm-engine.c (ALLOC_FRAME, RETURN_ONE_VALUE): (rtl_vm_engine): Update for 3 words per frame instead of 4. * libguile/vm.c (vm_return_to_continuation): Likewise. * module/language/cps/slot-allocation.scm (allocate-slots): 3 words per frame, not 4. * module/system/vm/assembler.scm (*bytecode-minor-version*): Bump. Also remove a couple of tc7's that aren't around any more.
This commit is contained in:
parent
840ec33422
commit
f8085163d6
7 changed files with 45 additions and 100 deletions
|
@ -270,7 +270,7 @@ void scm_ia64_longjmp (scm_i_jmp_buf *, int);
|
|||
|
||||
/* Major and minor versions must be single characters. */
|
||||
#define SCM_OBJCODE_MAJOR_VERSION 3
|
||||
#define SCM_OBJCODE_MINOR_VERSION 2
|
||||
#define SCM_OBJCODE_MINOR_VERSION 3
|
||||
#define SCM_OBJCODE_MAJOR_VERSION_STRING \
|
||||
SCM_CPP_STRINGIFY(SCM_OBJCODE_MAJOR_VERSION)
|
||||
#define SCM_OBJCODE_MINOR_VERSION_STRING \
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
/* Make sure assumptions on the layout of `struct scm_vm_frame' hold. */
|
||||
verify (sizeof (SCM) == sizeof (SCM *));
|
||||
verify (sizeof (struct scm_vm_frame) == 5 * sizeof (SCM));
|
||||
verify (sizeof (struct scm_vm_frame) == 4 * sizeof (SCM));
|
||||
verify (offsetof (struct scm_vm_frame, dynamic_link) == 0);
|
||||
|
||||
|
||||
|
@ -110,39 +110,28 @@ SCM_DEFINE (scm_frame_source, "frame-source", 1, 0, 0,
|
|||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
/* The number of locals would be a simple thing to compute, if it weren't for
|
||||
the presence of not-yet-active frames on the stack. So we have a cheap
|
||||
heuristic to detect not-yet-active frames, and skip over them. Perhaps we
|
||||
should represent them more usefully.
|
||||
*/
|
||||
SCM_DEFINE (scm_frame_num_locals, "frame-num-locals", 1, 0, 0,
|
||||
(SCM frame),
|
||||
"")
|
||||
#define FUNC_NAME s_scm_frame_num_locals
|
||||
{
|
||||
SCM *sp, *p;
|
||||
unsigned int n = 0;
|
||||
|
||||
SCM_VALIDATE_VM_FRAME (1, frame);
|
||||
|
||||
sp = SCM_VM_FRAME_SP (frame);
|
||||
p = SCM_FRAME_STACK_ADDRESS (SCM_VM_FRAME_FP (frame));
|
||||
|
||||
/* The frame size of an RTL program is fixed, except in the case of
|
||||
passing a wrong number of arguments to the program. So we do
|
||||
need to use an SP for determining the number of locals. */
|
||||
return scm_from_ptrdiff_t (sp + 1 - p);
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
||||
/* Need same not-yet-active frame logic here as in frame-num-locals */
|
||||
SCM_DEFINE (scm_frame_local_ref, "frame-local-ref", 2, 0, 0,
|
||||
(SCM frame, SCM index),
|
||||
"")
|
||||
#define FUNC_NAME s_scm_frame_local_ref
|
||||
{
|
||||
SCM *sp, *p;
|
||||
unsigned int n = 0;
|
||||
unsigned int i;
|
||||
|
||||
SCM_VALIDATE_VM_FRAME (1, frame);
|
||||
|
@ -150,19 +139,10 @@ SCM_DEFINE (scm_frame_local_ref, "frame-local-ref", 2, 0, 0,
|
|||
|
||||
sp = SCM_VM_FRAME_SP (frame);
|
||||
p = SCM_FRAME_STACK_ADDRESS (SCM_VM_FRAME_FP (frame));
|
||||
while (p <= sp)
|
||||
{
|
||||
if (SCM_UNPACK (p[0]) == 0)
|
||||
/* skip over not-yet-active frame */
|
||||
p += 3;
|
||||
else if (n == i)
|
||||
return *p;
|
||||
else
|
||||
{
|
||||
p++;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
if (p + i <= sp)
|
||||
return SCM_FRAME_VARIABLE (SCM_VM_FRAME_FP (frame), i);
|
||||
|
||||
SCM_OUT_OF_RANGE (SCM_ARG2, index);
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
@ -174,7 +154,6 @@ SCM_DEFINE (scm_frame_local_set_x, "frame-local-set!", 3, 0, 0,
|
|||
#define FUNC_NAME s_scm_frame_local_set_x
|
||||
{
|
||||
SCM *sp, *p;
|
||||
unsigned int n = 0;
|
||||
unsigned int i;
|
||||
|
||||
SCM_VALIDATE_VM_FRAME (1, frame);
|
||||
|
@ -182,22 +161,13 @@ SCM_DEFINE (scm_frame_local_set_x, "frame-local-set!", 3, 0, 0,
|
|||
|
||||
sp = SCM_VM_FRAME_SP (frame);
|
||||
p = SCM_FRAME_STACK_ADDRESS (SCM_VM_FRAME_FP (frame));
|
||||
while (p <= sp)
|
||||
|
||||
if (p + i <= sp)
|
||||
{
|
||||
if (SCM_UNPACK (p[0]) == 0)
|
||||
/* skip over not-yet-active frame */
|
||||
p += 3;
|
||||
else if (n == i)
|
||||
{
|
||||
*p = val;
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
p++;
|
||||
n++;
|
||||
}
|
||||
SCM_FRAME_VARIABLE (SCM_VM_FRAME_FP (frame), i) = val;
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
SCM_OUT_OF_RANGE (SCM_ARG2, index);
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
|
|
|
@ -50,21 +50,26 @@
|
|||
| Program | <- fp - 1
|
||||
+==================+
|
||||
| Return address | <- SCM_FRAME_UPPER_ADDRESS (fp)
|
||||
| MV return address|
|
||||
| Dynamic link | <- fp - 4 = SCM_FRAME_DATA_ADDRESS (fp) = SCM_FRAME_LOWER_ADDRESS (fp)
|
||||
| Dynamic link | <- fp - 3 = SCM_FRAME_DATA_ADDRESS (fp) = SCM_FRAME_LOWER_ADDRESS (fp)
|
||||
+==================+
|
||||
| |
|
||||
|
||||
As can be inferred from this drawing, it is assumed that
|
||||
`sizeof (SCM *) == sizeof (SCM)', since pointers (the `link' parts) are
|
||||
assumed to be as long as SCM objects. */
|
||||
assumed to be as long as SCM objects.
|
||||
|
||||
When a program returns multiple values, it will shuffle them down to
|
||||
start contiguously from slot 1, as for a tail call. This means that
|
||||
when the caller goes to access them, there are 2 or 3 empty words
|
||||
between the top of the caller stack and the bottom of the values,
|
||||
corresponding to the frame that was just popped.
|
||||
*/
|
||||
|
||||
/* This structure maps to the contents of a VM stack frame. It can
|
||||
alias a frame directly. */
|
||||
struct scm_vm_frame
|
||||
{
|
||||
SCM *dynamic_link;
|
||||
scm_t_uint8 *mv_return_address;
|
||||
scm_t_uint8 *return_address;
|
||||
SCM program;
|
||||
SCM stack[1]; /* Variable-length */
|
||||
|
@ -73,7 +78,7 @@ struct scm_vm_frame
|
|||
#define SCM_FRAME_STRUCT(fp) \
|
||||
((struct scm_vm_frame *) SCM_FRAME_DATA_ADDRESS (fp))
|
||||
|
||||
#define SCM_FRAME_DATA_ADDRESS(fp) (((SCM *) (fp)) - 4)
|
||||
#define SCM_FRAME_DATA_ADDRESS(fp) (((SCM *) (fp)) - 3)
|
||||
#define SCM_FRAME_STACK_ADDRESS(fp) (SCM_FRAME_STRUCT (fp)->stack)
|
||||
#define SCM_FRAME_UPPER_ADDRESS(fp) ((SCM*)&SCM_FRAME_STRUCT (fp)->return_address)
|
||||
#define SCM_FRAME_LOWER_ADDRESS(fp) ((SCM*)SCM_FRAME_STRUCT (fp))
|
||||
|
@ -85,8 +90,6 @@ struct scm_vm_frame
|
|||
(SCM_FRAME_STRUCT (fp)->return_address)
|
||||
#define SCM_FRAME_SET_RETURN_ADDRESS(fp, ra) \
|
||||
SCM_FRAME_STRUCT (fp)->return_address = (ra)
|
||||
#define SCM_FRAME_SET_MV_RETURN_ADDRESS(fp, mvra) \
|
||||
SCM_FRAME_STRUCT (fp)->mv_return_address = (mvra)
|
||||
#define SCM_FRAME_DYNAMIC_LINK(fp) \
|
||||
(SCM_FRAME_STRUCT (fp)->dynamic_link)
|
||||
#define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) \
|
||||
|
@ -97,34 +100,13 @@ struct scm_vm_frame
|
|||
(SCM_FRAME_STRUCT (fp)->program)
|
||||
|
||||
|
||||
/*
|
||||
* RTL frames
|
||||
*/
|
||||
|
||||
/* The frame format for the new RTL programs is almost like that for the
|
||||
stack-vm programs. They differ in their handling of MV returns,
|
||||
however. For RTL, every call is an MV call: every call has an MVRA.
|
||||
Unlike the stack-vm programs, the MVRA for RTL programs is computable
|
||||
from the RA -- it's always one word (4 bytes) before the RA.
|
||||
|
||||
Until we completely migrate to the RTL VM, we will also write the
|
||||
MVRA to the stack.
|
||||
|
||||
When an RTL program returns multiple values, it will shuffle them
|
||||
down to start contiguously from slot 0, as for a tail call. This
|
||||
means that when the caller goes to access them, there are 2 or 3
|
||||
empty words between the top of the caller stack and the bottom of the
|
||||
values, corresponding to the frame that was just popped.
|
||||
*/
|
||||
|
||||
/* FIXME: Replace SCM_FRAME_RETURN_ADDRESS with these. */
|
||||
#define SCM_FRAME_RTL_RETURN_ADDRESS(fp) \
|
||||
((scm_t_uint32 *) SCM_FRAME_RETURN_ADDRESS (fp))
|
||||
#define SCM_FRAME_SET_RTL_RETURN_ADDRESS(fp, ip) \
|
||||
SCM_FRAME_SET_RETURN_ADDRESS (fp, (scm_t_uint8 *) (ip))
|
||||
|
||||
#define SCM_FRAME_SET_RTL_MV_RETURN_ADDRESS(fp, ip) \
|
||||
SCM_FRAME_SET_MV_RETURN_ADDRESS (fp, (scm_t_uint8 *) (ip))
|
||||
|
||||
|
||||
/*
|
||||
* Heap frames
|
||||
|
|
|
@ -142,12 +142,12 @@
|
|||
|
||||
/* Reserve stack space for a frame. Will check that there is sufficient
|
||||
stack space for N locals, including the procedure, in addition to
|
||||
3 words to set up the next frame. Invoke after preparing the new
|
||||
2 words to set up the next frame. Invoke after preparing the new
|
||||
frame and setting the fp and ip. */
|
||||
#define ALLOC_FRAME(n) \
|
||||
do { \
|
||||
SCM *new_sp = vp->sp = fp - 1 + n - 1; \
|
||||
CHECK_OVERFLOW (new_sp + 4); \
|
||||
CHECK_OVERFLOW (new_sp + 3); \
|
||||
} while (0)
|
||||
|
||||
/* Reset the current frame to hold N locals. Used when we know that no
|
||||
|
@ -229,10 +229,9 @@
|
|||
/* Clear frame. */ \
|
||||
sp[0] = SCM_BOOL_F; \
|
||||
sp[1] = SCM_BOOL_F; \
|
||||
sp[2] = SCM_BOOL_F; \
|
||||
/* Leave proc. */ \
|
||||
sp[4] = val; \
|
||||
vp->sp = sp + 4; \
|
||||
sp[3] = val; \
|
||||
vp->sp = sp + 3; \
|
||||
POP_CONTINUATION_HOOK (sp, 1); \
|
||||
NEXT (0); \
|
||||
} while (0)
|
||||
|
@ -446,11 +445,11 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
{
|
||||
SCM *base;
|
||||
|
||||
/* Check that we have enough space: 4 words for the boot
|
||||
continuation, 4 + nargs for the procedure application, and 4 for
|
||||
/* Check that we have enough space: 3 words for the boot
|
||||
continuation, 3 + nargs for the procedure application, and 3 for
|
||||
setting up a new frame. */
|
||||
base = vp->sp + 1;
|
||||
CHECK_OVERFLOW (vp->sp + 4 + 4 + nargs_ + 4);
|
||||
CHECK_OVERFLOW (vp->sp + 3 + 3 + nargs_ + 3);
|
||||
|
||||
/* Since it's possible to receive the arguments on the stack itself,
|
||||
and indeed the regular VM invokes us that way, shuffle up the
|
||||
|
@ -458,24 +457,22 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
{
|
||||
int i;
|
||||
for (i = nargs_ - 1; i >= 0; i--)
|
||||
base[8 + i] = argv[i];
|
||||
base[6 + i] = argv[i];
|
||||
}
|
||||
|
||||
/* Initial frame, saving previous fp and ip, with the boot
|
||||
continuation. */
|
||||
base[0] = SCM_PACK (fp); /* dynamic link */
|
||||
base[1] = SCM_PACK (0); /* the boot continuation does not return to scheme */
|
||||
base[2] = SCM_PACK (ip); /* ra */
|
||||
base[3] = rtl_boot_continuation;
|
||||
fp = &base[4];
|
||||
base[1] = SCM_PACK (ip); /* ra */
|
||||
base[2] = rtl_boot_continuation;
|
||||
fp = &base[3];
|
||||
ip = (scm_t_uint32 *) rtl_boot_continuation_code;
|
||||
|
||||
/* MV-call frame, function & arguments */
|
||||
base[4] = SCM_PACK (fp); /* dynamic link */
|
||||
base[5] = SCM_PACK (ip); /* in RTL programs, MVRA same as RA */
|
||||
base[6] = SCM_PACK (ip); /* ra */
|
||||
base[7] = program;
|
||||
fp = vp->fp = &base[8];
|
||||
base[3] = SCM_PACK (fp); /* dynamic link */
|
||||
base[4] = SCM_PACK (ip); /* ra */
|
||||
base[5] = program;
|
||||
fp = vp->fp = &base[6];
|
||||
RESET_FRAME (nargs_ + 1);
|
||||
}
|
||||
|
||||
|
@ -525,20 +522,20 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
*/
|
||||
VM_DEFINE_OP (0, halt, "halt", OP1 (U8_X24))
|
||||
{
|
||||
scm_t_uint32 nvals = FRAME_LOCALS_COUNT() - 5;
|
||||
scm_t_uint32 nvals = FRAME_LOCALS_COUNT() - 4;
|
||||
SCM ret;
|
||||
|
||||
/* Boot closure in r0, empty frame in r1/r2/r3, proc in r4, values from r5. */
|
||||
/* Boot closure in r0, empty frame in r1/r2, proc in r3, values from r4. */
|
||||
|
||||
if (nvals == 1)
|
||||
ret = LOCAL_REF (5);
|
||||
ret = LOCAL_REF (4);
|
||||
else
|
||||
{
|
||||
scm_t_uint32 n;
|
||||
ret = SCM_EOL;
|
||||
SYNC_BEFORE_GC();
|
||||
for (n = nvals; n > 0; n--)
|
||||
ret = scm_cons (LOCAL_REF (5 + n - 1), ret);
|
||||
ret = scm_cons (LOCAL_REF (4 + n - 1), ret);
|
||||
ret = scm_values (ret);
|
||||
}
|
||||
|
||||
|
@ -574,7 +571,6 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
|
||||
fp = vp->fp = old_fp + proc;
|
||||
SCM_FRAME_SET_DYNAMIC_LINK (fp, old_fp);
|
||||
SCM_FRAME_SET_RTL_MV_RETURN_ADDRESS (fp, 0);
|
||||
SCM_FRAME_SET_RTL_RETURN_ADDRESS (fp, ip + 2);
|
||||
|
||||
RESET_FRAME (nlocals);
|
||||
|
@ -717,7 +713,6 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
|
|||
/* Clear stack frame. */
|
||||
base[-2] = SCM_BOOL_F;
|
||||
base[-3] = SCM_BOOL_F;
|
||||
base[-4] = SCM_BOOL_F;
|
||||
|
||||
POP_CONTINUATION_HOOK (base, nvalues);
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ vm_return_to_continuation (SCM vm, SCM cont, size_t n, SCM *argv)
|
|||
vp = SCM_VM_DATA (vm);
|
||||
cp = SCM_VM_CONT_DATA (cont);
|
||||
|
||||
if (vp->stack_size < cp->stack_size + n + 4)
|
||||
if (vp->stack_size < cp->stack_size + n + 3)
|
||||
scm_misc_error ("vm-engine", "not enough space to reinstate continuation",
|
||||
scm_list_2 (vm, cont));
|
||||
|
||||
|
@ -165,7 +165,7 @@ vm_return_to_continuation (SCM vm, SCM cont, size_t n, SCM *argv)
|
|||
size_t i;
|
||||
|
||||
/* Push on an empty frame, as the continuation expects. */
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
vp->sp++;
|
||||
*vp->sp = SCM_BOOL_F;
|
||||
|
|
|
@ -258,7 +258,7 @@ are comparable with eqv?. A tmp slot may be used."
|
|||
(find-first-zero live-slots)))
|
||||
|
||||
(define (compute-call-proc-slot live-slots)
|
||||
(+ 3 (find-first-trailing-zero live-slots)))
|
||||
(+ 2 (find-first-trailing-zero live-slots)))
|
||||
|
||||
(define (compute-prompt-handler-proc-slot live-slots)
|
||||
(1- (find-first-trailing-zero live-slots)))
|
||||
|
|
|
@ -701,11 +701,9 @@ returned instead."
|
|||
;(define-tc7-macro-assembler br-if-fluid 37)
|
||||
;(define-tc7-macro-assembler br-if-dynamic-state 45)
|
||||
;(define-tc7-macro-assembler br-if-frame 47)
|
||||
;(define-tc7-macro-assembler br-if-objcode 53)
|
||||
;(define-tc7-macro-assembler br-if-vm 55)
|
||||
;(define-tc7-macro-assembler br-if-vm-cont 71)
|
||||
;(define-tc7-macro-assembler br-if-rtl-program 69)
|
||||
;(define-tc7-macro-assembler br-if-program 79)
|
||||
;(define-tc7-macro-assembler br-if-weak-set 85)
|
||||
;(define-tc7-macro-assembler br-if-weak-table 87)
|
||||
;(define-tc7-macro-assembler br-if-array 93)
|
||||
|
@ -1202,7 +1200,7 @@ needed."
|
|||
|
||||
;; FIXME: Define these somewhere central, shared with C.
|
||||
(define *bytecode-major-version* #x0202)
|
||||
(define *bytecode-minor-version* 2)
|
||||
(define *bytecode-minor-version* 3)
|
||||
|
||||
(define (link-dynamic-section asm text rw rw-init)
|
||||
"Link the dynamic section for an ELF image with RTL text, given the
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue