add missing check-for-swap in non-tail calls; steps toward 3m JIT

svn: r2232
This commit is contained in:
Matthew Flatt 2006-02-15 13:48:50 +00:00
parent 1688611b34
commit 278efaec14
4 changed files with 116 additions and 78 deletions

View File

@ -106,13 +106,10 @@ MzScheme allocates the following kinds of memory objects:
size operation) for all xtagged objects. size operation) for all xtagged objects.
* Interior Array - Like array objects, but pointers to the object can * Interior Array - Like array objects, but pointers to the object can
reference its interior, rather than just the start of the object. reference its interior, rather than just the start of the object,
Such pointers will always be longword-aligned. MzScheme allocates and the object never moves. Such pointers will always be
interior objects infrequently, and only as relatively large longword-aligned. MzScheme allocates interior objects infrequently,
objects. Furthermore, if GC_INTERIORABLES_NEVER_MOVE is #defined as and only as relatively large objects.
1 in gc2.h, MzScheme will assume that such objects never move
(useful for skipping certain stack variables that do not need to be
updated).
* Weak Box - The object has the following initial structure: * Weak Box - The object has the following initial structure:

View File

@ -91,9 +91,9 @@ static Native_Get_Arity_Proc get_arity_code;
static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends); static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends);
static int generate(Scheme_Object *obj, mz_jit_state *jitter, int tail_ok, int multi_ok); static int generate(Scheme_Object *obj, mz_jit_state *jitter, int tail_ok, int multi_ok);
static void *generate_top_simple_arity_check(int num_params, int has_rest, int is_method, int permanent); static void *generate_lambda_simple_arity_check(int num_params, int has_rest, int is_method, int permanent);
static void generate_top_case_lambda_dispatch(Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata, static void generate_case_lambda(Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata,
int is_method); int is_method);
static void on_demand(); static void on_demand();
static int generate_non_tail_mark_pos_prefix(mz_jit_state *jitter); static int generate_non_tail_mark_pos_prefix(mz_jit_state *jitter);
static void generate_non_tail_mark_pos_suffix(mz_jit_state *jitter); static void generate_non_tail_mark_pos_suffix(mz_jit_state *jitter);
@ -164,14 +164,25 @@ static void *get_end_pointer(mz_jit_state *jitter)
return jit_get_ip().ptr; return jit_get_ip().ptr;
} }
static void mz_retain_it(mz_jit_state *jitter, void *v) static int mz_retain_it(mz_jit_state *jitter, void *v)
{ {
if (jitter->retain_start) { if (jitter->retain_start) {
jitter->retain_start[jitter->retained] = v; jitter->retain_start[jitter->retained] = v;
} }
jitter->retained++; jitter->retained++;
return jitter->retained;
} }
#ifdef MZ_PRECISE_GC
static void mz_load_retained(mz_jit_state *jitter, int rs, int retptr)
{
void *p;
p = jitter->retain_start + retptr;
(void)jit_movi_p(rs, p);
jit_ldr_p(rs, rs);
}
#endif
static void *generate_one(mz_jit_state *old_jitter, static void *generate_one(mz_jit_state *old_jitter,
Generate_Proc generate, Generate_Proc generate,
void *data, void *data,
@ -365,12 +376,6 @@ static void box_multiple_array_element(int pos)
p->ku.multiple.array = naya; p->ku.multiple.array = naya;
} }
static void thread_block()
{
scheme_thread_block(0);
scheme_current_thread->ran_some = 1;
}
/*========================================================================*/ /*========================================================================*/
/* code-gen utils */ /* code-gen utils */
/*========================================================================*/ /*========================================================================*/
@ -594,9 +599,7 @@ static int mz_is_closure(mz_jit_state *jitter, int i, int arity)
#define mz_remap(x) mz_remap_it(jitter, x) #define mz_remap(x) mz_remap_it(jitter, x)
#ifdef MZ_USE_JIT_PPC #ifdef MZ_USE_JIT_PPC
/* JIT_LOCAL1 and JIT_LOCAL2 are offsets in the stack frame. /* JIT_LOCAL1, JIT_LOCAL2, and JIT_LOCAL3 are offsets in the stack frame. */
We use the last two slots reserved for parameters to calless,
because we never call with more than 6 arguments. */
# define JIT_LOCAL1 56 # define JIT_LOCAL1 56
# define JIT_LOCAL2 60 # define JIT_LOCAL2 60
# define JIT_LOCAL3 64 # define JIT_LOCAL3 64
@ -888,19 +891,7 @@ static int generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na
/* Check for thread swap: */ /* Check for thread swap: */
(void)jit_movi_p(JIT_R1, &scheme_fuel_counter); (void)jit_movi_p(JIT_R1, &scheme_fuel_counter);
jit_ldr_i(JIT_R2, JIT_R1); jit_ldr_i(JIT_R2, JIT_R1);
ref5 = jit_bgti_i(jit_forward(), JIT_R2, 0); ref5 = jit_blei_i(jit_forward(), JIT_R2, 0);
if (need_set_rs) {
JIT_UPDATE_THREAD_RSPTR();
}
/* FIXME 3m: need to move JIT_V1 and JIT_R0 to GC-visible place */
mz_push_local_p(JIT_R0, JIT_LOCAL2);
(void)jit_calli(thread_block);
mz_pop_local_p(JIT_R0, JIT_LOCAL2);
#ifndef FUEL_AUTODECEREMENTS
(void)jit_movi_p(JIT_R1, &scheme_fuel_counter);
jit_ldr_i(JIT_R2, JIT_R1);
#endif
mz_patch_branch(ref5);
#ifndef FUEL_AUTODECEREMENTS #ifndef FUEL_AUTODECEREMENTS
jit_subi_p(JIT_R2, JIT_R2, 0x1); jit_subi_p(JIT_R2, JIT_R2, 0x1);
jit_str_i(JIT_R1, JIT_R2); jit_str_i(JIT_R1, JIT_R2);
@ -937,6 +928,7 @@ static int generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na
mz_patch_branch(ref2); mz_patch_branch(ref2);
} }
mz_patch_branch(ref4); mz_patch_branch(ref4);
mz_patch_branch(ref5);
CHECK_LIMIT(); CHECK_LIMIT();
if (need_set_rs) { if (need_set_rs) {
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
@ -980,27 +972,8 @@ static int generate_direct_prim_non_tail_call(mz_jit_state *jitter, int num_rand
mz_finishr(JIT_V1); mz_finishr(JIT_V1);
CHECK_LIMIT(); CHECK_LIMIT();
jit_retval(JIT_R0); jit_retval(JIT_R0);
#if 0
/* No need to check for multi values or tail-call, because /* No need to check for multi values or tail-call, because
we only use this for noncm primitives. */ we only use this for noncm primitives. */
jit_insn *ref;
if (!multi_ok) {
jit_insn *refm;
refm = jit_beqi_p(jit_forward(), JIT_R0, SCHEME_MULTIPLE_VALUES);
mz_patch_branch_at(refm, bad_result_arity_code);
}
ref = jit_bnei_p(jit_forward(), JIT_R0, SCHEME_TAIL_CALL_WAITING);
CHECK_LIMIT();
mz_prepare(1);
jit_pusharg_p(JIT_R0);
if (multi_ok) {
(void)mz_finish(scheme_force_value_same_mark);
} else {
(void)mz_finish(scheme_force_one_value_same_mark);
}
jit_retval(JIT_R0);
mz_patch_branch(ref);
#endif
if (num_rands == 1) { if (num_rands == 1) {
jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
@ -1018,7 +991,7 @@ static int generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
{ {
/* Non-tail call: */ /* Non-tail call: */
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref4, *ref5, *ref6, *ref7, *ref8, *ref9; GC_CAN_IGNORE jit_insn *ref, *ref2, *ref4, *ref5, *ref6, *ref7, *ref8, *ref9;
GC_CAN_IGNORE jit_insn *ref10; GC_CAN_IGNORE jit_insn *ref10, *ref11;
__START_SHORT_JUMPS__(num_rands < 100); __START_SHORT_JUMPS__(num_rands < 100);
@ -1049,6 +1022,15 @@ static int generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
jit_ldr_i(JIT_R1, JIT_R1); jit_ldr_i(JIT_R1, JIT_R1);
ref9 = jit_bltr_ul(jit_forward(), JIT_STACK, JIT_R1); ref9 = jit_bltr_ul(jit_forward(), JIT_STACK, JIT_R1);
CHECK_LIMIT(); CHECK_LIMIT();
/* Finally, check for thread swap: */
(void)jit_movi_p(JIT_R1, &scheme_fuel_counter);
jit_ldr_i(JIT_R2, JIT_R1);
ref11 = jit_blei_i(jit_forward(), JIT_R2, 0);
#ifndef FUEL_AUTODECEREMENTS
jit_subi_p(JIT_R2, JIT_R2, 0x1);
jit_str_i(JIT_R1, JIT_R2);
#endif
/* Fast inlined-native jump ok (proc will check argc); */ /* Fast inlined-native jump ok (proc will check argc); */
/* extract function and data: */ /* extract function and data: */
@ -1132,6 +1114,7 @@ static int generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
} }
mz_patch_branch(ref4); mz_patch_branch(ref4);
mz_patch_branch(ref9); mz_patch_branch(ref9);
mz_patch_branch(ref11);
if (need_set_rs) { if (need_set_rs) {
JIT_UPDATE_THREAD_RSPTR(); JIT_UPDATE_THREAD_RSPTR();
} }
@ -1999,6 +1982,8 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
if (SCHEME_TYPE(a1) > _scheme_values_types_) { if (SCHEME_TYPE(a1) > _scheme_values_types_) {
/* Compare to constant: */ /* Compare to constant: */
int retptr;
mz_runstack_skipped(jitter, 2); mz_runstack_skipped(jitter, 2);
generate_non_tail(a2, jitter, 0, 1); generate_non_tail(a2, jitter, 0, 1);
@ -2006,12 +1991,24 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
mz_runstack_unskipped(jitter, 2); mz_runstack_unskipped(jitter, 2);
if (!SCHEME_INTP(a1)) if (!SCHEME_INTP(a1)
mz_retain(a1); && !SCHEME_FALSEP(a1)
&& !SCHEME_VOIDP(a1)
&& !SAME_OBJ(a1, scheme_true))
retptr = mz_retain(a1);
else
retptr = 0;
__START_SHORT_JUMPS__(branch_short); __START_SHORT_JUMPS__(branch_short);
ref = jit_bnei_p(jit_forward(), JIT_R0, a1); #ifdef MZ_PRECISE_GC
if (retptr) {
mz_load_retained(jitter, JIT_R1, retptr);
ref = jit_bner_p(jit_forward(), JIT_R0, JIT_R1);
} else
#endif
ref = jit_bnei_p(jit_forward(), JIT_R0, a1);
if (for_branch) { if (for_branch) {
for_branch[0] = ref; for_branch[0] = ref;
} else { } else {
@ -2184,14 +2181,19 @@ static int generate_closure(Scheme_Closure_Data *data,
mz_jit_state *jitter) mz_jit_state *jitter)
{ {
Scheme_Native_Closure_Data *code; Scheme_Native_Closure_Data *code;
int retptr;
ensure_closure_native(data, NULL); ensure_closure_native(data, NULL);
code = data->native_code; code = data->native_code;
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
mz_prepare(1); mz_prepare(1);
mz_retain(code); retptr = mz_retain(code);
#ifdef MZ_PRECISE_GC
mz_load_retained(jitter, JIT_R0, retptr);
#else
(void)jit_movi_p(JIT_R0, code); /* !! */ (void)jit_movi_p(JIT_R0, code); /* !! */
#endif
jit_pusharg_p(JIT_R0); jit_pusharg_p(JIT_R0);
(void)mz_finish(scheme_make_native_closure); (void)mz_finish(scheme_make_native_closure);
jit_retval(JIT_R0); jit_retval(JIT_R0);
@ -2252,7 +2254,7 @@ Scheme_Native_Closure_Data *scheme_generate_case_lambda(Scheme_Case_Lambda *c)
is_method = ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_IS_METHOD) ? 1 : 0); is_method = ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_IS_METHOD) ? 1 : 0);
} }
generate_top_case_lambda_dispatch(c, ndata, is_method); generate_case_lambda(c, ndata, is_method);
return ndata; return ndata;
} }
@ -2266,21 +2268,25 @@ static void ensure_case_closure_native(Scheme_Case_Lambda *c)
} }
} }
static int generate_case_lambda(Scheme_Object *obj, mz_jit_state *jitter) static int generate_case_closure(Scheme_Object *obj, mz_jit_state *jitter)
{ {
Scheme_Case_Lambda *c = (Scheme_Case_Lambda *)obj; Scheme_Case_Lambda *c = (Scheme_Case_Lambda *)obj;
Scheme_Native_Closure_Data *ndata; Scheme_Native_Closure_Data *ndata;
Scheme_Closure_Data *data; Scheme_Closure_Data *data;
Scheme_Object *o; Scheme_Object *o;
int i, offset, count; int i, offset, count, retptr;
ensure_case_closure_native(c); ensure_case_closure_native(c);
ndata = c->native_code; ndata = c->native_code;
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
mz_prepare(1); mz_prepare(1);
mz_retain(ndata); retptr = mz_retain(ndata);
#ifdef MZ_PRECISE_GC
mz_load_retained(jitter, JIT_R0, retptr);
#else
(void)jit_movi_p(JIT_R0, ndata); /* !! */ (void)jit_movi_p(JIT_R0, ndata); /* !! */
#endif
jit_pusharg_p(JIT_R0); jit_pusharg_p(JIT_R0);
(void)mz_finish(scheme_make_native_case_closure); (void)mz_finish(scheme_make_native_case_closure);
jit_retval(JIT_R1); jit_retval(JIT_R1);
@ -2489,7 +2495,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
START_JIT_DATA(); START_JIT_DATA();
LOG_IT(("case-lambda\n")); LOG_IT(("case-lambda\n"));
/* case-lambda */ /* case-lambda */
generate_case_lambda(SCHEME_IPTR_VAL(obj), jitter); generate_case_closure(SCHEME_IPTR_VAL(obj), jitter);
END_JIT_DATA(5); END_JIT_DATA(5);
} }
break; break;
@ -3139,6 +3145,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
} }
default: default:
{ {
int retptr;
Scheme_Type type = SCHEME_TYPE(obj); Scheme_Type type = SCHEME_TYPE(obj);
START_JIT_DATA(); START_JIT_DATA();
@ -3162,9 +3169,16 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
&& !SAME_OBJ(obj, scheme_false) && !SAME_OBJ(obj, scheme_false)
&& !SAME_OBJ(obj, scheme_void) && !SAME_OBJ(obj, scheme_void)
&& !SAME_OBJ(obj, scheme_null)) { && !SAME_OBJ(obj, scheme_null)) {
mz_retain(obj); retptr = mz_retain(obj);
} } else
(void)jit_movi_p(JIT_R0, obj); /* !! */ retptr = 0;
#ifdef MZ_PRECISE_GC
if (retptr)
mz_load_retained(jitter, JIT_R0, retptr);
else
#endif
(void)jit_movi_p(JIT_R0, obj); /* !! */
END_JIT_DATA(19); END_JIT_DATA(19);
return 1; return 1;
@ -3342,6 +3356,10 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
__START_SHORT_JUMPS__(1); __START_SHORT_JUMPS__(1);
/* Load global array: */ /* Load global array: */
jit_ldxr_p(JIT_V1, JIT_RUNSTACK, JIT_R0); jit_ldxr_p(JIT_V1, JIT_RUNSTACK, JIT_R0);
#ifdef MZ_PRECISE_GC
/* Save global-array index before we lose it: */
mz_push_local_p(JIT_R0, JIT_LOCAL3);
#endif
/* Load syntax object: */ /* Load syntax object: */
jit_ldxr_p(JIT_R0, JIT_V1, JIT_R1); jit_ldxr_p(JIT_R0, JIT_V1, JIT_R1);
/* Is it null? */ /* Is it null? */
@ -3349,8 +3367,10 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
CHECK_LIMIT(); CHECK_LIMIT();
/* Syntax object is NULL, so we need to create it. */ /* Syntax object is NULL, so we need to create it. */
jit_ldxr_p(JIT_R0, JIT_V1, JIT_R2); /* put element at p in R0 */ jit_ldxr_p(JIT_R0, JIT_V1, JIT_R2); /* put element at p in R0 */
#ifndef MZ_PRECISE_GC
/* Save global array: */ /* Save global array: */
mz_push_local_p(JIT_V1, JIT_LOCAL3); mz_push_local_p(JIT_V1, JIT_LOCAL3);
#endif
/* Compute i in JIT_V1: */ /* Compute i in JIT_V1: */
jit_subr_p(JIT_V1, JIT_R1, JIT_R2); jit_subr_p(JIT_V1, JIT_R1, JIT_R2);
jit_subi_p(JIT_V1, JIT_V1, WORDS_TO_BYTES(1)); jit_subi_p(JIT_V1, JIT_V1, WORDS_TO_BYTES(1));
@ -3371,10 +3391,20 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
CHECK_LIMIT(); CHECK_LIMIT();
jit_retval(JIT_R0); jit_retval(JIT_R0);
/* Restore global array into JIT_R1, and put computed element at i+p+1: */ /* Restore global array into JIT_R1, and put computed element at i+p+1: */
#ifdef MZ_PRECISE_GC
mz_pop_local_p(JIT_R1, JIT_LOCAL3); mz_pop_local_p(JIT_R1, JIT_LOCAL3);
jit_ldxr_p(JIT_R1, JIT_RUNSTACK, JIT_R0);
mz_push_local_p(JIT_R1, JIT_LOCAL3); /* push anything to balanec pop below */
#else
mz_pop_local_p(JIT_R1, JIT_LOCAL3);
#endif
jit_stxr_p(JIT_V1, JIT_R1, JIT_R0); jit_stxr_p(JIT_V1, JIT_R1, JIT_R0);
mz_patch_branch(ref); mz_patch_branch(ref);
__END_SHORT_JUMPS__(1); __END_SHORT_JUMPS__(1);
#ifndef MZ_PRECISE_GC
/* Pop global-array index: */
mz_push_local_p(JIT_R1, JIT_LOCAL3);
#endif
mz_epilog(JIT_V1); mz_epilog(JIT_V1);
/* *** bad_{car,cdr}_code *** */ /* *** bad_{car,cdr}_code *** */
@ -3756,6 +3786,13 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
__END_SHORT_JUMPS__(cnt < 100); __END_SHORT_JUMPS__(cnt < 100);
} }
#ifdef MZ_PRECISE_GC
/* 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);
#endif
/* Extract closure to runstack: */ /* Extract closure to runstack: */
cnt = data->closure_size; cnt = data->closure_size;
if (cnt) { if (cnt) {
@ -3816,7 +3853,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
return 1; return 1;
} }
static void on_demand_generate_top(Scheme_Native_Closure_Data *ndata) static void on_demand_generate_lambda(Scheme_Native_Closure_Data *ndata)
{ {
Scheme_Closure_Data *data; Scheme_Closure_Data *data;
Generate_Closure_Data gdata; Generate_Closure_Data gdata;
@ -3850,15 +3887,15 @@ static void on_demand_generate_top(Scheme_Native_Closure_Data *ndata)
if (num_params < MAX_SHARED_ARITY_CHECK) { if (num_params < MAX_SHARED_ARITY_CHECK) {
arity_code = shared_arity_check[num_params][has_rest][is_method]; arity_code = shared_arity_check[num_params][has_rest][is_method];
if (!arity_code) { if (!arity_code) {
arity_code = generate_top_simple_arity_check(num_params, has_rest, is_method, 1); arity_code = generate_lambda_simple_arity_check(num_params, has_rest, is_method, 1);
shared_arity_check[num_params][has_rest][is_method] = arity_code; shared_arity_check[num_params][has_rest][is_method] = arity_code;
} }
} else } else
arity_code = generate_top_simple_arity_check(num_params, has_rest, is_method, 0); arity_code = generate_lambda_simple_arity_check(num_params, has_rest, is_method, 0);
max_depth = WORDS_TO_BYTES(data->max_let_depth + gdata.max_extra); max_depth = WORDS_TO_BYTES(data->max_let_depth + gdata.max_extra);
/* max_let_depth is used for flags by generate_top: */ /* max_let_depth is used for flags by generate_lambda: */
if (ndata->max_let_depth & 0x1) { if (ndata->max_let_depth & 0x1) {
data->code = NULL; data->code = NULL;
} }
@ -3889,7 +3926,7 @@ static void on_demand()
argv = (Scheme_Object **)MZ_RUNSTACK[2]; argv = (Scheme_Object **)MZ_RUNSTACK[2];
ndata = ((Scheme_Native_Closure *)c)->code; ndata = ((Scheme_Native_Closure *)c)->code;
on_demand_generate_top(ndata); on_demand_generate_lambda(ndata);
} }
Scheme_Native_Closure_Data *scheme_generate_lambda(Scheme_Closure_Data *data, int clear_code_after_jit, Scheme_Native_Closure_Data *scheme_generate_lambda(Scheme_Closure_Data *data, int clear_code_after_jit,
@ -3919,7 +3956,7 @@ Scheme_Native_Closure_Data *scheme_generate_lambda(Scheme_Closure_Data *data, in
#if 0 #if 0
/* Compile immediately: */ /* Compile immediately: */
on_demand_generate_top(ndata); on_demand_generate_lambda(ndata);
#endif #endif
return ndata; return ndata;
@ -4011,7 +4048,7 @@ typedef struct {
int is_method; int is_method;
} Generate_Arity_Check_Data; } Generate_Arity_Check_Data;
static int do_generate_top_simple_arity_check(mz_jit_state *jitter, void *_data) static int do_generate_lambda_simple_arity_check(mz_jit_state *jitter, void *_data)
{ {
Generate_Arity_Check_Data *data = (Generate_Arity_Check_Data *)_data; Generate_Arity_Check_Data *data = (Generate_Arity_Check_Data *)_data;
@ -4022,7 +4059,7 @@ static int do_generate_top_simple_arity_check(mz_jit_state *jitter, void *_data)
return generate_simple_arity_check(jitter, data->num_params, data->has_rest, data->is_method); return generate_simple_arity_check(jitter, data->num_params, data->has_rest, data->is_method);
} }
static void *generate_top_simple_arity_check(int num_params, int has_rest, int is_method, int permanent) static void *generate_lambda_simple_arity_check(int num_params, int has_rest, int is_method, int permanent)
{ {
Generate_Arity_Check_Data data; Generate_Arity_Check_Data data;
@ -4030,11 +4067,11 @@ static void *generate_top_simple_arity_check(int num_params, int has_rest, int i
data.has_rest = has_rest; data.has_rest = has_rest;
data.is_method = is_method; data.is_method = is_method;
return generate_one(NULL, do_generate_top_simple_arity_check, &data, !permanent, NULL); return generate_one(NULL, do_generate_lambda_simple_arity_check, &data, !permanent, NULL);
} }
int generate_case_lambda_dispatch(mz_jit_state *jitter, Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata, static int generate_case_lambda_dispatch(mz_jit_state *jitter, Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata,
int do_getarg) int do_getarg)
{ {
/* See top of generate_simple_arity_check for register info. */ /* See top of generate_simple_arity_check for register info. */
Scheme_Closure_Data *data; Scheme_Closure_Data *data;
@ -4131,7 +4168,7 @@ static int do_generate_case_lambda_dispatch(mz_jit_state *jitter, void *_data)
return 0; return 0;
} }
static void generate_top_case_lambda_dispatch(Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata, int is_method) static void generate_case_lambda(Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata, int is_method)
{ {
Generate_Case_Dispatch_Data gdata; Generate_Case_Dispatch_Data gdata;
Scheme_Closure_Data *data; Scheme_Closure_Data *data;

View File

@ -155,6 +155,7 @@ unclosed_proc {
gcMARK(d->closure_map); gcMARK(d->closure_map);
#ifdef MZ_USE_JIT #ifdef MZ_USE_JIT
gcMARK(d->native_code); gcMARK(d->native_code);
gcMARK(d->context);
#endif #endif
size: size:

View File

@ -1565,6 +1565,9 @@ typedef struct Scheme_Native_Closure_Data {
struct Scheme_Closure_Data *orig_code; /* For not-yet-JITted non-case-lambda */ struct Scheme_Closure_Data *orig_code; /* For not-yet-JITted non-case-lambda */
Scheme_Object *name; Scheme_Object *name;
} u2; } u2;
#ifdef MZ_PRECISE_GC
void *retain_start; /* up to arity_code */
#endif
} Scheme_Native_Closure_Data; } Scheme_Native_Closure_Data;
#define SCHEME_NATIVE_CLOSURE_DATA_FLAGS(obj) MZ_OPT_HASH_KEY(&(obj)->iso) #define SCHEME_NATIVE_CLOSURE_DATA_FLAGS(obj) MZ_OPT_HASH_KEY(&(obj)->iso)