racket/base: add `impersonator-ephemeron'
This commit is contained in:
parent
d46411d317
commit
79c4af4e45
|
@ -110,6 +110,16 @@ Otherwise, all chaperones of @racket[v2] must be intact in
|
|||
from @racket[v1] through one of the chaperone constructors (e.g.,
|
||||
@racket[chaperone-procedure]).}
|
||||
|
||||
@defproc[(impersonator-ephemeron [v any/c]) ephemeron?]{
|
||||
|
||||
Produces an @tech{ephemeron} that can be used to connect the
|
||||
reachability of @racket[v] (in the sense of garbage collection; see
|
||||
@secref["gc-model"]) with the reachability of any value for which
|
||||
@racket[v] is an @tech{impersonator}. That is, the value @racket[v]
|
||||
will be considered reachable as long as the result ephemeron is
|
||||
reachable in addition to any value that @racket[v] impersonates
|
||||
(including itself).}
|
||||
|
||||
@; ------------------------------------------------------------
|
||||
@section{Impersonator Constructors}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ A @deftech{weak box} is similar to a normal box (see
|
|||
only reachable via weak references, the content of the weak box is
|
||||
replaced with @racket[#f]. A @defterm{@tech{weak reference}} is a
|
||||
reference through a weak box, through a key reference in a weak hash
|
||||
table (see @secref["hashtables"]), through a value in an ephemeron
|
||||
table (see @secref["hashtables"]), through a value in an @tech{ephemeron}
|
||||
where the value can be replaced by @racket[#f] (see
|
||||
@secref["ephemerons"]), or through a custodian (see
|
||||
@secref["custodians"]).
|
||||
|
@ -56,7 +56,9 @@ are the same.
|
|||
One particularly common use of ephemerons is to combine them with a
|
||||
weak hash table (see @secref["hashtables"]) to produce a mapping where
|
||||
the memory manager can reclaim key--value pairs even when the value
|
||||
refers to the key.
|
||||
refers to the key. A related use is to retain a reference to a value
|
||||
as long as any value for which it is an @tech{impersonator} is
|
||||
reachable; see @racket[impersonator-ephemeron].
|
||||
|
||||
More precisely,
|
||||
@itemize[
|
||||
|
|
|
@ -1314,6 +1314,29 @@
|
|||
o)
|
||||
(test #"(a #0=(a #0#))" get-output-bytes o)))
|
||||
|
||||
;; ----------------------------------------
|
||||
;; Impersonators and ephemerons:
|
||||
|
||||
(let ()
|
||||
(define stuff
|
||||
(for/list ([n 100])
|
||||
(define v (vector n))
|
||||
(define c (chaperone-vector v
|
||||
(lambda (b i v) v)
|
||||
(lambda (b i v) v)))
|
||||
(define e (impersonator-ephemeron c))
|
||||
(test c ephemeron-value e)
|
||||
;; hold on to every other vector:
|
||||
(cons e (if (even? n) v #f))))
|
||||
(collect-garbage)
|
||||
(define n (for/fold ([n 0]) ([p stuff])
|
||||
(+ n
|
||||
;; add 1 if should-retained != is-retained
|
||||
(if (ephemeron-value (car p))
|
||||
(if (vector? (cdr p)) 0 1)
|
||||
(if (vector? (cdr p)) 1 0)))))
|
||||
(test #t < n 50))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(report-errs)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
Version 5.3.3.4
|
||||
Added impersonator-ephemeron
|
||||
|
||||
Version 5.3.3.3
|
||||
ffi/unsafe: added _size, _ssize, _ptrdiff, _intmax, _uintmax
|
||||
ffi/vector: added f8vectors
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -145,6 +145,7 @@ static Scheme_Object *weak_boxp(int argc, Scheme_Object *argv[]);
|
|||
static Scheme_Object *make_ephemeron(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *ephemeron_value(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *ephemeronp(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *impersonator_ephemeron(int argc, Scheme_Object *argv[]);
|
||||
|
||||
static Scheme_Object *make_graph(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *make_placeholder(int argc, Scheme_Object *argv[]);
|
||||
|
@ -693,6 +694,11 @@ scheme_init_list (Scheme_Env *env)
|
|||
"ephemeron?",
|
||||
1, 1, 1),
|
||||
env);
|
||||
scheme_add_global_constant("impersonator-ephemeron",
|
||||
scheme_make_immed_prim(impersonator_ephemeron,
|
||||
"impersonator-ephemeron",
|
||||
1, 1),
|
||||
env);
|
||||
|
||||
scheme_add_global_constant("make-reader-graph",
|
||||
scheme_make_prim_w_arity(make_graph,
|
||||
|
@ -3551,6 +3557,19 @@ static Scheme_Object *ephemeronp(int argc, Scheme_Object *argv[])
|
|||
: scheme_false);
|
||||
}
|
||||
|
||||
static Scheme_Object *impersonator_ephemeron(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
Scheme_Object *obj = argv[0];
|
||||
|
||||
if (SCHEME_CHAPERONEP(obj)) {
|
||||
return scheme_make_ephemeron(SCHEME_CHAPERONE_VAL(obj), obj);
|
||||
} else {
|
||||
/* This is a useless ephemeron, but we create one for consistency
|
||||
with the case that we have an impersonator: */
|
||||
return scheme_make_ephemeron(obj, obj);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef MZ_PRECISE_GC
|
||||
|
||||
int scheme_propagate_ephemeron_marks()
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#define USE_COMPILED_STARTUP 1
|
||||
|
||||
#define EXPECTED_PRIM_COUNT 1086
|
||||
#define EXPECTED_PRIM_COUNT 1087
|
||||
#define EXPECTED_UNSAFE_COUNT 100
|
||||
#define EXPECTED_FLFXNUM_COUNT 69
|
||||
#define EXPECTED_EXTFL_COUNT 45
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
consistently.)
|
||||
*/
|
||||
|
||||
#define MZSCHEME_VERSION "5.3.3.3"
|
||||
#define MZSCHEME_VERSION "5.3.3.4"
|
||||
|
||||
#define MZSCHEME_VERSION_X 5
|
||||
#define MZSCHEME_VERSION_Y 3
|
||||
#define MZSCHEME_VERSION_Z 3
|
||||
#define MZSCHEME_VERSION_W 3
|
||||
#define MZSCHEME_VERSION_W 4
|
||||
|
||||
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||
|
|
Loading…
Reference in New Issue
Block a user