diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index e3ffa81ca7..1852654f8c 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -1340,7 +1340,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte CHECK_LIMIT(); scheme_mz_flostack_restore(jitter, flostack, flostack_pos, !for_branch, 1); FOR_LOG(--jitter->log_depth); - /* mz_CLEAR_R0_STATUS(); --- not needed, since stack doesn't change */ + /* mz_SET_REG_STATUS_VALID(0); --- not needed, since stack doesn't change */ return v; } @@ -1429,7 +1429,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte } jitter->pushed_marks = save_pushed_marks; - mz_CLEAR_R0_STATUS(); + mz_SET_REG_STATUS_VALID(0); END_JIT_DATA(21); } @@ -1654,7 +1654,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail scheme_signal_error("internal error: self position moved across branch"); /* False branch */ - mz_CLEAR_R0_STATUS(); + mz_SET_REG_STATUS_VALID(0); scheme_mz_runstack_saved(jitter); flostack = scheme_mz_flostack_save(jitter, &flostack_pos); __START_SHORT_JUMPS__(then_short_ok); @@ -1718,7 +1718,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail if (nsrs1) jitter->need_set_rs = 1; - mz_CLEAR_R0_STATUS(); + mz_SET_REG_STATUS_VALID(0); return 1; } @@ -1820,19 +1820,44 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w pos = mz_remap(SCHEME_LOCAL_POS(obj)); LOG_IT(("local %d [%d]\n", pos, SCHEME_LOCAL_FLAGS(obj))); if (!result_ignored && (!flonum || !jitter->unbox)) { - int old_r0 = -1; - if (mz_CURRENT_R0_STATUS_VALID()) old_r0 = mz_CURRENT_R0_STATUS(); - if (pos != old_r0) { + int valid, old_r0 = -1, old_r1 = -1; + + if (mz_CURRENT_REG_STATUS_VALID()) { + valid = 1; + old_r0 = jitter->r0_status; + old_r1 = jitter->r1_status; + } else + valid = 0; + + if (pos == old_r0) { + if (target != JIT_R0) { + jit_movr_p(target, JIT_R0); + if (target == JIT_R1) + jitter->r1_status = pos; + mz_SET_REG_STATUS_VALID(1); + } + } else if (pos == old_r1) { + if (target != JIT_R1) { + jit_movr_p(target, JIT_R1); + if (target == JIT_R0) + jitter->r1_status = pos; + mz_SET_REG_STATUS_VALID(1); + } + } else { mz_rs_ldxi(target, pos); VALIDATE_RESULT(target); - if (target == JIT_R0) - mz_RECORD_R0_STATUS(pos); - else { - /* R0 is unchanged */ - mz_RECORD_R0_STATUS(old_r0); + if (target == JIT_R0) { + jitter->r0_status = pos; + jitter->r1_status = old_r1; + mz_SET_REG_STATUS_VALID(1); + } else if (target == JIT_R1) { + jitter->r1_status = pos; + jitter->r0_status = old_r0; + mz_SET_REG_STATUS_VALID(1); + } else if (valid) { + /* R0 and R1 are unchanged */ + mz_SET_REG_STATUS_VALID(1); } - } else if (target != JIT_R0) { - jit_movr_p(target, JIT_R0); } } if (SCHEME_GET_LOCAL_FLAGS(obj) == SCHEME_LOCAL_CLEAR_ON_READ) { @@ -2721,7 +2746,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w if (!unused) { mz_rs_str(JIT_R0); - mz_RECORD_R0_STATUS(0); + jitter->r0_status = 0; + jitter->r1_status = -1; + mz_SET_REG_STATUS_VALID(1); } END_JIT_DATA(17); diff --git a/src/racket/src/jit.h b/src/racket/src/jit.h index 27753a79d2..deb1b20b4d 100644 --- a/src/racket/src/jit.h +++ b/src/racket/src/jit.h @@ -310,7 +310,7 @@ typedef struct { Scheme_Native_Closure *nc; /* for extract_globals and extract_closure_local, only */ Scheme_Closure_Data *self_data; void *status_at_ptr; - int reg_status; + int r0_status, r1_status; void *patch_depth; int rs_virtual_offset; int unbox, unbox_depth; @@ -340,10 +340,11 @@ typedef struct { Branch_Info_Addr *addrs; } Branch_Info; -#define mz_RECORD_R0_STATUS(s) (jitter->status_at_ptr = _jit.x.pc, jitter->reg_status = (s)) -#define mz_CURRENT_R0_STATUS_VALID() (jitter->status_at_ptr == _jit.x.pc) -#define mz_CURRENT_R0_STATUS() (jitter->reg_status) -#define mz_CLEAR_R0_STATUS() (jitter->status_at_ptr = 0) +#define mz_CURRENT_REG_STATUS_VALID() (jitter->status_at_ptr == _jit.x.pc) +#define mz_SET_REG_STATUS_VALID(v) (jitter->status_at_ptr = (v ? _jit.x.pc : 0)) + +#define mz_SET_R0_STATUS_VALID(v) (jitter->status_at_ptr = (v ? _jit.x.pc : 0), \ + jitter->r1_status = -1) /* If JIT_THREAD_LOCAL is defined, then access to global variables goes through a thread_local_pointers table. Call @@ -511,8 +512,12 @@ static void *top4; register. */ #if 1 -# define mz_rs_dec(n) (((jitter->reg_status >= 0) ? jitter->reg_status += (n) : 0), jitter->rs_virtual_offset -= (n)) -# define mz_rs_inc(n) (jitter->reg_status -= (n), jitter->rs_virtual_offset += (n)) +# define mz_rs_dec(n) (((jitter->r0_status >= 0) ? jitter->r0_status += (n) : 0), \ + ((jitter->r1_status >= 0) ? jitter->r1_status += (n) : 0), \ + jitter->rs_virtual_offset -= (n)) +# define mz_rs_inc(n) (jitter->r0_status -= (n), \ + jitter->r1_status -= (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) diff --git a/src/racket/src/jitarith.c b/src/racket/src/jitarith.c index 872b6081ef..adac460c95 100644 --- a/src/racket/src/jitarith.c +++ b/src/racket/src/jitarith.c @@ -1085,8 +1085,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj va = JIT_R0; } else { if (simple_rand) { - pos = mz_remap(SCHEME_LOCAL_POS(rand)); - mz_rs_ldxi(JIT_R1, pos); + scheme_generate(rand, jitter, 0, 0, 0, JIT_R1, NULL); } if (!unsafe_fx && !unsafe_fl) { /* check both fixnum bits at once by ANDing into R2: */ diff --git a/src/racket/src/jitcall.c b/src/racket/src/jitcall.c index 9fee1ee2d9..00cc468574 100644 --- a/src/racket/src/jitcall.c +++ b/src/racket/src/jitcall.c @@ -1639,9 +1639,9 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_ && (!direct_self || !is_tail || no_call || (i + 1 < num_rands)) && !inline_direct_args) { int r0; - r0 = (mz_CURRENT_R0_STATUS_VALID() ? mz_CURRENT_R0_STATUS() : -1); + r0 = mz_CURRENT_REG_STATUS_VALID(); mz_rs_stxi(i + offset, JIT_R0); - if (r0 > -1) mz_RECORD_R0_STATUS(r0); + mz_SET_REG_STATUS_VALID(r0); } } /* not sync'd... */ diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index 1c9782e7c7..0188c783c4 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -177,7 +177,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app Branch_Info *for_branch, int branch_short, int need_sync) { GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *ref5; - int int_ok, r0_set, r0; + int int_ok, reg_valid; int_ok = ((lo_ty <= scheme_integer_type) && (scheme_integer_type <= hi_ty)); @@ -194,13 +194,9 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app __START_SHORT_JUMPS__(branch_short); - r0_set = 0; - r0 = 0; + reg_valid = 0; if (for_branch) { - if (mz_CURRENT_R0_STATUS_VALID()) { - r0_set = 1; - r0 = mz_CURRENT_R0_STATUS(); - } + reg_valid = mz_CURRENT_REG_STATUS_VALID(); scheme_prepare_branch_jump(jitter, for_branch); CHECK_LIMIT(); } @@ -256,9 +252,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app /* In case true is a fall-through, note that the test didn't disturb R0: */ - if (r0_set) { - mz_RECORD_R0_STATUS(r0); - } + mz_SET_R0_STATUS_VALID(reg_valid); scheme_branch_for_true(jitter, for_branch); CHECK_LIMIT(); @@ -1261,6 +1255,7 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ scheme_generate_non_tail(rand1, jitter, 0, 1, 0); /* no sync... */ CHECK_LIMIT(); + jit_movr_p(JIT_R1, JIT_R0); scheme_generate(rand2, jitter, 0, 0, 0, JIT_R0, NULL); /* no sync... */ @@ -1268,9 +1263,18 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ if (order_matters) { /* Swap arguments: */ + int reg_status; + reg_status = mz_CURRENT_REG_STATUS_VALID(); jit_movr_p(JIT_R2, JIT_R0); jit_movr_p(JIT_R0, JIT_R1); jit_movr_p(JIT_R1, JIT_R2); + if (reg_status) { + int pos; + pos = jitter->r0_status; + jitter->r0_status = jitter->r1_status; + jitter->r1_status = pos; + mz_SET_REG_STATUS_VALID(1); + } } else direction = -1; @@ -1673,7 +1677,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i if (SCHEME_TYPE(a1) > _scheme_values_types_) { /* Compare to constant: */ - int retptr; + int retptr, reg_status; mz_runstack_skipped(jitter, 2); @@ -1697,6 +1701,8 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_prepare_branch_jump(jitter, for_branch); CHECK_LIMIT(); } + + reg_status = mz_CURRENT_REG_STATUS_VALID(); #ifdef JIT_PRECISE_GC if (retptr) { @@ -1707,6 +1713,14 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i ref = mz_bnei_p(jit_forward(), JIT_R0, a1); if (for_branch) { + /* In case true is a fall-through, note that the test + didn't disturb R0 (and maybe not R1): */ +#ifdef JIT_PRECISE_GC + if (retptr) + mz_SET_R0_STATUS_VALID(reg_status); + else +#endif + mz_SET_REG_STATUS_VALID(reg_status); scheme_add_branch_false(for_branch, ref); scheme_branch_for_true(jitter, for_branch); CHECK_LIMIT();