Next: Control Flow, Previous: Dynamic Types, Up: General Libguile Concepts
As explained above, the SCM
type can represent all Scheme values.
Some values fit entirely into a SCM
value (such as small
integers), but other values require additional storage in the heap (such
as strings and vectors). This additional storage is managed
automatically by Guile. You don't need to explicitely deallocate it
when a SCM
value is no longer used.
Two things must be guaranteed so that Guile is able to manage the storage automatically: it must know about all blocks of memory that have ever been allocated for Scheme values, and it must know about all Scheme values that are still being used. Given this knowledge, Guile can periodically free all blocks that have been allocated but are not used by any active Scheme values. This activity is called garbage collection.
It is easy for Guile to remember all blocks of memory that it has allocated for use by Scheme values, but you need to help it with finding all Scheme values that are in use by C code.
You do this when writing a SMOB mark function, for example
(see Garbage Collecting Smobs). By calling this function, the
garbage collector learns about all references that your SMOB has to
other SCM
values.
Other references to SCM
objects, such as global variables of type
SCM
or other random data structures in the heap that contain
fields of type SCM
, can be made visible to the garbage collector
by calling the functions scm_gc_protect
or
scm_permanent_object
. You normally use these funtions for long
lived objects such as a hash table that is stored in a global variable.
For temporary references in local variables or function arguments, using
these functions would be too expensive.
These references are handled differently: Local variables (and function
arguments) of type SCM
are automatically visible to the garbage
collector. This works because the collector scans the stack for
potential references to SCM
objects and considers all referenced
objects to be alive. The scanning considers each and every word of the
stack, regardless of what it is actually used for, and then decides
whether it could possibly be a reference to a SCM
object. Thus,
the scanning is guaranteed to find all actual references, but it might
also find words that only accidentally look like references. These
`false positives' might keep SCM
objects alive that would
otherwise be considered dead. While this might waste memory, keeping an
object around longer than it strictly needs to is harmless. This is why
this technique is called “conservative garbage collection”. In
practice, the wasted memory seems to be no problem.
The stack of every thread is scanned in this way and the registers of the CPU and all other memory locations where local variables or function parameters might show up are included in this scan as well.
The consequence of the conservative scanning is that you can just
declare local variables and function parameters of type SCM
and
be sure that the garbage collector will not free the corresponding
objects.
However, a local variable or function parameter is only protected as
long as it is really on the stack (or in some register). As an
optimization, the C compiler might reuse its location for some other
value and the SCM
object would no longer be protected. Normally,
this leads to exactly the right behabvior: the compiler will only
overwrite a reference when it is no longer needed and thus the object
becomes unprotected precisely when the reference disappears, just as
wanted.
There are situations, however, where a SCM
object needs to be
around longer than its reference from a local variable or function
parameter. This happens, for example, when you retrieve some pointer
from a smob and work with that pointer directly. The reference to the
SCM
smob object might be dead after the pointer has been
retrieved, but the pointer itself (and the memory pointed to) is still
in use and thus the smob object must be protected. The compiler does
not know about this connection and might overwrite the SCM
reference too early.
To get around this problem, you can use scm_remember_upto_here_1
and its cousins. It will keep the compiler from overwriting the
reference. For a typical example of its use, see Remembering During Operations.