fix JIT bug in struct pred/get/set corner case
When thie JIT guesses that an identifier is bound to a structure predicate, getter, setter, etc., but that guess turns out to be wrong, and the call is in a tail position, then preserve tail-call behavior. (Changes include some setup to inline structure constructors.)
This commit is contained in:
parent
a59df8c7ee
commit
79ada3b16e
|
@ -2196,4 +2196,28 @@
|
|||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(module check-tail-call-by-jit-for-struct-predicate racket/base
|
||||
(provide go)
|
||||
|
||||
(struct s (x))
|
||||
|
||||
(define f #f)
|
||||
(set! f (lambda (v)
|
||||
(if (zero? v)
|
||||
(let ([vec (make-vector 6)])
|
||||
(vector-set-performance-stats! vec (current-thread))
|
||||
(vector-ref vec 3))
|
||||
(s? (sub1 v)))))
|
||||
|
||||
(void (f 5)) ; JIT decides that `s?' is a struct predicate
|
||||
(set! s? f) ; break the JIT's optimistic assumption
|
||||
|
||||
(define (go)
|
||||
(define size (f 500000)) ; make sure that this still leads to a tail loop
|
||||
(size . < . 80000)))
|
||||
|
||||
(test #t (dynamic-require ''check-tail-call-by-jit-for-struct-predicate 'go))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(report-errs)
|
||||
|
|
|
@ -621,7 +621,7 @@ int scheme_is_simple(Scheme_Object *obj, int depth, int just_markless, mz_jit_st
|
|||
break;
|
||||
|
||||
case scheme_application_type:
|
||||
if (scheme_inlined_nary_prim(((Scheme_App_Rec *)obj)->args[0], obj)
|
||||
if (scheme_inlined_nary_prim(((Scheme_App_Rec *)obj)->args[0], obj, jitter)
|
||||
&& !SAME_OBJ(((Scheme_App_Rec *)obj)->args[0], scheme_values_func))
|
||||
return 1;
|
||||
if (just_markless) {
|
||||
|
|
|
@ -250,13 +250,13 @@ struct scheme_jit_common_record {
|
|||
void *on_demand_jit_arity_code, *in_progress_on_demand_jit_arity_code;
|
||||
void *get_stack_pointer_code;
|
||||
void *stack_cache_pop_code;
|
||||
void *struct_pred_code, *struct_pred_multi_code;
|
||||
void *struct_pred_code, *struct_pred_tail_code, *struct_pred_multi_code;
|
||||
void *struct_pred_branch_code;
|
||||
void *struct_get_code, *struct_get_multi_code;
|
||||
void *struct_set_code, *struct_set_multi_code;
|
||||
void *struct_prop_get_code, *struct_prop_get_multi_code;
|
||||
void *struct_prop_get_defl_code, *struct_prop_get_defl_multi_code;
|
||||
void *struct_prop_pred_code, *struct_prop_pred_multi_code;
|
||||
void *struct_get_code, *struct_get_tail_code, *struct_get_multi_code;
|
||||
void *struct_set_code, *struct_set_tail_code, *struct_set_multi_code;
|
||||
void *struct_prop_get_code, *struct_prop_get_tail_code, *struct_prop_get_multi_code;
|
||||
void *struct_prop_get_defl_code, *struct_prop_get_defl_tail_code, *struct_prop_get_defl_multi_code;
|
||||
void *struct_prop_pred_code, *struct_prop_pred_tail_code, *struct_prop_pred_multi_code;
|
||||
void *struct_proc_extract_code;
|
||||
void *bad_app_vals_target;
|
||||
void *app_values_slow_code, *app_values_multi_slow_code, *app_values_tail_slow_code;
|
||||
|
@ -1170,7 +1170,7 @@ int scheme_mz_try_runstack_pop(mz_jit_state *jitter, int n);
|
|||
|
||||
int scheme_inlined_unary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter);
|
||||
int scheme_inlined_binary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter);
|
||||
int scheme_inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app);
|
||||
int scheme_inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter);
|
||||
int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, int is_tail, int multi_ok,
|
||||
Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored);
|
||||
int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, int is_tail, int multi_ok,
|
||||
|
@ -1232,6 +1232,7 @@ int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na
|
|||
int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direct_native, int need_set_rs,
|
||||
int multi_ok, int nontail_self, int pop_and_jump, int is_inlined, int unboxed_args);
|
||||
int scheme_generate_finish_tail_call(mz_jit_state *jitter, int direct_native);
|
||||
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_helper_func(mz_jit_state *jitter, void *code);
|
||||
#ifdef MZ_USE_FUTURES
|
||||
|
@ -1383,3 +1384,16 @@ Scheme_Object *scheme_jit_continuation_apply_install(Apply_LWC_Args *args);
|
|||
#define CMP_EVENP 4
|
||||
/* odd? */
|
||||
#define CMP_ODDP -4
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
#define INLINE_STRUCT_PROC_PRED 1
|
||||
#define INLINE_STRUCT_PROC_GET 2
|
||||
#define INLINE_STRUCT_PROC_SET 3
|
||||
#define INLINE_STRUCT_PROC_PROP_GET 4
|
||||
#define INLINE_STRUCT_PROC_PROP_GET_W_DEFAULT 5
|
||||
#define INLINE_STRUCT_PROC_PROP_PRED 6
|
||||
#define INLINE_STRUCT_PROC_CONSTR 7
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -515,6 +515,13 @@ int scheme_generate_tail_call(mz_jit_state *jitter, int num_rands, int direct_na
|
|||
return 1;
|
||||
}
|
||||
|
||||
int scheme_generate_finish_tail_apply(mz_jit_state *jitter)
|
||||
{
|
||||
GC_CAN_IGNORE jit_insn *refr;
|
||||
(void)mz_finish_lwe(_scheme_tail_apply_from_native, refr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int scheme_generate_finish_tail_call(mz_jit_state *jitter, int direct_native)
|
||||
{
|
||||
mz_prepare(3);
|
||||
|
|
|
@ -1356,7 +1356,7 @@ static int common3(mz_jit_state *jitter, void *_data)
|
|||
}
|
||||
|
||||
static int gen_struct_slow(mz_jit_state *jitter, int kind, int ok_proc,
|
||||
int for_branch, int multi_ok,
|
||||
int for_branch, int is_tail, int multi_ok,
|
||||
GC_CAN_IGNORE jit_insn **_bref5,
|
||||
GC_CAN_IGNORE jit_insn **_bref6)
|
||||
{
|
||||
|
@ -1376,7 +1376,10 @@ static int gen_struct_slow(mz_jit_state *jitter, int kind, int ok_proc,
|
|||
jit_pusharg_p(JIT_RUNSTACK);
|
||||
jit_pusharg_i(JIT_V1);
|
||||
jit_pusharg_p(JIT_R0);
|
||||
if (multi_ok) {
|
||||
if (is_tail) {
|
||||
scheme_generate_finish_tail_apply(jitter);
|
||||
CHECK_LIMIT();
|
||||
} else if (multi_ok) {
|
||||
(void)mz_finish_lwe(ts__scheme_apply_multi_from_native, refrts);
|
||||
} else {
|
||||
(void)mz_finish_lwe(ts__scheme_apply_from_native, refrts);
|
||||
|
@ -1560,25 +1563,28 @@ static int common4(mz_jit_state *jitter, void *_data)
|
|||
__END_TINY_JUMPS__(1);
|
||||
}
|
||||
|
||||
/* *** struct_{pred,get,set}[_branch]_code *** */
|
||||
/* *** struct_{pred,get,set}[_branch,_multi,_tail]_code *** */
|
||||
/* R0 is (potential) struct proc, R1 is (potential) struct. */
|
||||
/* In branch mode, V1 is target address for false branch. */
|
||||
/* In set mode, V1 is value to install. */
|
||||
for (ii = 0; ii < 2; ii++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (ii = 0; ii < 3; ii++) { /* single, multi, or tail */
|
||||
for (i = 0; i < 4; i++) { /* pred, pred_branch, get, or set */
|
||||
void *code;
|
||||
int kind, for_branch;
|
||||
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *refslow, *refslow2, *bref1, *bref2, *refretry;
|
||||
GC_CAN_IGNORE jit_insn *bref3, *bref4, *bref5, *bref6, *bref8, *ref9;
|
||||
|
||||
if ((ii == 1) && (i == 1)) continue; /* no multi variant of pred branch */
|
||||
if ((ii == 2) && (i == 1)) continue; /* no tail variant of pred branch */
|
||||
|
||||
code = jit_get_ip().ptr;
|
||||
|
||||
if (!i) {
|
||||
kind = 1;
|
||||
for_branch = 0;
|
||||
if (ii == 1)
|
||||
if (ii == 2)
|
||||
sjc.struct_pred_tail_code = jit_get_ip().ptr;
|
||||
else if (ii == 1)
|
||||
sjc.struct_pred_multi_code = jit_get_ip().ptr;
|
||||
else
|
||||
sjc.struct_pred_code = jit_get_ip().ptr;
|
||||
|
@ -1591,14 +1597,18 @@ static int common4(mz_jit_state *jitter, void *_data)
|
|||
} else if (i == 2) {
|
||||
kind = 2;
|
||||
for_branch = 0;
|
||||
if (ii == 1)
|
||||
if (ii == 2)
|
||||
sjc.struct_get_tail_code = jit_get_ip().ptr;
|
||||
else if (ii == 1)
|
||||
sjc.struct_get_multi_code = jit_get_ip().ptr;
|
||||
else
|
||||
sjc.struct_get_code = jit_get_ip().ptr;
|
||||
} else {
|
||||
kind = 3;
|
||||
for_branch = 0;
|
||||
if (ii == 1)
|
||||
if (ii == 2)
|
||||
sjc.struct_set_tail_code = jit_get_ip().ptr;
|
||||
else if (ii == 1)
|
||||
sjc.struct_set_multi_code = jit_get_ip().ptr;
|
||||
else
|
||||
sjc.struct_set_code = jit_get_ip().ptr;
|
||||
|
@ -1615,13 +1625,13 @@ static int common4(mz_jit_state *jitter, void *_data)
|
|||
|
||||
/* Slow path: non-struct proc. */
|
||||
refslow = _jit.x.pc;
|
||||
gen_struct_slow(jitter, kind, 0, for_branch, ii == 1, &bref5, &bref6);
|
||||
gen_struct_slow(jitter, kind, 0, for_branch, ii == 2, ii == 1, &bref5, &bref6);
|
||||
CHECK_LIMIT();
|
||||
|
||||
if ((kind == 2) || (kind == 3)) {
|
||||
/* Slow path: argument type is bad for a getter/setter. */
|
||||
refslow2 = _jit.x.pc;
|
||||
gen_struct_slow(jitter, kind, 1, 0, 0, NULL, NULL);
|
||||
gen_struct_slow(jitter, kind, 1, 0, 0, 0, NULL, NULL);
|
||||
CHECK_LIMIT();
|
||||
} else
|
||||
refslow2 = refslow;
|
||||
|
@ -1773,28 +1783,34 @@ static int common4b(mz_jit_state *jitter, void *_data)
|
|||
{
|
||||
int i, ii;
|
||||
|
||||
/* *** struct_prop_{pred,get[_defl]}_[multi_]code *** */
|
||||
/* *** struct_prop_{pred,get[_defl]}_[multi_,tail_]code *** */
|
||||
/* R0 is (potential) struct-prop proc, R1 is (potential) struct.
|
||||
If defl_, V1 is second argument for default value. */
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (ii = 0; ii < 2; ii++) {
|
||||
for (ii = 0; ii < 3; ii++) { /* single, multi, or tail */
|
||||
void *code;
|
||||
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *refno, *refslow, *refloop, *refrts;
|
||||
|
||||
code = jit_get_ip().ptr;
|
||||
|
||||
if (i == 0) {
|
||||
if (ii == 1)
|
||||
if (ii == 2)
|
||||
sjc.struct_prop_get_tail_code = code;
|
||||
else if (ii == 1)
|
||||
sjc.struct_prop_get_multi_code = code;
|
||||
else
|
||||
sjc.struct_prop_get_code = code;
|
||||
} else if (i == 1) {
|
||||
if (ii == 1)
|
||||
if (ii == 2)
|
||||
sjc.struct_prop_get_defl_tail_code = code;
|
||||
else if (ii == 1)
|
||||
sjc.struct_prop_get_defl_multi_code = code;
|
||||
else
|
||||
sjc.struct_prop_get_defl_code = code;
|
||||
} else if (i == 2) {
|
||||
if (ii == 1)
|
||||
if (ii == 2)
|
||||
sjc.struct_prop_pred_tail_code = code;
|
||||
else if (ii == 1)
|
||||
sjc.struct_prop_pred_multi_code = code;
|
||||
else
|
||||
sjc.struct_prop_pred_code = code;
|
||||
|
@ -1826,7 +1842,10 @@ static int common4b(mz_jit_state *jitter, void *_data)
|
|||
jit_pusharg_p(JIT_RUNSTACK);
|
||||
jit_pusharg_i(JIT_V1);
|
||||
jit_pusharg_p(JIT_R0);
|
||||
if (ii == 1) {
|
||||
if (ii == 2) {
|
||||
scheme_generate_finish_tail_apply(jitter);
|
||||
CHECK_LIMIT();
|
||||
} else if (ii == 1) {
|
||||
(void)mz_finish_lwe(ts__scheme_apply_multi_from_native, refrts);
|
||||
} else {
|
||||
(void)mz_finish_lwe(ts__scheme_apply_from_native, refrts);
|
||||
|
|
|
@ -121,22 +121,32 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
|
|||
static int check_val_struct_prim(Scheme_Object *p, int arity)
|
||||
{
|
||||
if (p && SCHEME_PRIMP(p)) {
|
||||
if (arity == 1) {
|
||||
int t = (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_OTHER_TYPE_MASK);
|
||||
int t = (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_OTHER_TYPE_MASK);
|
||||
if (t == SCHEME_PRIM_STRUCT_TYPE_CONSTR) {
|
||||
#if 0
|
||||
/* not yet ready... */
|
||||
Scheme_Struct_Type *t;
|
||||
t = (Scheme_Struct_Type *)SCHEME_PRIM_CLOSURE_ELS(p)[0];
|
||||
if ((arity == t->num_islots)
|
||||
&& scheme_is_simple_struct_type(t)) {
|
||||
return INLINE_STRUCT_PROC_CONSTR;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
} else if (arity == 1) {
|
||||
if (t == SCHEME_PRIM_STRUCT_TYPE_PRED)
|
||||
return 1;
|
||||
return INLINE_STRUCT_PROC_PRED;
|
||||
if (t == SCHEME_PRIM_STRUCT_TYPE_INDEXED_GETTER)
|
||||
return 2;
|
||||
return INLINE_STRUCT_PROC_GET;
|
||||
else if (t == SCHEME_PRIM_TYPE_STRUCT_PROP_GETTER)
|
||||
return 4;
|
||||
return INLINE_STRUCT_PROC_PROP_GET;
|
||||
else if (t == SCHEME_PRIM_STRUCT_TYPE_STRUCT_PROP_PRED)
|
||||
return 6;
|
||||
return INLINE_STRUCT_PROC_PROP_PRED;
|
||||
} else if (arity == 2) {
|
||||
int t = (((Scheme_Primitive_Proc *)p)->pp.flags & SCHEME_PRIM_OTHER_TYPE_MASK);
|
||||
if (t == SCHEME_PRIM_STRUCT_TYPE_INDEXED_SETTER)
|
||||
return 3;
|
||||
return INLINE_STRUCT_PROC_SET;
|
||||
else if (t == SCHEME_PRIM_TYPE_STRUCT_PROP_GETTER)
|
||||
return 5;
|
||||
return INLINE_STRUCT_PROC_PROP_GET_W_DEFAULT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -178,12 +188,15 @@ int scheme_inlined_binary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_sta
|
|||
|| inlineable_struct_prim(o, jitter, 2, 2));
|
||||
}
|
||||
|
||||
int scheme_inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app)
|
||||
int scheme_inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter)
|
||||
{
|
||||
return (SCHEME_PRIMP(o)
|
||||
&& (SCHEME_PRIM_PROC_FLAGS(o) & SCHEME_PRIM_IS_NARY_INLINED)
|
||||
&& (((Scheme_App_Rec *)_app)->num_args >= ((Scheme_Primitive_Proc *)o)->mina)
|
||||
&& (((Scheme_App_Rec *)_app)->num_args <= ((Scheme_Primitive_Proc *)o)->mu.maxa));
|
||||
int n = ((Scheme_App_Rec *)_app)->num_args;
|
||||
|
||||
return ((SCHEME_PRIMP(o)
|
||||
&& (SCHEME_PRIM_PROC_FLAGS(o) & SCHEME_PRIM_IS_NARY_INLINED)
|
||||
&& (n >= ((Scheme_Primitive_Proc *)o)->mina)
|
||||
&& (n <= ((Scheme_Primitive_Proc *)o)->mu.maxa))
|
||||
|| inlineable_struct_prim(o, jitter, n, n));
|
||||
}
|
||||
|
||||
static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec *app,
|
||||
|
@ -345,7 +358,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app
|
|||
static int generate_inlined_struct_op(int kind, mz_jit_state *jitter,
|
||||
Scheme_Object *rator, Scheme_Object *rand, Scheme_Object *rand2,
|
||||
Branch_Info *for_branch, int branch_short,
|
||||
int multi_ok)
|
||||
int is_tail, int multi_ok)
|
||||
/* de-sync'd ok; for branch, sync'd before */
|
||||
{
|
||||
LOG_IT(("inlined struct op\n"));
|
||||
|
@ -382,42 +395,62 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter,
|
|||
scheme_branch_for_true(jitter, for_branch);
|
||||
__END_SHORT_JUMPS__(for_branch->branch_short);
|
||||
CHECK_LIMIT();
|
||||
} else if (kind == 1) {
|
||||
if (multi_ok) {
|
||||
} else if (kind == INLINE_STRUCT_PROC_PRED) {
|
||||
if (is_tail) {
|
||||
(void)jit_calli(sjc.struct_pred_tail_code);
|
||||
} else if (multi_ok) {
|
||||
(void)jit_calli(sjc.struct_pred_multi_code);
|
||||
} else {
|
||||
(void)jit_calli(sjc.struct_pred_code);
|
||||
}
|
||||
} else if (kind == 2) {
|
||||
if (multi_ok) {
|
||||
} else if (kind == INLINE_STRUCT_PROC_GET) {
|
||||
if (is_tail) {
|
||||
(void)jit_calli(sjc.struct_get_tail_code);
|
||||
} else if (multi_ok) {
|
||||
(void)jit_calli(sjc.struct_get_multi_code);
|
||||
} else {
|
||||
(void)jit_calli(sjc.struct_get_code);
|
||||
}
|
||||
} else if (kind == 3) {
|
||||
if (multi_ok) {
|
||||
} else if (kind == INLINE_STRUCT_PROC_SET) {
|
||||
if (is_tail) {
|
||||
(void)jit_calli(sjc.struct_set_tail_code);
|
||||
} else if (multi_ok) {
|
||||
(void)jit_calli(sjc.struct_set_multi_code);
|
||||
} else {
|
||||
(void)jit_calli(sjc.struct_set_code);
|
||||
}
|
||||
} else if (kind == 4) {
|
||||
if (multi_ok) {
|
||||
} else if (kind == INLINE_STRUCT_PROC_PROP_GET) {
|
||||
if (is_tail) {
|
||||
(void)jit_calli(sjc.struct_prop_get_tail_code);
|
||||
} else if (multi_ok) {
|
||||
(void)jit_calli(sjc.struct_prop_get_multi_code);
|
||||
} else {
|
||||
(void)jit_calli(sjc.struct_prop_get_code);
|
||||
}
|
||||
} else if (kind == 5) {
|
||||
if (multi_ok) {
|
||||
} else if (kind == INLINE_STRUCT_PROC_PROP_GET_W_DEFAULT) {
|
||||
if (is_tail) {
|
||||
(void)jit_calli(sjc.struct_prop_get_defl_tail_code);
|
||||
} else if (multi_ok) {
|
||||
(void)jit_calli(sjc.struct_prop_get_defl_multi_code);
|
||||
} else {
|
||||
(void)jit_calli(sjc.struct_prop_get_defl_code);
|
||||
}
|
||||
} else if (kind == 6) {
|
||||
if (multi_ok) {
|
||||
} else if (kind == INLINE_STRUCT_PROC_PROP_PRED) {
|
||||
if (is_tail) {
|
||||
(void)jit_calli(sjc.struct_prop_pred_tail_code);
|
||||
} else if (multi_ok) {
|
||||
(void)jit_calli(sjc.struct_prop_pred_multi_code);
|
||||
} else {
|
||||
(void)jit_calli(sjc.struct_prop_pred_code);
|
||||
}
|
||||
} else if (kind == INLINE_STRUCT_PROC_CONSTR) {
|
||||
return 0;
|
||||
#if 0
|
||||
if (!rand2)
|
||||
(void)jit_calli(sjc.struct_constr_unary_code);
|
||||
else
|
||||
(void)jit_calli(sjc.struct_constr_binary_code);
|
||||
#endif
|
||||
} else {
|
||||
scheme_signal_error("internal error: unknown struct-op mode");
|
||||
}
|
||||
|
@ -425,6 +458,23 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int generate_inlined_nary_struct_op(int kind, mz_jit_state *jitter,
|
||||
Scheme_Object *rator, Scheme_App_Rec *app,
|
||||
Branch_Info *for_branch, int branch_short,
|
||||
int multi_ok)
|
||||
/* de-sync'd ok; for branch, sync'd before */
|
||||
{
|
||||
#if 1
|
||||
scheme_signal_error("shouldn't get here, yet"); /* REMOVEME */
|
||||
#else
|
||||
/* generate code to evaluate the arguments */
|
||||
scheme_generate_app(app, NULL, app->num_args, jitter, 0, 0, 2);
|
||||
CHECK_LIMIT();
|
||||
mz_rs_sync();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_cXr_prim(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
@ -503,12 +553,16 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
|
|||
{
|
||||
int k;
|
||||
k = inlineable_struct_prim(rator, jitter, 1, 1);
|
||||
if (k == 1) {
|
||||
generate_inlined_struct_op(1, jitter, rator, app->rand, NULL, for_branch, branch_short, multi_ok);
|
||||
if (k == INLINE_STRUCT_PROC_PRED) {
|
||||
generate_inlined_struct_op(1, jitter, rator, app->rand, NULL, for_branch, branch_short, is_tail, multi_ok);
|
||||
scheme_direct_call_count++;
|
||||
return 1;
|
||||
} else if (((k == 2) || (k == 4) || (k == 6)) && !for_branch) {
|
||||
generate_inlined_struct_op(k, jitter, rator, app->rand, NULL, for_branch, branch_short, multi_ok);
|
||||
} else if (((k == INLINE_STRUCT_PROC_GET)
|
||||
|| (k == INLINE_STRUCT_PROC_PROP_GET)
|
||||
|| (k == INLINE_STRUCT_PROC_PROP_PRED)
|
||||
|| (k == INLINE_STRUCT_PROC_CONSTR))
|
||||
&& !for_branch) {
|
||||
generate_inlined_struct_op(k, jitter, rator, app->rand, NULL, for_branch, branch_short, is_tail, multi_ok);
|
||||
scheme_direct_call_count++;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1730,7 +1784,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
int k;
|
||||
k = inlineable_struct_prim(rator, jitter, 2, 2);
|
||||
if (k) {
|
||||
generate_inlined_struct_op(k, jitter, rator, app->rand1, app->rand2, for_branch, branch_short, multi_ok);
|
||||
generate_inlined_struct_op(k, jitter, rator, app->rand1, app->rand2, for_branch, branch_short, is_tail, multi_ok);
|
||||
scheme_direct_call_count++;
|
||||
return 1;
|
||||
}
|
||||
|
@ -2790,7 +2844,17 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
|
|||
/* de-sync's; for branch, sync'd before */
|
||||
{
|
||||
Scheme_Object *rator = app->args[0];
|
||||
|
||||
|
||||
if (!for_branch) {
|
||||
int k;
|
||||
k = inlineable_struct_prim(rator, jitter, app->num_args, app->num_args);
|
||||
if (k) {
|
||||
generate_inlined_nary_struct_op(k, jitter, rator, app, for_branch, branch_short, multi_ok);
|
||||
scheme_direct_call_count++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SCHEME_PRIMP(rator))
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -819,6 +819,8 @@ Scheme_Object *scheme_extract_struct_procedure(Scheme_Object *obj, int num_rands
|
|||
Scheme_Object *scheme_proc_struct_name_source(Scheme_Object *a);
|
||||
Scheme_Object *scheme_object_name(Scheme_Object *a);
|
||||
|
||||
int scheme_is_simple_struct_type(Scheme_Struct_Type *stype);
|
||||
|
||||
Scheme_Object *scheme_is_writable_struct(Scheme_Object *s);
|
||||
Scheme_Object *scheme_print_attribute_ref(Scheme_Object *s);
|
||||
|
||||
|
|
|
@ -2265,7 +2265,7 @@ make_simple_struct_instance(int argc, Scheme_Object **args, Scheme_Object *prim)
|
|||
return (Scheme_Object *)inst;
|
||||
}
|
||||
|
||||
static int is_simple_struct_type(Scheme_Struct_Type *stype)
|
||||
int scheme_is_simple_struct_type(Scheme_Struct_Type *stype)
|
||||
{
|
||||
int p;
|
||||
|
||||
|
@ -3771,7 +3771,7 @@ make_struct_proc(Scheme_Struct_Type *struct_type,
|
|||
|
||||
if (proc_type == SCHEME_CONSTR) {
|
||||
int simple;
|
||||
simple = is_simple_struct_type(struct_type);
|
||||
simple = scheme_is_simple_struct_type(struct_type);
|
||||
a[0] = (Scheme_Object *)struct_type;
|
||||
p = scheme_make_folding_prim_closure((simple
|
||||
? make_simple_struct_instance
|
||||
|
|
Loading…
Reference in New Issue
Block a user