diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index 5447280ec9..f9a7c222ed 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -1530,7 +1530,7 @@ int scheme_generate_struct_op(mz_jit_state *jitter, int kind, int for_branch, int result_ignored, int check_proc, int check_arg_fixnum, int type_pos, int field_pos, - int authentic, + int authentic, int type_unpacked, int pop_and_jump, jit_insn *refslow, jit_insn *refslow2, jit_insn *bref_false, jit_insn *bref_true); diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 700c139a37..13c903c2b8 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -1595,7 +1595,7 @@ int scheme_generate_struct_op(mz_jit_state *jitter, int kind, int for_branch, int result_ignored, int check_proc, int check_arg_fixnum, int type_pos, int field_pos, - int authentic, + int authentic, int type_unpacked, int pop_and_jump, GC_CAN_IGNORE jit_insn *refslow, GC_CAN_IGNORE jit_insn *refslow2, GC_CAN_IGNORE jit_insn *bref_false, GC_CAN_IGNORE jit_insn *bref_true) @@ -1661,9 +1661,11 @@ int scheme_generate_struct_op(mz_jit_state *jitter, int kind, int for_branch, CHECK_LIMIT(); if (type_pos != 0) { - /* Put argument struct type in R2, target struct type in V1 */ + /* Put argument struct type in R2, target struct type in V1 if not unpacked */ + jit_ldxi_p(JIT_R2, JIT_R1, &((Scheme_Structure *)0x0)->stype); if (type_pos < 0) { + MZ_ASSERT(!type_unpacked); jit_ldxi_p(JIT_V1, JIT_R0, &((Scheme_Primitive_Closure *)0x0)->val); } CHECK_LIMIT(); @@ -1719,10 +1721,11 @@ int scheme_generate_struct_op(mz_jit_state *jitter, int kind, int for_branch, CHECK_LIMIT(); /* (Re-)load target type into V1: */ - jit_ldxi_p(JIT_V1, JIT_R0, &((Scheme_Primitive_Closure *)0x0)->val); + if (!type_unpacked) + jit_ldxi_p(JIT_V1, JIT_R0, &((Scheme_Primitive_Closure *)0x0)->val); if (kind == 1) { - bref4 = jit_bner_p(jit_forward(), JIT_R2, JIT_V1); + bref4 = jit_bner_p(jit_forward(), JIT_R2, (type_unpacked ? JIT_R0 : JIT_V1)); /* True branch: */ if (!for_branch) { @@ -1783,6 +1786,7 @@ int scheme_generate_struct_op(mz_jit_state *jitter, int kind, int for_branch, } } } else { + MZ_ASSERT(!type_unpacked); (void)jit_bner_p(refslow2, JIT_R2, JIT_V1); bref4 = NULL; if (bref8) { @@ -2024,7 +2028,7 @@ static int common4(mz_jit_state *jitter, void *_data) __END_SHORT_JUMPS__(1); scheme_generate_struct_op(jitter, kind, for_branch, NULL, 1, 0, - 1, 1, -1, -1, 0, + 1, 1, -1, -1, 0, 0, 1, refslow, refslow2, bref5, bref6); CHECK_LIMIT(); diff --git a/racket/src/racket/src/jitinline.c b/racket/src/racket/src/jitinline.c index 53c95b6b0d..58ad2ed549 100644 --- a/racket/src/racket/src/jitinline.c +++ b/racket/src/racket/src/jitinline.c @@ -640,9 +640,22 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, { GC_CAN_IGNORE jit_insn *ref, *ref2, *refslow; Scheme_Object *inline_rator; + int type_unpacked = 0; LOG_IT(("inlined struct op\n")); + if ((kind == INLINE_STRUCT_PROC_PRED) + && SAME_TYPE(SCHEME_TYPE(rator), scheme_static_toplevel_type)) { + /* If a static toplevel has a predicate, then we can extract the + structure type eagerly */ + inline_rator = extract_struct_constant(jitter, rator); + if (inline_rator) { + rator = ((Scheme_Primitive_Closure *)inline_rator)->val[0]; + type_unpacked = 1; + } + } else + inline_rator = NULL; + if (!rand2) { scheme_generate_two_args(rator, rand, jitter, 1, 1); /* sync'd below */ CHECK_LIMIT(); @@ -667,7 +680,8 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, if ((kind == INLINE_STRUCT_PROC_PRED) || (kind == INLINE_STRUCT_PROC_GET) || (kind == INLINE_STRUCT_PROC_SET)) { - inline_rator = extract_struct_constant(jitter, rator); + if (!inline_rator) + inline_rator = extract_struct_constant(jitter, rator); if (inline_rator && (kind != INLINE_STRUCT_PROC_PRED)) { __START_SHORT_JUMPS__(1); ref = jit_bmci_ul(jit_forward(), JIT_R1, 0x1); @@ -794,7 +808,7 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, result_ignored, 0, 0, tpos, pos, - authentic, + authentic, type_unpacked, 0, refslow, refslow, NULL, NULL); CHECK_LIMIT();