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.,
|
from @racket[v1] through one of the chaperone constructors (e.g.,
|
||||||
@racket[chaperone-procedure]).}
|
@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}
|
@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
|
only reachable via weak references, the content of the weak box is
|
||||||
replaced with @racket[#f]. A @defterm{@tech{weak reference}} is a
|
replaced with @racket[#f]. A @defterm{@tech{weak reference}} is a
|
||||||
reference through a weak box, through a key reference in a weak hash
|
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
|
where the value can be replaced by @racket[#f] (see
|
||||||
@secref["ephemerons"]), or through a custodian (see
|
@secref["ephemerons"]), or through a custodian (see
|
||||||
@secref["custodians"]).
|
@secref["custodians"]).
|
||||||
|
@ -56,7 +56,9 @@ are the same.
|
||||||
One particularly common use of ephemerons is to combine them with a
|
One particularly common use of ephemerons is to combine them with a
|
||||||
weak hash table (see @secref["hashtables"]) to produce a mapping where
|
weak hash table (see @secref["hashtables"]) to produce a mapping where
|
||||||
the memory manager can reclaim key--value pairs even when the value
|
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,
|
More precisely,
|
||||||
@itemize[
|
@itemize[
|
||||||
|
|
|
@ -1314,6 +1314,29 @@
|
||||||
o)
|
o)
|
||||||
(test #"(a #0=(a #0#))" get-output-bytes 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)
|
(report-errs)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
Version 5.3.3.4
|
||||||
|
Added impersonator-ephemeron
|
||||||
|
|
||||||
Version 5.3.3.3
|
Version 5.3.3.3
|
||||||
ffi/unsafe: added _size, _ssize, _ptrdiff, _intmax, _uintmax
|
ffi/unsafe: added _size, _ssize, _ptrdiff, _intmax, _uintmax
|
||||||
ffi/vector: added f8vectors
|
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 *make_ephemeron(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *ephemeron_value(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 *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_graph(int argc, Scheme_Object *argv[]);
|
||||||
static Scheme_Object *make_placeholder(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?",
|
"ephemeron?",
|
||||||
1, 1, 1),
|
1, 1, 1),
|
||||||
env);
|
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_add_global_constant("make-reader-graph",
|
||||||
scheme_make_prim_w_arity(make_graph,
|
scheme_make_prim_w_arity(make_graph,
|
||||||
|
@ -3551,6 +3557,19 @@ static Scheme_Object *ephemeronp(int argc, Scheme_Object *argv[])
|
||||||
: scheme_false);
|
: 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
|
#ifndef MZ_PRECISE_GC
|
||||||
|
|
||||||
int scheme_propagate_ephemeron_marks()
|
int scheme_propagate_ephemeron_marks()
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#define USE_COMPILED_STARTUP 1
|
#define USE_COMPILED_STARTUP 1
|
||||||
|
|
||||||
#define EXPECTED_PRIM_COUNT 1086
|
#define EXPECTED_PRIM_COUNT 1087
|
||||||
#define EXPECTED_UNSAFE_COUNT 100
|
#define EXPECTED_UNSAFE_COUNT 100
|
||||||
#define EXPECTED_FLFXNUM_COUNT 69
|
#define EXPECTED_FLFXNUM_COUNT 69
|
||||||
#define EXPECTED_EXTFL_COUNT 45
|
#define EXPECTED_EXTFL_COUNT 45
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
consistently.)
|
consistently.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MZSCHEME_VERSION "5.3.3.3"
|
#define MZSCHEME_VERSION "5.3.3.4"
|
||||||
|
|
||||||
#define MZSCHEME_VERSION_X 5
|
#define MZSCHEME_VERSION_X 5
|
||||||
#define MZSCHEME_VERSION_Y 3
|
#define MZSCHEME_VERSION_Y 3
|
||||||
#define MZSCHEME_VERSION_Z 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_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
|
||||||
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user