1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-01 04:10:18 +02:00

attempt to clear stale references on VM C stack

* libguile/vm-engine.h (DEAD): New macro, nulls out a value.

* libguile/vm-i-system.c:
* libguile/vm-i-loader.c:
* libguile/vm-i-scheme.c: Use DEAD when variables become dead.

Later we can #ifdef this out, but I want to give the buildbots a try
with this patch to make sure it's correct.
This commit is contained in:
Andy Wingo 2012-01-27 19:04:46 +01:00
parent c0e4449908
commit 04b2d77354
4 changed files with 229 additions and 10 deletions

View file

@ -84,6 +84,7 @@ VM_DEFINE_INSTRUCTION (3, dup, "dup", 0, 0, 1)
{
SCM x = *sp;
PUSH (x);
DEAD (x);
NEXT;
}
@ -226,6 +227,7 @@ VM_DEFINE_INSTRUCTION (18, vector, "vector", 2, -1, 1)
memcpy (SCM_I_VECTOR_WELTS(vect), sp, sizeof(SCM) * len);
NULLSTACK (len);
*sp = vect;
DEAD (vect);
NEXT;
}
@ -330,6 +332,7 @@ VM_DEFINE_INSTRUCTION (25, variable_ref, "variable-ref", 0, 1, 1)
{
SCM o = VARIABLE_REF (x);
*sp = o;
DEAD (o);
}
NEXT;
@ -347,18 +350,20 @@ VM_DEFINE_INSTRUCTION (26, variable_bound, "variable-bound?", 0, 1, 1)
}
else
*sp = scm_from_bool (VARIABLE_BOUNDP (x));
DEAD (x);
NEXT;
}
VM_DEFINE_INSTRUCTION (27, toplevel_ref, "toplevel-ref", 1, 0, 1)
{
unsigned objnum = FETCH ();
SCM what, resolved;
SCM what;
CHECK_OBJECT (objnum);
what = OBJECT_REF (objnum);
if (!SCM_VARIABLEP (what))
{
SCM resolved;
SYNC_REGISTER ();
resolved = resolve_variable (what, scm_program_module (program));
if (!VARIABLE_BOUNDP (resolved))
@ -367,16 +372,18 @@ VM_DEFINE_INSTRUCTION (27, toplevel_ref, "toplevel-ref", 1, 0, 1)
goto vm_error_unbound;
}
what = resolved;
DEAD (resolved);
OBJECT_SET (objnum, what);
}
PUSH (VARIABLE_REF (what));
DEAD (what);
NEXT;
}
VM_DEFINE_INSTRUCTION (28, long_toplevel_ref, "long-toplevel-ref", 2, 0, 1)
{
SCM what, resolved;
SCM what;
unsigned int objnum = FETCH ();
objnum <<= 8;
objnum += FETCH ();
@ -385,6 +392,7 @@ VM_DEFINE_INSTRUCTION (28, long_toplevel_ref, "long-toplevel-ref", 2, 0, 1)
if (!SCM_VARIABLEP (what))
{
SCM resolved;
SYNC_REGISTER ();
resolved = resolve_variable (what, scm_program_module (program));
if (!VARIABLE_BOUNDP (resolved))
@ -393,10 +401,12 @@ VM_DEFINE_INSTRUCTION (28, long_toplevel_ref, "long-toplevel-ref", 2, 0, 1)
goto vm_error_unbound;
}
what = resolved;
DEAD (resolved);
OBJECT_SET (objnum, what);
}
PUSH (VARIABLE_REF (what));
DEAD (what);
NEXT;
}
@ -407,6 +417,7 @@ VM_DEFINE_INSTRUCTION (29, local_set, "local-set", 1, 1, 0)
SCM x;
POP (x);
LOCAL_SET (FETCH (), x);
DEAD (x);
NEXT;
}
@ -418,6 +429,7 @@ VM_DEFINE_INSTRUCTION (30, long_local_set, "long-local-set", 2, 1, 0)
i += FETCH ();
POP (x);
LOCAL_SET (i, x);
DEAD (x);
NEXT;
}
@ -449,6 +461,7 @@ VM_DEFINE_INSTRUCTION (32, toplevel_set, "toplevel-set", 1, 1, 0)
}
VARIABLE_SET (what, *sp);
DEAD (what);
DROP ();
NEXT;
}
@ -470,6 +483,7 @@ VM_DEFINE_INSTRUCTION (33, long_toplevel_set, "long-toplevel-set", 2, 1, 0)
}
VARIABLE_SET (what, *sp);
DEAD (what);
DROP ();
NEXT;
}
@ -496,7 +510,6 @@ VM_DEFINE_INSTRUCTION (33, long_toplevel_set, "long-toplevel-set", 2, 1, 0)
ip += offset; \
if (offset < 0) \
VM_HANDLE_INTERRUPTS; \
NEXT; \
}
VM_DEFINE_INSTRUCTION (34, br, "br", 3, 0, 0)
@ -514,6 +527,8 @@ VM_DEFINE_INSTRUCTION (35, br_if, "br-if", 3, 0, 0)
SCM x;
POP (x);
BR (scm_is_true (x));
DEAD (x);
NEXT;
}
VM_DEFINE_INSTRUCTION (36, br_if_not, "br-if-not", 3, 0, 0)
@ -521,6 +536,8 @@ VM_DEFINE_INSTRUCTION (36, br_if_not, "br-if-not", 3, 0, 0)
SCM x;
POP (x);
BR (scm_is_false (x));
DEAD (x);
NEXT;
}
VM_DEFINE_INSTRUCTION (37, br_if_eq, "br-if-eq", 3, 0, 0)
@ -528,6 +545,9 @@ VM_DEFINE_INSTRUCTION (37, br_if_eq, "br-if-eq", 3, 0, 0)
SCM x, y;
POP2 (y, x);
BR (scm_is_eq (x, y));
DEAD (x);
DEAD (y);
NEXT;
}
VM_DEFINE_INSTRUCTION (38, br_if_not_eq, "br-if-not-eq", 3, 0, 0)
@ -535,6 +555,9 @@ VM_DEFINE_INSTRUCTION (38, br_if_not_eq, "br-if-not-eq", 3, 0, 0)
SCM x, y;
POP2 (y, x);
BR (!scm_is_eq (x, y));
DEAD (x);
DEAD (y);
NEXT;
}
VM_DEFINE_INSTRUCTION (39, br_if_null, "br-if-null", 3, 0, 0)
@ -542,6 +565,8 @@ VM_DEFINE_INSTRUCTION (39, br_if_null, "br-if-null", 3, 0, 0)
SCM x;
POP (x);
BR (scm_is_null (x));
DEAD (x);
NEXT;
}
VM_DEFINE_INSTRUCTION (40, br_if_not_null, "br-if-not-null", 3, 0, 0)
@ -549,6 +574,8 @@ VM_DEFINE_INSTRUCTION (40, br_if_not_null, "br-if-not-null", 3, 0, 0)
SCM x;
POP (x);
BR (!scm_is_null (x));
DEAD (x);
NEXT;
}
@ -712,6 +739,8 @@ VM_DEFINE_INSTRUCTION (48, bind_kwargs, "bind-kwargs", 5, 0, 0)
goto vm_error_kwargs_invalid_keyword;
}
DEAD (kw);
NEXT;
}
@ -729,6 +758,7 @@ VM_DEFINE_INSTRUCTION (49, push_rest, "push-rest", 2, -1, -1)
/* No need to check for underflow. */
CONS (rest, *sp--, rest);
PUSH (rest);
DEAD (rest);
NEXT;
}
@ -745,6 +775,7 @@ VM_DEFINE_INSTRUCTION (50, bind_rest, "bind-rest", 4, -1, -1)
/* No need to check for underflow. */
CONS (rest, *sp--, rest);
LOCAL_SET (i, rest);
DEAD (rest);
NEXT;
}
@ -935,6 +966,7 @@ VM_DEFINE_INSTRUCTION (55, subr_call, "subr-call", 1, -1, -1)
abort ();
}
DEAD (pointer);
NULLSTACK_FOR_NONLOCAL_EXIT ();
if (SCM_UNLIKELY (SCM_VALUESP (ret)))
@ -943,11 +975,13 @@ VM_DEFINE_INSTRUCTION (55, subr_call, "subr-call", 1, -1, -1)
ret = scm_struct_ref (ret, SCM_INUM0);
nvalues = scm_ilength (ret);
PUSH_LIST (ret, scm_is_null);
DEAD (ret);
goto vm_return_values;
}
else
{
PUSH (ret);
DEAD (ret);
goto vm_return;
}
}
@ -982,6 +1016,7 @@ VM_DEFINE_INSTRUCTION (56, smob_call, "smob-call", 1, -1, -1)
abort ();
}
DEAD (smob);
NULLSTACK_FOR_NONLOCAL_EXIT ();
if (SCM_UNLIKELY (SCM_VALUESP (ret)))
@ -990,11 +1025,13 @@ VM_DEFINE_INSTRUCTION (56, smob_call, "smob-call", 1, -1, -1)
ret = scm_struct_ref (ret, SCM_INUM0);
nvalues = scm_ilength (ret);
PUSH_LIST (ret, scm_is_null);
DEAD (ret);
goto vm_return_values;
}
else
{
PUSH (ret);
DEAD (ret);
goto vm_return;
}
}
@ -1010,6 +1047,7 @@ VM_DEFINE_INSTRUCTION (57, foreign_call, "foreign-call", 1, -1, -1)
ret = scm_i_foreign_call (foreign, sp - nargs + 1);
DEAD (foreign);
NULLSTACK_FOR_NONLOCAL_EXIT ();
if (SCM_UNLIKELY (SCM_VALUESP (ret)))
@ -1018,11 +1056,13 @@ VM_DEFINE_INSTRUCTION (57, foreign_call, "foreign-call", 1, -1, -1)
ret = scm_struct_ref (ret, SCM_INUM0);
nvalues = scm_ilength (ret);
PUSH_LIST (ret, scm_is_null);
DEAD (ret);
goto vm_return_values;
}
else
{
PUSH (ret);
DEAD (ret);
goto vm_return;
}
}
@ -1039,7 +1079,7 @@ VM_DEFINE_INSTRUCTION (58, continuation_call, "continuation-call", 0, -1, 0)
sp - (fp - 1), fp);
scm_i_reinstate_continuation (contregs);
/* no NEXT */
/* no DEAD, no NEXT */
abort ();
}
@ -1049,12 +1089,15 @@ VM_DEFINE_INSTRUCTION (59, partial_cont_call, "partial-cont-call", 0, -1, 0)
POP2 (intwinds, vmcont);
SYNC_REGISTER ();
if (SCM_UNLIKELY (!SCM_VM_CONT_REWINDABLE_P (vmcont)))
{ finish_args = vmcont;
{
finish_args = vmcont;
goto vm_error_continuation_not_rewindable;
}
prevwinds = scm_i_dynwinds ();
vm_reinstate_partial_continuation (vm, vmcont, intwinds, sp + 1 - fp, fp,
vm_cookie);
DEAD (vmcont);
DEAD (intwinds);
/* Rewind prompt jmpbuffers, if any. */
{
@ -1062,7 +1105,9 @@ VM_DEFINE_INSTRUCTION (59, partial_cont_call, "partial-cont-call", 0, -1, 0)
for (; !scm_is_eq (winds, prevwinds); winds = scm_cdr (winds))
if (SCM_PROMPT_P (scm_car (winds)) && SCM_PROMPT_SETJMP (scm_car (winds)))
break;
DEAD (winds);
}
DEAD (prevwinds);
CACHE_REGISTER ();
program = SCM_FRAME_PROGRAM (fp);
@ -1075,6 +1120,7 @@ VM_DEFINE_INSTRUCTION (60, tail_call_nargs, "tail-call/nargs", 0, 0, 1)
SCM x;
POP (x);
nargs = scm_to_int (x);
DEAD (x);
/* FIXME: should truncate values? */
goto vm_tail_call;
}
@ -1084,6 +1130,7 @@ VM_DEFINE_INSTRUCTION (61, call_nargs, "call/nargs", 0, 0, 1)
SCM x;
POP (x);
nargs = scm_to_int (x);
DEAD (x);
/* FIXME: should truncate values? */
goto vm_call;
}
@ -1158,6 +1205,7 @@ VM_DEFINE_INSTRUCTION (63, apply, "apply", 1, -1, 1)
}
PUSH_LIST (ls, SCM_NULL_OR_NIL_P);
DEAD (ls);
nargs += len - 2;
goto vm_call;
@ -1180,6 +1228,7 @@ VM_DEFINE_INSTRUCTION (64, tail_apply, "tail-apply", 1, -1, 1)
}
PUSH_LIST (ls, SCM_NULL_OR_NIL_P);
DEAD (ls);
nargs += len - 2;
goto vm_tail_call;
@ -1193,13 +1242,16 @@ VM_DEFINE_INSTRUCTION (65, call_cc, "call/cc", 0, 1, 1)
SYNC_ALL ();
vm_cont = scm_i_vm_capture_stack (vp->stack_base, fp, sp, ip, NULL, 0);
cont = scm_i_make_continuation (&first, vm, vm_cont);
DEAD (vm_cont);
if (first)
{
PUSH (SCM_PACK (0)); /* dynamic link */
PUSH (SCM_PACK (0)); /* mvra */
PUSH (SCM_PACK (0)); /* ra */
PUSH (proc);
DEAD (proc);
PUSH (cont);
DEAD (cont);
nargs = 1;
goto vm_call;
}
@ -1212,6 +1264,8 @@ VM_DEFINE_INSTRUCTION (65, call_cc, "call/cc", 0, 1, 1)
So, pull our regs back down from the vp, and march on to the
next instruction. */
DEAD (proc);
DEAD (cont);
CACHE_REGISTER ();
program = SCM_FRAME_PROGRAM (fp);
CACHE_PROGRAM ();
@ -1235,15 +1289,20 @@ VM_DEFINE_INSTRUCTION (66, tail_call_cc, "tail-call/cc", 0, 1, 1)
SCM_FRAME_MV_RETURN_ADDRESS (fp),
0);
cont = scm_i_make_continuation (&first, vm, vm_cont);
DEAD (vm_cont);
if (first)
{
PUSH (proc);
DEAD (proc);
PUSH (cont);
DEAD (cont);
nargs = 1;
goto vm_tail_call;
}
else
{
DEAD (proc);
DEAD (cont);
/* Otherwise, cache regs and NEXT, as above. Invoking the continuation
does a return from the frame, either to the RA or
MVRA. */
@ -1288,6 +1347,8 @@ VM_DEFINE_INSTRUCTION (67, return, "return", 0, 1, 1)
/* Set return value (sp is already pushed) */
*sp = ret;
DEAD (ret);
}
/* Restore the last program */
@ -1375,6 +1436,7 @@ VM_DEFINE_INSTRUCTION (69, return_values_star, "return/values*", 1, -1, -1)
goto vm_error_improper_list;
}
DEAD (l);
goto vm_return_values;
}
@ -1383,6 +1445,7 @@ VM_DEFINE_INSTRUCTION (70, return_nvalues, "return/nvalues", 0, 1, -1)
SCM n;
POP (n);
nvalues = scm_to_int (n);
DEAD (n);
ASSERT (nvalues >= 0);
goto vm_return_values;
}
@ -1393,6 +1456,7 @@ VM_DEFINE_INSTRUCTION (71, truncate_values, "truncate-values", 2, -1, -1)
int nbinds, rest;
POP (x);
nvalues = scm_to_int (x);
DEAD (x);
nbinds = FETCH ();
rest = FETCH ();
@ -1416,6 +1480,7 @@ VM_DEFINE_INSTRUCTION (72, box, "box", 1, 1, 0)
POP (val);
SYNC_BEFORE_GC ();
LOCAL_SET (FETCH (), scm_cell (scm_tc7_variable, SCM_UNPACK (val)));
DEAD (val);
NEXT;
}
@ -1437,6 +1502,7 @@ VM_DEFINE_INSTRUCTION (74, local_boxed_ref, "local-boxed-ref", 1, 0, 1)
SCM v = LOCAL_REF (FETCH ());
ASSERT_BOUND_VARIABLE (v);
PUSH (VARIABLE_REF (v));
DEAD (v);
NEXT;
}
@ -1447,6 +1513,8 @@ VM_DEFINE_INSTRUCTION (75, local_boxed_set, "local-boxed-set", 1, 1, 0)
POP (val);
ASSERT_VARIABLE (v);
VARIABLE_SET (v, val);
DEAD (v);
DEAD (val);
NEXT;
}
@ -1469,6 +1537,7 @@ VM_DEFINE_INSTRUCTION (77, free_boxed_ref, "free-boxed-ref", 1, 0, 1)
v = FREE_VARIABLE_REF (idx);
ASSERT_BOUND_VARIABLE (v);
PUSH (VARIABLE_REF (v));
DEAD (v);
NEXT;
}
@ -1481,6 +1550,8 @@ VM_DEFINE_INSTRUCTION (78, free_boxed_set, "free-boxed-set", 1, 1, 0)
v = FREE_VARIABLE_REF (idx);
ASSERT_BOUND_VARIABLE (v);
VARIABLE_SET (v, val);
DEAD (v);
DEAD (val);
NEXT;
}
@ -1499,6 +1570,7 @@ VM_DEFINE_INSTRUCTION (79, make_closure, "make-closure", 2, -1, 1)
sp[-len] = closure;
for (n = 0; n < len; n++)
SCM_PROGRAM_FREE_VARIABLE_SET (closure, n, sp[-len + 1 + n]);
DEAD (closure);
DROPN (len);
NEXT;
}
@ -1524,6 +1596,7 @@ VM_DEFINE_INSTRUCTION (81, fix_closure, "fix-closure", 2, -1, 0)
len = SCM_PROGRAM_NUM_FREE_VARIABLES (x);
for (n = 0; n < len; n++)
SCM_PROGRAM_FREE_VARIABLE_SET (x, n, sp[-len + 1 + n]);
DEAD (x);
DROPN (len);
NEXT;
}
@ -1536,6 +1609,8 @@ VM_DEFINE_INSTRUCTION (82, define, "define", 0, 0, 2)
VARIABLE_SET (scm_sym2var (sym, scm_current_module_lookup_closure (),
SCM_BOOL_T),
val);
DEAD (sym);
DEAD (val);
NEXT;
}
@ -1579,6 +1654,8 @@ VM_DEFINE_INSTRUCTION (85, prompt, "prompt", 4, 2, 0)
vm_engine that can be assigned *has* been assigned. So we need to pull
all our state back from the ip/fp/sp.
*/
DEAD (k);
DEAD (prompt);
CACHE_REGISTER ();
program = SCM_FRAME_PROGRAM (fp);
CACHE_PROGRAM ();
@ -1588,6 +1665,9 @@ VM_DEFINE_INSTRUCTION (85, prompt, "prompt", 4, 2, 0)
NEXT;
}
DEAD (k);
DEAD (prompt);
/* Otherwise setjmp returned for the first time, so we go to execute the
prompt's body. */
NEXT;
@ -1612,6 +1692,8 @@ VM_DEFINE_INSTRUCTION (86, wind, "wind", 0, 2, 0)
goto vm_error_not_a_thunk;
}
scm_i_set_dynwinds (scm_cons (scm_cons (wind, unwind), scm_i_dynwinds ()));
DEAD (wind);
DEAD (unwind);
NEXT;
}
@ -1647,6 +1729,7 @@ VM_DEFINE_INSTRUCTION (89, wind_fluids, "wind-fluids", 1, -1, 0)
scm_i_swap_with_fluids (wf, current_thread->dynamic_state);
scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ()));
DEAD (wf);
NEXT;
}
@ -1656,6 +1739,7 @@ VM_DEFINE_INSTRUCTION (90, unwind_fluids, "unwind-fluids", 0, 0, 0)
wf = scm_car (scm_i_dynwinds ());
scm_i_set_dynwinds (scm_cdr (scm_i_dynwinds ()));
scm_i_swap_with_fluids (wf, current_thread->dynamic_state);
DEAD (wf);
NEXT;
}
@ -1670,12 +1754,14 @@ VM_DEFINE_INSTRUCTION (91, fluid_ref, "fluid-ref", 0, 1, 1)
|| ((num = SCM_I_FLUID_NUM (*sp)) >= SCM_SIMPLE_VECTOR_LENGTH (fluids)))
{
/* Punt dynstate expansion and error handling to the C proc. */
DEAD (fluids);
SYNC_REGISTER ();
*sp = scm_fluid_ref (*sp);
}
else
{
SCM val = SCM_SIMPLE_VECTOR_REF (fluids, num);
DEAD (fluids);
if (scm_is_eq (val, SCM_UNDEFINED))
val = SCM_I_FLUID_DEFAULT (*sp);
if (SCM_UNLIKELY (scm_is_eq (val, SCM_UNDEFINED)))
@ -1705,7 +1791,9 @@ VM_DEFINE_INSTRUCTION (92, fluid_set, "fluid-set", 0, 2, 0)
}
else
SCM_SIMPLE_VECTOR_SET (fluids, num, val);
DEAD (fluids);
DEAD (fluid);
DEAD (val);
NEXT;
}