mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
Clarify use of the term "scanning" in the manual
* doc/ref/api-memory.texi (Garbage Collection Functions): * doc/ref/libguile-concepts.texi (Garbage Collection): Attempt to be clear that scanning is a thing that happens in the mark phase. Fixes #20907 I think.
This commit is contained in:
parent
f23dfc0fb5
commit
f84006c564
2 changed files with 56 additions and 34 deletions
|
@ -27,9 +27,10 @@ collection relates to using Guile from C.
|
|||
|
||||
@deffn {Scheme Procedure} gc
|
||||
@deffnx {C Function} scm_gc ()
|
||||
Scans all of SCM objects and reclaims for further use those that are
|
||||
no longer accessible. You normally don't need to call this function
|
||||
explicitly. It is called automatically when appropriate.
|
||||
Finds all of the ``live'' @code{SCM} objects and reclaims for further
|
||||
use those that are no longer accessible. You normally don't need to
|
||||
call this function explicitly. Its functionality is invoked
|
||||
automatically as needed.
|
||||
@end deffn
|
||||
|
||||
@deftypefn {C Function} SCM scm_gc_protect_object (SCM @var{obj})
|
||||
|
@ -43,8 +44,9 @@ than it has been protected. Returns the SCM object it was passed.
|
|||
|
||||
Note that storing @var{obj} in a C global variable has the same
|
||||
effect@footnote{In Guile up to version 1.8, C global variables were not
|
||||
scanned by the garbage collector; hence, @code{scm_gc_protect_object}
|
||||
was the only way in C to prevent a Scheme object from being freed.}.
|
||||
visited by the garbage collector in the mark phase; hence,
|
||||
@code{scm_gc_protect_object} was the only way in C to prevent a Scheme
|
||||
object from being freed.}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {C Function} SCM scm_gc_unprotect_object (SCM @var{obj})
|
||||
|
@ -123,16 +125,18 @@ live reference to it@footnote{In Guile up to version 1.8, memory
|
|||
allocated with @code{scm_gc_malloc} @emph{had} to be freed with
|
||||
@code{scm_gc_free}.}.
|
||||
|
||||
Memory allocated with @code{scm_gc_malloc} is scanned for live pointers.
|
||||
This means that if @code{scm_gc_malloc}-allocated memory contains a
|
||||
pointer to some other part of the memory, the garbage collector notices
|
||||
it and prevents it from being reclaimed@footnote{In Guile up to 1.8,
|
||||
memory allocated with @code{scm_gc_malloc} was @emph{not} scanned.
|
||||
Consequently, the GC had to be told explicitly about pointers to live
|
||||
objects contained in the memory block, e.g., @i{via} SMOB mark functions
|
||||
(@pxref{Smobs, @code{scm_set_smob_mark}})}. Conversely, memory
|
||||
allocated with @code{scm_gc_malloc_pointerless} is assumed to be
|
||||
``pointer-less'' and is not scanned.
|
||||
When garbage collection occurs, Guile will visit the words in memory
|
||||
allocated with @code{scm_gc_malloc}, looking for live pointers. This
|
||||
means that if @code{scm_gc_malloc}-allocated memory contains a pointer
|
||||
to some other part of the memory, the garbage collector notices it and
|
||||
prevents it from being reclaimed@footnote{In Guile up to 1.8, memory
|
||||
allocated with @code{scm_gc_malloc} was @emph{not} visited by the
|
||||
collector in the mark phase. Consequently, the GC had to be told
|
||||
explicitly about pointers to live objects contained in the memory block,
|
||||
e.g., @i{via} SMOB mark functions (@pxref{Smobs,
|
||||
@code{scm_set_smob_mark}})}. Conversely, memory allocated with
|
||||
@code{scm_gc_malloc_pointerless} is assumed to be ``pointer-less'' and
|
||||
is not scanned for pointers.
|
||||
|
||||
For memory that is not associated with a Scheme object, you can use
|
||||
@code{scm_malloc} instead of @code{malloc}. Like
|
||||
|
@ -193,9 +197,11 @@ Allocate @var{size} bytes of automatically-managed memory. The memory
|
|||
is automatically freed when no longer referenced from any live memory
|
||||
block.
|
||||
|
||||
Memory allocated with @code{scm_gc_malloc} or @code{scm_gc_calloc} is
|
||||
scanned for pointers. Memory allocated by
|
||||
@code{scm_gc_malloc_pointerless} is not scanned.
|
||||
When garbage collection occurs, Guile will visit the words in memory
|
||||
allocated with @code{scm_gc_malloc} or @code{scm_gc_calloc}, looking for
|
||||
pointers to other memory allocations that are managed by the GC. In
|
||||
contrast, memory allocated by @code{scm_gc_malloc_pointerless} is not
|
||||
scanned for pointers.
|
||||
|
||||
The @code{scm_gc_realloc} call preserves the ``pointerlessness'' of the
|
||||
memory area pointed to by @var{mem}. Note that you need to pass the old
|
||||
|
|
|
@ -203,22 +203,38 @@ set'' of garbage collection; any value on the heap that is referenced
|
|||
directly or indirectly by a member of the root set is preserved, and all
|
||||
other objects are eligible for reclamation.
|
||||
|
||||
The Scheme stack and heap are scanned precisely; that is to say, Guile
|
||||
knows about all inter-object pointers on the Scheme stack and heap.
|
||||
This is not the case, unfortunately, for pointers on the C stack and
|
||||
static data segment. For this reason we have to scan the C stack and
|
||||
static data segment @dfn{conservatively}; any value that looks like a
|
||||
pointer to a GC-managed object is treated as such, whether it actually
|
||||
is a reference or not. Thus, scanning the C stack and static data
|
||||
segment is guaranteed to find all actual references, but it might also
|
||||
find words that only accidentally look like references. These ``false
|
||||
positives'' might keep @code{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, as the static C root set is
|
||||
almost always finite and small, given that the Scheme stack is separate
|
||||
from the C stack.
|
||||
In Guile, garbage collection has two logical phases: the @dfn{mark
|
||||
phase}, in which the collector discovers the set of all live objects,
|
||||
and the @dfn{sweep phase}, in which the collector reclaims the resources
|
||||
associated with dead objects. The mark phase pauses the program and
|
||||
traces all @code{SCM} object references, starting with the root set.
|
||||
The sweep phase actually runs concurrently with the main program,
|
||||
incrementally reclaiming memory as needed by allocation.
|
||||
|
||||
In the mark phase, the garbage collector traces the Scheme stack and
|
||||
heap @dfn{precisely}. Because the Scheme stack and heap are managed by
|
||||
Guile, Guile can know precisely where in those data structures it might
|
||||
find references to other heap objects. This is not the case,
|
||||
unfortunately, for pointers on the C stack and static data segment.
|
||||
Instead of requiring the user to inform Guile about all variables in C
|
||||
that might point to heap objects, Guile traces the C stack and static
|
||||
data segment @dfn{conservatively}. That is to say, Guile just treats
|
||||
every word on the C stack and every C global variable as a potential
|
||||
reference in to the Scheme heap@footnote{Note that Guile does not scan
|
||||
the C heap for references, so a reference to a @code{SCM} object from a
|
||||
memory segment allocated with @code{malloc} will have to use some other
|
||||
means to keep the @code{SCM} object alive. @xref{Garbage Collection
|
||||
Functions}.}. Any value that looks like a pointer to a GC-managed
|
||||
object is treated as such, whether it actually is a reference or not.
|
||||
Thus, scanning the C stack and static data segment is guaranteed to find
|
||||
all actual references, but it might also find words that only
|
||||
accidentally look like references. These ``false positives'' might keep
|
||||
@code{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, as the static C root set is almost always finite
|
||||
and small, given that the Scheme stack is separate from the C stack.
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue