diff options
author | Andy Wingo <wingo@pobox.com> | 2012-01-27 19:04:46 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2012-01-27 19:34:19 +0100 |
commit | 04b2d773548c57b6eadd1808a8d15cce47af9630 (patch) | |
tree | 18fa47ca6a85f444788c286323a4c523be0f634e /libguile/vm-i-system.c | |
parent | c0e4449908eee84bcb293ec21c10fec646bde45d (diff) | |
download | guile-04b2d773548c57b6eadd1808a8d15cce47af9630.tar.gz |
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.
Diffstat (limited to 'libguile/vm-i-system.c')
-rw-r--r-- | libguile/vm-i-system.c | 100 |
1 files changed, 94 insertions, 6 deletions
diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c index 7a7bccc1b..1e3c2e54b 100644 --- a/libguile/vm-i-system.c +++ b/libguile/vm-i-system.c @@ -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; } |