enable JIT stack trace on arity errors

On x86_64 Linux and Win64.
This commit is contained in:
Matthew Flatt 2013-08-12 15:49:40 -06:00
parent 04454678eb
commit 74e49d8499
4 changed files with 28 additions and 10 deletions

View File

@ -3885,17 +3885,26 @@ typedef struct {
int num_params; int num_params;
int has_rest; int has_rest;
int is_method; int is_method;
int gcable;
} Generate_Arity_Check_Data; } Generate_Arity_Check_Data;
static int do_generate_lambda_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;
void *code;
int r;
#ifdef MZ_USE_JIT_PPC #ifdef MZ_USE_JIT_PPC
jitter->js.jitl.nbArgs = 2; /* matches check_arity_code prolog */ jitter->js.jitl.nbArgs = 2; /* matches check_arity_code prolog */
#endif #endif
return generate_simple_arity_check(jitter, data->num_params, data->has_rest, data->is_method); code = jit_get_ip();
r = generate_simple_arity_check(jitter, data->num_params, data->has_rest, data->is_method);
scheme_jit_register_helper_func(jitter, code, data->gcable);
return r;
} }
static void *generate_lambda_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)
@ -3905,6 +3914,7 @@ static void *generate_lambda_simple_arity_check(int num_params, int has_rest, in
data.num_params = num_params; data.num_params = num_params;
data.has_rest = has_rest; data.has_rest = has_rest;
data.is_method = is_method; data.is_method = is_method;
data.gcable = !permanent;
return scheme_generate_one(NULL, do_generate_lambda_simple_arity_check, &data, !permanent, NULL, NULL); return scheme_generate_one(NULL, do_generate_lambda_simple_arity_check, &data, !permanent, NULL, NULL);
} }
@ -3996,6 +4006,8 @@ static int do_generate_case_lambda_dispatch(mz_jit_state *jitter, void *_data)
data->ndata->retain_code = jit_unadjust_ip(start_code); data->ndata->retain_code = jit_unadjust_ip(start_code);
#endif #endif
scheme_jit_register_helper_func(jitter, start_code, 1);
return 1; return 1;
} }
} }

View File

@ -1463,7 +1463,7 @@ int scheme_generate_finish_apply(mz_jit_state *jitter);
int scheme_generate_finish_multi_apply(mz_jit_state *jitter); int scheme_generate_finish_multi_apply(mz_jit_state *jitter);
int scheme_generate_finish_tail_apply(mz_jit_state *jitter); int scheme_generate_finish_tail_apply(mz_jit_state *jitter);
void scheme_jit_register_sub_func(mz_jit_state *jitter, void *code, Scheme_Object *protocol); void scheme_jit_register_sub_func(mz_jit_state *jitter, void *code, Scheme_Object *protocol);
void scheme_jit_register_helper_func(mz_jit_state *jitter, void *code); void scheme_jit_register_helper_func(mz_jit_state *jitter, void *code, int gcable);
#ifdef MZ_USE_FUTURES #ifdef MZ_USE_FUTURES
Scheme_Object *scheme_noncm_prim_indirect(Scheme_Prim proc, int argc); Scheme_Object *scheme_noncm_prim_indirect(Scheme_Prim proc, int argc);
Scheme_Object *scheme_prim_indirect(Scheme_Primitive_Closure_Proc proc, int argc, Scheme_Object *self); Scheme_Object *scheme_prim_indirect(Scheme_Primitive_Closure_Proc proc, int argc, Scheme_Object *self);

View File

@ -1309,7 +1309,7 @@ typedef struct {
int direct_prim, direct_native, nontail_self, unboxed_args; int direct_prim, direct_native, nontail_self, unboxed_args;
} Generate_Call_Data; } Generate_Call_Data;
void scheme_jit_register_sub_func(mz_jit_state *jitter, void *code, Scheme_Object *protocol) static void jit_register_sub_func(mz_jit_state *jitter, void *code, Scheme_Object *protocol, int gcable)
/* protocol: #f => normal lightweight call protocol /* protocol: #f => normal lightweight call protocol
void => next return address is in LOCAL2 void => next return address is in LOCAL2
eof => name to use is in LOCAL2 */ eof => name to use is in LOCAL2 */
@ -1320,15 +1320,21 @@ void scheme_jit_register_sub_func(mz_jit_state *jitter, void *code, Scheme_Objec
if (jitter->retain_start) if (jitter->retain_start)
scheme_jit_add_symbol((uintptr_t)jit_unadjust_ip(code), scheme_jit_add_symbol((uintptr_t)jit_unadjust_ip(code),
(uintptr_t)jit_unadjust_ip(code_end) - 1, (uintptr_t)jit_unadjust_ip(code_end) - 1,
protocol, 0); protocol,
gcable);
} }
void scheme_jit_register_helper_func(mz_jit_state *jitter, void *code) void scheme_jit_register_sub_func(mz_jit_state *jitter, void *code, Scheme_Object *protocol)
{
return jit_register_sub_func(jitter, code, protocol, 0);
}
void scheme_jit_register_helper_func(mz_jit_state *jitter, void *code, int gcable)
{ {
#if defined(MZ_USE_DWARF_LIBUNWIND) || defined(_WIN64) #if defined(MZ_USE_DWARF_LIBUNWIND) || defined(_WIN64)
/* Null indicates that there's no function name to report, but the /* Null indicates that there's no function name to report, but the
stack should be unwound manually using the JJIT-generated convention. */ stack should be unwound manually using the JJIT-generated convention. */
scheme_jit_register_sub_func(jitter, code, scheme_null); jit_register_sub_func(jitter, code, scheme_null, gcable);
#endif #endif
} }
@ -1352,7 +1358,7 @@ static int do_generate_shared_call(mz_jit_state *jitter, void *_data)
ok = scheme_generate_tail_call(jitter, data->num_rands, data->direct_native, 1, 0, ok = scheme_generate_tail_call(jitter, data->num_rands, data->direct_native, 1, 0,
NULL, NULL); NULL, NULL);
scheme_jit_register_helper_func(jitter, code); scheme_jit_register_helper_func(jitter, code, 0);
return ok; return ok;
} else { } else {

View File

@ -790,7 +790,7 @@ static int common2(mz_jit_state *jitter, void *_data)
mz_pop_locals(); mz_pop_locals();
jit_ret(); jit_ret();
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, 0);
/* Used for the state of a function that is being JITted /* Used for the state of a function that is being JITted
(for a kind of cycle detection) without breaking concurrent (for a kind of cycle detection) without breaking concurrent
@ -819,11 +819,11 @@ static int common2(mz_jit_state *jitter, void *_data)
sjc.finish_tail_call_code = jit_get_ip(); sjc.finish_tail_call_code = jit_get_ip();
scheme_generate_finish_tail_call(jitter, 0); scheme_generate_finish_tail_call(jitter, 0);
CHECK_LIMIT(); CHECK_LIMIT();
scheme_jit_register_helper_func(jitter, sjc.finish_tail_call_code); scheme_jit_register_helper_func(jitter, sjc.finish_tail_call_code, 0);
sjc.finish_tail_call_fixup_code = jit_get_ip(); sjc.finish_tail_call_fixup_code = jit_get_ip();
scheme_generate_finish_tail_call(jitter, 2); scheme_generate_finish_tail_call(jitter, 2);
CHECK_LIMIT(); CHECK_LIMIT();
scheme_jit_register_helper_func(jitter, sjc.finish_tail_call_fixup_code); scheme_jit_register_helper_func(jitter, sjc.finish_tail_call_fixup_code, 0);
/* *** get_stack_pointer_code *** */ /* *** get_stack_pointer_code *** */
sjc.get_stack_pointer_code = jit_get_ip(); sjc.get_stack_pointer_code = jit_get_ip();