avoid a jump in fast-path arity checking
svn: r14217
This commit is contained in:
parent
8243dfaefb
commit
bf499a4e05
|
@ -7527,7 +7527,7 @@ static int generate_alloc_retry(mz_jit_state *jitter, int i)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Scheme_Closure_Data *data;
|
Scheme_Closure_Data *data;
|
||||||
void *code, *tail_code, *code_end, **patch_depth;
|
void *arity_code, *code, *tail_code, *code_end, **patch_depth;
|
||||||
int max_extra, max_depth;
|
int max_extra, max_depth;
|
||||||
Scheme_Native_Closure *nc;
|
Scheme_Native_Closure *nc;
|
||||||
} Generate_Closure_Data;
|
} Generate_Closure_Data;
|
||||||
|
@ -7536,8 +7536,8 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
|
||||||
{
|
{
|
||||||
Generate_Closure_Data *gdata = (Generate_Closure_Data *)_data;
|
Generate_Closure_Data *gdata = (Generate_Closure_Data *)_data;
|
||||||
Scheme_Closure_Data *data = gdata->data;
|
Scheme_Closure_Data *data = gdata->data;
|
||||||
void *code, *tail_code, *code_end;
|
void *code, *tail_code, *code_end, *arity_code;
|
||||||
int i, r, cnt, has_rest;
|
int i, r, cnt, has_rest, is_method, num_params;
|
||||||
|
|
||||||
code = jit_get_ip().ptr;
|
code = jit_get_ip().ptr;
|
||||||
|
|
||||||
|
@ -7553,7 +7553,35 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
|
||||||
(SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST),
|
(SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST),
|
||||||
data->num_params);
|
data->num_params);
|
||||||
CHECK_LIMIT();
|
CHECK_LIMIT();
|
||||||
|
|
||||||
|
/* A tail call with arity checking can start here.
|
||||||
|
(This is a little reundant checking when `code' is the
|
||||||
|
etry point, but that's the slow path anyway.) */
|
||||||
|
|
||||||
|
has_rest = ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST) ? 1 : 0);
|
||||||
|
is_method = ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_IS_METHOD) ? 1 : 0);
|
||||||
|
num_params = data->num_params;
|
||||||
|
if (num_params && has_rest)
|
||||||
|
--num_params;
|
||||||
|
|
||||||
|
if (num_params < MAX_SHARED_ARITY_CHECK) {
|
||||||
|
void *shared_arity_code;
|
||||||
|
|
||||||
|
shared_arity_code = shared_arity_check[num_params][has_rest][is_method];
|
||||||
|
if (!shared_arity_code) {
|
||||||
|
shared_arity_code = generate_lambda_simple_arity_check(num_params, has_rest, is_method, 1);
|
||||||
|
shared_arity_check[num_params][has_rest][is_method] = shared_arity_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
arity_code = jit_get_ip().ptr;
|
||||||
|
|
||||||
|
if (!has_rest)
|
||||||
|
(void)jit_bnei_i(shared_arity_code, JIT_R1, num_params);
|
||||||
|
else
|
||||||
|
(void)jit_blti_i(shared_arity_code, JIT_R1, num_params);
|
||||||
|
} else
|
||||||
|
arity_code = generate_lambda_simple_arity_check(num_params, has_rest, is_method, 0);
|
||||||
|
|
||||||
/* A tail call starts here. Caller must ensure that the
|
/* A tail call starts here. Caller must ensure that the
|
||||||
stack is big enough, right number of arguments, closure
|
stack is big enough, right number of arguments, closure
|
||||||
is in R0. If the closure has a rest arg, also ensure
|
is in R0. If the closure has a rest arg, also ensure
|
||||||
|
@ -7563,8 +7591,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
|
||||||
/* 0 params and has_rest => (lambda args E) where args is not in E,
|
/* 0 params and has_rest => (lambda args E) where args is not in E,
|
||||||
so accept any number of arguments and ignore them. */
|
so accept any number of arguments and ignore them. */
|
||||||
|
|
||||||
if ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST)
|
if (has_rest && data->num_params) {
|
||||||
&& data->num_params) {
|
|
||||||
/* If runstack == argv and argc == cnt, then we didn't
|
/* If runstack == argv and argc == cnt, then we didn't
|
||||||
copy args down, and we need to make room for scheme_null. */
|
copy args down, and we need to make room for scheme_null. */
|
||||||
jit_insn *ref, *ref2, *ref3;
|
jit_insn *ref, *ref2, *ref3;
|
||||||
|
@ -7622,7 +7649,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
|
||||||
/* Keeping the native-closure pointer on the runstack
|
/* Keeping the native-closure pointer on the runstack
|
||||||
ensures that the code won't be GCed while we're running
|
ensures that the code won't be GCed while we're running
|
||||||
it. */
|
it. */
|
||||||
mz_pushr_p(JIT_R0);
|
mz_pushr_p(JIT_R0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Extract closure to runstack: */
|
/* Extract closure to runstack: */
|
||||||
|
@ -7710,6 +7737,7 @@ static int do_generate_closure(mz_jit_state *jitter, void *_data)
|
||||||
code_end = jit_get_ip().ptr;
|
code_end = jit_get_ip().ptr;
|
||||||
|
|
||||||
if (jitter->retain_start) {
|
if (jitter->retain_start) {
|
||||||
|
gdata->arity_code = arity_code;
|
||||||
gdata->code = code;
|
gdata->code = code;
|
||||||
gdata->tail_code = tail_code;
|
gdata->tail_code = tail_code;
|
||||||
gdata->max_extra = jitter->max_extra_pushed;
|
gdata->max_extra = jitter->max_extra_pushed;
|
||||||
|
@ -7727,7 +7755,7 @@ static void on_demand_generate_lambda(Scheme_Native_Closure *nc)
|
||||||
Scheme_Closure_Data *data;
|
Scheme_Closure_Data *data;
|
||||||
Generate_Closure_Data gdata;
|
Generate_Closure_Data gdata;
|
||||||
void *code, *tail_code, *arity_code;
|
void *code, *tail_code, *arity_code;
|
||||||
int has_rest, is_method, num_params, max_depth;
|
int max_depth;
|
||||||
|
|
||||||
data = ndata->u2.orig_code;
|
data = ndata->u2.orig_code;
|
||||||
|
|
||||||
|
@ -7748,6 +7776,7 @@ static void on_demand_generate_lambda(Scheme_Native_Closure *nc)
|
||||||
if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_SINGLE_RESULT)
|
if (SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_SINGLE_RESULT)
|
||||||
SCHEME_NATIVE_CLOSURE_DATA_FLAGS(ndata) |= NATIVE_IS_SINGLE_RESULT;
|
SCHEME_NATIVE_CLOSURE_DATA_FLAGS(ndata) |= NATIVE_IS_SINGLE_RESULT;
|
||||||
|
|
||||||
|
arity_code = gdata.arity_code;
|
||||||
code = gdata.code;
|
code = gdata.code;
|
||||||
tail_code = gdata.tail_code;
|
tail_code = gdata.tail_code;
|
||||||
|
|
||||||
|
@ -7759,21 +7788,6 @@ static void on_demand_generate_lambda(Scheme_Native_Closure *nc)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
has_rest = ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_HAS_REST) ? 1 : 0);
|
|
||||||
is_method = ((SCHEME_CLOSURE_DATA_FLAGS(data) & CLOS_IS_METHOD) ? 1 : 0);
|
|
||||||
num_params = data->num_params;
|
|
||||||
if (num_params && has_rest)
|
|
||||||
--num_params;
|
|
||||||
|
|
||||||
if (num_params < MAX_SHARED_ARITY_CHECK) {
|
|
||||||
arity_code = shared_arity_check[num_params][has_rest][is_method];
|
|
||||||
if (!arity_code) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
arity_code = generate_lambda_simple_arity_check(num_params, has_rest, is_method, 0);
|
|
||||||
|
|
||||||
/* Add a couple of extra slots to computed let-depth, in case
|
/* Add a couple of extra slots to computed let-depth, in case
|
||||||
we haven't quite computed right for inlined uses, etc. */
|
we haven't quite computed right for inlined uses, etc. */
|
||||||
max_depth = WORDS_TO_BYTES(data->max_let_depth + gdata.max_extra + 2);
|
max_depth = WORDS_TO_BYTES(data->max_let_depth + gdata.max_extra + 2);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user