From 9092d31c29d567335b2ff2f6186e6d9bdf46b1b6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 22 Dec 2017 17:40:13 -0700 Subject: [PATCH] JIT: fix property predicate & selector handling Commit 89512eda had accientally disabled the JIT's fast path for structure-type property predicates and selectors. Re-enable it, but but repair a problem with the way that impersonator-property operations are handled by the same code. --- .../tests/racket/chaperone.rktl | 23 +++++++++++++++++++ .../racket-test-core/tests/racket/struct.rktl | 19 +++++++++++++++ racket/src/racket/src/jitcommon.c | 13 +++++++---- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/chaperone.rktl b/pkgs/racket-test-core/tests/racket/chaperone.rktl index f18cd8f702..978c930cec 100644 --- a/pkgs/racket-test-core/tests/racket/chaperone.rktl +++ b/pkgs/racket-test-core/tests/racket/chaperone.rktl @@ -3310,6 +3310,29 @@ s-y (lambda (s v) (collect-garbage 'minor) v) s-z (lambda (s v) (collect-garbage 'minor) v)))) + +;; ---------------------------------------- +;; Make sure that a JIT-inlined predicate is sensitive to `prop:impersonator-of` + +(let () + (define-values (p:a a? a-ref) (make-impersonator-property 'a)) + + (struct posn (x y) + #:property prop:impersonator-of + (lambda (p) (posn-y p))) + + (define p + (impersonate-struct (posn 1 #f) struct:posn + p:a 17)) + + (define (f p) + (a? p)) + (set! f f) + + (test #t f p) + (test #t f (posn 0 p)) + (test #f f (posn 0 #f))) + ;; ---------------------------------------- (report-errs) diff --git a/pkgs/racket-test-core/tests/racket/struct.rktl b/pkgs/racket-test-core/tests/racket/struct.rktl index e1f88482f9..3714b380ed 100644 --- a/pkgs/racket-test-core/tests/racket/struct.rktl +++ b/pkgs/racket-test-core/tests/racket/struct.rktl @@ -1216,6 +1216,25 @@ (-set! v 3 'ok) (test 'ok -ref v 3)) +;; ---------------------------------------- +;; Make sure that a JIT-inlined predicate doesn't +;; fail improperly on chaperones and struct types + +(let () + (define-values (prop:a a? a-ref) (make-struct-type-property 'a)) + + (struct posn (x y) + #:property prop:a 'yes) + + (define (f p) + (and (a? p) + (a-ref p 'no))) + (set! f f) + + (test 'yes f (posn 1 2)) + (test 'yes f struct:posn) + (test #f f 5)) + ;; ---------------------------------------- (report-errs) diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 0d15cd7ed8..912f01e75a 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -2164,8 +2164,6 @@ static int common4b(mz_jit_state *jitter, void *_data) (void)jit_bnei_i(refslow, JIT_R2, prim_other_type); CHECK_LIMIT(); - (void)jit_jmpi(refslow); - /* Check argument: */ (void)jit_bmsi_ul(refno, JIT_R1, 0x1); jit_ldxi_s(JIT_R2, JIT_R1, &((Scheme_Object *)0x0)->type); @@ -2208,9 +2206,16 @@ static int common4b(mz_jit_state *jitter, void *_data) /* target struct-type property in V1 */ jit_ldxi_p(JIT_V1, JIT_R0, &((Scheme_Primitive_Closure *)0x0)->val); - + ref3 = jit_beqr_p(jit_forward(), JIT_R2, JIT_V1); - + + /* If we're looking for an impersonator property, then we're + looking in the wrong place. But it's not ok to fail, because + we may need to go through a `prop:impersonator-of` mapping to + succeed. So, bail out for an impersonator-property operation, + since there was at least one property here. */ + (void)mz_beqi_t(refslow, JIT_V1, scheme_chaperone_property_type, JIT_R2); + mz_get_local_p(JIT_V1, JIT_LOCAL3); (void)jit_jmpi(refloop);