C:/Users/Dennis/src/lang/russell.orig/src/gc/gc.h

Go to the documentation of this file.
00001 /* 
00002  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
00003  * Copyright (c) 1991 by Xerox Corporation.  All rights reserved.
00004  *
00005  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00006  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00007  *
00008  * Permission is hereby granted to copy this garbage collector for any purpose,
00009  * provided the above notices are retained on all copies.
00010  */
00011  
00012 #ifndef GC_H
00013 
00014 # define GC_H
00015 
00016 # include <stddef.h>
00017 
00018 /* Define word and signed_word to be unsigned and signed types of the   */
00019 /* size as char * or void *.  There seems to be no way to do this       */
00020 /* even semi-portably.  The following is probably no better/worse       */
00021 /* than almost anything else.                                           */
00022 /* The ANSI standard suggests that size_t and ptr_diff_t might be       */
00023 /* better choices.  But those appear to have incorrect definitions      */
00024 /* on may systems.  Notably "typedef int size_t" seems to be both       */
00025 /* frequent and WRONG.                                                  */
00026 typedef unsigned long word;
00027 typedef long signed_word;
00028 
00029 /* Public read-only variables */
00030 
00031 extern word GC_heapsize;       /* Heap size in bytes */
00032 
00033 extern word GC_gc_no;   /* Counter incremented per collection.          */
00034                         /* Includes empty GCs at startup.               */
00035 
00036 /* Public R/W variables */
00037 
00038 extern int GC_dont_gc;  /* Dont collect unless explicitly requested, e.g. */
00039                         /* beacuse it's not safe.                         */
00040 
00041 extern int GC_dont_expand;
00042                         /* Dont expand heap unless explicitly requested */
00043                         /* or forced to.                                */
00044                         
00045 extern word GC_non_gc_bytes;
00046                         /* Bytes not considered candidates for collection. */
00047                         /* Used only to control scheduling of collections. */
00048 
00049 extern word GC_free_space_divisor;
00050                         /* We try to make sure that we allocate at      */
00051                         /* least N/GC_free_space_divisor bytes between  */
00052                         /* collections, where N is the heap size plus   */
00053                         /* a rough estimate of the root set size.       */
00054                         /* Initially, GC_free_space_divisor = 4.        */
00055                         /* Increasing its value will use less space     */
00056                         /* but more collection time.  Decreasing it     */
00057                         /* will appreciably decrease collection time    */
00058                         /* at the expens of space.                      */
00059                         /* GC_free_space_divisor = 1 will effectively   */
00060                         /* disable collections.                         */
00061                         
00062 /* Public procedures */
00063 /*
00064  * general purpose allocation routines, with roughly malloc calling conv.
00065  * The atomic versions promise that no relevant pointers are contained
00066  * in the object.  The nonatomic version guarantees that the new object
00067  * is cleared.
00068  */
00069 # ifdef __STDC__
00070   extern void * GC_malloc(size_t size_in_bytes);
00071   extern void * GC_malloc_atomic(size_t size_in_bytes);
00072 # else
00073   extern char * GC_malloc(/* size_in_bytes */);
00074   extern char * GC_malloc_atomic(/* size_in_bytes */);
00075 # endif
00076 
00077 /* Explicitly deallocate an object.  Dangerous if used incorrectly.     */
00078 /* Requires a pointer to the base of an object.                         */
00079 # ifdef __STDC__
00080   extern void GC_free(void * object_addr);
00081 # else
00082   extern void GC_free(/* object_addr */);
00083 # endif
00084 
00085 /* Return a pointer to the base (lowest address) of an object given     */
00086 /* a pointer to a location within the object.                           */
00087 /* Return 0 if displaced_pointer doesn't point to within a valid        */
00088 /* object.                                                              */
00089 # ifdef __STDC__
00090   void * GC_base(void * displaced_pointer);
00091 # else
00092   char * GC_base(/* char * displaced_pointer */);
00093 # endif
00094 
00095 /* Given a pointer to the base of an object, return its size in bytes.  */
00096 /* The returned size may be slightly larger than what was originally    */
00097 /* requested.                                                           */
00098 # ifdef __STDC__
00099   size_t GC_size(void * object_addr);
00100 # else
00101   size_t GC_size(/* char * object_addr */);
00102 # endif
00103 
00104 /* For compatibility with C library.  This is occasionally faster than  */
00105 /* a malloc followed by a bcopy.  But if you rely on that, either here  */
00106 /* or with the standard C library, your code is broken.  In my          */
00107 /* opinion, it shouldn't have been invented, but now we're stuck. -HB   */
00108 # ifdef __STDC__
00109     extern void * GC_realloc(void * old_object, size_t new_size_in_bytes);
00110 # else
00111     extern char * GC_realloc(/* old_object, new_size_in_bytes */);
00112 # endif
00113 
00114 
00115 /* Explicitly increase the heap size.   */
00116 /* Returns 0 on failure, 1 on success.  */
00117 extern int GC_expand_hp(/* number_of_4K_blocks */);
00118 
00119 /* Clear the set of root segments */
00120 extern void GC_clear_roots();
00121 
00122 /* Add a root segment */
00123 extern void GC_add_roots(/* low_address, high_address_plus_1 */);
00124 
00125 /* Add a displacement to the set of those considered valid by the       */
00126 /* collector.  GC_register_displacement(n) means that if p was returned */
00127 /* by GC_malloc, then (char *)p + n will be considered to be a valid    */
00128 /* pointer to n.  N must be small and less than the size of p.          */
00129 /* (All pointers to the interior of objects from the stack are          */
00130 /* considered valid in any case.  This applies to heap objects and      */
00131 /* static data.)                                                        */
00132 /* Preferably, this should be called before any other GC procedures.    */
00133 /* Calling it later adds to the probability of excess memory            */
00134 /* retention.                                                           */
00135 void GC_register_displacement(/* n */);
00136 
00137 /* Explicitly trigger a collection.     */
00138 void GC_gcollect();
00139 
00140 /* Debugging (annotated) allocation.  GC_gcollect will check            */
00141 /* objects allocated in this way for overwrites, etc.                   */
00142 # ifdef __STDC__
00143   extern void * GC_debug_malloc(size_t size_in_bytes,
00144                                 char * descr_string, int descr_int);
00145   extern void * GC_debug_malloc_atomic(size_t size_in_bytes,
00146                                        char * descr_string, int descr_int);
00147   extern void GC_debug_free(void * object_addr);
00148   extern void * GC_debug_realloc(void * old_object,
00149                                  size_t new_size_in_bytes,
00150                                  char * descr_string, int descr_int);
00151 # else
00152   extern char * GC_debug_malloc(/* size_in_bytes, descr_string, descr_int */);
00153   extern char * GC_debug_malloc_atomic(/* size_in_bytes, descr_string,
00154                                           descr_int */);
00155   extern void GC_debug_free(/* object_addr */);
00156   extern char * GC_debug_realloc(/* old_object, new_size_in_bytes,
00157                                     descr_string, descr_int */);
00158 # endif
00159 # ifdef GC_DEBUG
00160 #   define GC_MALLOC(sz) GC_debug_malloc(sz, __FILE__, __LINE__)
00161 #   define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, __FILE__, __LINE__)
00162 #   define GC_REALLOC(old, sz) GC_debug_realloc(old, sz, __FILE__, \
00163                                                                __LINE__)
00164 #   define GC_FREE(p) GC_debug_free(p)
00165 #   define GC_REGISTER_FINALIZER(p, f, d, of, od) \
00166         GC_register_finalizer(GC_base(p), GC_debug_invoke_finalizer, \
00167                               GC_make_closure(f,d), of, od)
00168 # else
00169 #   define GC_MALLOC(sz) GC_malloc(sz)
00170 #   define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
00171 #   define GC_REALLOC(old, sz) GC_realloc(old, sz)
00172 #   define GC_FREE(p) GC_free(p)
00173 #   define GC_REGISTER_FINALIZER(p, f, d, of, od) \
00174         GC_register_finalizer(p, f, d, of, od)
00175 # endif
00176 
00177 /* Finalization.  Some of these primitives are grossly unsafe.          */
00178 /* The idea is to make them both cheap, and sufficient to build         */
00179 /* a safer layer, closer to PCedar finalization.                        */
00180 /* The interface represents my conclusions from a long discussion       */
00181 /* with Alan Demers, Dan Greene, Carl Hauser, Barry Hayes,              */
00182 /* Christian Jacobi, and Russ Atkinson.  It's not perfect, and          */
00183 /* probably nobody else agrees with it.     Hans-J. Boehm  3/13/92      */
00184 # ifdef __STDC__
00185   typedef void (*GC_finalization_proc)(void * obj, void * client_data);
00186 # else
00187   typedef void (*GC_finalization_proc)(/* void * obj, void * client_data */);
00188 # endif
00189         
00190 void GC_register_finalizer(/* void * obj,
00191                               GC_finalization_proc fn, void * cd,
00192                               GC_finalization_proc *ofn, void ** ocd */);
00193         /* When obj is no longer accessible, invoke             */
00194         /* (*fn)(obj, cd).  If a and b are inaccessible, and    */
00195         /* a points to b (after disappearing links have been    */
00196         /* made to disappear), then only a will be              */
00197         /* finalized.  (If this does not create any new         */
00198         /* pointers to b, then b will be finalized after the    */
00199         /* next collection.)  Any finalizable object that       */
00200         /* is reachable from itself by following one or more    */
00201         /* pointers will not be finalized (or collected).       */
00202         /* Thus cycles involving finalizable objects should     */
00203         /* be avoided, or broken by disappearing links.         */
00204         /* fn is invoked with the allocation lock held.  It may */
00205         /* not allocate.  (Any storage it might need            */
00206         /* should be preallocated and passed as part of cd.)    */
00207         /* fn should terminate as quickly as possible, and      */
00208         /* defer extended computation.                          */
00209         /* All but the last finalizer registered for an object  */
00210         /* is ignored.                                          */
00211         /* Finalization may be removed by passing 0 as fn.      */
00212         /* The old finalizer and client data are stored in      */
00213         /* *ofn and *ocd.                                       */ 
00214         /* Fn is never invoked on an accessible object,         */
00215         /* provided hidden pointers are converted to real       */
00216         /* pointers only if the allocation lock is held, and    */
00217         /* such conversions are not performed by finalization   */
00218         /* routines.                                            */
00219 
00220 /* The following routine may be used to break cycles between    */
00221 /* finalizable objects, thus causing cyclic finalizable         */
00222 /* objects to be finalized in the cirrect order.  Standard      */
00223 /* use involves calling GC_register_disappearing_link(&p),      */
00224 /* where p is a pointer that is not followed by finalization    */
00225 /* code, and should not be considered in determining            */
00226 /* finalization order.                                          */ 
00227 int GC_register_disappearing_link(/* void ** link */);
00228         /* Link should point to a field of a heap allocated     */
00229         /* object obj.  *link will be cleared when obj is       */
00230         /* found to be inaccessible.  This happens BEFORE any   */
00231         /* finalization code is invoked, and BEFORE any         */
00232         /* decisions about finalization order are made.         */
00233         /* This is useful in telling the finalizer that         */
00234         /* some pointers are not essential for proper           */
00235         /* finalization.  This may avoid finalization cycles.   */
00236         /* Note that obj may be resurrected by another          */
00237         /* finalizer, and thus the clearing of *link may        */
00238         /* be visible to non-finalization code.                 */
00239         /* There's an argument that an arbitrary action should  */
00240         /* be allowed here, instead of just clearing a pointer. */
00241         /* But this causes problems if that action alters, or   */
00242         /* examines connectivity.                               */
00243         /* Returns 1 if link was already registered, 0          */
00244         /* otherise.                                            */
00245 int GC_unregister_disappearing_link(/* void ** link */);
00246         /* Returns 0 if link was not actually registered.       */
00247 
00248 /* Auxiliary fns to make finalization work correctly with displaced     */
00249 /* pointers introduced by the debugging allocators.                     */
00250 # ifdef __STDC__
00251     void * GC_make_closure(GC_finalization_proc fn, void * data);
00252     void GC_debug_invoke_finalizer(void * obj, void * data);
00253 # else
00254     char * GC_make_closure(/* GC_finalization_proc fn, char * data */);
00255     void GC_debug_invoke_finalizer(/* void * obj, void * data */);
00256 # endif
00257 
00258         
00259 /* The following is intended to be used by a higher level       */
00260 /* (e.g. cedar-like) finalization facility.  It is expected     */
00261 /* that finalization code will arrange for hidden pointers to   */
00262 /* disappear.  Otherwise objects can be accessed after they     */
00263 /* have been collected.                                         */
00264 # ifdef I_HIDE_POINTERS
00265 #   ifdef __STDC__
00266 #     define HIDE_POINTER(p) (~(size_t)(p))
00267 #     define REVEAL_POINTER(p) ((void *)(HIDE_POINTER(p)))
00268 #   else
00269 #     define HIDE_POINTER(p) (~(unsigned long)(p))
00270 #     define REVEAL_POINTER(p) ((char *)(HIDE_POINTER(p)))
00271 #   endif
00272     /* Converting a hidden pointer to a real pointer requires verifying */
00273     /* that the object still exists.  This involves acquiring the       */
00274     /* allocator lock to avoid a race with the collector.               */
00275     typedef char * (*GC_fn_type)();
00276 #   ifdef __STDC__
00277         void * GC_call_with_alloc_lock(GC_fn_type fn, void * client_data);
00278 #   else
00279         char * GC_call_with_alloc_lock(/* GC_fn_type fn, char * client_data */);
00280 #   endif
00281 # endif
00282 
00283 #endif

Generated on Fri Jan 25 10:39:45 2008 for russell by  doxygen 1.5.4