fix a problem with unboxed arguments in self tail calls

This is an old bug, but it was exposed by recent improvements
in unboxing.

Also, fix JIT implementation of explicitly decremented fuel on
a 64-bit platform, plus some other code clean-up.
This commit is contained in:
Matthew Flatt 2012-07-06 08:03:01 -06:00
parent f71037c775
commit 29c83cd254
8 changed files with 57 additions and 37 deletions

View File

@ -360,6 +360,13 @@ Configuration Options
Athough `configure' flags control most options, some configrations Athough `configure' flags control most options, some configrations
options can be modified by setting flags in "racket/sconfig.h". options can be modified by setting flags in "racket/sconfig.h".
Some CPP flags control default settings in "racket/sconfig.h":
* MZ_{USE_,NO_}JIT_SSE - {en,dis}ables use of SSE floating point
* MZ_USE_DETERMINSTIC_FUEL - disables use of itimer or pthread for
Racket thread scheduling.
Modifying Racket Modifying Racket
---------------- ----------------

View File

@ -34,6 +34,7 @@ libffi/libffi@FOREIGN_CONVENIENCE@.la:
cd libffi; $(MAKE) libffi@FOREIGN_CONVENIENCE@.la cd libffi; $(MAKE) libffi@FOREIGN_CONVENIENCE@.la
foreign.@LTO@: $(srcdir)/foreign.c \ foreign.@LTO@: $(srcdir)/foreign.c \
$(srcdir)/../racket/sconfig.h \
$(srcdir)/../racket/include/scheme.h \ $(srcdir)/../racket/include/scheme.h \
$(srcdir)/../racket/include/schthread.h \ $(srcdir)/../racket/include/schthread.h \
$(srcdir)/../racket/src/schemef.h \ $(srcdir)/../racket/src/schemef.h \

View File

@ -597,7 +597,9 @@
# define NO_SLEEP # define NO_SLEEP
# define WINDOWS_PROCESSES # define WINDOWS_PROCESSES
# define WINDOWS_FILE_HANDLES # define WINDOWS_FILE_HANDLES
# define USE_WIN32_THREAD_TIMER # ifndef MZ_USE_DETERMINSTIC_FUEL
# define USE_WIN32_THREAD_TIMER
# endif
# define SIGSET_IS_SIGNAL # define SIGSET_IS_SIGNAL
# define SIGSET_NEEDS_REINSTALL # define SIGSET_NEEDS_REINSTALL
@ -728,8 +730,10 @@
# define SYSTEM_TYPE_NAME "macosx" # define SYSTEM_TYPE_NAME "macosx"
#endif #endif
# undef USE_ITIMER # ifndef MZ_USE_DETERMINSTIC_FUEL
# define USE_PTHREAD_THREAD_TIMER # undef USE_ITIMER
# define USE_PTHREAD_THREAD_TIMER
# endif
# define USE_MAP_ANON # define USE_MAP_ANON

View File

@ -1058,6 +1058,23 @@ static int finish_branch(mz_jit_state *jitter, int target, Branch_Info *for_bran
#ifdef USE_FLONUM_UNBOXING #ifdef USE_FLONUM_UNBOXING
int scheme_generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int offset, int target)
{
GC_CAN_IGNORE jit_insn *ref;
__START_TINY_JUMPS__(1);
ref = jit_bnei_p(jit_forward(), target, NULL);
__END_TINY_JUMPS__(1);
CHECK_LIMIT();
jit_movi_l(JIT_R0, offset);
(void)jit_calli(sjc.box_flonum_from_stack_code);
mz_rs_stxi(pos, JIT_R0);
__START_TINY_JUMPS__(1);
mz_patch_branch(ref);
__END_TINY_JUMPS__(1);
return 1;
}
static int generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int local_pos, int target) static int generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int local_pos, int target)
{ {
int offset; int offset;
@ -1069,18 +1086,8 @@ static int generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int local
jit_ldxi_d_fppush(fpr0, JIT_FP, offset); jit_ldxi_d_fppush(fpr0, JIT_FP, offset);
jitter->unbox_depth++; jitter->unbox_depth++;
} else { } else {
GC_CAN_IGNORE jit_insn *ref;
mz_rs_sync(); mz_rs_sync();
__START_TINY_JUMPS__(1); scheme_generate_flonum_local_boxing(jitter, pos, offset, target);
ref = jit_bnei_p(jit_forward(), target, NULL);
__END_TINY_JUMPS__(1);
CHECK_LIMIT();
jit_movi_l(JIT_R0, offset);
(void)jit_calli(sjc.box_flonum_from_stack_code);
mz_rs_stxi(pos, JIT_R0);
__START_TINY_JUMPS__(1);
mz_patch_branch(ref);
__END_TINY_JUMPS__(1);
} }
return 1; return 1;
@ -3292,7 +3299,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
GC_CAN_IGNORE jit_insn *zref; GC_CAN_IGNORE jit_insn *zref;
int f_offset; int f_offset;
/* In the case of an direct native call, the flonums can be /* In the case of a direct native call, the flonums can be
already unpacked, in which case JIT_SP is set up. Check whether already unpacked, in which case JIT_SP is set up. Check whether
JIT_SP is already different than the 0-flonums case. */ JIT_SP is already different than the 0-flonums case. */
f_offset = JIT_FRAME_FLONUM_OFFSET - (jitter->flostack_space * sizeof(double)); f_offset = JIT_FRAME_FLONUM_OFFSET - (jitter->flostack_space * sizeof(double));

View File

@ -417,6 +417,9 @@ void *scheme_jit_get_threadlocal_table();
# define _mz_tl_str_p(addr, tmp_reg, reg) jit_str_p(tmp_reg, reg) # define _mz_tl_str_p(addr, tmp_reg, reg) jit_str_p(tmp_reg, reg)
# define _mz_tl_str_l(addr, tmp_reg, reg) jit_str_l(tmp_reg, reg) # define _mz_tl_str_l(addr, tmp_reg, reg) jit_str_l(tmp_reg, reg)
# define _mz_tl_str_i(addr, tmp_reg, reg) jit_str_i(tmp_reg, reg) # define _mz_tl_str_i(addr, tmp_reg, reg) jit_str_i(tmp_reg, reg)
# define mz_tl_addr_tmp_i(tmp_reg, addr) (jit_movr_l(JIT_R10, tmp_reg), mz_tl_addr(tmp_reg, addr))
# define mz_tl_addr_untmp_i(tmp_reg) jit_movr_l(tmp_reg, JIT_R10)
# define mz_tl_tmp_reg_i(tmp_reg) tmp_reg
# else # else
# define THREAD_LOCAL_USES_JIT_V2 # define THREAD_LOCAL_USES_JIT_V2
# ifdef THREAD_LOCAL_USES_JIT_V2 # ifdef THREAD_LOCAL_USES_JIT_V2
@ -436,12 +439,15 @@ void *scheme_jit_get_threadlocal_table();
# define _mz_tl_str_l(addr, tmp_reg, reg) jit_str_l(tmp_reg, reg) # define _mz_tl_str_l(addr, tmp_reg, reg) jit_str_l(tmp_reg, reg)
# define _mz_tl_str_i(addr, tmp_reg, reg) jit_str_i(tmp_reg, reg) # define _mz_tl_str_i(addr, tmp_reg, reg) jit_str_i(tmp_reg, reg)
# endif # endif
# define mz_tl_addr_tmp_i(tmp_reg, addr) mz_tl_addr_tmp(tmp_reg, addr)
# define mz_tl_addr_untmp_i(tmp_reg) mz_tl_addr_untmp(tmp_reg)
# define mz_tl_tmp_reg_i(tmp_reg) mz_tl_tmp_reg(tmp_reg)
# endif # endif
/* A given tmp_reg doesn't have to be unused; it just has to be distinct from other arguments. */ /* A given tmp_reg doesn't have to be unused; it just has to be distinct from other arguments. */
# define mz_tl_sti_p(addr, reg, tmp_reg) (mz_tl_addr_tmp(tmp_reg, addr), _mz_tl_str_p(addr, mz_tl_tmp_reg(tmp_reg), reg), mz_tl_addr_untmp(tmp_reg)) # define mz_tl_sti_p(addr, reg, tmp_reg) (mz_tl_addr_tmp(tmp_reg, addr), _mz_tl_str_p(addr, mz_tl_tmp_reg(tmp_reg), reg), mz_tl_addr_untmp(tmp_reg))
# define mz_tl_sti_l(addr, reg, tmp_reg) (mz_tl_addr_tmp(tmp_reg, addr), _mz_tl_str_l(addr, mz_tl_tmp_reg(tmp_reg), reg), mz_tl_addr_untmp(tmp_reg)) # define mz_tl_sti_l(addr, reg, tmp_reg) (mz_tl_addr_tmp(tmp_reg, addr), _mz_tl_str_l(addr, mz_tl_tmp_reg(tmp_reg), reg), mz_tl_addr_untmp(tmp_reg))
# define mz_tl_sti_i(addr, reg, tmp_reg) (mz_tl_addr_tmp(tmp_reg, addr), _mz_tl_str_i(addr, mz_tl_tmp_reg(tmp_reg), reg), mz_tl_addr_untmp(tmp_reg)) # define mz_tl_sti_i(addr, reg, tmp_reg) (mz_tl_addr_tmp_i(tmp_reg, addr), _mz_tl_str_i(addr, mz_tl_tmp_reg_i(tmp_reg), reg), mz_tl_addr_untmp_i(tmp_reg))
# define mz_tl_ldi_p(reg, addr) (mz_tl_addr(reg, addr), jit_ldr_p(reg, reg)) # define mz_tl_ldi_p(reg, addr) (mz_tl_addr(reg, addr), jit_ldr_p(reg, reg))
# define mz_tl_ldi_l(reg, addr) (mz_tl_addr(reg, addr), jit_ldr_l(reg, reg)) # define mz_tl_ldi_l(reg, addr) (mz_tl_addr(reg, addr), jit_ldr_l(reg, reg))
# define mz_tl_ldi_i(reg, addr) (mz_tl_addr(reg, addr), jit_ldr_i(reg, reg)) # define mz_tl_ldi_i(reg, addr) (mz_tl_addr(reg, addr), jit_ldr_i(reg, reg))
@ -1264,6 +1270,7 @@ int scheme_generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inline
#ifdef USE_FLONUM_UNBOXING #ifdef USE_FLONUM_UNBOXING
int scheme_generate_flonum_local_unboxing(mz_jit_state *jitter, int push); int scheme_generate_flonum_local_unboxing(mz_jit_state *jitter, int push);
int scheme_generate_flonum_local_boxing(mz_jit_state *jitter, int pos, int offset, int target);
#endif #endif
int scheme_generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inlined_ok, int unbox_anyway); int scheme_generate_unboxed(Scheme_Object *obj, mz_jit_state *jitter, int inlined_ok, int unbox_anyway);
int scheme_generate_non_tail_mark_pos_prefix(mz_jit_state *jitter); int scheme_generate_non_tail_mark_pos_prefix(mz_jit_state *jitter);

View File

@ -375,7 +375,7 @@ int scheme_generate_unboxing(mz_jit_state *jitter, int target)
int fpr0; int fpr0;
fpr0 = JIT_FPR_0(jitter->unbox_depth); fpr0 = JIT_FPR_0(jitter->unbox_depth);
jit_ldxi_d_fppush(fpr0, target, &((Scheme_Double *)0x0)->double_val); jit_ldxi_d_fppush(fpr0, target, &((Scheme_Double *)0x0)->double_val);
jitter->unbox_depth++; jitter->unbox_depth++;
return 1; return 1;

View File

@ -1165,18 +1165,19 @@ static int generate_self_tail_call(Scheme_Object *rator, mz_jit_state *jitter, i
GC_CAN_IGNORE jit_insn *iref; GC_CAN_IGNORE jit_insn *iref;
mz_pushr_p(JIT_R0); mz_pushr_p(JIT_R0);
mz_ld_runstack_base_alt(JIT_R2); mz_ld_runstack_base_alt(JIT_R2);
jit_subi_p(JIT_R2, JIT_RUNSTACK_BASE_OR_ALT(JIT_R2), WORDS_TO_BYTES(num_rands + closure_size + args_already_in_place)); jit_subi_p(JIT_R2, JIT_RUNSTACK_BASE_OR_ALT(JIT_R2), WORDS_TO_BYTES(num_rands + args_already_in_place));
jit_ldxi_p(JIT_R0, JIT_R2, WORDS_TO_BYTES(i+closure_size)); jit_ldxi_p(JIT_R0, JIT_R2, WORDS_TO_BYTES(i));
mz_rs_sync(); mz_rs_sync();
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
iref = jit_bnei_p(jit_forward(), JIT_R0, NULL); iref = jit_bnei_p(jit_forward(), JIT_R0, NULL);
__END_TINY_JUMPS__(1); __END_TINY_JUMPS__(1);
{ {
mz_ld_fppush(JIT_FPR0, arg_tmp_offset); int aoffset = JIT_FRAME_FLONUM_OFFSET - (arg_tmp_offset * sizeof(double));
jit_movi_l(JIT_R0, aoffset);
(void)jit_calli(sjc.box_flonum_from_stack_code); (void)jit_calli(sjc.box_flonum_from_stack_code);
mz_ld_runstack_base_alt(JIT_R2); mz_ld_runstack_base_alt(JIT_R2);
jit_subi_p(JIT_R2, JIT_RUNSTACK_BASE_OR_ALT(JIT_R2), WORDS_TO_BYTES(num_rands + closure_size + args_already_in_place)); jit_subi_p(JIT_R2, JIT_RUNSTACK_BASE_OR_ALT(JIT_R2), WORDS_TO_BYTES(num_rands + args_already_in_place));
jit_stxi_p(WORDS_TO_BYTES(i+closure_size), JIT_R2, JIT_R0); jit_stxi_p(WORDS_TO_BYTES(i), JIT_R2, JIT_R0);
} }
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
mz_patch_branch(iref); mz_patch_branch(iref);
@ -1501,7 +1502,7 @@ static int generate_call_path_with_unboxes(mz_jit_state *jitter, int direct_flos
GC_CAN_IGNORE jit_insn **_refdone, GC_CAN_IGNORE jit_insn **_refdone,
int num_rands, Scheme_Closure_Data *direct_data, Scheme_Object *rator) int num_rands, Scheme_Closure_Data *direct_data, Scheme_Object *rator)
{ {
GC_CAN_IGNORE jit_insn *refdone, *refgo, *refcopy, *ref; GC_CAN_IGNORE jit_insn *refdone, *refgo, *refcopy;
int i, k, offset; int i, k, offset;
refgo = jit_jmpi(jit_forward()); refgo = jit_jmpi(jit_forward());
@ -1547,16 +1548,7 @@ static int generate_call_path_with_unboxes(mz_jit_state *jitter, int direct_flos
offset = jitter->flostack_offset - direct_flostack_offset + k; offset = jitter->flostack_offset - direct_flostack_offset + k;
offset = JIT_FRAME_FLONUM_OFFSET - (offset * sizeof(double)); offset = JIT_FRAME_FLONUM_OFFSET - (offset * sizeof(double));
jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(i)); jit_ldxi_p(JIT_R0, JIT_RUNSTACK, WORDS_TO_BYTES(i));
__START_TINY_JUMPS__(1); scheme_generate_flonum_local_boxing(jitter, i, offset, JIT_R0);
ref = jit_bnei_p(jit_forward(), JIT_R0, NULL);
__END_TINY_JUMPS__(1);
CHECK_LIMIT();
jit_movi_l(JIT_R0, offset);
(void)jit_calli(sjc.box_flonum_from_stack_code);
jit_stxi_p(WORDS_TO_BYTES(i), JIT_RUNSTACK, JIT_R0);
__START_TINY_JUMPS__(1);
mz_patch_branch(ref);
__END_TINY_JUMPS__(1);
} }
} }

View File

@ -37,8 +37,10 @@
#define USE_GETRUSAGE #define USE_GETRUSAGE
#if defined(MZ_USE_PLACES) || defined(USE_PTHREAD_INSTEAD_OF_ITIMER) #ifndef MZ_USE_DETERMINSTIC_FUEL
# define USE_PTHREAD_THREAD_TIMER # if defined(MZ_USE_PLACES) || defined(USE_PTHREAD_INSTEAD_OF_ITIMER)
#else # define USE_PTHREAD_THREAD_TIMER
# define USE_ITIMER # else
# define USE_ITIMER
# endif
#endif #endif