Scheme 48 uses a copying, precise garbage collector.
Any procedure that allocates objects within the Scheme 48 heap may trigger
a garbage collection.
Variables bound to values in the Scheme 48 heap need to be registered with
the garbage collector so that the value will be retained and so that the
variables will be updated if the garbage collector moves the object.
The garbage collector has no facility for updating pointers to the interiors
of objects, so such pointers, for example the ones returned by
EXTRACT_STRING
, will likely become invalid when a garbage collection
occurs.
A set of macros are used to manage the registration of local variables with the garbage collector.
S48_DECLARE_GC_PROTECT(n)
void S48_GC_PROTECT_n(s48_value1, ..., s48_valuen)
void S48_GC_UNPROTECT()
S48_DECLARE_GC_PROTECT(n)
, where 1 <= n <= 9, allocates
storage for registering n variables.
At most one use of S48_DECLARE_GC_PROTECT
may occur in a
block.
S48_GC_PROTECT_n(v1, ..., vn)
registers the
n variables (l-values) with the garbage collector.
It must be within scope of a S48_DECLARE_GC_PROTECT(n)
and be before any code which can cause a GC.
S48_GC_UNPROTECT
removes the block's protected variables from
the garbage collector's list.
It must be called at the end of the block after
any code which may cause a garbage collection.
Omitting any of the three may cause serious and
hard-to-debug problems.
Notably, the garbage collector may relocate an object and
invalidate s48_value
variables which are not protected.
A gc-protection-mismatch
exception is raised if, when a C
procedure returns to Scheme, the calls
to S48_GC_PROTECT()
have not been matched by an equal number of
calls to S48_GC_UNPROTECT()
.
Global variables may also be registered with the garbage collector.
void S48_GC_PROTECT_GLOBAL(value
)
S48_GC_PROTECT_GLOBAL
permanently registers the
variable value
(an l-value) with the garbage collector.
There is no way to unregister the variable.
C data structures can be kept in the Scheme heap by embedding them inside byte vectors. The following macros can be used to create and access embedded C objects.
s48_value S48_MAKE_VALUE(type) | (may GC) |
type S48_EXTRACT_VALUE(s48_value, type)
type * S48_EXTRACT_VALUE_POINTER(s48_value, type)
void S48_SET_VALUE(s48_value, type, value)
S48_MAKE_VALUE
makes a byte vector large enough to hold an object
whose type is type
.
S48_EXTRACT_VALUE
returns the contents of a byte vector cast to
type
, and S48_EXTRACT_VALUE_POINTER
returns a pointer
to the contents of the byte vector.
The value returned by S48_EXTRACT_VALUE_POINTER
is valid only until
the next garbage collection.
S48_SET_VALUE
stores value
into the byte vector.
Scheme 48 uses dumped heap images to restore a previous system state. The Scheme 48 heap is written into a file in a machine-independent and operating-system-independent format. The procedures described above may be used to create objects in the Scheme heap that contain information specific to the current machine, operating system, or process. A heap image containing such objects may not work correctly when resumed.
To address this problem, a record type may be given a `resumer' procedure. On startup, the resumer procedure for a type is applied to each record of that type in the image being restarted. This procedure can update the record in a manner appropriate to the machine, operating system, or process used to resume the image.
Define-record-resumer
defines procedure
,
which should accept one argument, to be the resumer for
record-type.
The order in which resumer procedures are called is not specified.
The procedure
argument to define-record-resumer
may
be #f
, in which case records of the given type are
not written out in heap images.
When writing a heap image any reference to such a record is replaced by
the value of the record's first field, and an exception is raised
after the image is written.
Previous: Calling Scheme functions from C | Next: Using Scheme records in C code