improve JIT support for property reference with failure value
For a non-procedure failure value, stay in the fast path and return that value.
This commit is contained in:
parent
9092d31c29
commit
8444b70bc1
|
@ -1222,18 +1222,36 @@
|
|||
|
||||
(let ()
|
||||
(define-values (prop:a a? a-ref) (make-struct-type-property 'a))
|
||||
(define (mk-prop)
|
||||
(define-values (prop:b b? b-ref) (make-struct-type-property 'b))
|
||||
prop:b)
|
||||
|
||||
(struct posn (x y)
|
||||
#:property prop:a 'yes)
|
||||
(struct posn2 posn ()
|
||||
#:property (mk-prop) 0
|
||||
#:property (mk-prop) 1
|
||||
#:property (mk-prop) 2
|
||||
#:property (mk-prop) 3
|
||||
#:property (mk-prop) 4
|
||||
#:property (mk-prop) 5)
|
||||
|
||||
(define (f p)
|
||||
(and (a? p)
|
||||
(a-ref p 'no)))
|
||||
(define (g p get-no)
|
||||
(a-ref p get-no))
|
||||
(set! f f)
|
||||
(set! g g)
|
||||
|
||||
(test 'yes f (posn 1 2))
|
||||
(test 'yes f (posn2 1 2))
|
||||
(test 'yes f (chaperone-struct (posn 1 2) posn-x (lambda (p x) x)))
|
||||
(test 'yes f struct:posn)
|
||||
(test #f f 5))
|
||||
(test #f f struct:arity-at-least)
|
||||
(test #f f 5)
|
||||
(test 'nope g 5 (lambda () 'nope))
|
||||
(test 'nope g struct:arity-at-least (lambda () 'nope)))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
|
|
|
@ -2072,7 +2072,7 @@ static int common4b(mz_jit_state *jitter, void *_data)
|
|||
for (i = 0; i < 3; i++) {
|
||||
for (ii = 0; ii < 3; ii++) { /* single, multi, or tail */
|
||||
void *code;
|
||||
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *refno, *refslow, *refloop;
|
||||
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *refno, *refslow, *refloop;
|
||||
int prim_other_type;
|
||||
|
||||
code = jit_get_ip();
|
||||
|
@ -2153,6 +2153,23 @@ static int common4b(mz_jit_state *jitter, void *_data)
|
|||
(void)jit_movi_p(JIT_R0, scheme_false);
|
||||
mz_epilog(JIT_V1);
|
||||
CHECK_LIMIT();
|
||||
} else if (i == 1) {
|
||||
refno = jit_get_ip();
|
||||
jit_ldr_p(JIT_V1, JIT_RUNSTACK);
|
||||
/* If the failure argument is not a procedure, we can
|
||||
return it directly, otherwise take slow path. */
|
||||
jit_ldxi_s(JIT_R2, JIT_V1, &((Scheme_Object *)0x0)->type);
|
||||
__START_INNER_TINY__(1);
|
||||
ref4 = jit_blti_i(jit_forward(), JIT_R2, scheme_prim_type);
|
||||
__END_INNER_TINY__(1);
|
||||
(void)jit_blei_i(refslow, JIT_R2, scheme_proc_chaperone_type);
|
||||
__START_INNER_TINY__(1);
|
||||
mz_patch_branch(ref4);
|
||||
__END_INNER_TINY__(1);
|
||||
jit_movr_p(JIT_R0, JIT_V1);
|
||||
jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
|
||||
mz_epilog(JIT_V1);
|
||||
CHECK_LIMIT();
|
||||
} else
|
||||
refno = refslow;
|
||||
|
||||
|
@ -2170,7 +2187,7 @@ static int common4b(mz_jit_state *jitter, void *_data)
|
|||
__START_INNER_TINY__(1);
|
||||
ref2 = jit_beqi_i(jit_forward(), JIT_R2, scheme_structure_type);
|
||||
__END_INNER_TINY__(1);
|
||||
if (i == 2) {
|
||||
if (i != 0) { /* for i == 0 mode, `refno` is already `refslow` */
|
||||
(void)jit_beqi_i(refslow, JIT_R2, scheme_proc_chaperone_type);
|
||||
(void)jit_beqi_i(refslow, JIT_R2, scheme_chaperone_type);
|
||||
(void)jit_beqi_i(refslow, JIT_R2, scheme_struct_type_type);
|
||||
|
@ -2188,7 +2205,7 @@ static int common4b(mz_jit_state *jitter, void *_data)
|
|||
|
||||
/* negative count means use the hash table (in the slow path);
|
||||
zero count means we've run out */
|
||||
if (i == 2) {
|
||||
if (i != 0) {
|
||||
(void)jit_blei_i(refslow, JIT_V1, 0);
|
||||
}
|
||||
refloop = jit_get_ip();
|
||||
|
|
Loading…
Reference in New Issue
Block a user