diff --git a/src/racket/include/mzwin.def b/src/racket/include/mzwin.def index d38b385319..c2ca31989d 100644 --- a/src/racket/include/mzwin.def +++ b/src/racket/include/mzwin.def @@ -180,6 +180,7 @@ EXPORTS scheme_set_tail_buffer_size scheme_force_value scheme_force_one_value + scheme_ignore_result scheme_set_cont_mark scheme_push_continuation_frame scheme_pop_continuation_frame diff --git a/src/racket/include/mzwin3m.def b/src/racket/include/mzwin3m.def index 2f1e18cdfb..14d32513ce 100644 --- a/src/racket/include/mzwin3m.def +++ b/src/racket/include/mzwin3m.def @@ -180,6 +180,7 @@ EXPORTS scheme_set_tail_buffer_size scheme_force_value scheme_force_one_value + scheme_ignore_result scheme_set_cont_mark scheme_push_continuation_frame scheme_pop_continuation_frame diff --git a/src/racket/include/racket.exp b/src/racket/include/racket.exp index 551b863a13..96a6ec3778 100644 --- a/src/racket/include/racket.exp +++ b/src/racket/include/racket.exp @@ -188,6 +188,7 @@ scheme_tail_eval_expr scheme_set_tail_buffer_size scheme_force_value scheme_force_one_value +scheme_ignore_result scheme_set_cont_mark scheme_push_continuation_frame scheme_pop_continuation_frame diff --git a/src/racket/include/racket3m.exp b/src/racket/include/racket3m.exp index 5dccc8a59d..b45f182381 100644 --- a/src/racket/include/racket3m.exp +++ b/src/racket/include/racket3m.exp @@ -188,6 +188,7 @@ scheme_tail_eval_expr scheme_set_tail_buffer_size scheme_force_value scheme_force_one_value +scheme_ignore_result scheme_set_cont_mark scheme_push_continuation_frame scheme_pop_continuation_frame diff --git a/src/racket/src/eval.c b/src/racket/src/eval.c index 5bb62fe862..11161de02c 100644 --- a/src/racket/src/eval.c +++ b/src/racket/src/eval.c @@ -371,6 +371,18 @@ void scheme_init_eval_places() #endif } +XFORM_NONGCING static void ignore_result(Scheme_Object *v) +{ + if (SAME_OBJ(v, SCHEME_MULTIPLE_VALUES)) { + scheme_current_thread->ku.multiple.array = NULL; + } +} + +void scheme_ignore_result(Scheme_Object *v) +{ + ignore_result(v); +} + /*========================================================================*/ /* C stack and Scheme stack handling */ /*========================================================================*/ @@ -1903,9 +1915,9 @@ define_execute_with_dynamic_state(Scheme_Object *vec, int delta, int defmacro, int is_st; values = scheme_current_thread->ku.multiple.array; - scheme_current_thread->ku.multiple.array = NULL; if (SAME_OBJ(values, scheme_current_thread->values_buffer)) scheme_current_thread->values_buffer = NULL; + scheme_current_thread->ku.multiple.array = NULL; if (dm_env) is_st = 0; @@ -1946,10 +1958,10 @@ define_execute_with_dynamic_state(Scheme_Object *vec, int delta, int defmacro, scheme_pop_prefix(save_runstack); return scheme_void; + } else { + if (SAME_OBJ(scheme_current_thread->ku.multiple.array, scheme_current_thread->values_buffer)) + scheme_current_thread->values_buffer = NULL; } - - if (SAME_OBJ(scheme_current_thread->ku.multiple.array, scheme_current_thread->values_buffer)) - scheme_current_thread->values_buffer = NULL; } else if (SCHEME_VEC_SIZE(vec) == delta + 1) { /* => single var */ var = SCHEME_VEC_ELS(vec)[delta]; if (dm_env) { @@ -2096,6 +2108,7 @@ static Scheme_Object *apply_values_execute(Scheme_Object *data) v = _scheme_eval_linked_expr_multi(SCHEME_PTR2_VAL(data)); if (SAME_OBJ(v, SCHEME_MULTIPLE_VALUES)) { Scheme_Thread *p = scheme_current_thread; + Scheme_Object **rands; int num_rands = p->ku.multiple.count; if (num_rands > p->tail_buffer_size) { @@ -2103,7 +2116,9 @@ static Scheme_Object *apply_values_execute(Scheme_Object *data) if (SAME_OBJ(p->ku.multiple.array, p->values_buffer)) p->values_buffer = NULL; } - return scheme_tail_apply(f, num_rands, p->ku.multiple.array); + rands = p->ku.multiple.array; + p->ku.multiple.array = NULL; + return scheme_tail_apply(f, num_rands, rands); } else { Scheme_Object *a[1]; a[0] = v; @@ -2223,7 +2238,7 @@ static Scheme_Object *begin0_execute(Scheme_Object *obj) apos = 1; while (i--) { - (void)_scheme_eval_linked_expr_multi(((Scheme_Sequence *)obj)->array[apos++]); + ignore_result(_scheme_eval_linked_expr_multi(((Scheme_Sequence *)obj)->array[apos++])); } if (mv) { @@ -2247,7 +2262,7 @@ static Scheme_Object *splice_execute(Scheme_Object *data) int i, cnt = seq->count - 1; for (i = 0; i < cnt; i++) { - (void)_scheme_call_with_prompt_multi(splice_one_expr, seq->array[i]); + ignore_result(_scheme_call_with_prompt_multi(splice_one_expr, seq->array[i])); } return _scheme_eval_linked_expr_multi(seq->array[cnt]); @@ -2327,7 +2342,7 @@ do_define_syntaxes_execute(Scheme_Object *form, Scheme_Env *dm_env) save_runstack = scheme_push_prefix(dm_env->exp_env, rp, NULL, NULL, 1, 1, NULL, scheme_false); while (!SCHEME_NULLP(form)) { - (void)scheme_eval_linked_expr_multi_with_dynamic_state(SCHEME_CAR(form), &dyn_state); + ignore_result(scheme_eval_linked_expr_multi_with_dynamic_state(SCHEME_CAR(form), &dyn_state)); form = SCHEME_CDR(form); } @@ -3407,7 +3422,7 @@ scheme_do_eval(Scheme_Object *obj, int num_rands, Scheme_Object **rands, UPDATE_THREAD_RSPTR(); for (i = 0; i < cnt; i++) { - (void)_scheme_eval_linked_expr_multi_wp(((Scheme_Sequence *)obj)->array[i], p); + ignore_result(_scheme_eval_linked_expr_multi_wp(((Scheme_Sequence *)obj)->array[i], p)); } obj = ((Scheme_Sequence *)obj)->array[cnt]; @@ -5192,6 +5207,7 @@ static Scheme_Object *do_eval_string_all(Scheme_Object *port, const char *str, S if (SAME_OBJ(p->ku.multiple.array, p->values_buffer)) p->values_buffer = NULL; a = p->ku.multiple.array; + p->ku.multiple.array = NULL; cnt = p->ku.multiple.count; } else { _a[0] = result; diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index 53df7a96bd..18ed6524e5 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -3402,7 +3402,8 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object GC_CAN_IGNORE Scheme_Thread *p = scheme_current_thread; c = p->ku.multiple.count; argv2 = p->ku.multiple.array; - if (SAME_OBJ(p->ku.multiple.array, p->values_buffer)) { + p->ku.multiple.array = NULL; + if (SAME_OBJ(argv2, p->values_buffer)) { if (c <= MAX_QUICK_CHAP_ARGV) { for (i = 0; i < c; i++) { a2[i] = argv2[i]; @@ -3544,6 +3545,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object p->values_buffer = NULL; c = p->ku.multiple.count; argv = p->ku.multiple.array; + p->ku.multiple.array = NULL; } else { c = 1; a[0] = v; @@ -3575,6 +3577,7 @@ Scheme_Object *scheme_apply_chaperone(Scheme_Object *o, int argc, Scheme_Object p->values_buffer = NULL; argc = p->ku.multiple.count; argv2 = p->ku.multiple.array; + p->ku.multiple.array = NULL; } else { argc = 1; a2[0] = v; @@ -3713,9 +3716,9 @@ static Scheme_Object *call_with_values(int argc, Scheme_Object *argv[]) Scheme_Object **a; if (SAME_OBJ(p->ku.multiple.array, p->values_buffer)) p->values_buffer = NULL; - /* Beware: the fields overlap! */ n = p->ku.multiple.count; a = p->ku.multiple.array; + p->ku.multiple.array = NULL; p->ku.apply.tail_num_rands = n; p->ku.apply.tail_rands = a; } else { @@ -5110,6 +5113,7 @@ static void restore_continuation(Scheme_Cont *cont, Scheme_Thread *p, int for_pr mc = p->ku.multiple.count; if (SAME_OBJ(mv, p->values_buffer)) p->values_buffer = NULL; + p->ku.multiple.array = NULL; } else { mv = NULL; mc = 0; @@ -6394,6 +6398,7 @@ static Scheme_Object **chaperone_do_control(const char *name, int mode, p->values_buffer = NULL; num_args = p->ku.multiple.count; vals = p->ku.multiple.array; + p->ku.multiple.array = NULL; } else { num_args = 1; vals = MALLOC_N(Scheme_Object *, 1); @@ -6470,6 +6475,7 @@ static Scheme_Object *do_cc_guard(Scheme_Object *v, Scheme_Object *cc_guard, Sch p->values_buffer = NULL; argc = p->ku.multiple.count; argv = p->ku.multiple.array; + p->ku.multiple.array = NULL; } else { a[0] = v; argv = a; @@ -8591,7 +8597,7 @@ static void pre_post_dyn_wind(Scheme_Object *prepost) scheme_push_break_enable(&cframe, 0, 0); /* Here's the main call: */ - (void)_scheme_apply_multi(prepost, 0, NULL); + scheme_ignore_result(_scheme_apply_multi(prepost, 0, NULL)); scheme_pop_break_enable(&cframe, 0); @@ -9441,10 +9447,12 @@ static Scheme_Object *time_apply(int argc, Scheme_Object *argv[]) if (v == SCHEME_MULTIPLE_VALUES) { Scheme_Thread *cp = scheme_current_thread; + Scheme_Object **args; if (SAME_OBJ(cp->ku.multiple.array, cp->values_buffer)) cp->values_buffer = NULL; - v = scheme_build_list(cp->ku.multiple.count, - cp->ku.multiple.array); + args = cp->ku.multiple.array; + cp->ku.multiple.array = NULL; + v = scheme_build_list(cp->ku.multiple.count, args); } else v = scheme_make_pair(v, scheme_null); diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index a2015760b5..d8bf71e3e6 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -2276,9 +2276,13 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w (void)jit_jmpi(refloop); CHECK_LIMIT(); mz_patch_branch(ref3); + /* clear array pointer and re-laod argc: */ (void)mz_tl_ldi_p(JIT_R0, tl_scheme_current_thread); + (void)jit_movi_p(JIT_R1, NULL); + jit_stxi_l(&((Scheme_Thread *)0x0)->ku.multiple.array, JIT_R0, JIT_R1); jit_ldxi_l(JIT_R0, JIT_R0, &((Scheme_Thread *)0x0)->ku.multiple.count); - + CHECK_LIMIT(); + /* Perform call --------------------- */ /* Function is in V1, argc in R0, args on RUNSTACK */ mz_patch_ucbranch(ref2); @@ -2286,16 +2290,18 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w if (is_tail) { if (!sjc.shared_tail_argc_code) { - sjc.shared_tail_argc_code = scheme_generate_shared_call(-1, jitter, 1, 1, 0, 0, 0, 0); + sjc.shared_tail_argc_code = scheme_generate_shared_call(-1, jitter, 1, 0, 1, 0, 0, 0, 0); } mz_set_local_p(JIT_R0, JIT_LOCAL2); (void)jit_jmpi(sjc.shared_tail_argc_code); } else { - int mo = multi_ok ? 1 : 0; + int mo = (multi_ok + ? (result_ignored ? SHARED_RESULT_IGNORED_CASE : SHARED_MULTI_OK_CASE) + : SHARED_SINGLE_VALUE_CASE); void *code; if (!sjc.shared_non_tail_argc_code[mo]) { - scheme_ensure_retry_available(jitter, multi_ok); - code = scheme_generate_shared_call(-2, jitter, multi_ok, 0, 0, 0, 0, 0); + scheme_ensure_retry_available(jitter, multi_ok, result_ignored); + code = scheme_generate_shared_call(-2, jitter, multi_ok, result_ignored, 0, 0, 0, 0, 0); sjc.shared_non_tail_argc_code[mo] = code; } code = sjc.shared_non_tail_argc_code[mo]; @@ -2438,7 +2444,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w return r; } - r = scheme_generate_app(app, NULL, app->num_args, jitter, is_tail, multi_ok, 0); + r = scheme_generate_app(app, NULL, app->num_args, jitter, is_tail, multi_ok, result_ignored, 0); CHECK_LIMIT(); if (target != JIT_R0) @@ -2468,7 +2474,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w args[0] = app->rator; args[1] = app->rand; - r = scheme_generate_app(NULL, args, 1, jitter, is_tail, multi_ok, 0); + r = scheme_generate_app(NULL, args, 1, jitter, is_tail, multi_ok, result_ignored, 0); CHECK_LIMIT(); if (target != JIT_R0) @@ -2499,7 +2505,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w args[1] = app->rand1; args[2] = app->rand2; - r = scheme_generate_app(NULL, args, 2, jitter, is_tail, multi_ok, 0); + r = scheme_generate_app(NULL, args, 2, jitter, is_tail, multi_ok, result_ignored, 0); CHECK_LIMIT(); if (target != JIT_R0) @@ -2601,9 +2607,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w /* Did we get multiple results? If not, go to error: */ ref = jit_bnei_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES); /* Load count and result array: */ - mz_tl_ldi_p(JIT_R2, tl_scheme_current_thread); - jit_ldxi_l(JIT_R1, JIT_R2, &((Scheme_Thread *)0x0)->ku.multiple.count); - jit_ldxi_p(JIT_R2, JIT_R2, &((Scheme_Thread *)0x0)->ku.multiple.array); + mz_tl_ldi_p(JIT_V1, tl_scheme_current_thread); + jit_ldxi_p(JIT_R2, JIT_V1, &((Scheme_Thread *)0x0)->ku.multiple.array); + jit_ldxi_l(JIT_R1, JIT_V1, &((Scheme_Thread *)0x0)->ku.multiple.count); CHECK_LIMIT(); /* If we got the expected count, jump to installing values: */ ref2 = jit_beqi_i(jit_forward(), JIT_R1, lv->count); @@ -2630,9 +2636,11 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w (void)mz_finish_lwe(ts_lexical_binding_wrong_return_arity, ref); CHECK_LIMIT(); - /* Continue with expected values; R2 has value array: */ + /* Continue with expected values; R2 has values and V1 has thread pointer: */ mz_patch_branch(ref2); __END_SHORT_JUMPS__(1); + (void)jit_movi_p(JIT_R0, NULL); + jit_stxi_p(&((Scheme_Thread *)0x0)->ku.multiple.array, JIT_V1, JIT_R0); for (i = 0; i < lv->count; i++) { jit_ldxi_p(JIT_R1, JIT_R2, WORDS_TO_BYTES(i)); if (ab) { diff --git a/src/racket/src/jit.h b/src/racket/src/jit.h index 73d9459fb5..0bd01ae12b 100644 --- a/src/racket/src/jit.h +++ b/src/racket/src/jit.h @@ -210,9 +210,13 @@ struct scheme_jit_common_record { #define MAX_SHARED_CALL_RANDS 25 void *shared_tail_code[4][MAX_SHARED_CALL_RANDS]; - void *shared_non_tail_code[5][MAX_SHARED_CALL_RANDS][2]; - void *shared_non_tail_retry_code[2]; - void *shared_non_tail_argc_code[2]; +# define SHARED_SINGLE_VALUE_CASE 0 +# define SHARED_MULTI_OK_CASE 1 +# define SHARED_RESULT_IGNORED_CASE 2 +# define SHARED_NUM_NONTAIL_CASES 3 + void *shared_non_tail_code[5][MAX_SHARED_CALL_RANDS][SHARED_NUM_NONTAIL_CASES]; + void *shared_non_tail_retry_code[SHARED_NUM_NONTAIL_CASES]; + void *shared_non_tail_argc_code[SHARED_NUM_NONTAIL_CASES]; void *shared_tail_argc_code; #define MAX_SHARED_ARITY_CHECK 25 @@ -1228,15 +1232,17 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj typedef struct jit_direct_arg jit_direct_arg; -void *scheme_generate_shared_call(int num_rands, mz_jit_state *old_jitter, int multi_ok, int is_tail, - int direct_prim, int direct_native, int nontail_self, int unboxed_args); -void scheme_ensure_retry_available(mz_jit_state *jitter, int multi_ok); +void *scheme_generate_shared_call(int num_rands, mz_jit_state *old_jitter, int multi_ok, int result_ignored, + int is_tail, int direct_prim, int direct_native, int nontail_self, int unboxed_args); +void scheme_ensure_retry_available(mz_jit_state *jitter, int multi_ok, int result_ignored); int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_rands, - mz_jit_state *jitter, int is_tail, int multi_ok, int no_call); + mz_jit_state *jitter, int is_tail, int multi_ok, int ignored_result, + int no_call); int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_native, int need_set_rs, int is_inline, Scheme_Native_Closure *direct_to_code, jit_direct_arg *direct_arg); int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direct_native, int need_set_rs, - int multi_ok, int nontail_self, int pop_and_jump, int is_inlined, int unboxed_args); + int multi_ok, int result_ignored, int nontail_self, int pop_and_jump, + int is_inlined, int unboxed_args); int scheme_generate_finish_tail_call(mz_jit_state *jitter, int direct_native); int scheme_generate_finish_apply(mz_jit_state *jitter); int scheme_generate_finish_multi_apply(mz_jit_state *jitter); diff --git a/src/racket/src/jitarith.c b/src/racket/src/jitarith.c index 8d6d2e7486..9cf7ce4994 100644 --- a/src/racket/src/jitarith.c +++ b/src/racket/src/jitarith.c @@ -1920,7 +1920,7 @@ int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app, } if (stack_c) - scheme_generate_app(app, alt_args, stack_c, jitter, 0, 0, 2); + scheme_generate_app(app, alt_args, stack_c, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); diff --git a/src/racket/src/jitcall.c b/src/racket/src/jitcall.c index bfbda3673a..a9200b65fa 100644 --- a/src/racket/src/jitcall.c +++ b/src/racket/src/jitcall.c @@ -604,7 +604,8 @@ static int generate_direct_prim_non_tail_call(mz_jit_state *jitter, int num_rand return 1; } -static int generate_retry_call(mz_jit_state *jitter, int num_rands, int multi_ok, GC_CAN_IGNORE jit_insn *reftop) +static int generate_retry_call(mz_jit_state *jitter, int num_rands, int multi_ok, int result_ignored, + GC_CAN_IGNORE jit_insn *reftop) /* If num_rands < 0, original argc is in V1, and we should pop argc arguments off runstack before pushing more. This function is called with short jumps enabled. */ @@ -612,7 +613,10 @@ static int generate_retry_call(mz_jit_state *jitter, int num_rands, int multi_ok GC_CAN_IGNORE jit_insn *ref, *ref2, *refloop; if (!reftop) { - reftop = sjc.shared_non_tail_retry_code[multi_ok ? 1 : 0]; + int mo = (multi_ok + ? (result_ignored ? SHARED_RESULT_IGNORED_CASE : SHARED_MULTI_OK_CASE) + : SHARED_SINGLE_VALUE_CASE); + reftop = sjc.shared_non_tail_retry_code[mo]; } /* Get new argc: */ @@ -637,7 +641,7 @@ static int generate_retry_call(mz_jit_state *jitter, int num_rands, int multi_ok /* Copy arguments 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_V1, JIT_R1, &((Scheme_Thread *)0x0)->ku.apply.tail_rands); + jit_ldxi_p(JIT_V1, JIT_R1, &((Scheme_Thread *)0x0)->ku.apply.tail_rands); jit_lshi_l(JIT_R2, JIT_R2, JIT_LOG_WORD_SIZE); CHECK_LIMIT(); refloop = _jit.x.pc; @@ -648,10 +652,15 @@ static int generate_retry_call(mz_jit_state *jitter, int num_rands, int multi_ok (void)jit_jmpi(refloop); CHECK_LIMIT(); + /* Clear tail-call arguments pointer: */ + (void)jit_movi_p(JIT_V1, NULL); + jit_stxi_p(&((Scheme_Thread *)0x0)->ku.apply.tail_rands, JIT_R1, JIT_V1); + CHECK_LIMIT(); + /* R1 is still the thread. Put procedure and argc in place, then jump to apply: */ mz_patch_branch(ref2); - jit_ldxi_l(JIT_V1, JIT_R1, &((Scheme_Thread *)0x0)->ku.apply.tail_rator); + jit_ldxi_p(JIT_V1, JIT_R1, &((Scheme_Thread *)0x0)->ku.apply.tail_rator); jit_ldxi_l(JIT_R0, JIT_R1, &((Scheme_Thread *)0x0)->ku.apply.tail_num_rands); __END_SHORT_JUMPS__(1); (void)jit_jmpi(reftop); @@ -690,9 +699,28 @@ static int generate_clear_slow_previous_args(mz_jit_state *jitter) return 1; } +static int generate_ignored_result_check(mz_jit_state *jitter) +{ + /* if multiple results, need to clear ignored result in thread */ + GC_CAN_IGNORE jit_insn *refm; + + __START_INNER_TINY__(1); + + refm = jit_bnei_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES); + mz_tl_ldi_p(JIT_R1, tl_scheme_current_thread); + (void)jit_movi_p(JIT_R0, NULL); + jit_stxi_p(&((Scheme_Thread *)0x0)->ku.multiple.array, JIT_R1, JIT_R0); + (void)jit_movi_p(JIT_R0, scheme_void); + mz_patch_branch(refm); + + __END_INNER_TINY__(1); + + return 1; +} + int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direct_native, int need_set_rs, - int multi_ok, int nontail_self, int pop_and_jump, int is_inlined, - int unboxed_args) + int multi_ok, int result_ignored, int nontail_self, int pop_and_jump, + int is_inlined, int unboxed_args) { /* Non-tail call. Proc is in V1, args are at RUNSTACK. @@ -876,7 +904,7 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc CHECK_LIMIT(); if (pop_and_jump) { /* Expects argc in V1 if num_rands < 0: */ - generate_retry_call(jitter, num_rands, multi_ok, reftop); + generate_retry_call(jitter, num_rands, multi_ok, result_ignored, reftop); } CHECK_LIMIT(); if (need_set_rs) { @@ -939,7 +967,7 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc CHECK_LIMIT(); if (pop_and_jump) { /* Expects argc in V1 if num_rands < 0: */ - generate_retry_call(jitter, num_rands, multi_ok, reftop); + generate_retry_call(jitter, num_rands, multi_ok, result_ignored, reftop); } CHECK_LIMIT(); if (num_rands < 0) { @@ -1023,6 +1051,10 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc mz_patch_branch(ref6); if (!direct_native) { mz_patch_branch(ref10); + if (result_ignored) { + generate_ignored_result_check(jitter); + CHECK_LIMIT(); + } } /* Note: same return code is above for faster common-case return */ if (num_rands < 0) { @@ -1237,6 +1269,7 @@ typedef struct { int num_rands; mz_jit_state *old_jitter; int multi_ok; + int result_ignored; int is_tail; int direct_prim, direct_native, nontail_self, unboxed_args; } Generate_Call_Data; @@ -1295,7 +1328,8 @@ static int do_generate_shared_call(mz_jit_state *jitter, void *_data) ok = generate_direct_prim_non_tail_call(jitter, data->num_rands, data->multi_ok, 1); else ok = scheme_generate_non_tail_call(jitter, data->num_rands, data->direct_native, 1, - data->multi_ok, data->nontail_self, 1, 0, data->unboxed_args); + data->multi_ok, data->result_ignored, data->nontail_self, + 1, 0, data->unboxed_args); scheme_jit_register_sub_func(jitter, code, scheme_false); @@ -1303,14 +1337,16 @@ static int do_generate_shared_call(mz_jit_state *jitter, void *_data) } } -void *scheme_generate_shared_call(int num_rands, mz_jit_state *old_jitter, int multi_ok, int is_tail, - int direct_prim, int direct_native, int nontail_self, int unboxed_args) +void *scheme_generate_shared_call(int num_rands, mz_jit_state *old_jitter, int multi_ok, int result_ignored, + int is_tail, int direct_prim, int direct_native, int nontail_self, + int unboxed_args) { Generate_Call_Data data; data.num_rands = num_rands; data.old_jitter = old_jitter; data.multi_ok = multi_ok; + data.result_ignored = result_ignored; data.is_tail = is_tail; data.direct_prim = direct_prim; data.direct_native = direct_native; @@ -1320,12 +1356,14 @@ void *scheme_generate_shared_call(int num_rands, mz_jit_state *old_jitter, int m return scheme_generate_one(old_jitter, do_generate_shared_call, &data, 0, NULL, NULL); } -void scheme_ensure_retry_available(mz_jit_state *jitter, int multi_ok) +void scheme_ensure_retry_available(mz_jit_state *jitter, int multi_ok, int result_ignored) { - int mo = multi_ok ? 1 : 0; + int mo = (multi_ok + ? (result_ignored ? SHARED_RESULT_IGNORED_CASE : SHARED_MULTI_OK_CASE) + : SHARED_SINGLE_VALUE_CASE); if (!sjc.shared_non_tail_retry_code[mo]) { void *code; - code = scheme_generate_shared_call(-1, jitter, multi_ok, 0, 0, 0, 0, 0); + code = scheme_generate_shared_call(-1, jitter, multi_ok, result_ignored, 0, 0, 0, 0, 0); sjc.shared_non_tail_retry_code[mo] = code; } } @@ -1586,7 +1624,8 @@ static int generate_call_path_with_unboxes(mz_jit_state *jitter, int direct_flos #endif int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_rands, - mz_jit_state *jitter, int is_tail, int multi_ok, int no_call) + mz_jit_state *jitter, int is_tail, int multi_ok, int result_ignored, + int no_call) /* de-sync'd ok If no_call is 2, then rator is not necssarily evaluated. If no_call is 1, then rator is left in V1 and arguments are on runstack. */ @@ -1624,6 +1663,8 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if ((num_rands >= 2) && SAME_OBJ(rator, scheme_apply_proc)) apply_to_list = 1; } + if (!(((Scheme_Primitive_Proc *)rator)->pp.flags & SCHEME_PRIM_IS_MULTI_RESULT)) + result_ignored = 0; /* don't need to check for multiple values to ignore */ } else { Scheme_Type t; t = SCHEME_TYPE(rator); @@ -1970,7 +2011,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ generate_nontail_self_setup(jitter); } scheme_generate_non_tail_call(jitter, num_rands, direct_native, jitter->need_set_rs, - multi_ok, nontail_self, 0, 1, 0); + multi_ok, result_ignored, nontail_self, 0, 1, 0); } } } else { @@ -1981,7 +2022,8 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (is_tail) { if (!sjc.shared_tail_code[dp][num_rands]) { - code = scheme_generate_shared_call(num_rands, jitter, multi_ok, is_tail, direct_prim, direct_native, 0, 0); + code = scheme_generate_shared_call(num_rands, jitter, multi_ok, result_ignored, is_tail, + direct_prim, direct_native, 0, 0); sjc.shared_tail_code[dp][num_rands] = code; } code = sjc.shared_tail_code[dp][num_rands]; @@ -2024,7 +2066,9 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ } } } else { - int mo = (multi_ok ? 1 : 0); + int mo = (multi_ok + ? (result_ignored ? SHARED_RESULT_IGNORED_CASE : SHARED_MULTI_OK_CASE) + : SHARED_SINGLE_VALUE_CASE); #ifdef USE_FLONUM_UNBOXING void *unboxed_code; #endif @@ -2035,8 +2079,9 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ #ifdef USE_FLONUM_UNBOXING if (unboxed_non_tail_args) { if (!sjc.shared_non_tail_code[4][num_rands][mo]) { - scheme_ensure_retry_available(jitter, multi_ok); - code = scheme_generate_shared_call(num_rands, jitter, multi_ok, is_tail, direct_prim, direct_native, nontail_self, 1); + scheme_ensure_retry_available(jitter, multi_ok, result_ignored); + code = scheme_generate_shared_call(num_rands, jitter, multi_ok, result_ignored, is_tail, + direct_prim, direct_native, nontail_self, 1); sjc.shared_non_tail_code[4][num_rands][mo] = code; } unboxed_code = sjc.shared_non_tail_code[4][num_rands][mo]; @@ -2045,8 +2090,9 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ #endif if (!sjc.shared_non_tail_code[dp][num_rands][mo]) { - scheme_ensure_retry_available(jitter, multi_ok); - code = scheme_generate_shared_call(num_rands, jitter, multi_ok, is_tail, direct_prim, direct_native, nontail_self, 0); + scheme_ensure_retry_available(jitter, multi_ok, result_ignored); + code = scheme_generate_shared_call(num_rands, jitter, multi_ok, result_ignored, is_tail, + direct_prim, direct_native, nontail_self, 0); sjc.shared_non_tail_code[dp][num_rands][mo] = code; } LOG_IT(("<-non-tail %d %d %d\n", dp, num_rands, mo)); diff --git a/src/racket/src/jitcommon.c b/src/racket/src/jitcommon.c index c338efc6be..5d7f9e0e00 100644 --- a/src/racket/src/jitcommon.c +++ b/src/racket/src/jitcommon.c @@ -979,7 +979,7 @@ static int generate_apply_proxy(mz_jit_state *jitter, int setter) CHECK_LIMIT(); JIT_UPDATE_THREAD_RSPTR(); __END_SHORT_JUMPS__(1); - scheme_generate_non_tail_call(jitter, 3, 0, 0, 0, 0, 0, 1, 0); + scheme_generate_non_tail_call(jitter, 3, 0, 0, 0, 0, 0, 0, 1, 0); __START_SHORT_JUMPS__(1); CHECK_LIMIT(); if (setter) { @@ -3041,7 +3041,7 @@ static int more_common0(mz_jit_state *jitter, void *_data) mz_rs_sync(); __END_SHORT_JUMPS__(1); - scheme_generate_non_tail_call(jitter, 2, 0, 1, 0, 0, 0, 0, 0); + scheme_generate_non_tail_call(jitter, 2, 0, 1, 0, 0, 0, 0, 0, 0); CHECK_LIMIT(); __START_SHORT_JUMPS__(1); @@ -3476,7 +3476,7 @@ static int more_common1(mz_jit_state *jitter, void *_data) __END_SHORT_JUMPS__(1); - scheme_generate_non_tail_call(jitter, -1, 0, 1, multi_ok, 0, 1, 0, 0); + scheme_generate_non_tail_call(jitter, -1, 0, 1, multi_ok, 0, 0, 1, 0, 0); scheme_jit_register_sub_func(jitter, code, scheme_false); } diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index a601bf54a0..8f9cbab4cc 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -383,7 +383,7 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, args[0] = rator; args[1] = rand; args[2] = rand2; - scheme_generate_app(NULL, args, 2, jitter, 0, 0, 1); /* sync'd below */ + scheme_generate_app(NULL, args, 2, jitter, 0, 0, 0, 1); /* sync'd below */ CHECK_LIMIT(); jit_movr_p(JIT_R0, JIT_V1); mz_rs_ldr(JIT_R1); @@ -600,7 +600,7 @@ static int generate_inlined_nary_struct_op(int kind, mz_jit_state *jitter, /* de-sync'd ok; for branch, sync'd before */ { /* generate code to evaluate the arguments */ - scheme_generate_app(app, NULL, app->num_args, jitter, 0, 0, 1); + scheme_generate_app(app, NULL, app->num_args, jitter, 0, 0, 0, 1); CHECK_LIMIT(); mz_rs_sync(); @@ -3165,7 +3165,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i args[1] = app->rand1; args[2] = app->rand2; - scheme_generate_app(NULL, args, 2, jitter, 0, 0, 2); + scheme_generate_app(NULL, args, 2, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); @@ -3271,7 +3271,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } /* generate code to evaluate the arguments */ - scheme_generate_app(app, NULL, 3, jitter, 0, 0, 2); + scheme_generate_app(app, NULL, 3, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); @@ -3680,7 +3680,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } else { got_two = 1; mz_runstack_skipped(jitter, 1); - scheme_generate_app(app, NULL, 2, jitter, 0, 0, 2); + scheme_generate_app(app, NULL, 2, jitter, 0, 0, 0, 2); } if (scheme_can_unbox_inline(app->args[3], 5, JIT_FPR_NUM-1, 1)) @@ -3737,7 +3737,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int star = IS_NAMED_PRIM(rator, "list*"); if (c) - scheme_generate_app(app, NULL, c, jitter, 0, 0, 2); + scheme_generate_app(app, NULL, c, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); @@ -3775,7 +3775,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int if (!multi_ok) return 0; if (c) { - scheme_generate_app(app, NULL, c, jitter, 0, 0, 2); + scheme_generate_app(app, NULL, c, jitter, 0, 0, 0, 2); CHECK_LIMIT(); mz_rs_sync(); @@ -3812,7 +3812,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } else if (IS_NAMED_PRIM(rator, "max")) { return scheme_generate_nary_arith(jitter, app, ARITH_MAX, 0, NULL, 1); } else if (IS_NAMED_PRIM(rator, "checked-procedure-check-and-extract")) { - scheme_generate_app(app, NULL, 5, jitter, 0, 0, 2); /* sync'd below */ + scheme_generate_app(app, NULL, 5, jitter, 0, 0, 0, 2); /* sync'd below */ CHECK_LIMIT(); mz_rs_sync(); @@ -3893,7 +3893,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, } else { c = app->num_args; if (c) - scheme_generate_app(app, NULL, c, jitter, 0, 0, 2); /* sync'd below */ + scheme_generate_app(app, NULL, c, jitter, 0, 0, 0, 2); /* sync'd below */ } CHECK_LIMIT(); diff --git a/src/racket/src/module.c b/src/racket/src/module.c index 0b8223c5fc..b9bebb5c5d 100644 --- a/src/racket/src/module.c +++ b/src/racket/src/module.c @@ -5536,7 +5536,9 @@ static Scheme_Object *body_one_expr(void *prefix_plus_expr, int argc, Scheme_Obj v = _scheme_eval_linked_expr_multi(SCHEME_CDR((Scheme_Object *)prefix_plus_expr)); scheme_suspend_prefix(saved_runstack); - return v; + scheme_ignore_result(v); + + return scheme_void; } static int needs_prompt(Scheme_Object *e) @@ -5632,7 +5634,7 @@ void *scheme_module_run_finish(Scheme_Env *menv, Scheme_Env *env) scheme_make_raw_pair(save_prefix, body)); scheme_resume_prefix(save_prefix); } else - (void)_scheme_eval_linked_expr_multi(body); + scheme_ignore_result(_scheme_eval_linked_expr_multi(body)); } if (scheme_module_demand_hook) { diff --git a/src/racket/src/schemef.h b/src/racket/src/schemef.h index 09d7e14d9c..beddc17b97 100644 --- a/src/racket/src/schemef.h +++ b/src/racket/src/schemef.h @@ -361,6 +361,8 @@ MZ_EXTERN void scheme_set_tail_buffer_size(int s); MZ_EXTERN Scheme_Object *scheme_force_value(Scheme_Object *); MZ_EXTERN Scheme_Object *scheme_force_one_value(Scheme_Object *); +XFORM_NONGCING MZ_EXTERN void scheme_ignore_result(Scheme_Object *); + MZ_EXTERN MZ_MARK_STACK_TYPE scheme_set_cont_mark(Scheme_Object *key, Scheme_Object *val); MZ_EXTERN void scheme_push_continuation_frame(Scheme_Cont_Frame_Data *); MZ_EXTERN void scheme_pop_continuation_frame(Scheme_Cont_Frame_Data *); diff --git a/src/racket/src/schemex.h b/src/racket/src/schemex.h index b6ad149f57..10e32c36ea 100644 --- a/src/racket/src/schemex.h +++ b/src/racket/src/schemex.h @@ -278,6 +278,7 @@ Scheme_Object *(*scheme_tail_eval_expr)(Scheme_Object *obj); void (*scheme_set_tail_buffer_size)(int s); Scheme_Object *(*scheme_force_value)(Scheme_Object *); Scheme_Object *(*scheme_force_one_value)(Scheme_Object *); +void (*scheme_ignore_result)(Scheme_Object *); MZ_MARK_STACK_TYPE (*scheme_set_cont_mark)(Scheme_Object *key, Scheme_Object *val); void (*scheme_push_continuation_frame)(Scheme_Cont_Frame_Data *); void (*scheme_pop_continuation_frame)(Scheme_Cont_Frame_Data *); diff --git a/src/racket/src/schemex.inc b/src/racket/src/schemex.inc index f5fd7186c0..3e3e6f2cec 100644 --- a/src/racket/src/schemex.inc +++ b/src/racket/src/schemex.inc @@ -196,6 +196,7 @@ scheme_extension_table->scheme_set_tail_buffer_size = scheme_set_tail_buffer_size; scheme_extension_table->scheme_force_value = scheme_force_value; scheme_extension_table->scheme_force_one_value = scheme_force_one_value; + scheme_extension_table->scheme_ignore_result = scheme_ignore_result; scheme_extension_table->scheme_set_cont_mark = scheme_set_cont_mark; scheme_extension_table->scheme_push_continuation_frame = scheme_push_continuation_frame; scheme_extension_table->scheme_pop_continuation_frame = scheme_pop_continuation_frame; diff --git a/src/racket/src/schemexm.h b/src/racket/src/schemexm.h index 962b73ffd5..a3ef033eb5 100644 --- a/src/racket/src/schemexm.h +++ b/src/racket/src/schemexm.h @@ -196,6 +196,7 @@ #define scheme_set_tail_buffer_size (scheme_extension_table->scheme_set_tail_buffer_size) #define scheme_force_value (scheme_extension_table->scheme_force_value) #define scheme_force_one_value (scheme_extension_table->scheme_force_one_value) +#define scheme_ignore_result (scheme_extension_table->scheme_ignore_result) #define scheme_set_cont_mark (scheme_extension_table->scheme_set_cont_mark) #define scheme_push_continuation_frame (scheme_extension_table->scheme_push_continuation_frame) #define scheme_pop_continuation_frame (scheme_extension_table->scheme_pop_continuation_frame)