cs: use new immobile-object support

Implement 'atomic-interior allocation and immobile cells using
`make-immobile-bytevector` and `make-immobile-vector`, which avoids
having to unlock through a finalizer.

Also, the Chez Scheme GC can now mostly mark a major generation,
instead of copying it, which can significantly reduce memory
use during a GC for an old, large heap (such as DrRacket's).
This commit is contained in:
Matthew Flatt 2020-04-21 14:39:07 -06:00
parent dccd841adf
commit 16ad9ed522
7 changed files with 21 additions and 35 deletions

View File

@ -12,7 +12,7 @@
(define collection 'multi)
(define version "7.7.0.2")
(define version "7.7.0.3")
(define deps `("racket-lib"
["racket" #:version ,version]))

View File

@ -280,23 +280,12 @@ specification is required at minimum:
@item{@indexed-racket['atomic-interior] --- Like
@racket['atomic], but the allocated object will not be moved by
the garbage collector as long as the allocated object is
sufficiently retained as described below.
retained.
For the @3m[] and @CGC[] Racket variants, ``sufficiently retained''
means that the garbage collector does not collect the allocated
object because some pointer (that is visible to the collector)
refers to the object. Furthermore, that reference can point to
the interior of the object, insteda of its starting address.
For the @3m[] and @CGC[] Racket variants, a reference can point
to the interior of the object, instead of its starting address.
This allocation mode corresponds to
@cpp{scheme_malloc_atomic_allow_interior} in the C API.
For the @CS[] Racket variant, ``sufficiently retained'' means that the
specific C pointer object returned by @racket[malloc] remains
accessible. Note that casting the pointer via @racket[cast], for example,
generates a new pointer object which would not by itself
prevent the result of @racket[malloc] from moving, even though
a reference to the same memory could prevent the object from
being reclaimed.}
@cpp{scheme_malloc_atomic_allow_interior} in the C API.}
@item{@indexed-racket['nonatomic-interior] --- Like
@racket['nonatomic], but the allocated object will not be moved

View File

@ -2,7 +2,7 @@
;; Check to make we're using a build of Chez Scheme
;; that has all the features we need.
(define-values (need-maj need-min need-sub need-dev)
(values 9 5 3 26))
(values 9 5 3 27))
(unless (guard (x [else #f]) (eval 'scheme-fork-version-number))
(error 'compile-file

View File

@ -475,7 +475,6 @@
[else
(post-as-asynchronous-callback go)]))))])
(let ([callable (foreign-callable __collect_safe glib-log-message (string int string) void)])
(lock-object callable)
(foreign-callable-entry-point callable))))
;; ----------------------------------------

View File

@ -15,7 +15,7 @@
(if (eq? v #!bwp)
gced-v
v))]
[(e gced-v keep-live)
[(e gced-v keep-live-v)
(let ([v (ephemeron-value e gced-v)])
(#%$keep-live keep-live)
(keep-live keep-live-v)
v)]))

View File

@ -1409,11 +1409,8 @@
;; a finalizer is associated with the cpointer (as opposed to
;; the address that is wrapped by the cpointer). Also, interior
;; pointers are not allowed as GCable pointers.
(let* ([bstr (make-bytevector size 0)]
[p (make-cpointer bstr #f)])
(lock-object bstr)
(unsafe-add-global-finalizer p (lambda () (unlock-object bstr)))
p)]
(let* ([bstr (make-immobile-bytevector size)])
(make-cpointer bstr #f))]
[else
(raise-unsupported-error 'malloc
(format "'~a mode is not supported" mode))]))
@ -1427,13 +1424,18 @@
(parent cpointer)
(fields))
(define immobile-cells (make-eq-hashtable))
(define (malloc-immobile-cell v)
(let ([vec (vector v)])
(lock-object vec)
(let ([vec (make-immobile-vector 1)])
(#%vector-set! vec 0 v)
(with-global-lock
(eq-hashtable-set! immobile-cells vec #t))
(make-cpointer/cell vec #f)))
(define (free-immobile-cell b)
(unlock-object (cpointer-memory b)))
(with-global-lock
(eq-hashtable-delete! immobile-cells (cpointer-memory b))))
(define (immobile-cell-ref b)
(#%vector-ref (cpointer-memory b) 0))
@ -1542,7 +1544,7 @@
;; so uses of the FFI can rely on passing an argument to a foreign
;; function as retaining the argument until the function returns.
(let ([result e])
(#%$keep-live v) ...
(keep-live v) ...
result))
(define call-locks (make-eq-hashtable))
@ -1945,11 +1947,7 @@
(let ([make-code (ffi-call/callable #f in-types out-type abi #f #f #f #f (and atomic? #t) async-apply)])
(lambda (proc)
(check 'make-ffi-callback procedure? proc)
(let* ([code (make-code proc)]
[cb (create-callback code)])
(lock-object code)
(unsafe-add-global-finalizer cb (lambda () (unlock-object code)))
cb)))]))
(create-callback (make-code proc))))]))
;; ----------------------------------------

View File

@ -16,7 +16,7 @@
#define MZSCHEME_VERSION_X 7
#define MZSCHEME_VERSION_Y 7
#define MZSCHEME_VERSION_Z 0
#define MZSCHEME_VERSION_W 2
#define MZSCHEME_VERSION_W 3
/* A level of indirection makes `#` work as needed: */
#define AS_a_STR_HELPER(x) #x