expander: adjust module-path-index cache implementation
Change the implementation to one that is a simpler and slightly more effective.
This commit is contained in:
parent
b7908e97a1
commit
12bc1b3841
|
@ -1,6 +1,7 @@
|
|||
#lang racket/base
|
||||
(require racket/private/place-local
|
||||
ffi/unsafe/atomic
|
||||
racket/fixnum
|
||||
"../compile/serialize-property.rkt"
|
||||
"../common/performance.rkt"
|
||||
"contract.rkt"
|
||||
|
@ -190,6 +191,8 @@
|
|||
(fprintf port "=~a" (module-path-index-resolved r))])
|
||||
(write-string ">" port)))
|
||||
|
||||
(define empty-shift-cache '())
|
||||
|
||||
;; Serialization of a module path index is handled specially, because they
|
||||
;; must be shared across phases of a module
|
||||
(define deserialize-module-path-index
|
||||
|
@ -259,7 +262,7 @@
|
|||
[(and (pair? mod-path) (eq? 'submod (car mod-path)))
|
||||
(loop (cadr mod-path))]
|
||||
[else base])))
|
||||
(module-path-index mod-path keep-base #f #f)]))
|
||||
(module-path-index mod-path keep-base #f empty-shift-cache)]))
|
||||
|
||||
(define (module-path-index-resolve/maybe base load?)
|
||||
(if (module-path-index? base)
|
||||
|
@ -282,7 +285,7 @@
|
|||
|
||||
(define make-self-module-path-index
|
||||
(case-lambda
|
||||
[(name) (module-path-index #f #f name #f)]
|
||||
[(name) (module-path-index #f #f name empty-shift-cache)]
|
||||
[(name enclosing)
|
||||
(make-self-module-path-index (build-module-name name
|
||||
(and enclosing
|
||||
|
@ -310,7 +313,7 @@
|
|||
(begin0
|
||||
(or (let ([e (hash-ref generic-self-mpis r #f)])
|
||||
(and e (ephemeron-value e)))
|
||||
(let ([mpi (module-path-index #f #f r #f)])
|
||||
(let ([mpi (module-path-index #f #f r empty-shift-cache)])
|
||||
(hash-set! generic-self-mpis r (make-ephemeron r mpi))
|
||||
mpi))
|
||||
(end-atomic)))
|
||||
|
@ -346,28 +349,35 @@
|
|||
[(shift-cache-ref (module-path-index-shift-cache shifted-base) mpi)]
|
||||
[else
|
||||
(define shifted-mpi
|
||||
(module-path-index (module-path-index-path mpi) shifted-base #f #f))
|
||||
(shift-cache-set! (module-path-index-shift-cache! shifted-base) mpi shifted-mpi)
|
||||
(module-path-index (module-path-index-path mpi) shifted-base #f empty-shift-cache))
|
||||
(shift-cache-set! shifted-base shifted-mpi)
|
||||
shifted-mpi])])]))
|
||||
|
||||
(define (module-path-index-shift-cache! mpi)
|
||||
(or (let ([cache (module-path-index-shift-cache mpi)])
|
||||
(and cache
|
||||
(weak-box-value cache)
|
||||
cache))
|
||||
(let ([cache (make-weak-box (box #hasheq()))])
|
||||
(set-module-path-index-shift-cache! mpi cache)
|
||||
cache)))
|
||||
(define (shift-cache-ref cache mpi)
|
||||
(for/or ([wb (in-list cache)])
|
||||
(define v (weak-box-value wb))
|
||||
(and v
|
||||
(equal? (module-path-index-path v)
|
||||
(module-path-index-path mpi))
|
||||
v)))
|
||||
|
||||
(define (shift-cache-ref cache v)
|
||||
(and cache
|
||||
(let ([b (weak-box-value cache)])
|
||||
(and b (hash-ref (unbox b) v #f)))))
|
||||
|
||||
(define (shift-cache-set! cache v r)
|
||||
(define b (weak-box-value cache))
|
||||
(when b
|
||||
(set-box! b (hash-set (unbox b) v r))))
|
||||
(define (shift-cache-set! base v)
|
||||
(define new-cache
|
||||
(cons (make-weak-box v)
|
||||
;; Prune empty cache entries, and keep only up to a certain
|
||||
;; number of cached values to avoid quadratic behavior.
|
||||
(let loop ([n 32] [l (module-path-index-shift-cache base)])
|
||||
(cond
|
||||
[(null? l) null]
|
||||
[(eqv? n 0) null]
|
||||
[(not (weak-box-value (car l)))
|
||||
(loop n (cdr l))]
|
||||
[else
|
||||
(let ([r (loop (fx- n 1) (cdr l))])
|
||||
(if (eq? r (cdr l))
|
||||
l
|
||||
(cons (car l) r)))]))))
|
||||
(set-module-path-index-shift-cache! base new-cache))
|
||||
|
||||
;; A constant module path index to represent the top level
|
||||
(define top-level-module-path-index
|
||||
|
|
|
@ -2876,6 +2876,7 @@ static const char *startup_source =
|
|||
" extra-depth_0)"
|
||||
"(unsafe-place-local-set! cell.4$2 extra-depth_0)"
|
||||
"(unsafe-place-local-set! cell.1$10(current-thread)))))))))))))))"
|
||||
" (define-values (not-an-fX.1) (lambda (who_0 v_0) (begin 'not-an-fX (raise-argument-error who_0 \"fixnum?\" v_0))))"
|
||||
"(define-values(prop:serialize serialize? serialize-ref)(make-struct-type-property 'serialize))"
|
||||
"(define-values"
|
||||
"(prop:serialize-fill! serialize-fill!? serialize-fill!-ref)"
|
||||
|
@ -4586,6 +4587,7 @@ static const char *startup_source =
|
|||
"(make-struct-field-accessor -ref_0 3 'shift-cache)"
|
||||
"(make-struct-field-mutator -set!_0 2 'resolved)"
|
||||
"(make-struct-field-mutator -set!_0 3 'shift-cache))))"
|
||||
"(define-values(empty-shift-cache) '())"
|
||||
"(define-values"
|
||||
"(deserialize-module-path-index)"
|
||||
"(case-lambda"
|
||||
|
@ -4738,7 +4740,7 @@ static const char *startup_source =
|
|||
"(let-values() base_0)))))))))"
|
||||
" loop_0)"
|
||||
" mod-path_0)))"
|
||||
"(module-path-index2.1 mod-path_0 keep-base_0 #f #f)))))))))))))))"
|
||||
"(module-path-index2.1 mod-path_0 keep-base_0 #f empty-shift-cache)))))))))))))))"
|
||||
"(case-lambda"
|
||||
"((mod-path_0 base_0)(begin 'module-path-index-join(module-path-index-join_0 mod-path_0 base_0 #f)))"
|
||||
"((mod-path_0 base_0 submod5_0)(module-path-index-join_0 mod-path_0 base_0 submod5_0)))))"
|
||||
|
@ -4776,7 +4778,7 @@ static const char *startup_source =
|
|||
"(define-values"
|
||||
"(make-self-module-path-index)"
|
||||
"(case-lambda"
|
||||
"((name_0)(begin(module-path-index2.1 #f #f name_0 #f)))"
|
||||
"((name_0)(begin(module-path-index2.1 #f #f name_0 empty-shift-cache)))"
|
||||
"((name_0 enclosing_0)"
|
||||
"(make-self-module-path-index"
|
||||
"(let-values(((name19_0) name_0)((temp20_0)(if enclosing_0(1/module-path-index-resolve enclosing_0) #f)))"
|
||||
|
@ -4797,7 +4799,7 @@ static const char *startup_source =
|
|||
"(if e_0(ephemeron-value e_0) #f))))"
|
||||
"(if or-part_0"
|
||||
" or-part_0"
|
||||
"(let-values(((mpi_0)(module-path-index2.1 #f #f r_0 #f)))"
|
||||
"(let-values(((mpi_0)(module-path-index2.1 #f #f r_0 empty-shift-cache)))"
|
||||
"(begin(hash-set!(unsafe-place-local-ref cell.1$8) r_0(make-ephemeron r_0 mpi_0)) mpi_0))))"
|
||||
"(end-atomic)))))))"
|
||||
"(define-values"
|
||||
|
@ -4835,31 +4837,70 @@ static const char *startup_source =
|
|||
" c1_0"
|
||||
"(let-values()"
|
||||
"(let-values(((shifted-mpi_0)"
|
||||
"(module-path-index2.1(module-path-index-path mpi_0) shifted-base_0 #f #f)))"
|
||||
"(begin"
|
||||
"(shift-cache-set!(module-path-index-shift-cache! shifted-base_0) mpi_0 shifted-mpi_0)"
|
||||
" shifted-mpi_0)))))))))))))))"
|
||||
"(define-values"
|
||||
"(module-path-index-shift-cache!)"
|
||||
"(lambda(mpi_0)"
|
||||
"(begin"
|
||||
"(let-values(((or-part_0)"
|
||||
"(let-values(((cache_0)(module-path-index-shift-cache mpi_0)))"
|
||||
"(if cache_0(if(weak-box-value cache_0) cache_0 #f) #f))))"
|
||||
"(if or-part_0"
|
||||
" or-part_0"
|
||||
"(let-values(((cache_0)(make-weak-box(box '#hasheq()))))"
|
||||
"(begin(set-module-path-index-shift-cache! mpi_0 cache_0) cache_0)))))))"
|
||||
"(module-path-index2.1"
|
||||
"(module-path-index-path mpi_0)"
|
||||
" shifted-base_0"
|
||||
" #f"
|
||||
" empty-shift-cache)))"
|
||||
"(begin(shift-cache-set! shifted-base_0 shifted-mpi_0) shifted-mpi_0)))))))))))))))"
|
||||
"(define-values"
|
||||
"(shift-cache-ref)"
|
||||
"(lambda(cache_0 v_0)"
|
||||
"(begin(if cache_0(let-values(((b_0)(weak-box-value cache_0)))(if b_0(hash-ref(unbox b_0) v_0 #f) #f)) #f))))"
|
||||
"(lambda(cache_0 mpi_0)"
|
||||
"(begin"
|
||||
"(let-values(((lst_0) cache_0))"
|
||||
"(begin"
|
||||
"(if(variable-reference-from-unsafe?(#%variable-reference))(void)(let-values()(check-list lst_0)))"
|
||||
"((letrec-values(((for-loop_0)"
|
||||
"(lambda(result_0 lst_1)"
|
||||
"(begin"
|
||||
" 'for-loop"
|
||||
"(if(pair? lst_1)"
|
||||
"(let-values(((wb_0)(unsafe-car lst_1))((rest_0)(unsafe-cdr lst_1)))"
|
||||
"(let-values(((result_1)"
|
||||
"(let-values()"
|
||||
"(let-values(((result_1)"
|
||||
"(let-values()"
|
||||
"(let-values()"
|
||||
"(let-values(((v_0)(weak-box-value wb_0)))"
|
||||
"(if v_0"
|
||||
"(if(equal?"
|
||||
"(module-path-index-path v_0)"
|
||||
"(module-path-index-path mpi_0))"
|
||||
" v_0"
|
||||
" #f)"
|
||||
" #f))))))"
|
||||
"(values result_1)))))"
|
||||
"(if(if(not((lambda x_0 result_1) wb_0))(not #f) #f)"
|
||||
"(for-loop_0 result_1 rest_0)"
|
||||
" result_1)))"
|
||||
" result_0)))))"
|
||||
" for-loop_0)"
|
||||
" #f"
|
||||
" lst_0))))))"
|
||||
"(define-values"
|
||||
"(shift-cache-set!)"
|
||||
"(lambda(cache_0 v_0 r_0)"
|
||||
"(lambda(base_0 v_0)"
|
||||
"(begin"
|
||||
"(let-values(((b_0)(weak-box-value cache_0)))"
|
||||
"(if b_0(let-values()(set-box! b_0(hash-set(unbox b_0) v_0 r_0)))(void))))))"
|
||||
"(let-values(((new-cache_0)"
|
||||
"(cons"
|
||||
"(make-weak-box v_0)"
|
||||
"((letrec-values(((loop_0)"
|
||||
"(lambda(n_0 l_0)"
|
||||
"(begin"
|
||||
" 'loop"
|
||||
"(if(null? l_0)"
|
||||
"(let-values() null)"
|
||||
"(if(eqv? n_0 0)"
|
||||
"(let-values() null)"
|
||||
"(if(not(weak-box-value(car l_0)))"
|
||||
"(let-values()(loop_0 n_0(cdr l_0)))"
|
||||
"(let-values()"
|
||||
"(let-values(((r_0)(loop_0(fx- n_0 1)(cdr l_0))))"
|
||||
"(if(eq? r_0(cdr l_0)) l_0(cons(car l_0) r_0)))))))))))"
|
||||
" loop_0)"
|
||||
" 32"
|
||||
"(module-path-index-shift-cache base_0)))))"
|
||||
"(set-module-path-index-shift-cache! base_0 new-cache_0)))))"
|
||||
"(define-values(top-level-module-path-index)(make-self-module-path-index(1/make-resolved-module-path 'top-level)))"
|
||||
"(define-values(top-level-module-path-index?)(lambda(mpi_0)(begin(eq? top-level-module-path-index mpi_0))))"
|
||||
"(define-values(non-self-module-path-index?)(lambda(mpi_0)(begin(if(module-path-index-path mpi_0) #t #f))))"
|
||||
|
@ -5278,7 +5319,6 @@ static const char *startup_source =
|
|||
"(pop-syntax-context!)"
|
||||
"(lambda(state_0)"
|
||||
"(begin(let-values(((b_0)(serialize-state-syntax-context state_0)))(set-box! b_0(cdr(unbox b_0)))))))"
|
||||
" (define-values (not-an-fX.1) (lambda (who_0 v_0) (begin 'not-an-fX (raise-argument-error who_0 \"fixnum?\" v_0))))"
|
||||
"(define-values(root-tag)(unsafe-root-continuation-prompt-tag))"
|
||||
"(define-values(default-val.1$2) #f)"
|
||||
"(define-values"
|
||||
|
|
Loading…
Reference in New Issue
Block a user