fix bug related to tail calls an struct procedures; also disable GC accounting on minor collections

svn: r7413
This commit is contained in:
Matthew Flatt 2007-09-25 16:28:19 +00:00
parent ebc4e70a01
commit d0d6136356
6 changed files with 144 additions and 45 deletions

View File

@ -2971,7 +2971,8 @@ static void garbage_collect(int force_full)
TIME_STEP("cleaned heap"); TIME_STEP("cleaned heap");
reset_nursery(); reset_nursery();
TIME_STEP("reset nursurey"); TIME_STEP("reset nursurey");
do_btc_accounting(); if (gc_full)
do_btc_accounting();
TIME_STEP("accounted"); TIME_STEP("accounted");
if (generations_available) if (generations_available)
protect_old_pages(); protect_old_pages();

View File

@ -708,9 +708,11 @@ void *scheme_enlarge_runstack(long size, void *(*k)())
if (size) { if (size) {
/* If we keep growing the stack, then probably it /* If we keep growing the stack, then probably it
needs to be much larger, so at least double the needs to be much larger, so at least double the
stack size each time: */ stack size, to a point: */
long min_size; long min_size;
min_size = 2 * (p->runstack_size); min_size = 2 * (p->runstack_size);
if (min_size > 128000)
min_size = 128000;
if (size < min_size) if (size < min_size)
size = min_size; size = min_size;
} else { } else {
@ -5612,9 +5614,9 @@ static Scheme_Object *do_apply_known_k(void)
if ((v != SCHEME_MULTIPLE_VALUES) \ if ((v != SCHEME_MULTIPLE_VALUES) \
&& (v != SCHEME_TAIL_CALL_WAITING) \ && (v != SCHEME_TAIL_CALL_WAITING) \
&& (v != SCHEME_EVAL_WAITING) \ && (v != SCHEME_EVAL_WAITING) \
&& (SCHEME_TYPE(v) > (_scheme_last_type_ + 5))) \ && (SCHEME_TYPE(v) > (_scheme_last_type_ + 25))) \
{ Scheme_Object *o = *(Scheme_Object **)(v); \ { Scheme_Object *o = *(Scheme_Object **)(v); \
if (SCHEME_TYPE(o) > (_scheme_last_type_ + 5))\ if (SCHEME_TYPE(o) > (_scheme_last_type_ + 25))\
scheme_signal_error("bad type"); } scheme_signal_error("bad type"); }
#else #else
# define DEBUG_CHECK_TYPE(v) /**/ # define DEBUG_CHECK_TYPE(v) /**/
@ -6554,41 +6556,51 @@ scheme_do_eval(Scheme_Object *obj, int num_rands, Scheme_Object **rands,
return NULL; return NULL;
} else if (type == scheme_proc_struct_type) { } else if (type == scheme_proc_struct_type) {
int is_method; int is_method;
int check_rands = num_rands;
UPDATE_THREAD_RSPTR_FOR_ERROR(); /* in case */ do {
VACATE_TAIL_BUFFER_USE_RUNSTACK();
v = obj; UPDATE_THREAD_RSPTR_FOR_ERROR(); /* in case */
obj = scheme_extract_struct_procedure(obj, num_rands, rands, &is_method);
if (is_method) {
/* Have to add an extra argument to the front of rands */
if ((rands == RUNSTACK) && (RUNSTACK != RUNSTACK_START)){
/* Common case: we can just push self onto the front: */
rands = PUSH_RUNSTACK(p, RUNSTACK, 1);
rands[0] = v;
} else {
int i;
Scheme_Object **a;
if (p->tail_buffer && (num_rands < p->tail_buffer_size)) { v = obj;
/* Use tail-call buffer. Shift in such a way that this works if obj = scheme_extract_struct_procedure(obj, check_rands, rands, &is_method);
rands == p->tail_buffer */ if (is_method) {
a = p->tail_buffer; /* Have to add an extra argument to the front of rands */
} else { if ((rands == RUNSTACK) && (RUNSTACK != RUNSTACK_START)){
/* Uncommon general case --- allocate an array */ /* Common case: we can just push self onto the front: */
UPDATE_THREAD_RSPTR_FOR_GC(); rands = PUSH_RUNSTACK(p, RUNSTACK, 1);
a = MALLOC_N(Scheme_Object *, num_rands + 1); rands[0] = v;
} } else {
int i;
Scheme_Object **a;
for (i = num_rands; i--; ) { if (p->tail_buffer && (num_rands < p->tail_buffer_size)) {
a[i + 1] = rands[i]; /* Use tail-call buffer. Shift in such a way that this works if
} rands == p->tail_buffer */
a[0] = v; a = p->tail_buffer;
rands = a; } else {
} /* Uncommon general case --- allocate an array */
num_rands++; UPDATE_THREAD_RSPTR_FOR_GC();
} a = MALLOC_N(Scheme_Object *, num_rands + 1);
}
DO_CHECK_FOR_BREAK(p, UPDATE_THREAD_RSPTR_FOR_GC(); if (rands == p->tail_buffer) make_tail_buffer_safe();); for (i = num_rands; i--; ) {
a[i + 1] = rands[i];
}
a[0] = v;
rands = a;
}
num_rands++;
}
/* After we check arity once, no need to check again
(which would lead to O(n^2) checking for nested
struct procs): */
check_rands = -1;
DO_CHECK_FOR_BREAK(p, UPDATE_THREAD_RSPTR_FOR_GC(); if (rands == p->tail_buffer) make_tail_buffer_safe(););
} while (SAME_TYPE(scheme_proc_struct_type, SCHEME_TYPE(obj)));
goto apply_top; goto apply_top;
} else if (type == scheme_closed_prim_type) { } else if (type == scheme_closed_prim_type) {

View File

@ -600,6 +600,30 @@ static Scheme_Object *tail_call_with_values_from_multiple_result(Scheme_Object *
JIT_UPDATE_THREAD_RSPTR(); \ JIT_UPDATE_THREAD_RSPTR(); \
} }
#if 0
/* Debugging: checking for runstack overflow. A CHECK_RUNSTACK_OVERFLOW() should
be included after each decrement of JIT_RUNTACK. Failure is "reported" by
going into an immediate loop. */
static void *top;
static void *cr_tmp;
# define CHECK_RUNSTACK_OVERFLOW_NOCL() \
jit_sti_l(&cr_tmp, JIT_R0); jit_ldi_l(JIT_R0, &scheme_current_runstack_start); \
top = (_jit.x.pc); (void)jit_bltr_ul(top, JIT_RUNSTACK, JIT_R0); jit_ldi_l(JIT_R0, &cr_tmp)
# define CHECK_RUNSTACK_OVERFLOW() \
CHECK_LIMIT(); CHECK_RUNSTACK_OVERFLOW_NOCL()
#else
# define CHECK_RUNSTACK_OVERFLOW() /* empty */
# define CHECK_RUNSTACK_OVERFLOW_NOCL() /* empty */
#endif
#if 0
/* Debugging: ... */
static void *top4;
# define VALIDATE_RESULT(reg) top4 = (_jit.x.pc); (void)jit_beqi_ul(top4, reg, 0)
#else
# define VALIDATE_RESULT(reg) /* empty */
#endif
static void new_mapping(mz_jit_state *jitter) static void new_mapping(mz_jit_state *jitter)
{ {
jitter->num_mappings++; jitter->num_mappings++;
@ -630,6 +654,7 @@ static void mz_pushr_p_it(mz_jit_state *jitter, int reg)
jitter->mappings[jitter->num_mappings] = ((v << 1) | 0x1); jitter->mappings[jitter->num_mappings] = ((v << 1) | 0x1);
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW_NOCL();
jit_str_p(JIT_RUNSTACK, reg); jit_str_p(JIT_RUNSTACK, reg);
jitter->need_set_rs = 1; jitter->need_set_rs = 1;
@ -810,9 +835,25 @@ static int mz_is_closure(mz_jit_state *jitter, int i, int arity, int *_flags)
#define mz_pushr_p(x) mz_pushr_p_it(jitter, x) #define mz_pushr_p(x) mz_pushr_p_it(jitter, x)
#define mz_popr_p(x) mz_popr_p_it(jitter, x) #define mz_popr_p(x) mz_popr_p_it(jitter, x)
#if 0
/* Debugging: at each _finish(), double-check that the runstack register has been
copied into scheme_current_runstack. This code assumes that mz_finishr() is not
used with JIT_R0. Failure is "reported" by going into an immediate loop, but
check_location is set to the source line number to help indicate where the
problem originated. */
static void *top;
int check_location;
# define CONFIRM_RUNSTACK() (jit_movi_l(JIT_R0, __LINE__), jit_sti_l(&check_location, JIT_R0), \
jit_ldi_p(JIT_R0, &MZ_RUNSTACK), top = (_jit.x.pc), jit_bner_p(top, JIT_RUNSTACK, JIT_R0))
#else
# define CONFIRM_RUNSTACK() 0
#endif
#define mz_prepare(x) jit_prepare(x) #define mz_prepare(x) jit_prepare(x)
#define mz_finish(x) jit_finish(x) #define mz_finish(x) ((void)CONFIRM_RUNSTACK(), jit_finish(x))
#define mz_finishr(x) jit_finishr(x) #define mz_finishr(x) ((void)CONFIRM_RUNSTACK(), jit_finishr(x))
#define mz_nonrs_finish(x) jit_finish(x)
#define mz_retain(x) mz_retain_it(jitter, x) #define mz_retain(x) mz_retain_it(jitter, x)
#define mz_remap(x) mz_remap_it(jitter, x) #define mz_remap(x) mz_remap_it(jitter, x)
@ -1240,6 +1281,7 @@ static int generate_direct_prim_tail_call(mz_jit_state *jitter, int num_rands)
have the argument. */ have the argument. */
if (num_rands == 1) { if (num_rands == 1) {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
} }
@ -1304,6 +1346,7 @@ static int generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na
/* Fixed argc: */ /* Fixed argc: */
if (num_rands) { if (num_rands) {
jit_subi_p(JIT_R2, JIT_RUNSTACK_BASE, WORDS_TO_BYTES(num_rands)); jit_subi_p(JIT_R2, JIT_RUNSTACK_BASE, WORDS_TO_BYTES(num_rands));
CHECK_RUNSTACK_OVERFLOW();
for (i = num_rands; i--; ) { for (i = num_rands; i--; ) {
jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(i)); jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(i));
jit_stxi_p(WORDS_TO_BYTES(i), JIT_R2, JIT_R1); jit_stxi_p(WORDS_TO_BYTES(i), JIT_R2, JIT_R1);
@ -1317,6 +1360,7 @@ static int generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na
mz_get_local_p(JIT_R1, JIT_LOCAL2); mz_get_local_p(JIT_R1, JIT_LOCAL2);
jit_lshi_l(JIT_R1, JIT_R1, JIT_LOG_WORD_SIZE); jit_lshi_l(JIT_R1, JIT_R1, JIT_LOG_WORD_SIZE);
jit_subr_p(JIT_RUNSTACK, JIT_RUNSTACK, JIT_R1); jit_subr_p(JIT_RUNSTACK, JIT_RUNSTACK, JIT_R1);
CHECK_RUNSTACK_OVERFLOW();
} }
} else { } else {
/* Variable argc (in LOCAL2): /* Variable argc (in LOCAL2):
@ -1418,6 +1462,7 @@ static int generate_direct_prim_non_tail_call(mz_jit_state *jitter, int num_rand
if (num_rands == 1) { if (num_rands == 1) {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
} }
@ -1430,11 +1475,13 @@ static int generate_direct_prim_non_tail_call(mz_jit_state *jitter, int num_rand
mz_finishr(JIT_V1); mz_finishr(JIT_V1);
CHECK_LIMIT(); CHECK_LIMIT();
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
/* No need to check for multi values or tail-call, because /* No need to check for multi values or tail-call, because
we only use this for noncm primitives. */ we only use this for noncm primitives. */
if (num_rands == 1) { if (num_rands == 1) {
jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
jitter->need_set_rs = 1;
} }
if (pop_and_jump) { if (pop_and_jump) {
@ -1473,6 +1520,7 @@ static int generate_retry_call(mz_jit_state *jitter, int num_rands, int multi_ok
/* Yes, there's enough room. Adjust the runstack. */ /* Yes, there's enough room. Adjust the runstack. */
jit_subr_l(JIT_RUNSTACK, JIT_RUNSTACK, JIT_R2); jit_subr_l(JIT_RUNSTACK, JIT_RUNSTACK, JIT_R2);
CHECK_RUNSTACK_OVERFLOW();
/* Copy argument to runstack, then jump to reftop. */ /* Copy argument to runstack, then jump to reftop. */
jit_ldxi_l(JIT_R2, JIT_R1, &((Scheme_Thread *)0x0)->ku.apply.tail_num_rands); jit_ldxi_l(JIT_R2, JIT_R1, &((Scheme_Thread *)0x0)->ku.apply.tail_num_rands);
@ -1597,6 +1645,7 @@ static int generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
} }
CHECK_LIMIT(); CHECK_LIMIT();
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
if (!multi_ok) { if (!multi_ok) {
jit_insn *refm; jit_insn *refm;
__END_SHORT_JUMPS__(1); __END_SHORT_JUMPS__(1);
@ -1647,6 +1696,7 @@ static int generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
(void)mz_finishr(JIT_R1); (void)mz_finishr(JIT_R1);
CHECK_LIMIT(); CHECK_LIMIT();
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
if (!multi_ok) { if (!multi_ok) {
jit_insn *refm; jit_insn *refm;
__END_SHORT_JUMPS__(1); __END_SHORT_JUMPS__(1);
@ -1705,6 +1755,7 @@ static int generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
mz_patch_ucbranch(ref8); mz_patch_ucbranch(ref8);
} }
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
mz_patch_branch(ref6); mz_patch_branch(ref6);
if (!direct_native) { if (!direct_native) {
mz_patch_branch(ref10); mz_patch_branch(ref10);
@ -2002,6 +2053,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
if (num_rands) { if (num_rands) {
if (!direct_prim || (num_rands > 1)) { if (!direct_prim || (num_rands > 1)) {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(num_rands)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(num_rands));
CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, num_rands); mz_runstack_pushed(jitter, num_rands);
} else { } else {
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
@ -2141,8 +2193,12 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
(void)jit_calli(code); (void)jit_calli(code);
/* Whether we call a prim, a native, or something else, /* Whether we call a prim, a native, or something else,
scheme_current_runstack is up-to-date. */ scheme_current_runstack is up-to-date --- unless
jitter->need_set_rs = 0; it was a direct-prim call with 1 argument. */
if (direct_prim && (num_rands == 1))
jitter->need_set_rs = 1;
else
jitter->need_set_rs = 0;
} }
} }
@ -2282,6 +2338,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
if (rand2 && !simple_rand) { if (rand2 && !simple_rand) {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, 1); mz_runstack_pushed(jitter, 1);
generate_non_tail(rand, jitter, 0, 1); generate_non_tail(rand, jitter, 0, 1);
CHECK_LIMIT(); CHECK_LIMIT();
@ -2676,6 +2733,7 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter,
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, 1); mz_runstack_pushed(jitter, 1);
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
CHECK_LIMIT(); CHECK_LIMIT();
@ -2846,6 +2904,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
} else { } else {
(void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.cdr); (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.cdr);
} }
VALIDATE_RESULT(JIT_R0);
CHECK_LIMIT(); CHECK_LIMIT();
} }
__END_SHORT_JUMPS__(1); __END_SHORT_JUMPS__(1);
@ -2943,6 +3002,7 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
mz_runstack_unskipped(jitter, 2); mz_runstack_unskipped(jitter, 2);
} else { } else {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, 1); mz_runstack_pushed(jitter, 1);
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
@ -3220,6 +3280,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
if (!simple) { if (!simple) {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, 1); mz_runstack_pushed(jitter, 1);
} }
@ -3380,6 +3441,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
if (pushed) { if (pushed) {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(pushed)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(pushed));
CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, pushed); mz_runstack_pushed(jitter, pushed);
} }
@ -3823,6 +3885,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("local\n")); LOG_IT(("local\n"));
pos = mz_remap(SCHEME_LOCAL_POS(obj)); pos = mz_remap(SCHEME_LOCAL_POS(obj));
jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos));
VALIDATE_RESULT(JIT_R0);
END_JIT_DATA(2); END_JIT_DATA(2);
return 1; return 1;
} }
@ -3835,6 +3898,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
pos = mz_remap(SCHEME_LOCAL_POS(obj)); pos = mz_remap(SCHEME_LOCAL_POS(obj));
jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos));
jit_ldr_p(JIT_R0, JIT_R0); jit_ldr_p(JIT_R0, JIT_R0);
VALIDATE_RESULT(JIT_R0);
END_JIT_DATA(3); END_JIT_DATA(3);
return 1; return 1;
@ -4008,6 +4072,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
} else { } else {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
} }
CHECK_RUNSTACK_OVERFLOW();
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
jit_movi_l(JIT_R0, 1); jit_movi_l(JIT_R0, 1);
ref2 = jit_jmpi(jit_forward()); ref2 = jit_jmpi(jit_forward());
@ -4052,6 +4117,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
} else { } else {
jit_subr_ul(JIT_RUNSTACK, JIT_RUNSTACK, JIT_R2); jit_subr_ul(JIT_RUNSTACK, JIT_RUNSTACK, JIT_R2);
} }
CHECK_RUNSTACK_OVERFLOW();
/* Copy args: */ /* Copy args: */
jit_ldxi_l(JIT_R1, JIT_R1, &((Scheme_Thread *)0x0)->ku.multiple.array); jit_ldxi_l(JIT_R1, JIT_R1, &((Scheme_Thread *)0x0)->ku.multiple.array);
refloop = _jit.x.pc; refloop = _jit.x.pc;
@ -4142,6 +4208,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
(void)mz_finish(scheme_syntax_executers[pos]); (void)mz_finish(scheme_syntax_executers[pos]);
CHECK_LIMIT(); CHECK_LIMIT();
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
} }
} }
return 1; return 1;
@ -4437,6 +4504,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("letv...\n")); LOG_IT(("letv...\n"));
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(c)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(c));
CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, c); mz_runstack_pushed(jitter, c);
if (SCHEME_LET_AUTOBOX(lv)) { if (SCHEME_LET_AUTOBOX(lv)) {
@ -4521,6 +4589,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("leto...\n")); LOG_IT(("leto...\n"));
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, 1); mz_runstack_pushed(jitter, 1);
PAUSE_JIT_DATA(); PAUSE_JIT_DATA();
@ -4693,6 +4762,7 @@ static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_
if (cnt) { if (cnt) {
CHECK_LIMIT(); CHECK_LIMIT();
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt));
CHECK_RUNSTACK_OVERFLOW();
if (has_rest) if (has_rest)
--cnt; --cnt;
} }
@ -4845,6 +4915,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
break; break;
} }
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
if (i < 2) { if (i < 2) {
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
} else { } else {
@ -4891,6 +4962,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
break; break;
} }
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(2)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(2));
CHECK_RUNSTACK_OVERFLOW();
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
jit_stxi_p(WORDS_TO_BYTES(1), JIT_RUNSTACK, JIT_R1); jit_stxi_p(WORDS_TO_BYTES(1), JIT_RUNSTACK, JIT_R1);
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
@ -4943,6 +5015,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
argc = 2; argc = 2;
} }
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(argc)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(argc));
CHECK_RUNSTACK_OVERFLOW();
if (i == 2) { if (i == 2) {
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
jit_stxi_p(WORDS_TO_BYTES(1), JIT_RUNSTACK, JIT_R1); jit_stxi_p(WORDS_TO_BYTES(1), JIT_RUNSTACK, JIT_R1);
@ -4960,6 +5033,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
(void)mz_finishr(JIT_R2); (void)mz_finishr(JIT_R2);
CHECK_LIMIT(); CHECK_LIMIT();
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(argc)); jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(argc));
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
if (!j) { if (!j) {
@ -4996,6 +5070,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
mz_set_local_p(JIT_RUNSTACK, JIT_LOCAL1); mz_set_local_p(JIT_RUNSTACK, JIT_LOCAL1);
on_demand_jit_arity_code = jit_get_ip().ptr; /* <<<- arity variant starts here */ on_demand_jit_arity_code = jit_get_ip().ptr; /* <<<- arity variant starts here */
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(3)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(3));
CHECK_RUNSTACK_OVERFLOW();
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
jit_lshi_ul(JIT_R1, JIT_R1, 0x1); jit_lshi_ul(JIT_R1, JIT_R1, 0x1);
jit_ori_ul(JIT_R1, JIT_R1, 0x1); jit_ori_ul(JIT_R1, JIT_R1, 0x1);
@ -5036,6 +5111,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
mz_patch_branch(ref); mz_patch_branch(ref);
mz_patch_branch(ref2); mz_patch_branch(ref2);
CHECK_LIMIT(); CHECK_LIMIT();
JIT_UPDATE_THREAD_RSPTR();
mz_prepare(3); mz_prepare(3);
jit_pusharg_p(JIT_R2); jit_pusharg_p(JIT_R2);
jit_pusharg_p(JIT_R1); jit_pusharg_p(JIT_R1);
@ -5056,6 +5132,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
jit_pusharg_p(JIT_V1); jit_pusharg_p(JIT_V1);
(void)mz_finish(tail_call_with_values_from_multiple_result); (void)mz_finish(tail_call_with_values_from_multiple_result);
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
/* Pop saved runstack val and return: */ /* Pop saved runstack val and return: */
mz_get_local_p(JIT_NOT_RET, JIT_LOCAL1); mz_get_local_p(JIT_NOT_RET, JIT_LOCAL1);
jit_sti_p(&scheme_current_runstack, JIT_NOT_RET); jit_sti_p(&scheme_current_runstack, JIT_NOT_RET);
@ -5141,6 +5218,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
(void)mz_finish(call_with_values_from_multiple_result); (void)mz_finish(call_with_values_from_multiple_result);
} }
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
mz_epilog(JIT_R1); mz_epilog(JIT_R1);
CHECK_LIMIT(); CHECK_LIMIT();
} }
@ -5232,6 +5310,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
jit_ori_ul(JIT_R1, JIT_R1, 0x1); jit_ori_ul(JIT_R1, JIT_R1, 0x1);
} }
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(2)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(2));
CHECK_RUNSTACK_OVERFLOW();
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
jit_stxi_p(WORDS_TO_BYTES(1), JIT_RUNSTACK, JIT_R1); jit_stxi_p(WORDS_TO_BYTES(1), JIT_RUNSTACK, JIT_R1);
if (!iii) { if (!iii) {
@ -5366,6 +5445,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
reffail = _jit.x.pc; reffail = _jit.x.pc;
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
jit_movi_i(JIT_R1, 1); jit_movi_i(JIT_R1, 1);
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
@ -5449,6 +5529,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
bad for a getter. */ bad for a getter. */
refslow = _jit.x.pc; refslow = _jit.x.pc;
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
CHECK_RUNSTACK_OVERFLOW();
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
jit_movi_i(JIT_V1, 1); jit_movi_i(JIT_V1, 1);
@ -5458,6 +5539,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
jit_pusharg_p(JIT_R1); jit_pusharg_p(JIT_R1);
(void)mz_finish(_scheme_apply_from_native); (void)mz_finish(_scheme_apply_from_native);
jit_retval(JIT_R0); jit_retval(JIT_R0);
VALIDATE_RESULT(JIT_R0);
jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
if (!for_branch) { if (!for_branch) {
@ -5642,6 +5724,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
ref = jit_bner_p(jit_forward(), JIT_RUNSTACK, JIT_R2); ref = jit_bner_p(jit_forward(), JIT_RUNSTACK, JIT_R2);
ref3 = jit_bgti_p(jit_forward(), JIT_R1, cnt); ref3 = jit_bgti_p(jit_forward(), JIT_R1, cnt);
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt+1)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt+1));
CHECK_RUNSTACK_OVERFLOW();
for (i = cnt; i--; ) { for (i = cnt; i--; ) {
jit_ldxi_p(JIT_V1, JIT_R2, WORDS_TO_BYTES(i)); jit_ldxi_p(JIT_V1, JIT_R2, WORDS_TO_BYTES(i));
jit_stxi_p(WORDS_TO_BYTES(i), JIT_RUNSTACK, JIT_V1); jit_stxi_p(WORDS_TO_BYTES(i), JIT_RUNSTACK, JIT_V1);
@ -5694,6 +5777,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
cnt = data->closure_size; cnt = data->closure_size;
if (cnt) { if (cnt) {
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt)); jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt));
CHECK_RUNSTACK_OVERFLOW();
for (i = cnt; i--; ) { for (i = cnt; i--; ) {
int pos; int pos;
@ -5938,7 +6022,7 @@ static int generate_simple_arity_check(mz_jit_state *jitter, int num_params, int
jit_pusharg_p(JIT_R1); jit_pusharg_p(JIT_R1);
jit_pusharg_p(JIT_R0); jit_pusharg_p(JIT_R0);
CHECK_LIMIT(); CHECK_LIMIT();
(void)mz_finish(wrong_argument_count); (void)mz_nonrs_finish(wrong_argument_count);
CHECK_LIMIT(); CHECK_LIMIT();
/* Arity check or reporting. If argv is NULL, it's a reporting request */ /* Arity check or reporting. If argv is NULL, it's a reporting request */
@ -5971,7 +6055,7 @@ static int generate_simple_arity_check(mz_jit_state *jitter, int num_params, int
if (is_method) { if (is_method) {
mz_prepare(1); mz_prepare(1);
jit_pusharg_p(JIT_R0); jit_pusharg_p(JIT_R0);
(void)mz_finish(scheme_box); (void)mz_nonrs_finish(scheme_box);
mz_pop_locals(); mz_pop_locals();
jit_ret(); jit_ret();
} else { } else {

View File

@ -1811,13 +1811,13 @@ static int runstack_val_FIXUP(void *p) {
a = (void **)s + 4; a = (void **)s + 4;
b = (void **)s + 4 + s[2]; b = (void **)s + 4 + s[2];
while (a < b) { while (a < b) {
*a = NULL; *a = RUNSTACK_ZERO_VAL;
a++; a++;
} }
a = (void **)s + 4 + s[3]; a = (void **)s + 4 + s[3];
b = (void **)s + 4 + (s[1] - 4); b = (void **)s + 4 + (s[1] - 4);
while (a < b) { while (a < b) {
*a = NULL; *a = RUNSTACK_ZERO_VAL;
a++; a++;
} }
return return

View File

@ -710,13 +710,13 @@ runstack_val {
a = (void **)s + 4; a = (void **)s + 4;
b = (void **)s + 4 + s[2]; b = (void **)s + 4 + s[2];
while (a < b) { while (a < b) {
*a = NULL; *a = RUNSTACK_ZERO_VAL;
a++; a++;
} }
a = (void **)s + 4 + s[3]; a = (void **)s + 4 + s[3];
b = (void **)s + 4 + (s[1] - 4); b = (void **)s + 4 + (s[1] - 4);
while (a < b) { while (a < b) {
*a = NULL; *a = RUNSTACK_ZERO_VAL;
a++; a++;
} }
size: size:

View File

@ -454,6 +454,8 @@ static void FIXUP_jmpup(Scheme_Jumpup_Buf *buf)
new_stack); new_stack);
} }
#define RUNSTACK_ZERO_VAL NULL
#define MARKS_FOR_TYPE_C #define MARKS_FOR_TYPE_C
#include "mzmark.c" #include "mzmark.c"