1
Fork 0
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:
Andy Wingo 2016-06-24 08:56:21 +02:00
parent f23dfc0fb5
commit f84006c564
2 changed files with 56 additions and 34 deletions

View file

@ -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

View file

@ -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