unboxing of intermediate results in some 'unsafe-fl' combinations

svn: r16229
This commit is contained in:
Matthew Flatt 2009-10-03 14:10:55 +00:00
parent c579734e6b
commit 9852bb16a2
2 changed files with 783 additions and 594 deletions

View File

@ -122,6 +122,24 @@
(test-un 8.0 'unsafe-fx->fl 8) (test-un 8.0 'unsafe-fx->fl 8)
(test-un -8.0 'unsafe-fx->fl -8) (test-un -8.0 'unsafe-fx->fl -8)
;; test unboxing:
(test-tri 9.0 '(lambda (x y z) (unsafe-fl+ (unsafe-fl- x z) y)) 4.5 7.0 2.5)
(test-tri 9.0 '(lambda (x y z) (unsafe-fl+ y (unsafe-fl- x z))) 4.5 7.0 2.5)
(test-bin 10.0 '(lambda (x y) (unsafe-fl+ (unsafe-fx->fl x) y)) 2 8.0)
(test-bin 10.0 '(lambda (x y) (unsafe-fl+ (unsafe-fx->fl x) y)) 2 8.0)
(test-tri (/ 20.0 0.8) '(lambda (x y z) (unsafe-fl/ (unsafe-fl* x z) y)) 4.0 0.8 5.0)
(test-tri (/ 0.8 20.0) '(lambda (x y z) (unsafe-fl/ y (unsafe-fl* x z))) 4.0 0.8 5.0)
(test-tri #t '(lambda (x y z) (unsafe-fl< (unsafe-fl+ x y) z)) 1.2 3.4 5.0)
(test-tri 'yes '(lambda (x y z) (if (unsafe-fl< (unsafe-fl+ x y) z) 'yes 'no)) 1.2 3.4 5.0)
(test-tri #f '(lambda (x y z) (unsafe-fl> (unsafe-fl+ x y) z)) 1.2 3.4 5.0)
(test-tri 'no '(lambda (x y z) (if (unsafe-fl> (unsafe-fl+ x y) z) 'yes 'no)) 1.2 3.4 5.0)
;; test unboxing interaction with free variables:
(test-tri 4.4 '(lambda (x y z) (with-handlers ([exn:fail:contract:variable?
(lambda (exn) (unsafe-fl+ x y))])
(unsafe-fl- (unsafe-fl+ x y) NO-SUCH-VARIABLE)))
1.1 3.3 5.2)
(test-un 5 'unsafe-car (cons 5 9)) (test-un 5 'unsafe-car (cons 5 9))
(test-un 9 'unsafe-cdr (cons 5 9)) (test-un 9 'unsafe-cdr (cons 5 9))
(test-un 15 'unsafe-mcar (mcons 15 19)) (test-un 15 'unsafe-mcar (mcons 15 19))

View File

@ -189,6 +189,7 @@ typedef struct {
int reg_status; int reg_status;
void *patch_depth; void *patch_depth;
int rs_virtual_offset; int rs_virtual_offset;
int unbox, unbox_depth;
} mz_jit_state; } mz_jit_state;
#define mz_RECORD_STATUS(s) (jitter->status_at_ptr = _jit.x.pc, jitter->reg_status = (s)) #define mz_RECORD_STATUS(s) (jitter->status_at_ptr = _jit.x.pc, jitter->reg_status = (s))
@ -3185,6 +3186,76 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
return is_tail ? 2 : 1; return is_tail ? 2 : 1;
} }
static int is_unboxable_op(Scheme_Object *obj, int flag)
{
if (!SCHEME_PRIMP(obj))
return 0;
if (!(SCHEME_PRIM_PROC_FLAGS(obj) & flag))
return 0;
if (IS_NAMED_PRIM(obj, "unsafe-fl+")) return 1;
if (IS_NAMED_PRIM(obj, "unsafe-fl-")) return 1;
if (IS_NAMED_PRIM(obj, "unsafe-fl*")) return 1;
if (IS_NAMED_PRIM(obj, "unsafe-fl/")) return 1;
if (IS_NAMED_PRIM(obj, "unsafe-fx->fl")) return 1;
return 0;
}
static int generate_pop_unboxed(mz_jit_state *jitter)
{
#if defined(MZ_USE_JIT_I386)
/* If we have some arguments pushed on the FP stack, we need
to pop them off before escaping. */
int i;
for (i = jitter->unbox_depth; i--; ) {
FUCOMPr(1); /* compare with single pop; we ignore the compare result, of course */
}
CHECK_LIMIT();
#endif
return 1;
}
static int can_unbox(Scheme_Object *obj, int fuel, int regs)
/* Assuming that `arg' is unsafely assumed to produce a flonum, can we
just unbox it without using more than `regs' registers? There
cannot be any errors or function calls, unless we've specifically
instrumented them to save/pop floating-point values before
jumping. */
{
Scheme_Type t;
if (!fuel) return 0;
if (!regs) return 0;
t = SCHEME_TYPE(obj);
switch (t) {
case scheme_application2_type:
{
Scheme_App2_Rec *app = (Scheme_App2_Rec *)obj;
if (!is_unboxable_op(app->rator, SCHEME_PRIM_IS_UNARY_INLINED))
return 0;
return can_unbox(app->rand, fuel - 1, regs);
}
case scheme_application3_type:
{
Scheme_App3_Rec *app = (Scheme_App3_Rec *)obj;
if (!is_unboxable_op(app->rator, SCHEME_PRIM_IS_BINARY_INLINED))
return 0;
if (!can_unbox(app->rand1, fuel - 1, regs))
return 0;
return can_unbox(app->rand2, fuel - 1, regs - 1);
}
case scheme_toplevel_type:
case scheme_local_type:
case scheme_local_unbox_type:
return 1;
break;
default:
return (t > _scheme_values_types_);
}
}
static jit_insn *generate_arith_slow_path(mz_jit_state *jitter, Scheme_Object *rator, static jit_insn *generate_arith_slow_path(mz_jit_state *jitter, Scheme_Object *rator,
jit_insn **_ref, jit_insn **_ref4, jit_insn **_ref, jit_insn **_ref4,
jit_insn **for_branch, jit_insn **for_branch,
@ -3291,6 +3362,7 @@ static int can_fast_double(int arith, int cmp, int two_args)
#if !defined(MZ_USE_JIT_I386) #if !defined(MZ_USE_JIT_I386)
/* Not FP stack, so use normal variants. */ /* Not FP stack, so use normal variants. */
#define DIRECT_FPR_ACCESS
#define jit_movi_d_fppush(rd,immd) jit_movi_d(rd,immd) #define jit_movi_d_fppush(rd,immd) jit_movi_d(rd,immd)
#define jit_ldi_d_fppush(rd, is) jit_ldi_d(rd, is) #define jit_ldi_d_fppush(rd, is) jit_ldi_d(rd, is)
#define jit_ldr_d_fppush(rd, rs) jit_ldr_d(rd, rs) #define jit_ldr_d_fppush(rd, rs) jit_ldr_d(rd, rs)
@ -3318,16 +3390,28 @@ static int can_fast_double(int arith, int cmp, int two_args)
#define jit_extr_l_d_fppush(rd, rs) jit_extr_l_d(rd, rs) #define jit_extr_l_d_fppush(rd, rs) jit_extr_l_d(rd, rs)
#endif #endif
static int generate_unboxing(mz_jit_state *jitter)
{
int fpr0;
fpr0 = JIT_FPR(jitter->unbox_depth);
jit_ldxi_d_fppush(fpr0, JIT_R0, &((Scheme_Double *)0x0)->double_val);
jitter->unbox_depth++;
return 1;
}
static int generate_alloc_double(mz_jit_state *jitter) static int generate_alloc_double(mz_jit_state *jitter)
/* value should be in JIT_FPR0 */
{ {
#ifdef INLINE_FP_OPS #ifdef INLINE_FP_OPS
# ifdef CAN_INLINE_ALLOC # ifdef CAN_INLINE_ALLOC
inline_alloc(jitter, sizeof(Scheme_Double), scheme_double_type, 0, 0, 1, 0); inline_alloc(jitter, sizeof(Scheme_Double), scheme_double_type, 0, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
jit_addi_p(JIT_R0, JIT_V1, GC_OBJHEAD_SIZE); jit_addi_p(JIT_R0, JIT_V1, GC_OBJHEAD_SIZE);
(void)jit_stxi_d_fppop(&((Scheme_Double *)0x0)->double_val, JIT_R0, JIT_FPR1); (void)jit_stxi_d_fppop(&((Scheme_Double *)0x0)->double_val, JIT_R0, JIT_FPR0);
# else # else
(void)jit_sti_d_fppop(&double_result, JIT_FPR1); (void)jit_sti_d_fppop(&double_result, JIT_FPR0);
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
mz_prepare(0); mz_prepare(0);
(void)mz_finish(malloc_double); (void)mz_finish(malloc_double);
@ -3339,11 +3423,15 @@ static int generate_alloc_double(mz_jit_state *jitter)
static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int reversed, int two_args, int second_const, static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int reversed, int two_args, int second_const,
jit_insn **_refd, jit_insn **_refdt, jit_insn **_refd, jit_insn **_refdt,
int branch_short, int unsafe_fl) int branch_short, int unsafe_fl, int unboxed, int unboxed_result)
/* Unless unboxed, first arg is in JIT_R1, second in JIT_R0.
If unboxed in push/pop mode, first arg is pushed before second.
If unboxed in direct mode, first arg is in JIT_FPR0+depth
and second is in JIT_FPR1+depth (which is backward). */
{ {
#if defined(INLINE_FP_OPS) || defined(INLINE_FP_COMP) #if defined(INLINE_FP_OPS) || defined(INLINE_FP_COMP)
GC_CAN_IGNORE jit_insn *ref8, *ref9, *ref10, *refd, *refdt; GC_CAN_IGNORE jit_insn *ref8, *ref9, *ref10, *refd, *refdt;
int no_alloc = 0; int no_alloc = unboxed_result;
if (!unsafe_fl) { if (!unsafe_fl) {
/* Maybe they're doubles */ /* Maybe they're doubles */
@ -3370,12 +3458,17 @@ static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int r
/* Special case: multiplication by exact 0 */ /* Special case: multiplication by exact 0 */
(void)jit_movi_p(JIT_R0, scheme_make_integer(0)); (void)jit_movi_p(JIT_R0, scheme_make_integer(0));
} else { } else {
/* Yes, they're doubles. */ /* Yes, they're doubles. First arg is in JIT_R1, second is in JIT_R0.
if (arith != 12) { Put the first arg in fpr0 and second (if any) into fpr1. To work
jit_ldxi_d_fppush(JIT_FPR1, JIT_R0, &((Scheme_Double *)0x0)->double_val); right with stacks, that means pushing the second argument first. */
} int fpr1, fpr0;
fpr0 = JIT_FPR(jitter->unbox_depth);
fpr1 = JIT_FPR(1+jitter->unbox_depth);
if (two_args) { if (two_args) {
jit_ldxi_d_fppush(JIT_FPR0, JIT_R1, &((Scheme_Double *)0x0)->double_val); if (!unboxed)
jit_ldxi_d_fppush(fpr1, JIT_R1, &((Scheme_Double *)0x0)->double_val);
} else if ((arith == -1) && !second_const && reversed) { } else if ((arith == -1) && !second_const && reversed) {
reversed = 0; reversed = 0;
} else if (arith == 11) { } else if (arith == 11) {
@ -3384,33 +3477,48 @@ static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int r
/* exact->inexact needs no extra number */ /* exact->inexact needs no extra number */
} else { } else {
double d = second_const; double d = second_const;
jit_movi_d_fppush(JIT_FPR0, d); jit_movi_d_fppush(fpr1, d);
reversed = !reversed; reversed = !reversed;
cmp = -cmp; cmp = -cmp;
} }
if (!unboxed) {
if (arith != 12) {
jit_ldxi_d_fppush(fpr0, JIT_R0, &((Scheme_Double *)0x0)->double_val);
}
}
#ifdef DIRECT_FPR_ACCESS
if (unboxed) {
/* arguments are backward */
reversed = !reversed;
cmp = -cmp;
}
#endif
if (arith) { if (arith) {
switch (arith) { switch (arith) {
case 1: case 1:
jit_addr_d_fppop(JIT_FPR1, JIT_FPR0, JIT_FPR1); jit_addr_d_fppop(fpr0, fpr0, fpr1);
break; break;
case 2: case 2:
jit_mulr_d_fppop(JIT_FPR1, JIT_FPR0, JIT_FPR1); jit_mulr_d_fppop(fpr0, fpr0, fpr1);
break; break;
case -2: case -2:
if (reversed) if (!reversed)
jit_divrr_d_fppop(JIT_FPR1, JIT_FPR0, JIT_FPR1); jit_divrr_d_fppop(fpr0, fpr0, fpr1);
else else
jit_divr_d_fppop(JIT_FPR1, JIT_FPR0, JIT_FPR1); jit_divr_d_fppop(fpr0, fpr0, fpr1);
break; break;
case -1: case -1:
{ {
if (!two_args && !second_const && !reversed) { if (!two_args && !second_const && !reversed) {
/* Need a special case to make sure that (- 0.0) => -0.0 */ /* Need a special case to make sure that (- 0.0) => -0.0 */
jit_negr_d_fppop(JIT_FPR1, JIT_FPR1); jit_negr_d_fppop(fpr0, fpr0);
} else if (reversed) } else if (reversed)
jit_subrr_d_fppop(JIT_FPR1, JIT_FPR0, JIT_FPR1); jit_subr_d_fppop(fpr0, fpr0, fpr1);
else else
jit_subr_d_fppop(JIT_FPR1, JIT_FPR0, JIT_FPR1); jit_subrr_d_fppop(fpr0, fpr0, fpr1);
} }
break; break;
case 9: /* min */ case 9: /* min */
@ -3419,22 +3527,24 @@ static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int r
GC_CAN_IGNORE jit_insn *refc, *refn; GC_CAN_IGNORE jit_insn *refc, *refn;
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
/* If R0 is nan, then copy to R1, ensuring nan result */ /* If R0 is nan, then copy to R1, ensuring nan result */
refn = jit_beqr_d(jit_forward(), JIT_FPR1, JIT_FPR1); refn = jit_beqr_d(jit_forward(), fpr0, fpr0);
jit_movr_p(JIT_R1, JIT_R0); jit_movr_p(JIT_R1, JIT_R0);
mz_patch_branch(refn); mz_patch_branch(refn);
if (arith == 9) { if (arith == 9) {
refc = jit_bger_d_fppop(jit_forward(), JIT_FPR0, JIT_FPR1); refc = jit_bltr_d_fppop(jit_forward(), fpr0, fpr1);
} else { } else {
refc = jit_bltr_d_fppop(jit_forward(), JIT_FPR0, JIT_FPR1); refc = jit_bger_d_fppop(jit_forward(), fpr0, fpr1);
} }
jit_movr_p(JIT_R0, JIT_R1); jit_movr_p(JIT_R0, JIT_R1);
mz_patch_branch(refc); mz_patch_branch(refc);
__END_TINY_JUMPS__(1); __END_TINY_JUMPS__(1);
/* no unsafe version of `min' and `max', so we never need an
unboxed result, but we've already set JIT_R0 */
no_alloc = 1; no_alloc = 1;
} }
break; break;
case 11: /* abs */ case 11: /* abs */
jit_abs_d_fppop(JIT_FPR1, JIT_FPR1); jit_abs_d_fppop(fpr0, fpr0);
break; break;
case 12: /* exact->inexact */ case 12: /* exact->inexact */
no_alloc = 1; no_alloc = 1;
@ -3445,8 +3555,11 @@ static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int r
CHECK_LIMIT(); CHECK_LIMIT();
if (!no_alloc) { if (!no_alloc) {
mz_rs_sync(); /* needed if arguments were unboxed */
generate_alloc_double(jitter); generate_alloc_double(jitter);
CHECK_LIMIT(); CHECK_LIMIT();
} else if (unboxed_result) {
jitter->unbox_depth++;
} }
} else { } else {
/* The "anti" variants below invert the branch. Unlike the "un" /* The "anti" variants below invert the branch. Unlike the "un"
@ -3455,19 +3568,19 @@ static int generate_double_arith(mz_jit_state *jitter, int arith, int cmp, int r
__START_SHORT_JUMPS__(branch_short); __START_SHORT_JUMPS__(branch_short);
switch (cmp) { switch (cmp) {
case -2: case -2:
refd = jit_bantiltr_d_fppop(jit_forward(), JIT_FPR0, JIT_FPR1); refd = jit_bantigtr_d_fppop(jit_forward(), fpr0, fpr1);
break; break;
case -1: case -1:
refd = jit_bantiler_d_fppop(jit_forward(), JIT_FPR0, JIT_FPR1); refd = jit_bantiger_d_fppop(jit_forward(), fpr0, fpr1);
break; break;
case 0: case 0:
refd = jit_bantieqr_d_fppop(jit_forward(), JIT_FPR0, JIT_FPR1); refd = jit_bantieqr_d_fppop(jit_forward(), fpr0, fpr1);
break; break;
case 1: case 1:
refd = jit_bantiger_d_fppop(jit_forward(), JIT_FPR0, JIT_FPR1); refd = jit_bantiler_d_fppop(jit_forward(), fpr0, fpr1);
break; break;
case 2: case 2:
refd = jit_bantigtr_d_fppop(jit_forward(), JIT_FPR0, JIT_FPR1); refd = jit_bantiltr_d_fppop(jit_forward(), fpr0, fpr1);
break; break;
default: default:
refd = NULL; refd = NULL;
@ -3533,6 +3646,40 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
LOG_IT(("inlined %s\n", ((Scheme_Primitive_Proc *)rator)->name)); LOG_IT(("inlined %s\n", ((Scheme_Primitive_Proc *)rator)->name));
if (unsafe_fl
&& can_unbox(rand, 5, JIT_FPR_NUM-2)
&& (!rand2 || can_unbox(rand2, 5, JIT_FPR_NUM-3))) {
/* Unsafe, unboxed floating-point ops. */
jitter->unbox++;
if (!rand2) {
mz_runstack_skipped(jitter, 1);
generate(rand, jitter, 0, 1, JIT_R0);
CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1);
} else {
mz_runstack_skipped(jitter, 2);
generate(rand, jitter, 0, 1, JIT_R0);
CHECK_LIMIT();
generate(rand2, jitter, 0, 1, JIT_R0);
CHECK_LIMIT();
mz_runstack_unskipped(jitter, 2);
}
--jitter->unbox;
jitter->unbox_depth -= (rand2 ? 2 : 1);
generate_double_arith(jitter, arith, cmp, 0, !!rand2, 0,
&refd, &refdt, branch_short, 1, 1, jitter->unbox);
CHECK_LIMIT();
ref3 = NULL;
ref = NULL;
ref4 = NULL;
__START_SHORT_JUMPS__(branch_short);
} else {
int unbox = jitter->unbox;
/* While generating a fixnum op, don't unbox! */
jitter->unbox = 0;
if (rand2) { if (rand2) {
if (SCHEME_INTP(rand2) if (SCHEME_INTP(rand2)
&& SCHEME_INT_SMALL_ENOUGH(rand2) && SCHEME_INT_SMALL_ENOUGH(rand2)
@ -3663,7 +3810,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
if (unsafe_fl || (!unsafe_fx && !SCHEME_INTP(rand) && can_fast_double(arith, cmp, 1))) { if (unsafe_fl || (!unsafe_fx && !SCHEME_INTP(rand) && can_fast_double(arith, cmp, 1))) {
/* Maybe they're both doubles... */ /* Maybe they're both doubles... */
if (unsafe_fl) mz_rs_sync(); if (unsafe_fl) mz_rs_sync();
generate_double_arith(jitter, arith, cmp, reversed, 1, 0, &refd, &refdt, branch_short, unsafe_fl); generate_double_arith(jitter, arith, cmp, reversed, 1, 0, &refd, &refdt, branch_short, unsafe_fl, 0, 0);
CHECK_LIMIT(); CHECK_LIMIT();
} }
@ -3712,7 +3859,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
if (unsafe_fl || (!unsafe_fx && can_fast_double(arith, cmp, 1))) { if (unsafe_fl || (!unsafe_fx && can_fast_double(arith, cmp, 1))) {
/* Maybe they're both doubles... */ /* Maybe they're both doubles... */
if (unsafe_fl) mz_rs_sync(); if (unsafe_fl) mz_rs_sync();
generate_double_arith(jitter, arith, cmp, reversed, 1, 0, &refd, &refdt, branch_short, unsafe_fl); generate_double_arith(jitter, arith, cmp, reversed, 1, 0, &refd, &refdt, branch_short, unsafe_fl, 0, 0);
CHECK_LIMIT(); CHECK_LIMIT();
} }
@ -3758,7 +3905,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
/* watch out: divide by 0 is special: */ /* watch out: divide by 0 is special: */
&& ((arith != -2) || v || reversed))) { && ((arith != -2) || v || reversed))) {
/* Maybe it's a double... */ /* Maybe it's a double... */
generate_double_arith(jitter, arith, cmp, reversed, 0, v, &refd, &refdt, branch_short, unsafe_fl); generate_double_arith(jitter, arith, cmp, reversed, 0, v, &refd, &refdt, branch_short, unsafe_fl, 0, 0);
CHECK_LIMIT(); CHECK_LIMIT();
} }
@ -4074,12 +4221,19 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
CHECK_LIMIT(); CHECK_LIMIT();
} else if (arith == 12) { } else if (arith == 12) {
/* exact->inexact */ /* exact->inexact */
int fpr0;
fpr0 = JIT_FPR(jitter->unbox_depth);
jit_rshi_l(JIT_R0, JIT_R0, 1); jit_rshi_l(JIT_R0, JIT_R0, 1);
jit_extr_l_d_fppush(JIT_FPR1, JIT_R0); jit_extr_l_d_fppush(fpr0, JIT_R0);
CHECK_LIMIT(); CHECK_LIMIT();
if (!unbox) {
mz_rs_sync(); /* needed for unsafe op before allocation */
__END_SHORT_JUMPS__(branch_short); __END_SHORT_JUMPS__(branch_short);
generate_alloc_double(jitter); generate_alloc_double(jitter);
__START_SHORT_JUMPS__(branch_short); __START_SHORT_JUMPS__(branch_short);
} else {
jitter->unbox_depth++;
}
CHECK_LIMIT(); CHECK_LIMIT();
} }
} }
@ -4168,6 +4322,9 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
ref3 = NULL; ref3 = NULL;
} }
jitter->unbox = unbox;
}
if (!arith) { if (!arith) {
if (refdt) if (refdt)
mz_patch_ucbranch(refdt); mz_patch_ucbranch(refdt);
@ -6232,8 +6389,11 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
if (!(SCHEME_TOPLEVEL_FLAGS(obj) if (!(SCHEME_TOPLEVEL_FLAGS(obj)
& (SCHEME_TOPLEVEL_CONST | SCHEME_TOPLEVEL_READY))) { & (SCHEME_TOPLEVEL_CONST | SCHEME_TOPLEVEL_READY))) {
/* Is it NULL? */ /* Is it NULL? */
generate_pop_unboxed(jitter);
CHECK_LIMIT();
(void)jit_beqi_p(unbound_global_code, target, 0); (void)jit_beqi_p(unbound_global_code, target, 0);
} }
if (jitter->unbox) generate_unboxing(jitter);
END_JIT_DATA(0); END_JIT_DATA(0);
return 1; return 1;
} }
@ -6253,6 +6413,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) { if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) {
mz_rs_stxi(pos, JIT_RUNSTACK); mz_rs_stxi(pos, JIT_RUNSTACK);
} }
CHECK_LIMIT();
if (jitter->unbox) generate_unboxing(jitter);
END_JIT_DATA(2); END_JIT_DATA(2);
return 1; return 1;
} }
@ -6270,6 +6432,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
mz_rs_stxi(pos, JIT_RUNSTACK); mz_rs_stxi(pos, JIT_RUNSTACK);
} }
VALIDATE_RESULT(target); VALIDATE_RESULT(target);
CHECK_LIMIT();
if (jitter->unbox) generate_unboxing(jitter);
END_JIT_DATA(3); END_JIT_DATA(3);
return 1; return 1;
@ -7143,7 +7307,14 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
return 1; return 1;
} }
default: default:
{ if (jitter->unbox && SCHEME_FLOATP(obj)) {
double d = SCHEME_FLOAT_VAL(obj);
int fpr0;
fpr0 = JIT_FPR(jitter->unbox_depth);
jit_movi_d_fppush(fpr0, d);
jitter->unbox_depth++;
return 1;
} else {
int retptr; int retptr;
Scheme_Type type = SCHEME_TYPE(obj); Scheme_Type type = SCHEME_TYPE(obj);
START_JIT_DATA(); START_JIT_DATA();