From f84006c5644997ce9854df9070ec2f1fb8acd420 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Fri, 24 Jun 2016 08:56:21 +0200 Subject: [PATCH] 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. --- doc/ref/api-memory.texi | 42 ++++++++++++++++++++---------------- doc/ref/libguile-concepts.texi | 48 ++++++++++++++++++++++++++++-------------- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/doc/ref/api-memory.texi b/doc/ref/api-memory.texi index 142eb01..ce0187b 100644 --- a/doc/ref/api-memory.texi +++ b/doc/ref/api-memory.texi @@ -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 diff --git a/doc/ref/libguile-concepts.texi b/doc/ref/libguile-concepts.texi index 9785f4d..e93d987 100644 --- a/doc/ref/libguile-concepts.texi +++ b/doc/ref/libguile-concepts.texi @@ -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 -- 2.8.3