smalltalk: per-call-site inline cache + 10 IC tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
This commit is contained in:
@@ -212,6 +212,23 @@
|
||||
exprs)
|
||||
result))))
|
||||
|
||||
;; Per-call-site monomorphic inline cache: each `send` AST node stores
|
||||
;; the receiver class and method record from the last dispatch. When the
|
||||
;; next dispatch sees the same class AND the runtime's IC generation
|
||||
;; hasn't changed, we skip the global method-lookup. Mutations to the
|
||||
;; class table bump `st-ic-generation` (defined in runtime.sx) so stale
|
||||
;; method records can't fire.
|
||||
(define st-ic-hits 0)
|
||||
(define st-ic-misses 0)
|
||||
|
||||
(define
|
||||
st-ic-reset-stats!
|
||||
(fn () (begin (set! st-ic-hits 0) (set! st-ic-misses 0))))
|
||||
|
||||
(define
|
||||
st-ic-stats
|
||||
(fn () {:hits st-ic-hits :misses st-ic-misses :gen st-ic-generation}))
|
||||
|
||||
(define
|
||||
st-eval-send
|
||||
(fn
|
||||
@@ -223,7 +240,35 @@
|
||||
(cond
|
||||
(super?
|
||||
(st-super-send (get frame :self) selector args (get frame :method-class)))
|
||||
(else (st-send receiver selector args))))))
|
||||
(else
|
||||
(let ((cls (st-class-of-for-send receiver)))
|
||||
(cond
|
||||
;; Inline-cache hit: same receiver class, same generation.
|
||||
((and (has-key? ast :ic-class)
|
||||
(= (get ast :ic-class) cls)
|
||||
(has-key? ast :ic-gen)
|
||||
(= (get ast :ic-gen) st-ic-generation)
|
||||
(has-key? ast :ic-method))
|
||||
(begin
|
||||
(set! st-ic-hits (+ st-ic-hits 1))
|
||||
(st-invoke (get ast :ic-method) receiver args)))
|
||||
(else
|
||||
(begin
|
||||
(set! st-ic-misses (+ st-ic-misses 1))
|
||||
(let
|
||||
((class-side? (st-class-ref? receiver))
|
||||
(recv-class (if (st-class-ref? receiver)
|
||||
(get receiver :name)
|
||||
cls)))
|
||||
(let ((method (st-method-lookup recv-class selector class-side?)))
|
||||
(cond
|
||||
((not (= method nil))
|
||||
(begin
|
||||
(dict-set! ast :ic-class cls)
|
||||
(dict-set! ast :ic-method method)
|
||||
(dict-set! ast :ic-gen st-ic-generation)
|
||||
(st-invoke method receiver args)))
|
||||
(else (st-send receiver selector args))))))))))))))
|
||||
|
||||
(define
|
||||
st-eval-cascade
|
||||
|
||||
Reference in New Issue
Block a user