diff --git a/src/mzscheme/src/jit.c b/src/mzscheme/src/jit.c index bc6ae41b13..235c69cbb7 100644 --- a/src/mzscheme/src/jit.c +++ b/src/mzscheme/src/jit.c @@ -175,6 +175,7 @@ typedef struct { void *status_at_ptr; int reg_status; void *patch_depth; + int rs_virtual_offset; } mz_jit_state; #define mz_RECORD_STATUS(s) (jitter->status_at_ptr = _jit.x.pc, jitter->reg_status = (s)) @@ -690,6 +691,40 @@ static void *top4; # define VALIDATE_RESULT(reg) /* empty */ #endif +/* The mz_rs_... family of operations operate on a virtual + JIT_RUNSTACK register to perform a kind of peephole optimization. + The virtual register can be de-sync'd from the actual register, so + that multiple adjustments to the register can be collapsed; this + mostly improves code size, rather than speed. Functions that cause + the register to be de-sync'd are marked as such. Functions that can + accomodate a de-sync'd register on entry are marked as such. All + other fuctions can assume a sync'd regsiter and ensure a sync'd + register. Note that branches and calls normally require a sync'd + register. */ + +#if 1 +# define mz_rs_dec(n) (jitter->rs_virtual_offset -= (n)) +# define mz_rs_inc(n) (jitter->rs_virtual_offset += (n)) +# define mz_rs_ldxi(reg, n) jit_ldxi_p(reg, JIT_RUNSTACK, WORDS_TO_BYTES(((n) + jitter->rs_virtual_offset))) +# define mz_rs_ldr(reg) mz_rs_ldxi(reg, 0) +# define mz_rs_stxi(n, reg) jit_stxi_p(WORDS_TO_BYTES(((n) + jitter->rs_virtual_offset)), JIT_RUNSTACK, reg) +# define mz_rs_str(reg) mz_rs_stxi(0, reg) +# define mz_rs_sync() (jitter->rs_virtual_offset \ + ? (jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(jitter->rs_virtual_offset)), \ + jitter->rs_virtual_offset = 0) \ + : 0) +# define mz_rs_sync_0() (jitter->rs_virtual_offset = 0) +#else +# define mz_rs_dec(n) jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(n)) +# define mz_rs_inc(n) jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(n)) +# define mz_rs_ldr(reg) jit_ldr_p(reg, JIT_RUNSTACK) +# define mz_rs_ldxi(reg, n) jit_ldxi_p(reg, JIT_RUNSTACK, WORDS_TO_BYTES(n)) +# define mz_rs_str(reg) jit_str_p(JIT_RUNSTACK, reg) +# define mz_rs_stxi(n, reg) jit_stxi_p(WORDS_TO_BYTES(n), JIT_RUNSTACK, reg) +# define mz_rs_sync() /* empty */ +# define mz_rs_sync_0() /* empty */ +#endif + static void new_mapping(mz_jit_state *jitter) { jitter->num_mappings++; @@ -704,6 +739,7 @@ static void new_mapping(mz_jit_state *jitter) } static void mz_pushr_p_it(mz_jit_state *jitter, int reg) +/* de-sync's rs */ { int v; @@ -719,14 +755,15 @@ static void mz_pushr_p_it(mz_jit_state *jitter, int reg) v++; jitter->mappings[jitter->num_mappings] = ((v << 1) | 0x1); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_dec(1); CHECK_RUNSTACK_OVERFLOW_NOCL(); - jit_str_p(JIT_RUNSTACK, reg); + mz_rs_str(reg); jitter->need_set_rs = 1; } static void mz_popr_p_it(mz_jit_state *jitter, int reg) +/* de-sync's rs */ { int v; @@ -740,8 +777,8 @@ static void mz_popr_p_it(mz_jit_state *jitter, int reg) else jitter->mappings[jitter->num_mappings] = ((v << 1) | 0x1); - jit_ldr_p(reg, JIT_RUNSTACK); - jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_ldr(reg); + mz_rs_inc(1); jitter->need_set_rs = 1; } @@ -919,18 +956,21 @@ static int mz_is_closure(mz_jit_state *jitter, int i, int arity, int *_flags) } static int stack_safety(mz_jit_state *jitter, int cnt, int offset) +/* de-sync'd rs ok */ { /* To preserve space safety, we must initialize any stack room that we make, so that whatever happens to be there isn't - traversed in case of a GC. */ + traversed in case of a GC. the value of JIT_RUNSTACK is + handy to use as a "clear" value. */ int i; for (i = 0; i < cnt; i++) { - jit_stxi_p(WORDS_TO_BYTES(i+offset), JIT_RUNSTACK, JIT_RUNSTACK); + mz_rs_stxi(i+offset, JIT_RUNSTACK); CHECK_LIMIT(); } return 1; } +/* de-sync's rs: */ #define mz_pushr_p(x) mz_pushr_p_it(jitter, x) #define mz_popr_p(x) mz_popr_p_it(jitter, x) @@ -2380,6 +2420,7 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i jit_stxi_p(WORDS_TO_BYTES(num_rands - 1), JIT_RUNSTACK, JIT_R0); generate(rator, jitter, 0, 0, JIT_V1); CHECK_LIMIT(); + mz_rs_sync(); (void)jit_jmpi(slow_code); @@ -2560,6 +2601,7 @@ static int can_direct_native(Scheme_Object *p, int num_rands, long *extract_case static int 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) +/* de-sync'd ok */ { int i, offset, need_safety = 0; int direct_prim = 0, need_non_tail = 0, direct_native = 0, direct_self = 0, nontail_self = 0; @@ -2696,7 +2738,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (num_rands) { if (!direct_prim || (num_rands > 1)) { - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(num_rands)); + mz_rs_dec(num_rands); need_safety = num_rands; CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, num_rands); @@ -2726,7 +2768,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ need_safety = 0; } - generate_non_tail(rator, jitter, 0, !need_non_tail); + generate_non_tail(rator, jitter, 0, !need_non_tail); /* sync'd after args below */ CHECK_LIMIT(); if (num_rands) { @@ -2742,7 +2784,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ jit_movr_p(JIT_V1, JIT_R0); proc_already_in_place = 1; } else { - jit_stxi_p(WORDS_TO_BYTES(num_rands - 1 + offset), JIT_RUNSTACK, JIT_R0); + mz_rs_stxi(num_rands - 1 + offset, JIT_R0); if (need_safety) need_safety--; } @@ -2750,6 +2792,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ jit_movr_p(JIT_V1, JIT_R0); } } + /* not sync'd...*/ for (i = 0; i < num_rands; i++) { PAUSE_JIT_DATA(); @@ -2761,18 +2804,19 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ CHECK_LIMIT(); need_safety = 0; } - generate_non_tail(arg, jitter, 0, !need_non_tail); + generate_non_tail(arg, jitter, 0, !need_non_tail); /* sync'd below */ RESUME_JIT_DATA(); CHECK_LIMIT(); if ((i == num_rands - 1) && !direct_prim && !reorder_ok && !direct_self && !proc_already_in_place) { /* Move rator back to register: */ - jit_ldxi_p(JIT_V1, JIT_RUNSTACK, WORDS_TO_BYTES(i + offset)); + mz_rs_ldxi(JIT_V1, i + offset); } if ((!direct_prim || (num_rands > 1)) && (!direct_self || !is_tail || no_call || (i + 1 < num_rands))) { - jit_stxi_p(WORDS_TO_BYTES(i + offset), JIT_RUNSTACK, JIT_R0); + mz_rs_stxi(i + offset, JIT_R0); } } + /* not sync'd... */ if (need_non_tail) { /* Uses JIT_R2: */ @@ -2786,6 +2830,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ if (num_rands == 1) { mz_runstack_unskipped(jitter, 1); } else { + mz_rs_sync(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); } LOG_IT(("direct: %s\n", ((Scheme_Primitive_Proc *)rator)->name)); @@ -2793,11 +2838,14 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ } if (reorder_ok) { - if (!no_call) - generate(rator, jitter, 0, 0, JIT_V1); + if (!no_call) { + generate(rator, jitter, 0, 0, JIT_V1); /* sync'd below */ + } CHECK_LIMIT(); } + mz_rs_sync(); + END_JIT_DATA(20); if (direct_prim || direct_native || direct_self || nontail_self) @@ -3191,6 +3239,7 @@ static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int r static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Object *rand, Scheme_Object *rand2, int orig_args, int arith, int cmp, int v, jit_insn **for_branch, int branch_short) +/* needs de-sync */ /* Either arith is non-zero or it's a cmp; the value of each determines the operation: arith = 1 -> + or add1 (if !rand2) arith = -1 -> - or sub1 @@ -3279,28 +3328,31 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj if (rand2 && !simple_rand && !simple_rand2) { mz_runstack_skipped(jitter, 1); - generate_non_tail(rand, jitter, 0, 1); + generate_non_tail(rand, jitter, 0, 1); /* sync'd later */ CHECK_LIMIT(); mz_runstack_unskipped(jitter, 1); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_dec(1); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, 1); - jit_str_p(JIT_RUNSTACK, JIT_R0); + mz_rs_str(JIT_R0); } + /* not sync'd... */ if (simple_rand2) { if (SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type)) - generate(rand, jitter, 0, 0, JIT_R1); + generate(rand, jitter, 0, 0, JIT_R1); /* sync'd below */ else { - generate_non_tail(rand, jitter, 0, 1); + generate_non_tail(rand, jitter, 0, 1); /* sync'd below */ + CHECK_LIMIT(); jit_movr_p(JIT_R1, JIT_R0); } CHECK_LIMIT(); - generate(rand2, jitter, 0, 0, JIT_R0); + generate(rand2, jitter, 0, 0, JIT_R0); /* sync'd below */ } else { - generate_non_tail(rand2 ? rand2 : rand, jitter, 0, 1); + generate_non_tail(rand2 ? rand2 : rand, jitter, 0, 1); /* sync'd below */ } CHECK_LIMIT(); + /* sync'd in three branches below */ if (arith == -2) { if (rand2 || (v != 1) || reversed) @@ -3318,13 +3370,15 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj } else { if (simple_rand) { pos = mz_remap(SCHEME_LOCAL_POS(rand)); - jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); + mz_rs_ldxi(JIT_R1, pos); } /* check both fixnum bits at once by ANDing into R2: */ jit_andr_ul(JIT_R2, JIT_R0, JIT_R1); va = JIT_R2; } + mz_rs_sync(); + __START_TINY_JUMPS__(1); ref2 = jit_bmsi_ul(jit_forward(), va, 0x1); __END_TINY_JUMPS__(1); @@ -3352,10 +3406,12 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj CHECK_LIMIT(); } else if (rand2) { /* Move rand result back into R1 */ - jit_ldr_p(JIT_R1, JIT_RUNSTACK); - jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_ldr(JIT_R1); + mz_rs_inc(1); mz_runstack_popped(jitter, 1); + mz_rs_sync(); + /* check both fixnum bits at once by ANDing into R2: */ jit_andr_ul(JIT_R2, JIT_R0, JIT_R1); __START_TINY_JUMPS__(1); @@ -3386,6 +3442,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj } CHECK_LIMIT(); } else { + mz_rs_sync(); /* Only one argument: */ __START_TINY_JUMPS__(1); ref2 = jit_bmsi_ul(jit_forward(), JIT_R0, 0x1); @@ -3731,6 +3788,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec *app, Scheme_Object *cnst, Scheme_Object *cnst2, jit_insn **for_branch, int branch_short) +/* de-sync'd ok */ { GC_CAN_IGNORE jit_insn *ref, *ref2; @@ -3743,6 +3801,8 @@ static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec mz_runstack_unskipped(jitter, 1); + mz_rs_sync(); + __START_SHORT_JUMPS__(branch_short); if (cnst2) { @@ -3786,6 +3846,8 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app mz_runstack_unskipped(jitter, 1); + mz_rs_sync(); + __START_SHORT_JUMPS__(branch_short); ref = jit_bmsi_ul(jit_forward(), JIT_R0, 0x1); @@ -3831,35 +3893,38 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, Scheme_Object *rator, Scheme_Object *rand, jit_insn **for_branch, int branch_short) +/* de-sync'd ok; for branch, sync'd before */ { mz_runstack_skipped(jitter, 1); LOG_IT(("inlined struct op\n")); - generate(rator, jitter, 0, 0, JIT_R0); + generate(rator, jitter, 0, 0, JIT_R0); /* sync'd below */ CHECK_LIMIT(); if (SAME_TYPE(scheme_local_type, SCHEME_TYPE(rand))) { jit_movr_p(JIT_R1, JIT_R0); - generate(rand, jitter, 0, 0, JIT_R0); + generate(rand, jitter, 0, 0, JIT_R0); /* sync'd below */ mz_runstack_unskipped(jitter, 1); } else { mz_runstack_unskipped(jitter, 1); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_dec(1); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, 1); - jit_str_p(JIT_RUNSTACK, JIT_R0); + mz_rs_str(JIT_R0); CHECK_LIMIT(); - generate_non_tail(rand, jitter, 0, 1); + generate_non_tail(rand, jitter, 0, 1); /* sync'd below */ CHECK_LIMIT(); - jit_ldr_p(JIT_R1, JIT_RUNSTACK); - jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_ldr(JIT_R1); + mz_rs_inc(1); mz_runstack_popped(jitter, 1); } + mz_rs_sync(); + /* R1 is [potential] predicate/getter, R0 is value */ if (for_branch) { @@ -3880,6 +3945,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, int is_tail, int multi_ok, jit_insn **for_branch, int branch_short) +/* de-sync's, unless branch */ { Scheme_Object *rator = app->rator; @@ -3984,6 +4050,8 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); + mz_rs_sync(); + /* Jump ahead if it's a fixnum: */ __START_TINY_JUMPS__(1); ref = jit_bmsi_ul(jit_forward(), JIT_R0, 0x1); @@ -4055,6 +4123,8 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); + mz_rs_sync(); + __START_TINY_JUMPS__(1); if (steps > 1) { @@ -4118,6 +4188,8 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); + mz_rs_sync(); + __START_TINY_JUMPS__(1); ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); @@ -4154,6 +4226,8 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); + mz_rs_sync(); + __START_TINY_JUMPS__(1); ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); __END_TINY_JUMPS__(1); @@ -4184,6 +4258,8 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); + mz_rs_sync(); + __START_TINY_JUMPS__(1); ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); __END_TINY_JUMPS__(1); @@ -4210,6 +4286,8 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); + mz_rs_sync(); + (void)jit_calli(syntax_e_code); return 1; @@ -4242,6 +4320,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_skipped(jitter, 1); generate_non_tail(app->rand, jitter, 0, 1); CHECK_LIMIT(); + mz_rs_sync(); mz_runstack_unskipped(jitter, 1); (void)jit_movi_p(JIT_R1, &scheme_null); return generate_cons_alloc(jitter, 0, 0); @@ -4250,7 +4329,8 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in generate_non_tail(app->rand, jitter, 0, 1); CHECK_LIMIT(); mz_runstack_unskipped(jitter, 1); - + mz_rs_sync(); + #ifdef CAN_INLINE_ALLOC /* Inlined alloc */ (void)jit_movi_p(JIT_R1, NULL); /* needed because R1 is marked during a GC */ @@ -4283,7 +4363,8 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in } static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_state *jitter, int order_matters) -/* Results go into R0 and R1. If !order_matters, and if only the +/* de-sync's rs. + Results go into R0 and R1. If !order_matters, and if only the second is simple, then the arguments will be in reverse order. */ { int simple1, simple2, direction = 1; @@ -4295,11 +4376,11 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ if (simple2) { mz_runstack_skipped(jitter, 2); - generate_non_tail(rand1, jitter, 0, 1); + generate_non_tail(rand1, jitter, 0, 1); /* no sync... */ CHECK_LIMIT(); jit_movr_p(JIT_R1, JIT_R0); - generate(rand2, jitter, 0, 0, JIT_R0); + generate(rand2, jitter, 0, 0, JIT_R0); /* no sync... */ CHECK_LIMIT(); if (order_matters) { @@ -4313,39 +4394,39 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ mz_runstack_unskipped(jitter, 2); } else { mz_runstack_skipped(jitter, 2); - generate_non_tail(rand1, jitter, 0, 1); + generate_non_tail(rand1, jitter, 0, 1); /* no sync... */ CHECK_LIMIT(); mz_runstack_unskipped(jitter, 2); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_dec(1); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, 1); - jit_str_p(JIT_RUNSTACK, JIT_R0); + mz_rs_str(JIT_R0); mz_runstack_skipped(jitter, 1); - generate_non_tail(rand2, jitter, 0, 1); + generate_non_tail(rand2, jitter, 0, 1); /* no sync... */ CHECK_LIMIT(); jit_movr_p(JIT_R1, JIT_R0); - jit_ldr_p(JIT_R0, JIT_RUNSTACK); + mz_rs_ldr(JIT_R0); mz_runstack_unskipped(jitter, 1); - jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_inc(1); mz_runstack_popped(jitter, 1); } } else { mz_runstack_skipped(jitter, 2); if (simple2) { - generate(rand2, jitter, 0, 0, JIT_R1); + generate(rand2, jitter, 0, 0, JIT_R1); /* no sync... */ CHECK_LIMIT(); } else { - generate_non_tail(rand2, jitter, 0, 1); + generate_non_tail(rand2, jitter, 0, 1); /* no sync... */ CHECK_LIMIT(); jit_movr_p(JIT_R1, JIT_R0); } - generate(rand1, jitter, 0, 0, JIT_R0); + generate(rand1, jitter, 0, 0, JIT_R0); /* no sync... */ CHECK_LIMIT(); mz_runstack_unskipped(jitter, 2); @@ -4356,6 +4437,7 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, jit_insn **for_branch, int branch_short) +/* de-sync'd ok */ { Scheme_Object *r1, *r2, *rator = app->rator; GC_CAN_IGNORE jit_insn *reffail = NULL, *ref; @@ -4368,6 +4450,8 @@ static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, direction = generate_two_args(r1, r2, jitter, 1); CHECK_LIMIT(); + mz_rs_sync(); + __START_SHORT_JUMPS__(branch_short); if (!SCHEME_CHARP(r1)) { @@ -4483,6 +4567,7 @@ static int generate_vector_op(mz_jit_state *jitter, int set) static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, int is_tail, int multi_ok, jit_insn **for_branch, int branch_short) +/* de-sync's; for branch, sync'd before */ { Scheme_Object *rator = app->rator; @@ -4516,6 +4601,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i generate_non_tail(a2, jitter, 0, 1); CHECK_LIMIT(); + mz_rs_sync(); mz_runstack_unskipped(jitter, 2); @@ -4551,7 +4637,10 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } else { /* Two complex expressions: */ generate_two_args(a2, a1, jitter, 0); - + CHECK_LIMIT(); + + mz_rs_sync(); + __START_SHORT_JUMPS__(branch_short); ref = jit_bner_p(jit_forward(), JIT_R0, JIT_R1); @@ -4643,6 +4732,8 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i generate_two_args(app->rand1, app->rand2, jitter, 1); CHECK_LIMIT(); + mz_rs_sync(); + if (!which) { /* vector-ref is relatively simple and worth inlining */ generate_vector_op(jitter, 0); @@ -4659,6 +4750,8 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i generate_non_tail(app->rand1, jitter, 0, 1); CHECK_LIMIT(); + + mz_rs_sync(); offset = SCHEME_INT_VAL(app->rand2); (void)jit_movi_p(JIT_R1, offset); @@ -4690,6 +4783,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i generate_two_args(app->rand1, app->rand2, jitter, 1); CHECK_LIMIT(); + mz_rs_sync(); __START_TINY_JUMPS__(1); ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); @@ -4720,6 +4814,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i generate_two_args(app->rand1, app->rand2, jitter, 1); CHECK_LIMIT(); + mz_rs_sync(); return generate_cons_alloc(jitter, 0, 0); } else if (IS_NAMED_PRIM(rator, "mcons")) { @@ -4727,6 +4822,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i generate_two_args(app->rand1, app->rand2, jitter, 1); CHECK_LIMIT(); + mz_rs_sync(); #ifdef CAN_INLINE_ALLOC /* Inlined alloc */ @@ -4753,12 +4849,13 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i generate_two_args(app->rand1, app->rand2, jitter, 1); CHECK_LIMIT(); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_dec(1); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, 1); - jit_str_p(JIT_RUNSTACK, JIT_R0); + mz_rs_str(JIT_R0); (void)jit_movi_p(JIT_R0, &scheme_null); CHECK_LIMIT(); + mz_rs_sync(); generate_cons_alloc(jitter, 1, 0); CHECK_LIMIT(); @@ -4787,6 +4884,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int is_tail, int multi_ok, jit_insn **for_branch, int branch_short) +/* de-sync's; for branch, sync'd before */ { Scheme_Object *rator = app->args[0]; @@ -4833,33 +4931,34 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int mz_runstack_skipped(jitter, 3 - pushed); if (pushed) { - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(pushed)); + mz_rs_dec(pushed); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, pushed); stack_safety(jitter, pushed, 0); CHECK_LIMIT(); } - generate_non_tail(app->args[1], jitter, 0, 1); + generate_non_tail(app->args[1], jitter, 0, 1); /* sync'd below */ CHECK_LIMIT(); if (!constval || !simple) { - jit_str_p(JIT_RUNSTACK, JIT_R0); + mz_rs_str(JIT_R0); } else { jit_movr_p(JIT_V1, JIT_R0); } if (!simple) { - generate_non_tail(app->args[2], jitter, 0, 1); + generate_non_tail(app->args[2], jitter, 0, 1); /* sync'd below */ CHECK_LIMIT(); if (!constval) { - jit_stxi_p(WORDS_TO_BYTES(1), JIT_RUNSTACK, JIT_R0); + mz_rs_stxi(1, JIT_R0); } else { jit_movr_p(JIT_R1, JIT_R0); } } - generate_non_tail(app->args[3], jitter, 0, 1); + generate_non_tail(app->args[3], jitter, 0, 1); /* sync'd below */ CHECK_LIMIT(); + mz_rs_sync(); if (!constval || !simple) { jit_movr_p(JIT_R2, JIT_R0); @@ -4901,7 +5000,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int } } - jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(pushed)); + mz_rs_inc(pushed); /* no sync */ mz_runstack_popped(jitter, pushed); mz_runstack_unskipped(jitter, 3 - pushed); @@ -4920,6 +5019,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int if (c) generate_app(app, NULL, c, jitter, 0, 0, 1); CHECK_LIMIT(); + mz_rs_sync(); #ifdef CAN_INLINE_ALLOC jit_movi_l(JIT_R2, c); @@ -4940,7 +5040,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int #endif if (c) { - jit_addi_l(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(c)); + mz_rs_inc(c); /* no sync */ mz_runstack_popped(jitter, c); } @@ -4995,6 +5095,7 @@ static int generate_cons_alloc(mz_jit_state *jitter, int rev, int inline_retry) static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3) +/* de-sync'd ok */ { int imm, i, c; @@ -5002,20 +5103,22 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, if (app2) { mz_runstack_skipped(jitter, 1); - generate_non_tail(app2->rand, jitter, 0, 1); + generate_non_tail(app2->rand, jitter, 0, 1); /* sync'd below */ CHECK_LIMIT(); mz_runstack_unskipped(jitter, 1); c = 1; } else if (app3) { - generate_two_args(app3->rand1, app3->rand2, jitter, 1); + generate_two_args(app3->rand1, app3->rand2, jitter, 1); /* sync'd below */ c = 2; } else { c = app->num_args; if (c) - generate_app(app, NULL, c, jitter, 0, 0, 1); + generate_app(app, NULL, c, jitter, 0, 0, 1); /* sync'd below */ } CHECK_LIMIT(); + mz_rs_sync(); + #ifdef CAN_INLINE_ALLOC /* Inlined alloc */ if (app2) @@ -5073,6 +5176,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, } if (c) { + /* could use mz_rs */ jit_addi_l(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(c)); mz_runstack_popped(jitter, c); } @@ -5082,6 +5186,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, } int generate_inlined_test(mz_jit_state *jitter, Scheme_Object *obj, int branch_short, jit_insn **refs) +/* de-sync'd ok; syncs before jump */ { switch (SCHEME_TYPE(obj)) { case scheme_application2_type: @@ -5248,6 +5353,7 @@ static void ensure_case_closure_native(Scheme_Case_Lambda *c) } static int generate_case_closure(Scheme_Object *obj, mz_jit_state *jitter, int target) +/* de-sync's */ { Scheme_Case_Lambda *c = (Scheme_Case_Lambda *)obj; Scheme_Native_Closure_Data *ndata; @@ -5258,6 +5364,8 @@ static int generate_case_closure(Scheme_Object *obj, mz_jit_state *jitter, int t ensure_case_closure_native(c); ndata = c->native_code; + mz_rs_sync(); + JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); mz_prepare(1); retptr = mz_retain(ndata); @@ -5279,6 +5387,7 @@ static int generate_case_closure(Scheme_Object *obj, mz_jit_state *jitter, int t o = (Scheme_Object *)((Scheme_Closure *)o)->code; data = (Scheme_Closure_Data *)o; mz_pushr_p(JIT_R1); + mz_rs_sync(); generate_closure(data, jitter, 1); CHECK_LIMIT(); generate_closure_fill(data, jitter); @@ -5299,7 +5408,8 @@ static int generate_case_closure(Scheme_Object *obj, mz_jit_state *jitter, int t static int generate_non_tail_mark_pos_prefix(mz_jit_state *jitter) { - /* This part of a non-tail setup can be done once for a sequence + /* dsync'd ok. + This part of a non-tail setup can be done once for a sequence of non-tail calls. In that case, pass 0 for the `mark_pos_ends' argument to generate_non_tail(), so that it can skip this prefix and suffix. In case this prefix needs to adjust the runstack, @@ -5311,6 +5421,7 @@ static int generate_non_tail_mark_pos_prefix(mz_jit_state *jitter) } static void generate_non_tail_mark_pos_suffix(mz_jit_state *jitter) +/* dsync'd ok */ { jit_ldi_l(JIT_R2, &scheme_current_cont_mark_pos); jit_subi_l(JIT_R2, JIT_R2, 2); @@ -5318,6 +5429,7 @@ static void generate_non_tail_mark_pos_suffix(mz_jit_state *jitter) } static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int mark_pos_ends) +/* de-sync's rs */ { if (is_simple(obj, INIT_SIMPLE_DEPTH, 0, jitter, 0)) { /* Simple; doesn't change the stack or set marks: */ @@ -5348,7 +5460,7 @@ static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi /* mark stack is an integer... turn it into a pointer */ jit_lshi_l(JIT_R2, JIT_R2, 0x1); jit_ori_l(JIT_R2, JIT_R2, 0x1); - mz_pushr_p(JIT_R2); + mz_pushr_p(JIT_R2); /* no sync */ } CHECK_LIMIT(); } @@ -5358,7 +5470,7 @@ static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi PAUSE_JIT_DATA(); FOR_LOG(jitter->log_depth++); - generate(obj, jitter, 0, multi_ok, JIT_R0); + generate(obj, jitter, 0, multi_ok, JIT_R0); /* no sync */ FOR_LOG(--jitter->log_depth); RESUME_JIT_DATA(); @@ -5366,14 +5478,14 @@ static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi amt = mz_runstack_restored(jitter); if (amt) { - jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(amt)); + mz_rs_inc(amt); } if (need_ends) { if (using_local1) { mz_get_local_p(JIT_R2, JIT_LOCAL1); jitter->local1_busy = 0; } else { - mz_popr_p(JIT_R2); + mz_popr_p(JIT_R2); /* no sync */ jit_rshi_l(JIT_R2, JIT_R2, 0x1); /* pointer back to integer */ } jit_sti_p(&scheme_current_cont_mark_stack, JIT_R2); @@ -5393,6 +5505,7 @@ static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi /*========================================================================*/ static int generate_ignored_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends) +/* de-sync's */ { Scheme_Type t = SCHEME_TYPE(obj); @@ -5404,7 +5517,7 @@ static int generate_ignored_non_tail(Scheme_Object *obj, mz_jit_state *jitter, i START_JIT_DATA(); pos = mz_remap(SCHEME_LOCAL_POS(obj)); LOG_IT(("clear %d\n", pos)); - jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_RUNSTACK); + mz_rs_stxi(pos, JIT_RUNSTACK); END_JIT_DATA(2); } return 1; @@ -5429,7 +5542,7 @@ static Scheme_Object *generate_k(void) } static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int multi_ok, int target) -/* result goes to JIT_R0 */ +/* de-sync's; result goes to target */ { Scheme_Type type; @@ -5468,9 +5581,10 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m /* Other parts of the JIT rely on this code not modifying R1 */ START_JIT_DATA(); LOG_IT(("top-level\n")); + mz_rs_sync(); /* Load global array: */ pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj)); - jit_ldxi_p(JIT_R2, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); + mz_rs_ldxi(JIT_R2, pos); /* Load bucket: */ pos = SCHEME_TOPLEVEL_POS(obj); jit_ldxi_p(JIT_R2, JIT_R2, WORDS_TO_BYTES(pos)); @@ -5493,13 +5607,13 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m pos = mz_remap(SCHEME_LOCAL_POS(obj)); LOG_IT(("local %d [%d]\n", pos, SCHEME_LOCAL_FLAGS(obj))); if (pos || (mz_CURRENT_STATUS() != mz_RS_R0_HAS_RUNSTACK0)) { - jit_ldxi_p(target, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); + mz_rs_ldxi(target, pos); VALIDATE_RESULT(target); } else if (target != JIT_R0) { jit_movr_p(target, JIT_R0); } if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) { - jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_RUNSTACK); + mz_rs_stxi(pos, JIT_RUNSTACK); } END_JIT_DATA(2); return 1; @@ -5511,11 +5625,11 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m LOG_IT(("unbox local\n")); pos = mz_remap(SCHEME_LOCAL_POS(obj)); - jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); + mz_rs_ldxi(JIT_R0, pos); jit_ldr_p(target, JIT_R0); if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) { LOG_IT(("clear-on-read\n")); - jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_RUNSTACK); + mz_rs_stxi(pos, JIT_RUNSTACK); } VALIDATE_RESULT(target); @@ -5525,6 +5639,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m case scheme_syntax_type: { int pos; + mz_rs_sync(); pos = SCHEME_PINT_VAL(obj); switch (pos) { case CASE_LAMBDA_EXPD: @@ -5551,17 +5666,19 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m evaluation, allow multiple values. */ generate_non_tail(seq->array[0], jitter, 1, 1); CHECK_LIMIT(); + mz_rs_sync(); /* Save value(s) */ jit_movr_p(JIT_V1, JIT_R0); mz_pushr_p(JIT_V1); mz_pushr_p(JIT_V1); mz_pushr_p(JIT_V1); + mz_rs_sync(); __START_SHORT_JUMPS__(1); ref = jit_bnei_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES); CHECK_LIMIT(); /* Save away multiple values */ - mz_popr_p(JIT_V1); + mz_popr_p(JIT_V1); /* sync'd below... */ mz_popr_p(JIT_V1); mz_popr_p(JIT_V1); jit_ldi_p(JIT_R0, &scheme_current_thread); @@ -5569,14 +5686,15 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m jit_ldxi_l(JIT_V1, JIT_R0, &((Scheme_Thread *)0x0)->ku.multiple.count); jit_lshi_l(JIT_V1, JIT_V1, 0x1); jit_ori_l(JIT_V1, JIT_V1, 0x1); - mz_pushr_p(JIT_V1); + mz_pushr_p(JIT_V1); /* sync'd below */ jit_ldxi_p(JIT_V1, JIT_R0, &((Scheme_Thread *)0x0)->ku.multiple.array); - mz_pushr_p(JIT_V1); + mz_pushr_p(JIT_V1); /* sync'd below */ CHECK_LIMIT(); (void)jit_movi_p(JIT_R1, 0x0); mz_pushr_p(JIT_R1); /* pushing 0 indicates that multi-array follows */ /* If multi-value array is values buffer, zero out values buffer */ jit_ldxi_p(JIT_R2, JIT_R0, &((Scheme_Thread *)0x0)->values_buffer); + mz_rs_sync(); ref2 = jit_bner_p(jit_forward(), JIT_V1, JIT_R2); jit_stxi_p(&((Scheme_Thread *)0x0)->values_buffer, JIT_R0, JIT_R1); CHECK_LIMIT(); @@ -5586,7 +5704,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m mz_patch_branch(ref2); __END_SHORT_JUMPS__(1); for (i = 1; i < seq->count; i++) { - generate_ignored_non_tail(seq->array[i], jitter, 1, 1); + generate_ignored_non_tail(seq->array[i], jitter, 1, 1); /* sync's below */ CHECK_LIMIT(); } @@ -5594,6 +5712,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m mz_popr_p(JIT_R0); mz_popr_p(JIT_R1); mz_popr_p(JIT_R2); + mz_rs_sync(); CHECK_LIMIT(); __START_TINY_JUMPS__(1); ref = jit_bnei_p(jit_forward(), JIT_R0, 0x0); @@ -5629,7 +5748,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m generate_non_tail(p, jitter, 0, 1); CHECK_LIMIT(); - + mz_rs_sync(); + /* Load global+stx array: */ pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(v)); jit_ldxi_p(JIT_R2, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); @@ -5666,7 +5786,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m generate_non_tail(v, jitter, 0, 1); CHECK_LIMIT(); - + mz_rs_sync(); + /* If v is not known to produce a procedure, then check result: */ if (!is_a_procedure(v, jitter)) { (void)jit_bmsi_l(bad_app_vals_target, JIT_R0, 0x1); @@ -5683,6 +5804,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m mz_popr_p(JIT_V1); /* Function is in V1, argument(s) in R0 */ + mz_rs_sync(); + __START_SHORT_JUMPS__(1); ref = jit_beqi_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES); /* Single-value case: --------------- */ @@ -5985,6 +6108,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m if (!generate_inlined_test(jitter, branch->test, then_short_ok, refs)) { CHECK_LIMIT(); generate_non_tail(branch->test, jitter, 0, 1); + mz_rs_sync(); CHECK_LIMIT(); __START_SHORT_JUMPS__(then_short_ok); refs[0] = jit_beqi_p(jit_forward(), JIT_R0, scheme_false); @@ -6003,9 +6127,11 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m CHECK_LIMIT(); amt = mz_runstack_restored(jitter); if (g1 != 2) { - if (amt && !is_tail) { - jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(amt)); - } + if (!is_tail) { + if (amt) + mz_rs_inc(amt); + mz_rs_sync(); + } __START_SHORT_JUMPS__(else_short_ok); ref2 = jit_jmpi(jit_forward()); __END_SHORT_JUMPS__(else_short_ok); @@ -6015,7 +6141,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m nsrs1 = 0; } jitter->need_set_rs = nsrs; - + mz_rs_sync_0(); + /* False branch */ mz_runstack_saved(jitter); __START_SHORT_JUMPS__(then_short_ok); @@ -6047,9 +6174,11 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m CHECK_LIMIT(); amt = mz_runstack_restored(jitter); if (g2 != 2) { - if (amt && !is_tail) { - jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(amt)); - } + if (!is_tail) { + if (amt) + mz_rs_inc(amt); + mz_rs_sync(); + } } else { jitter->need_set_rs = 0; } @@ -6079,6 +6208,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m LOG_IT(("lambda\n")); + mz_rs_sync(); + /* Allocate closure */ generate_closure(data, jitter, 1); CHECK_LIMIT(); @@ -6102,15 +6233,15 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m if (lv->count == 1) { /* Expect one result: */ - generate_non_tail(lv->value, jitter, 0, 1); + generate_non_tail(lv->value, jitter, 0, 1); /* no sync */ CHECK_LIMIT(); if (ab) { pos = mz_remap(lv->position); - jit_ldxi_p(JIT_R2, JIT_RUNSTACK, WORDS_TO_BYTES(pos)); + mz_rs_ldxi(JIT_R2, pos); jit_str_p(JIT_R2, JIT_R0); } else { pos = mz_remap(lv->position); - jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_R0); + mz_rs_stxi(pos, JIT_R0); } CHECK_LIMIT(); } else { @@ -6119,6 +6250,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m generate_non_tail(lv->value, jitter, 1, 1); CHECK_LIMIT(); + + mz_rs_sync(); __START_SHORT_JUMPS__(1); @@ -6185,13 +6318,14 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m LOG_IT(("letv...\n")); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(c)); + mz_rs_dec(c); CHECK_RUNSTACK_OVERFLOW(); stack_safety(jitter, c, 0); mz_runstack_pushed(jitter, c); if (SCHEME_LET_AUTOBOX(lv)) { int i; + mz_rs_sync(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); for (i = 0; i < c; i++) { CHECK_LIMIT(); @@ -6219,6 +6353,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m LOG_IT(("letrec...\n")); + mz_rs_sync(); + /* Create unfinished closures */ for (i = 0; i < l->count; i++) { ((Scheme_Closure_Data *)l->procs[i])->context = (Scheme_Object *)l; @@ -6274,17 +6410,17 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m mz_runstack_skipped(jitter, 1); PAUSE_JIT_DATA(); - generate_non_tail(lv->value, jitter, 0, 1); + generate_non_tail(lv->value, jitter, 0, 1); /* no sync */ RESUME_JIT_DATA(); CHECK_LIMIT(); mz_runstack_unskipped(jitter, 1); - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); + mz_rs_dec(1); CHECK_RUNSTACK_OVERFLOW(); mz_runstack_pushed(jitter, 1); - jit_str_p(JIT_RUNSTACK, JIT_R0); + mz_rs_str(JIT_R0); END_JIT_DATA(17); @@ -6302,20 +6438,21 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m LOG_IT(("wcm...\n")); /* Key: */ - generate_non_tail(wcm->key, jitter, 0, 1); + generate_non_tail(wcm->key, jitter, 0, 1); /* sync'd below */ CHECK_LIMIT(); if (SCHEME_TYPE(wcm->val) > _scheme_values_types_) { /* No need to push mark onto value stack: */ jit_movr_p(JIT_V1, JIT_R0); - generate_non_tail(wcm->val, jitter, 0, 1); + generate_non_tail(wcm->val, jitter, 0, 1); /* sync'd below */ CHECK_LIMIT(); } else { mz_pushr_p(JIT_R0); - generate_non_tail(wcm->val, jitter, 0, 1); + generate_non_tail(wcm->val, jitter, 0, 1); /* sync'd below */ CHECK_LIMIT(); - mz_popr_p(JIT_V1); + mz_popr_p(JIT_V1); /* sync'd below */ } + mz_rs_sync(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); mz_prepare(2); @@ -6341,7 +6478,9 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m i = qs->position; c = mz_remap(qs->depth); p = qs->midpoint; - + + mz_rs_sync(); + jit_movi_i(JIT_R0, WORDS_TO_BYTES(c)); jit_movi_i(JIT_R1, WORDS_TO_BYTES(i + p + 1)); jit_movi_i(JIT_R2, WORDS_TO_BYTES(p)); @@ -7620,7 +7759,10 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) #ifndef JIT_PRECISE_GC if (data->closure_size) #endif - mz_pushr_p(JIT_R0); + { + mz_pushr_p(JIT_R0); + mz_rs_sync(); + } JIT_UPDATE_THREAD_RSPTR(); CHECK_LIMIT(); mz_prepare(3); @@ -7634,7 +7776,10 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) #ifndef JIT_PRECISE_GC if (data->closure_size) #endif - mz_popr_p(JIT_R0); + { + mz_popr_p(JIT_R0); + mz_rs_sync(); + } jit_stxi_p(WORDS_TO_BYTES(cnt), JIT_RUNSTACK, JIT_V1); mz_patch_ucbranch(ref2); /* jump here if we copied and produced null */ CHECK_LIMIT(); @@ -7649,24 +7794,26 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) /* Keeping the native-closure pointer on the runstack ensures that the code won't be GCed while we're running it. */ - mz_pushr_p(JIT_R0); + mz_pushr_p(JIT_R0); /* no sync */ #endif /* Extract closure to runstack: */ cnt = data->closure_size; if (cnt) { - jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(cnt)); + mz_rs_dec(cnt); CHECK_RUNSTACK_OVERFLOW(); for (i = cnt; i--; ) { int pos; pos = WORDS_TO_BYTES(i) + (long)&((Scheme_Native_Closure *)0x0)->vals; jit_ldxi_p(JIT_R1, JIT_R0, pos); - jit_stxi_p(WORDS_TO_BYTES(i), JIT_RUNSTACK, JIT_R1); + mz_rs_stxi(i, JIT_R1); CHECK_LIMIT(); } } + mz_rs_sync(); + /* If we have a letrec context, record arities */ if (data->context && SAME_TYPE(SCHEME_TYPE(data->context), scheme_letrec_type)) { Scheme_Letrec *lr = (Scheme_Letrec *)data->context; @@ -7722,7 +7869,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data) /* Generate code for the body: */ jitter->need_set_rs = 1; - r = generate(data->code, jitter, 1, 1, JIT_R0); + r = generate(data->code, jitter, 1, 1, JIT_R0); /* no need for sync */ /* Result is in JIT_R0 */ CHECK_LIMIT();