fix JIT problem that can break futures

A recent (weeks-old) JIT change set one of a function's code
 pointers to NULL to indicate that JIT-compilation of the
 function is in progress, but that breaks futures. Set the
 code pointer to a different not-yet-ready function, instead.

 Merge to 5.1.2

 Closes PR 12037
This commit is contained in:
Matthew Flatt 2011-07-11 06:37:57 -06:00
parent 904ef63ce2
commit 09eab9c3eb
4 changed files with 9 additions and 3 deletions

View File

@ -3312,7 +3312,7 @@ static void on_demand_generate_lambda(Scheme_Native_Closure *nc, int argc, Schem
if (ndata->code != scheme_on_demand_jit_code) if (ndata->code != scheme_on_demand_jit_code)
return; return;
ndata->arity_code = NULL; /* => in progress */ ndata->arity_code = sjc.in_progress_on_demand_jit_arity_code; /* => in progress */
scheme_generate_one(NULL, do_generate_closure, &gdata, 1, data->name, ndata); scheme_generate_one(NULL, do_generate_closure, &gdata, 1, data->name, ndata);

View File

@ -227,7 +227,7 @@ struct scheme_jit_common_record {
void *fxvector_ref_code, *fxvector_ref_check_index_code, *fxvector_set_code, *fxvector_set_check_index_code; void *fxvector_ref_code, *fxvector_ref_check_index_code, *fxvector_set_code, *fxvector_set_check_index_code;
void *struct_raw_ref_code, *struct_raw_set_code; void *struct_raw_ref_code, *struct_raw_set_code;
void *syntax_e_code; void *syntax_e_code;
void *on_demand_jit_arity_code; void *on_demand_jit_arity_code, *in_progress_on_demand_jit_arity_code;
void *get_stack_pointer_code; void *get_stack_pointer_code;
void *stack_cache_pop_code; void *stack_cache_pop_code;
void *struct_pred_code, *struct_pred_multi_code; void *struct_pred_code, *struct_pred_multi_code;

View File

@ -1454,7 +1454,7 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
Scheme_Native_Closure *nc; Scheme_Native_Closure *nc;
nc = (Scheme_Native_Closure *)scheme_jit_closure((Scheme_Object *)data, NULL); nc = (Scheme_Native_Closure *)scheme_jit_closure((Scheme_Object *)data, NULL);
if (nc->code->code == scheme_on_demand_jit_code) { if (nc->code->code == scheme_on_demand_jit_code) {
if (nc->code->arity_code) { /* i.e., not in progress */ if (nc->code->arity_code != sjc.in_progress_on_demand_jit_arity_code) {
scheme_on_demand_generate_lambda(nc, 0, NULL); scheme_on_demand_generate_lambda(nc, 0, NULL);
} }
} }

View File

@ -729,6 +729,12 @@ static int common2(mz_jit_state *jitter, void *_data)
CHECK_LIMIT(); CHECK_LIMIT();
scheme_jit_register_helper_func(jitter, scheme_on_demand_jit_code); scheme_jit_register_helper_func(jitter, scheme_on_demand_jit_code);
/* Used for the state of a function that is being JITted
(for a kind of cycle detection) without breaking concurrent
future threads that might try to call the function. */
sjc.in_progress_on_demand_jit_arity_code = jit_get_ip().ptr;
(void)jit_jmpi(sjc.on_demand_jit_arity_code);
/* *** app_values_tail_slow_code *** */ /* *** app_values_tail_slow_code *** */
/* RELIES ON jit_prolog(NATIVE_ARG_COUNT) FROM ABOVE */ /* RELIES ON jit_prolog(NATIVE_ARG_COUNT) FROM ABOVE */
/* Rator in V1, arguments are in thread's multiple-values cells. */ /* Rator in V1, arguments are in thread's multiple-values cells. */