mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-12 14:50:19 +02:00
* scheme-memory.texi: Added a short explanation of the GC and the
conservative stack scanning. (scm_gc_protect_object, scm_gc_unprotect_object, scm_permanent_object): New. * data-rep.texi, scheme-memory.texi (scm_remember_upto_here_1, scm_remember_upto_here_2): Moved from data-rep.texi to scheme-memory.texi.
This commit is contained in:
parent
02b0c69289
commit
3446b6ef07
2 changed files with 117 additions and 29 deletions
|
@ -18,7 +18,7 @@
|
||||||
@c essay @ifinfo
|
@c essay @ifinfo
|
||||||
@c essay Data Representation in Guile
|
@c essay Data Representation in Guile
|
||||||
|
|
||||||
@c essay Copyright (C) 1998, 1999, 2000 Free Software Foundation
|
@c essay Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation
|
||||||
|
|
||||||
@c essay Permission is granted to make and distribute verbatim copies of
|
@c essay Permission is granted to make and distribute verbatim copies of
|
||||||
@c essay this manual provided the copyright notice and this permission notice
|
@c essay this manual provided the copyright notice and this permission notice
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
@c essay @sp 10
|
@c essay @sp 10
|
||||||
@c essay @comment The title is printed in a large font.
|
@c essay @comment The title is printed in a large font.
|
||||||
@c essay @title Data Representation in Guile
|
@c essay @title Data Representation in Guile
|
||||||
@c essay @subtitle $Id: data-rep.texi,v 1.14 2003-08-29 23:32:21 kryde Exp $
|
@c essay @subtitle $Id: data-rep.texi,v 1.15 2003-10-06 19:24:15 mvo Exp $
|
||||||
@c essay @subtitle For use with Guile @value{VERSION}
|
@c essay @subtitle For use with Guile @value{VERSION}
|
||||||
@c essay @author Jim Blandy
|
@c essay @author Jim Blandy
|
||||||
@c essay @author Free Software Foundation
|
@c essay @author Free Software Foundation
|
||||||
|
@ -1908,23 +1908,6 @@ It's important that a smob is visible to the garbage collector
|
||||||
whenever its contents are being accessed. Otherwise it could be freed
|
whenever its contents are being accessed. Otherwise it could be freed
|
||||||
while code is still using it.
|
while code is still using it.
|
||||||
|
|
||||||
@c NOTE: The varargs scm_remember_upto_here is deliberately not
|
|
||||||
@c documented, because we don't think it can be implemented as a nice
|
|
||||||
@c inline compiler directive or asm block. New _3, _4 or whatever
|
|
||||||
@c forms could certainly be added though, if needed.
|
|
||||||
|
|
||||||
@deftypefn {C Macro} void scm_remember_upto_here_1 (SCM obj)
|
|
||||||
@deftypefnx {C Macro} void scm_remember_upto_here_2 (SCM obj1, SCM obj2)
|
|
||||||
Create a reference to the given object or objects, so they're certain
|
|
||||||
to be present on the stack or in a register and hence will not be
|
|
||||||
freed by the garbage collector before this point.
|
|
||||||
|
|
||||||
Note that these functions can only be applied to ordinary C local
|
|
||||||
variables (ie.@: ``automatics''). Objects held in global or static
|
|
||||||
variables or some malloced block or the like cannot be protected with
|
|
||||||
this mechanism.
|
|
||||||
@end deftypefn
|
|
||||||
|
|
||||||
For example, consider a procedure to convert image data to a list of
|
For example, consider a procedure to convert image data to a list of
|
||||||
pixel values.
|
pixel values.
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,12 @@ Guile uses a @emph{garbage collector} to manage most of its objects.
|
||||||
This means that the memory used to store a Scheme string, say, is
|
This means that the memory used to store a Scheme string, say, is
|
||||||
automatically reclaimed when no one is using this string any longer.
|
automatically reclaimed when no one is using this string any longer.
|
||||||
This can work because Guile knows enough about its objects at run-time
|
This can work because Guile knows enough about its objects at run-time
|
||||||
to be able to trace all references between them. Thus, it can find
|
to be able to trace all references between them. Thus, it can find all
|
||||||
all 'live' objects (objects that are still in use) by starting from a
|
'live' objects (objects that are still in use) by starting from a known
|
||||||
known set of 'root' objects and following the links that these objects
|
set of 'root' objects and following the links that these objects have to
|
||||||
have to other objects, and so on. The objects that are not reached by
|
other objects, and so on. The objects that are not reached by this
|
||||||
this recursive process can be considered 'dead' and their memory can
|
recursive process can be considered 'dead' and their memory can be
|
||||||
be reused for new objects.
|
reused for new objects.
|
||||||
|
|
||||||
When you are programming in Scheme, you don't need to worry about the
|
|
||||||
garbage collector. When programming in C, there are a few rules that
|
|
||||||
you must follow so that the garbage collector can do its job.
|
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Garbage Collection::
|
* Garbage Collection::
|
||||||
|
@ -28,6 +24,72 @@ you must follow so that the garbage collector can do its job.
|
||||||
@node Garbage Collection
|
@node Garbage Collection
|
||||||
@section Garbage Collection
|
@section Garbage Collection
|
||||||
|
|
||||||
|
The general process of collecting dead objects outlined above relies on
|
||||||
|
the fact that the garbage collector is able to find all references to
|
||||||
|
SCM objects that might be used by the program in the future. When you
|
||||||
|
are programming in Scheme, you don't need to worry about this: The
|
||||||
|
collector is automatically aware of all objects in use by Scheme code.
|
||||||
|
|
||||||
|
When programming in C, you must help the garbage collector a bit so that
|
||||||
|
it can find all objects that are accessible from C. You do this when
|
||||||
|
writing a SMOB mark function, for example. By calling this function,
|
||||||
|
the garbage collector learns about all references that your SMOB has to
|
||||||
|
other SCM objects.
|
||||||
|
|
||||||
|
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 @code{scm_gc_protect} or @code{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 possible 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 the array of characters
|
||||||
|
from a Scheme string and work on that array directly. The reference to
|
||||||
|
the SCM string object might be dead after the character array has been
|
||||||
|
retrieved, but the array itself is still in use and thus the string
|
||||||
|
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 @code{scm_remember_upto_here_1}
|
||||||
|
and its cousins. It will keep the compiler from overwriting the
|
||||||
|
reference. For an example of its use, see @ref{Remembering During
|
||||||
|
Operations}.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} gc
|
@deffn {Scheme Procedure} gc
|
||||||
@deffnx {C Function} scm_gc ()
|
@deffnx {C Function} scm_gc ()
|
||||||
Scans all of SCM objects and reclaims for further use those that are
|
Scans all of SCM objects and reclaims for further use those that are
|
||||||
|
@ -35,6 +97,49 @@ no longer accessible. You normally don't need to call this function
|
||||||
explicitly. It is called automatically when appropriate.
|
explicitly. It is called automatically when appropriate.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deftypefn {C Function} SCM scm_gc_protect_object (SCM @var{obj})
|
||||||
|
Protects @var{obj} from being freed by the garbage collector, when it
|
||||||
|
otherwise might be. When you are done with the object, call
|
||||||
|
@code{scm_gc_unprotect_object} on the object. Calls to
|
||||||
|
@code{scm_gc_protect}/@code{scm_gc_unprotect_object} can be nested, and
|
||||||
|
the object remains protected until it has been unprotected as many times
|
||||||
|
as it was protected. It is an error to unprotect an object more times
|
||||||
|
than it has been protected. Returns the SCM object it was passed.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {C Function} SCM scm_gc_unprotect_object (SCM @var{obj})
|
||||||
|
|
||||||
|
Unprotects an object from the garbage collector which was protected by
|
||||||
|
@code{scm_gc_unprotect_object}. Returns the SCM object it was passed.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {C Function} SCM scm_permanent_object (SCM @var{obj})
|
||||||
|
|
||||||
|
Similar to @code{scm_gc_protect_object} in that it causes the
|
||||||
|
collector to always mark the object, except that it should not be
|
||||||
|
nested (only call @code{scm_permanent_object} on an object once), and
|
||||||
|
it has no corresponding unpermanent function. Once an object is
|
||||||
|
declared permanent, it will never be freed. Returns the SCM object it
|
||||||
|
was passed.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@c NOTE: The varargs scm_remember_upto_here is deliberately not
|
||||||
|
@c documented, because we don't think it can be implemented as a nice
|
||||||
|
@c inline compiler directive or asm block. New _3, _4 or whatever
|
||||||
|
@c forms could certainly be added though, if needed.
|
||||||
|
|
||||||
|
@deftypefn {C Macro} void scm_remember_upto_here_1 (SCM obj)
|
||||||
|
@deftypefnx {C Macro} void scm_remember_upto_here_2 (SCM obj1, SCM obj2)
|
||||||
|
Create a reference to the given object or objects, so they're certain
|
||||||
|
to be present on the stack or in a register and hence will not be
|
||||||
|
freed by the garbage collector before this point.
|
||||||
|
|
||||||
|
Note that these functions can only be applied to ordinary C local
|
||||||
|
variables (ie.@: ``automatics''). Objects held in global or static
|
||||||
|
variables or some malloced block or the like cannot be protected with
|
||||||
|
this mechanism.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} gc-stats
|
@deffn {Scheme Procedure} gc-stats
|
||||||
@deffnx {C Function} scm_gc_stats ()
|
@deffnx {C Function} scm_gc_stats ()
|
||||||
Return an association list of statistics about Guile's current
|
Return an association list of statistics about Guile's current
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue