Do the impersonator? check up front.
original commit: 60f3074ccd6b2d399765c3254180afe1bcf2830d
This commit is contained in:
parent
30792214ae
commit
9e995978e1
|
@ -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)))))))
|
||||
|
|
Loading…
Reference in New Issue
Block a user