Do the impersonator? check up front.

original commit: 60f3074ccd6b2d399765c3254180afe1bcf2830d
This commit is contained in:
Vincent St-Amour 2011-07-06 16:55:59 -04:00
parent 30792214ae
commit 9e995978e1

View File

@ -14,8 +14,8 @@
(define-syntax-class vector-op
#:commit
;; we need the * versions of these unsafe operations to be chaperone-safe
(pattern (~literal vector-ref) #:with unsafe #'unsafe-vector-ref)
(pattern (~literal vector-set!) #:with unsafe #'unsafe-vector-set!))
(pattern (~literal vector-ref) #:with unsafe #'unsafe-vector-ref #:with unsafe-no-impersonator #'unsafe-vector*-ref)
(pattern (~literal vector-set!) #:with unsafe #'unsafe-vector-set! #:with unsafe-no-impersonator #'unsafe-vector*-set!))
(define-syntax-class known-length-vector-expr
#:commit
@ -64,17 +64,30 @@
(begin (log-optimization "vector" #'op)
#`(op.unsafe v.opt #,((optimize) #'i)
#,@(syntax-map (optimize) #'(new ...)))))
;; we can do the bounds checking separately, to eliminate some of the checks
(pattern (#%plain-app op:vector-op v:expr i:fixnum-expr new:expr ...)
#:with opt
(begin (log-optimization "vector access splitting" this-syntax)
#`(let ([new-i #,((optimize) #'i)]
[new-v #,((optimize) #'v)])
(if #,(let ([one-sided #'(unsafe-fx< new-i (unsafe-vector*-length v))])
(if (subtypeof? #'i -NonNegFixnum)
;; we know it's nonnegative, one-sided check
one-sided
#`(and (unsafe-fx>= new-i 0)
#,one-sided)))
(op.unsafe new-v new-i #,@(syntax-map (optimize) #'(new ...)))
(op new-v new-i #,@(syntax-map (optimize) #'(new ...))))))))
(let ([safe-fallback #`(op new-v new-i #,@(syntax-map (optimize) #'(new ...)))])
#`(let ([new-i #,((optimize) #'i)]
[new-v #,((optimize) #'v)])
;; do the impersonator check up front, to avoid doing it twice (length and op)
(if (impersonator? new-v)
(if #,(let ([one-sided #'(unsafe-fx< new-i (unsafe-vector-length v))])
(if (subtypeof? #'i -NonNegFixnum)
;; we know it's nonnegative, one-sided check
one-sided
#`(and (unsafe-fx>= new-i 0)
#,one-sided)))
(op.unsafe new-v new-i #,@(syntax-map (optimize) #'(new ...)))
#,safe-fallback)
;; not an impersonator, can use unsafe-vector* ops
(if #,(let ([one-sided #'(unsafe-fx< new-i (unsafe-vector*-length v))])
(if (subtypeof? #'i -NonNegFixnum)
;; we know it's nonnegative, one-sided check
one-sided
#`(and (unsafe-fx>= new-i 0)
#,one-sided)))
(op.unsafe-no-impersonator new-v new-i #,@(syntax-map (optimize) #'(new ...)))
#,safe-fallback)))))))