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

Go to the documentation of this file.
00001 # define SILENT
00002 /* 
00003  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
00004  * Copyright (c) 1991, 1992 by Xerox Corporation.  All rights reserved.
00005  *
00006  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00007  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00008  *
00009  * Permission is hereby granted to copy this garbage collector for any purpose,
00010  * provided the above notices are retained on all copies.
00011  */
00012  
00013 
00014 # ifndef GC_PRIVATE_H
00015 # define GC_PRIVATE_H
00016 
00017 # ifndef GC_H
00018 #   include "gc.h"
00019 # endif
00020 
00021 # ifndef CONFIG_H
00022 #   include "config.h"
00023 # endif
00024 
00025 # ifndef HEADERS_H
00026 #   include "gc_headers.h"
00027 # endif
00028 
00029 # ifndef bool
00030     typedef int bool;
00031 # endif
00032 # define TRUE 1
00033 # define FALSE 0
00034 
00035 typedef char * ptr_t;   /* A generic pointer to which we can add        */
00036                         /* byte displacments.                           */
00037                         
00038 #ifdef __STDC__
00039 #   if !(defined( sony_news ) )
00040 #       include <stddef.h>
00041 #   endif
00042     typedef void * extern_ptr_t;
00043 #else
00044     typedef char * extern_ptr_t;
00045 #endif
00046 
00047 # ifndef OS2
00048 #   include <sys/types.h>
00049 # endif
00050 
00051 /*********************************/
00052 /*                               */
00053 /* Definitions for conservative  */
00054 /* collector                     */
00055 /*                               */
00056 /*********************************/
00057 
00058 /*********************************/
00059 /*                               */
00060 /* Easily changeable parameters  */
00061 /*                               */
00062 /*********************************/
00063 
00064 
00065 #define ALL_INTERIOR_POINTERS
00066                     /* Forces all pointers into the interior of an      */
00067                     /* object to be considered valid.  Also causes the  */
00068                     /* sizes of all objects to be inflated by at least  */
00069                     /* one byte.  This should suffice to guarantee      */
00070                     /* that in the presence of a compiler that does     */
00071                     /* not perform garbage-collector-unsafe             */
00072                     /* optimizations, all portable, strictly ANSI       */
00073                     /* conforming C programs should be safely usable    */
00074                     /* with malloc replaced by GC_malloc and free       */
00075                     /* calls removed.  There are several disadvantages: */
00076                     /* 1. There are probably no interesting, portable,  */
00077                     /*    strictly ANSI conforming C programs.          */
00078                     /* 2. This option makes it hard for the collector   */
00079                     /*    to allocate space that is not ``pointed to''  */
00080                     /*    by integers, etc.  Under SunOS 4.X with a     */
00081                     /*    statically linked libc, we empiricaly         */
00082                     /*    observed that it would be difficult to        */
00083                     /*    allocate individual objects larger than 100K. */
00084                     /*    Even if only smaller objects are allocated,   */
00085                     /*    more swap space is likely to be needed.       */
00086                     /*    Fortunately, much of this will never be       */
00087                     /*    touched.                                      */
00088                     /* If you can easily avoid using this option, do.   */
00089                     /* If not, try to keep individual objects small.    */
00090 #undef ALL_INTERIOR_POINTERS
00091                     
00092 #define PRINTSTATS  /* Print garbage collection statistics              */
00093                     /* For less verbose output, undefine in reclaim.c   */
00094 
00095 #define PRINTTIMES  /* Print the amount of time consumed by each garbage   */
00096                     /* collection.                                         */
00097 
00098 #define PRINTBLOCKS /* Print object sizes associated with heap blocks,     */
00099                     /* whether the objects are atomic or composite, and    */
00100                     /* whether or not the block was found to be empty      */
00101                     /* duing the reclaim phase.  Typically generates       */
00102                     /* about one screenful per garbage collection.         */
00103 #undef PRINTBLOCKS
00104 
00105 #define PRINTBLACKLIST  /* Print black listed blocks, i.e. values that     */
00106                         /* cause the allocator to avoid allocating certain */
00107                         /* blocks in order to avoid introducing "false     */
00108                         /* hits".                                          */
00109 #undef PRINTBLACKLIST
00110 
00111 #ifdef SILENT
00112 #  ifdef PRINTSTATS
00113 #    undef PRINTSTATS
00114 #  endif
00115 #  ifdef PRINTTIMES
00116 #    undef PRINTTIMES
00117 #  endif
00118 #  ifdef PRINTNBLOCKS
00119 #    undef PRINTNBLOCKS
00120 #  endif
00121 #endif
00122 
00123 #if defined(PRINTSTATS) && !defined(GATHERSTATS)
00124 #   define GATHERSTATS
00125 #endif
00126 
00127 
00128 #ifdef SPARC
00129 #   define ALIGN_DOUBLE  /* Align objects of size > 1 word on 2 word   */
00130                          /* boundaries.  Wasteful of memory, but       */
00131                          /* apparently required by SPARC architecture. */
00132 #endif
00133 
00134 #if defined(SPARC) || defined(M68K) && defined(SUNOS)
00135 # if !defined(PCR)
00136 #   define DYNAMIC_LOADING /* Search dynamic libraries for roots.       */
00137 # else
00138     /* PCR handles any dynamic loading whether with dlopen or otherwise */
00139 # endif
00140 #endif
00141 
00142 #define MERGE_SIZES /* Round up some object sizes, so that fewer distinct */
00143                     /* free lists are actually maintained.  This applies  */
00144                     /* only to the top level routines in misc.c, not to   */
00145                     /* user generated code that calls GC_allocobj and     */
00146                     /* GC_allocaobj directly.                             */
00147                     /* Slows down average programs slightly.  May however */
00148                     /* substantially reduce fragmentation if allocation   */
00149                     /* request sizes are widely scattered.                */
00150                     /* May save significant amounts of space for obj_map  */
00151                     /* entries.                                           */
00152 
00153 /* ALIGN_DOUBLE requires MERGE_SIZES at present. */
00154 # if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES)
00155 #   define MERGE_SIZES
00156 # endif
00157 
00158 
00159 # define HINCR 16          /* Initial heap increment, in blocks of 4K        */
00160 # define MAXHINCR 512      /* Maximum heap increment, in blocks              */
00161 # define HINCR_MULT 3      /* After each new allocation, GC_hincr is multiplied */
00162 # define HINCR_DIV 2       /* by HINCR_MULT/HINCR_DIV                        */
00163 # define GC_MULT 3         /* Don't collect if the fraction of   */
00164                            /* non-collectable memory in the heap */
00165                            /* exceeds GC_MUL/GC_DIV              */
00166 # define GC_DIV  4
00167 
00168 # define NON_GC_HINCR ((word)8)
00169                            /* Heap increment if most of heap if collection */
00170                            /* was suppressed because most of heap is not   */
00171                            /* collectable                                  */
00172 
00173 /*********************************/
00174 /*                               */
00175 /* OS interface routines         */
00176 /*                               */
00177 /*********************************/
00178 
00179 #include <time.h>
00180 #if !defined(CLOCKS_PER_SEC)
00181 #   define CLOCKS_PER_SEC 1000000
00182 /*
00183  * This is technically a bug in the implementation.  ANSI requires that
00184  * CLOCKS_PER_SEC be defined.  But at least under SunOS4.1.1, it isn't.
00185  * Also note that the combination of ANSI C and POSIX is incredibly gross
00186  * here. The type clock_t is used by both clock() and times().  But on
00187  * some machines thes use different notions of a clock tick,  CLOCKS_PER_SEC
00188  * seems to apply only to clock.  Hence we use it here.  On many machines,
00189  * including SunOS, clock actually uses units of microseconds (which are
00190  * not really clock ticks).
00191  */
00192 #endif
00193 #define CLOCK_TYPE clock_t
00194 #define GET_TIME(x) x = clock()
00195 #define MS_TIME_DIFF(a,b) ((unsigned long) \
00196                 (1000.0*(double)((a)-(b))/(double)CLOCKS_PER_SEC))
00197 
00198 /* We use bzero and bcopy internally.  They may not be available.       */
00199 # if defined(SPARC) && defined(SUNOS4)
00200 #   define BCOPY_EXISTS
00201 # endif
00202 # if defined(M68K) && defined(SUNOS)
00203 #   define BCOPY_EXISTS
00204 # endif
00205 # if defined(VAX)
00206 #   define BCOPY_EXISTS
00207 # endif
00208 
00209 # ifndef BCOPY_EXISTS
00210 #   include <string.h>
00211 #   define bcopy(x,y,n) memcpy(y,x,n)
00212 #   define bzero(x,n)  memset(x, 0, n)
00213 # endif
00214 
00215 /* HBLKSIZE aligned allocation.  0 is taken to mean failure     */
00216 /* space is assumed to be cleared.                              */
00217 # ifdef PCR
00218     char * real_malloc();
00219 #   define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + HBLKSIZE) \
00220                                   + HBLKSIZE-1)
00221 #   define THREADS
00222 # else
00223 #   ifdef OS2
00224       void * os2_alloc(size_t bytes);
00225 #     define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes + HBLKSIZE) \
00226                                     + HBLKSIZE-1)
00227 #   else
00228       caddr_t sbrk();
00229 #     ifdef __STDC__
00230 #       define GET_MEM(bytes) HBLKPTR(sbrk((size_t)(bytes + HBLKSIZE)) \
00231                                     + HBLKSIZE-1)
00232 #     else
00233 #       define GET_MEM(bytes) HBLKPTR(sbrk((int)(bytes + HBLKSIZE)) \
00234                                       + HBLKSIZE-1)
00235 #     endif
00236 #   endif
00237 # endif
00238 
00239 /*
00240  * Mutual exclusion between allocator/collector routines.
00241  * Needed if there is more than one allocator thread.
00242  * FASTLOCK() is assumed to try to acquire the lock in a cheap and
00243  * dirty way that is acceptable for a few instructions, e.g. by
00244  * inhibiting preemption.  This is assumed to have succeeded only
00245  * if a subsequent call to FASTLOCK_SUCCEEDED() returns TRUE.
00246  * If signals cannot be tolerated with the FASTLOCK held, then
00247  * FASTLOCK should disable signals.  The code executed under
00248  * FASTLOCK is otherwise immune to interruption, provided it is
00249  * not restarted.
00250  * DCL_LOCK_STATE declares any local variables needed by LOCK and UNLOCK
00251  * and/or DISABLE_SIGNALS and ENABLE_SIGNALS and/or FASTLOCK.
00252  * (There is currently no equivalent for FASTLOCK.)
00253  */  
00254 # ifdef PCR
00255 #    include  "pcr/th/PCR_Th.h"
00256 #    include  "pcr/th/PCR_ThCrSec.h"
00257      extern struct PCR_Th_MLRep GC_allocate_ml;
00258 #    define DCL_LOCK_STATE  PCR_sigset_t GC_old_sig_mask
00259 #    define LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml) 
00260 #    define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml)
00261 #    define FASTLOCK() PCR_ThCrSec_EnterSys()
00262      /* Here we cheat (a lot): */
00263 #        define FASTLOCK_SUCCEEDED() (*(int *)(&GC_allocate_ml) == 0)
00264                 /* TRUE if nobody currently holds the lock */
00265 #    define FASTUNLOCK() PCR_ThCrSec_ExitSys()
00266 # else
00267 #    define DCL_LOCK_STATE
00268 #    define LOCK()
00269 #    define UNLOCK()
00270 #    define FASTLOCK() LOCK()
00271 #    define FASTLOCK_SUCCEEDED() TRUE
00272 #    define FASTUNLOCK() UNLOCK()
00273 # endif
00274 
00275 /* Delay any interrupts or signals that may abort this thread.  Data    */
00276 /* structures are in a consistent state outside this pair of calls.     */
00277 /* ANSI C allows both to be empty (though the standard isn't very       */
00278 /* clear on that point).  Standard malloc implementations are usually   */
00279 /* neither interruptable nor thread-safe, and thus correspond to        */
00280 /* empty definitions.                                                   */
00281 # ifdef PCR
00282 #   define DISABLE_SIGNALS() \
00283                  PCR_Th_SetSigMask(PCR_allSigsBlocked,&GC_old_sig_mask)
00284 #   define ENABLE_SIGNALS() \
00285                 PCR_Th_SetSigMask(&GC_old_sig_mask, NIL)
00286 # else
00287 #   if 0        /* Useful for debugging, and unusually          */
00288                 /* correct client code.                         */
00289 #     define DISABLE_SIGNALS()
00290 #     define ENABLE_SIGNALS()
00291 #   else
00292 #     define DISABLE_SIGNALS() GC_disable_signals()
00293         void GC_disable_signals();
00294 #     define ENABLE_SIGNALS() GC_enable_signals()
00295         void GC_enable_signals();
00296 #   endif
00297 # endif
00298 
00299 /*
00300  * Stop and restart mutator threads.
00301  */
00302 # ifdef PCR
00303 #     include "pcr/th/PCR_ThCtl.h"
00304 #     define STOP_WORLD() \
00305         PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_stopNormal, \
00306                                    PCR_allSigsBlocked, \
00307                                    PCR_waitForever)
00308 #     define START_WORLD() \
00309         PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_null, \
00310                                    PCR_allSigsBlocked, \
00311                                    PCR_waitForever);
00312 # else
00313 #     define STOP_WORLD()
00314 #     define START_WORLD()
00315 # endif
00316 
00317 /* Abandon ship */
00318 # ifdef PCR
00319     void PCR_Base_Panic(const char *fmt, ...);
00320 #   define ABORT(s) PCR_Base_Panic(s)
00321 # else
00322 #   define ABORT(s) abort(s)
00323 # endif
00324 
00325 /* Exit abnormally, but without making a mess (e.g. out of memory) */
00326 # ifdef PCR
00327     void PCR_Base_Exit(int status);
00328 #   define EXIT() PCR_Base_Exit(1)
00329 # else
00330 #   define EXIT() (void)exit(1)
00331 # endif
00332 
00333 /* Print warning message, e.g. almost out of memory.    */
00334 # define WARN(s) GC_printf0(s)
00335 
00336 /*********************************/
00337 /*                               */
00338 /* Word-size-dependent defines   */
00339 /*                               */
00340 /*********************************/
00341 
00342 #if CPP_WORDSZ == 32
00343 #  define WORDS_TO_BYTES(x)   ((x)<<2)
00344 #  define BYTES_TO_WORDS(x)   ((x)>>2)
00345 #  define LOGWL               ((word)5)    /* log[2] of CPP_WORDSZ */
00346 #  define modWORDSZ(n) ((n) & 0x1f)          /* n mod size of word          */
00347 #endif
00348 
00349 #if CPP_WORDSZ == 64
00350 #  define WORDS_TO_BYTES(x)   ((x)<<3)
00351 #  define BYTES_TO_WORDS(x)   ((x)>>3)
00352 #  define LOGWL               ((word)6)    /* log[2] of CPP_WORDSZ */
00353 #  define modWORDSZ(n) ((n) & 0x3f)          /* n mod size of word          */
00354 #endif
00355 
00356 #define WORDSZ ((word)CPP_WORDSZ)
00357 #define SIGNB  ((word)1 << (WORDSZ-1))
00358 #define BYTES_PER_WORD      ((word)(sizeof (word)))
00359 #define ONES                ((word)(-1))
00360 #define divWORDSZ(n) ((n) >> LOGWL)        /* divide n by size of word      */
00361 
00362 /*********************/
00363 /*                   */
00364 /*  Size Parameters  */
00365 /*                   */
00366 /*********************/
00367 
00368 /*  heap block size, bytes. Should be power of 2 */
00369 
00370 #define CPP_LOG_HBLKSIZE 12
00371 #define LOG_HBLKSIZE   ((word)CPP_LOG_HBLKSIZE)
00372 #define CPP_HBLKSIZE (1 << CPP_LOG_HBLKSIZE)
00373 #define HBLKSIZE ((word)CPP_HBLKSIZE)
00374 
00375 
00376 /*  max size objects supported by freelist (larger objects may be   */
00377 /*  allocated, but less efficiently)                                */
00378 
00379 #define CPP_MAXOBJSZ    BYTES_TO_WORDS(CPP_HBLKSIZE/2)
00380 #define MAXOBJSZ ((word)CPP_MAXOBJSZ)
00381                 
00382 # define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE)
00383  
00384 # define modHBLKSZ(n) ((n) & (HBLKSIZE-1))
00385  
00386 # define HBLKPTR(objptr) ((struct hblk *)(((word) (objptr)) & ~(HBLKSIZE-1)))
00387 
00388 # define HBLKDISPL(objptr) (((word) (objptr)) & (HBLKSIZE-1))
00389 
00390 
00391 /********************************************/
00392 /*                                          */
00393 /*    H e a p   B l o c k s                 */
00394 /*                                          */
00395 /********************************************/
00396 
00397 /*  heap block header */
00398 #define HBLKMASK   (HBLKSIZE-1)
00399 
00400 #define BITS_PER_HBLK (HBLKSIZE * 8)
00401 
00402 #define MARK_BITS_PER_HBLK (BITS_PER_HBLK/CPP_WORDSZ)
00403            /* upper bound                                    */
00404            /* We allocate 1 bit/word.  Only the first word   */
00405            /* in each object is actually marked.             */
00406 
00407 # ifdef ALIGN_DOUBLE
00408 #   define MARK_BITS_SZ (((MARK_BITS_PER_HBLK + 2*CPP_WORDSZ - 1) \
00409                           / (2*CPP_WORDSZ))*2)
00410 # else
00411 #   define MARK_BITS_SZ ((MARK_BITS_PER_HBLK + CPP_WORDSZ - 1)/CPP_WORDSZ)
00412 # endif
00413            /* Upper bound on number of mark words per heap block  */
00414            
00415 /* Mark stack entries. */
00416 typedef struct ms_entry {
00417     word * mse_start;  /* inclusive */
00418     word * mse_end;     /* exclusive */
00419 } mse;
00420 
00421 typedef mse * (*mark_proc)(/* word * addr, hdr * hhdr, mse * msp, mse * msl */);
00422           /* Procedure to arrange for the descendents of the object at  */
00423           /* addr to be marked.  Msp points at the top entry on the     */
00424           /* mark stack.  Msl delimits the hot end of the mark stack.   */
00425           /* hhdr is the hdr structure corresponding to addr.           */
00426           /* Returns the new mark stack pointer.                        */
00427 
00428 struct hblkhdr {
00429     word hb_sz;  /* If in use, size in words, of objects in the block. */
00430                  /* if free, the size in bytes of the whole block      */
00431     struct hblk * hb_next;      /* Link field for hblk free list         */
00432                                 /* and for lists of chunks waiting to be */
00433                                 /* reclaimed.                            */
00434     mark_proc hb_mark_proc;   /* Procedure to mark objects.  Can         */
00435                                 /* also be retrived through obj_kind.    */
00436                                 /* But one level of indirection matters  */
00437                                 /* here.                                 */
00438     char* hb_map;       /* A pointer to a pointer validity map of the block. */
00439                         /* See GC_obj_map.                                   */
00440                         /* Valid for all blocks with headers.                */
00441                         /* Free blocks point to GC_invalid_map.              */
00442     int hb_obj_kind;   /* Kind of objects in the block.  Each kind      */
00443                         /* identifies a mark procedure and a set of     */
00444                         /* list headers.  sometimes called regions.     */
00445         
00446     word hb_marks[MARK_BITS_SZ];
00447                             /* Bit i in the array refers to the             */
00448                             /* object starting at the ith word (header      */
00449                             /* INCLUDED) in the heap block.                 */
00450 };
00451 
00452 /*  heap block body */
00453 
00454 # define DISCARD_WORDS 0
00455         /* Number of words to be dropped at the beginning of each block */
00456         /* Must be a multiple of 32.  May reasonably be nonzero         */
00457         /* on mcachines that don't guarantee longword alignment of      */
00458         /* pointers, so that the number of false hits is minimized.     */
00459         /* 0 and 32 are probably the only reasonable values.            */
00460 
00461 # define BODY_SZ ((HBLKSIZE-WORDS_TO_BYTES(DISCARD_WORDS))/sizeof(word))
00462 
00463 struct hblk {
00464 #   if (DISCARD_WORDS != 0)
00465         word garbage[DISCARD_WORDS];
00466 #   endif
00467     word hb_body[BODY_SZ];
00468 };
00469 
00470 # define HDR_WORDS ((word)DISCARD_WORDS)
00471 # define HDR_BYTES ((word)WORDS_TO_BYTES(DISCARD_WORDS))
00472 
00473 /* Object free list link */
00474 # define obj_link(p) (*(ptr_t *)(p))
00475 
00476 /*  lists of all heap blocks and free lists     */
00477 /* These are grouped together in a struct       */
00478 /* so that they can be easily skipped by the    */
00479 /* GC_mark routine.                             */
00480 /* The ordering is weird to make GC_malloc      */
00481 /* faster by keeping the important fields       */
00482 /* sufficiently close together that a           */
00483 /* single load of a base register will do.      */
00484 /* Scalars that could easily appear to          */
00485 /* be pointers are also put here.               */
00486 
00487 struct _GC_arrays {
00488   word _heapsize;
00489   ptr_t _last_heap_addr;
00490   ptr_t _prev_heap_addr;
00491   word _words_allocd_before_gc;
00492                 /* Number of words allocated before this        */
00493                 /* collection cycle.                            */
00494 # ifdef GATHERSTATS
00495     word _composite_in_use;
00496                 /* Number of words in accessible composite      */
00497                 /* objects.                                     */
00498     word _atomic_in_use;
00499                 /* Number of words in accessible atomic         */
00500                 /* objects.                                     */
00501 # endif
00502   word _words_allocd;
00503         /* Number of words allocated during this collection cycle */
00504   word _non_gc_bytes_at_gc;
00505         /* Number of explicitly managed bytes of storage        */
00506         /* at last collection.                                  */
00507   word _mem_freed;
00508         /* Number of explicitly deallocated words of memory     */
00509         /* since last collection.                               */
00510         
00511   ptr_t _objfreelist[MAXOBJSZ+1];
00512                           /* free list for objects */
00513 # ifdef MERGE_SIZES
00514     unsigned _size_map[WORDS_TO_BYTES(MAXOBJSZ+1)];
00515         /* Number of words to allocate for a given allocation request in */
00516         /* bytes.                                                        */
00517 # endif 
00518   ptr_t _aobjfreelist[MAXOBJSZ+1];
00519                           /* free list for atomic objs*/
00520   ptr_t _obj_map[MAXOBJSZ+1];
00521                        /* If not NIL, then a pointer to a map of valid  */
00522                        /* object addresses. hbh_map[sz][i] is j if the  */
00523                        /* address block_start+i is a valid pointer      */
00524                        /* to an object at                               */
00525                        /* block_start+i&~3 - WORDS_TO_BYTES(j).         */
00526                        /* (If ALL_INTERIOR_POINTERS is defined, then    */
00527                        /* instead ((short *)(hbh_map[sz])[i] is j if    */
00528                        /* block_start+WORDS_TO_BYTES(i) is in the       */
00529                        /* interior of an object starting at             */
00530                        /* block_start+WORDS_TO_BYTES(i-j)).             */
00531                        /* It is OBJ_INVALID if                          */
00532                        /* block_start+WORDS_TO_BYTES(i) is not          */
00533                        /* valid as a pointer to an object.              */
00534                        /* We assume that all values of j <= OBJ_INVALID */
00535                        /* The zeroth entry corresponds to large objects.*/
00536 #   ifdef ALL_INTERIOR_POINTERS
00537 #       define map_entry_type short
00538 #       define OBJ_INVALID 0x7fff
00539 #       define MAP_ENTRY(map, bytes) \
00540                 (((map_entry_type *)(map))[BYTES_TO_WORDS(bytes)])
00541 #       define MAP_ENTRIES BYTES_TO_WORDS(HBLKSIZE)
00542 #       define MAP_SIZE (MAP_ENTRIES * sizeof(map_entry_type))
00543 #       define OFFSET_VALID(displ) TRUE
00544 #       define CPP_MAX_OFFSET (HBLKSIZE - HDR_BYTES - 1)
00545 #       define MAX_OFFSET ((word)CPP_MAX_OFFSET)
00546 #   else
00547 #       define map_entry_type char
00548 #       define OBJ_INVALID 0x7f
00549 #       define MAP_ENTRY(map, bytes) \
00550                 (map)[bytes]
00551 #       define MAP_ENTRIES HBLKSIZE
00552 #       define MAP_SIZE MAP_ENTRIES
00553 #       define CPP_MAX_OFFSET (WORDS_TO_BYTES(OBJ_INVALID) - 1) 
00554 #       define MAX_OFFSET ((word)CPP_MAX_OFFSET)
00555 #       define VALID_OFFSET_SZ \
00556           (CPP_MAX_OFFSET > WORDS_TO_BYTES(CPP_MAXOBJSZ)? \
00557            CPP_MAX_OFFSET+1 \
00558            : WORDS_TO_BYTES(CPP_MAXOBJSZ)+1)
00559         char _valid_offsets[VALID_OFFSET_SZ];
00560                                 /* GC_valid_offsets[i] == TRUE ==> i    */
00561                                 /* is registered as a displacement.     */
00562 #       define OFFSET_VALID(displ) GC_valid_offsets[displ]
00563         char _modws_valid_offsets[sizeof(word)];
00564                                 /* GC_valid_offsets[i] ==>                */
00565                                 /* GC_modws_valid_offsets[i%sizeof(word)] */
00566 #   endif
00567   struct hblk * _reclaim_list[MAXOBJSZ+1];
00568   struct hblk * _areclaim_list[MAXOBJSZ+1];
00569 };
00570 
00571 extern struct _GC_arrays GC_arrays; 
00572 
00573 # define GC_objfreelist GC_arrays._objfreelist
00574 # define GC_aobjfreelist GC_arrays._aobjfreelist
00575 # define GC_valid_offsets GC_arrays._valid_offsets
00576 # define GC_modws_valid_offsets GC_arrays._modws_valid_offsets
00577 # define GC_reclaim_list GC_arrays._reclaim_list
00578 # define GC_areclaim_list GC_arrays._areclaim_list
00579 # define GC_obj_map GC_arrays._obj_map
00580 # define GC_last_heap_addr GC_arrays._last_heap_addr
00581 # define GC_prev_heap_addr GC_arrays._prev_heap_addr
00582 # define GC_words_allocd GC_arrays._words_allocd
00583 # define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc
00584 # define GC_mem_freed GC_arrays._mem_freed
00585 # define GC_heapsize GC_arrays._heapsize
00586 # define GC_words_allocd_before_gc GC_arrays._words_allocd_before_gc
00587 # ifdef GATHERSTATS
00588 #   define GC_composite_in_use GC_arrays._composite_in_use
00589 #   define GC_atomic_in_use GC_arrays._atomic_in_use
00590 # endif
00591 # ifdef MERGE_SIZES
00592 #   define GC_size_map GC_arrays._size_map
00593 # endif
00594 
00595 # define beginGC_arrays ((ptr_t)(&GC_arrays))
00596 # define endGC_arrays (((ptr_t)(&GC_arrays)) + (sizeof GC_arrays))
00597 
00598 
00599 # define MAXOBJKINDS 16
00600 
00601 /* Object kinds: */
00602 extern struct obj_kind {
00603    ptr_t *ok_freelist;  /* Array of free listheaders for this kind of object */
00604                         /* Point either to GC_arrays or to storage allocated */
00605                         /* with GC_scratch_alloc.                            */
00606    struct hblk **ok_reclaim_list;
00607                         /* List headers for lists of blocks waiting to be */
00608                         /* swept.                                         */
00609    mark_proc ok_mark_proc; /* Procedure to either mark referenced objects,  */
00610                            /* or push them on the mark stack.               */
00611    bool ok_init;     /* Clear objects before putting them on the free list. */
00612 } GC_obj_kinds[MAXOBJKINDS];
00613 /* Predefined kinds: */
00614 # define PTRFREE 0
00615 # define NORMAL  1
00616 
00617 extern int GC_n_kinds;
00618 
00619 extern char * GC_invalid_map;
00620                         /* Pointer to the nowhere valid hblk map */
00621                         /* Blocks pointing to this map are free. */
00622 
00623 extern struct hblk * GC_hblkfreelist;
00624                                 /* List of completely empty heap blocks */
00625                                 /* Linked through hb_next field of      */
00626                                 /* header structure associated with     */
00627                                 /* block.                               */
00628 
00629 extern bool GC_is_initialized;          /* GC_init() has been run.      */
00630 
00631 # ifndef PCR
00632     extern ptr_t GC_stackbottom;        /* Cool end of user stack       */
00633 # endif
00634 
00635 extern word GC_hincr;           /* current heap increment, in blocks    */
00636 
00637 extern word GC_root_size;       /* Total size of registered root sections */
00638 
00639 extern bool GC_debugging_started;       /* GC_debug_malloc has been called. */ 
00640 
00641 extern ptr_t GC_least_plausible_heap_addr;
00642 extern ptr_t GC_greatest_plausible_heap_addr;
00643                         /* Bounds on the heap.  Guaranteed valid        */
00644                         /* Likely to include future heap expansion.     */
00645                         
00646 /* Operations */
00647 # define update_GC_hincr  GC_hincr = (GC_hincr * HINCR_MULT)/HINCR_DIV; \
00648                        if (GC_hincr > MAXHINCR) {GC_hincr = MAXHINCR;}
00649 # ifndef abs
00650 #   define abs(x)  ((x) < 0? (-(x)) : (x))
00651 # endif
00652 
00653 /****************************/
00654 /*                          */
00655 /*   Objects                */
00656 /*                          */
00657 /****************************/
00658 
00659 
00660 /*  Marks are in a reserved area in                          */
00661 /*  each heap block.  Each word has one mark bit associated  */
00662 /*  with it. Only those corresponding to the beginning of an */
00663 /*  object are used.                                         */
00664 
00665 
00666 /* Operations */
00667 
00668 /*
00669  * Retrieve, set, clear the mark bit corresponding
00670  * to the nth word in a given heap block.
00671  *
00672  * (Recall that bit n corresponds to object beginning at word n
00673  * relative to the beginning of the block, including unused words)
00674  */
00675 
00676 # define mark_bit_from_hdr(hhdr,n) (((hhdr)->hb_marks[divWORDSZ(n)] \
00677                             >> (modWORDSZ(n))) & 1)
00678 # define set_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \
00679                                 |= 1 << modWORDSZ(n)
00680 
00681 # define clear_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \
00682                                 &= ~(1 << modWORDSZ(n))
00683 
00684 /* Important internal collector routines */
00685 
00686 void GC_apply_to_all_blocks(/*fn, client_data*/);
00687                         /* Invoke fn(hbp, client_data) for each         */
00688                         /* allocated heap block.                        */
00689 mse * GC_no_mark_proc(/*addr,hhdr,msp,msl*/);
00690                         /* Mark procedure for PTRFREE objects.  */
00691 mse * GC_normal_mark_proc(/*addr,hhdr,msp,msl*/);
00692                         /* Mark procedure for NORMAL objects.   */
00693 void GC_mark_init();
00694 void GC_mark();                 /* Mark from everything on the mark stack. */
00695 void GC_mark_reliable();        /* as above, but fix things up after    */
00696                                 /* a mark stack overflow.               */
00697 void GC_mark_all(/*b,t*/);      /* Mark from everything in a range.     */
00698 void GC_mark_all_stack(/*b,t*/);    /* Mark from everything in a range,     */
00699                                     /* consider interior pointers as valid  */
00700 void GC_remark();       /* Mark from all marked objects.  Used  */
00701                         /* only if we had to drop something.    */
00702 void GC_tl_mark(/*p*/); /* Mark from a single root.             */
00703 void GC_clear_hdr_marks(/* hhdr */);  /* Clear the mark bits in a header */
00704 void GC_add_roots_inner();
00705 void GC_register_dynamic_libraries();
00706                 /* Add dynamic library data sections to the root set. */
00707 
00708 /* Machine dependent startup routines */
00709 ptr_t GC_get_stack_base();
00710 void GC_register_data_segments();
00711                         
00712 # ifndef ALL_INTERIOR_POINTERS
00713     void GC_add_to_black_list_normal(/* bits */);
00714                         /* Register bits as a possible future false     */
00715                         /* reference from the heap or static data       */
00716 #   define GC_ADD_TO_BLACK_LIST_NORMAL(bits) GC_add_to_black_list_normal(bits)
00717 # else
00718 #   define GC_ADD_TO_BLACK_LIST_NORMAL(bits) GC_add_to_black_list_stack(bits)
00719 # endif
00720 
00721 void GC_add_to_black_list_stack(/* bits */);
00722 struct hblk * GC_is_black_listed(/* h, len */);
00723                         /* If there are likely to be false references   */
00724                         /* to a block starting at h of the indicated    */
00725                         /* length, then return the next plausible       */
00726                         /* starting location for h that might avoid     */
00727                         /* these false references.                      */
00728 void GC_promote_black_lists();
00729                         /* Declare an end to a black listing phase.     */
00730                         
00731 ptr_t GC_scratch_alloc(/*bytes*/);
00732                                 /* GC internal memory allocation for    */
00733                                 /* small objects.  Deallocation is not  */
00734                                 /* possible.                            */
00735                                 
00736 void GC_invalidate_map(/* hdr */);
00737                                 /* Remove the object map associated     */
00738                                 /* with the block.  This identifies     */
00739                                 /* the block as invalid to the mark     */
00740                                 /* routines.                            */
00741 void GC_add_map_entry(/*sz*/);
00742                                 /* Add a heap block map for objects of  */
00743                                 /* size sz to obj_map.                  */
00744 void GC_register_displacement_inner(/*offset*/);
00745                                 /* Version of GC_register_displacement  */
00746                                 /* that assumes lock is already held    */
00747                                 /* and signals are already disabled.    */
00748                                 
00749 void GC_init_inner();
00750                                 
00751 void GC_new_hblk(/*size_in_words, kind*/);
00752                                 /* Allocate a new heap block, and build */
00753                                 /* a free list in it.                   */                              
00754 struct hblk * GC_allochblk(/*size_in_words, kind*/);
00755                                 /* Allocate a heap block, clear it if   */
00756                                 /* for composite objects, inform        */
00757                                 /* the marker that block is valid       */
00758                                 /* for objects of indicated size.       */
00759                                 /* sz < 0 ==> atomic.                   */ 
00760 void GC_freehblk();             /* Deallocate a heap block and mark it  */
00761                                 /* as invalid.                          */
00762                                 
00763 void GC_start_reclaim(/*abort_if_found*/);
00764                                 /* Restore unmarked objects to free     */
00765                                 /* lists, or (if abort_if_found is      */
00766                                 /* TRUE) report them.                   */
00767                                 /* Sweeping of small object pages is    */
00768                                 /* largely deferred.                    */
00769 void GC_continue_reclaim(/*size, kind*/);
00770                                 /* Sweep pages of the given size and    */
00771                                 /* kind, as long as possible, and       */
00772                                 /* as long as the corr. free list is    */
00773                                 /* empty.                               */
00774 bool GC_gcollect_inner(/* force */);
00775                                 /* Collect; caller must have acquired   */
00776                                 /* lock and disabled signals.           */
00777                                 /* FALSE return indicates nothing was   */
00778                                 /* done due to insufficient allocation. */
00779 void GC_collect_or_expand(/* needed_blocks */);
00780                                 /* Collect or expand heap in an attempt */
00781                                 /* make the indicated number of free    */
00782                                 /* blocks available.  Should be called  */
00783                                 /* until it succeeds or exits.          */
00784 void GC_init();                 /* Initialize collector.                */
00785 
00786 ptr_t GC_generic_malloc(/* bytes, kind */);
00787                                 /* Allocate an object of the given      */
00788                                 /* kind.  By default, there are only    */
00789                                 /* two kinds: composite, and atomic.    */
00790                                 /* We claim it's possible for clever    */
00791                                 /* client code that understands GC      */
00792                                 /* internals to add more, e.g. to       */
00793                                 /* communicate object layout info       */
00794                                 /* to the collector.                    */
00795 ptr_t GC_generic_malloc_words_small(/*words, kind*/);
00796                                 /* As above, but size in units of words */
00797                                 /* Bypasses MERGE_SIZES.  Assumes       */
00798                                 /* words <= MAXOBJSZ.                   */
00799 ptr_t GC_allocobj(/* sz_inn_words, kind */);
00800                                 /* Make the indicated                     */
00801                                 /* free list nonempty, and return its   */
00802                                 /* head.                                */
00803                                 
00804 void GC_install_header(/*h*/);
00805                                 /* Install a header for block h.        */
00806 void GC_install_counts(/*h, sz*/);
00807                                 /* Set up forwarding counts for block   */
00808                                 /* h of size sz.                        */
00809 void GC_remove_header(/*h*/);
00810                                 /* Remove the header for block h.       */
00811 void GC_remove_counts(/*h, sz*/);
00812                                 /* Remove forwarding counts for h.      */
00813 hdr * GC_find_header(/*p*/);    /* Debugging only.                      */
00814 
00815 void GC_finalize();     /* Perform all indicated finalization actions   */
00816                         /* on unmarked objects.                         */
00817                         
00818 void GC_add_to_heap(/*p, bytes*/);
00819                         /* Add a HBLKSIZE aligned chunk to the heap.    */
00820 
00821 void GC_print_obj(/* ptr_t p */);
00822                         /* P points to somewhere inside an object with  */
00823                         /* debugging info.  Print a human readable      */
00824                         /* description of the object to stderr.         */
00825 void GC_check_heap();
00826                         /* Check that all objects in the heap with      */
00827                         /* debugging info are intact.  Print            */
00828                         /* descriptions of any that are not.            */
00829 
00830 void GC_printf(/* format, a, b, c, d, e, f */);
00831                         /* A version of printf that doesn't allocate,   */
00832                         /* is restricted to long arguments, and         */
00833                         /* (unfortunately) doesn't use varargs for      */
00834                         /* portability.  Restricted to 6 args and       */
00835                         /* 1K total output length.                      */
00836                         /* (We use sprintf.  Hopefully that doesn't     */
00837                         /* allocate for long arguments.)                */
00838 # define GC_printf0(f) GC_printf(f, 0l, 0l, 0l, 0l, 0l, 0l)
00839 # define GC_printf1(f,a) GC_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l)
00840 # define GC_printf2(f,a,b) GC_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l)
00841 # define GC_printf3(f,a,b,c) GC_printf(f, (long)a, (long)b, (long)c, 0l, 0l, 0l)
00842 # define GC_printf4(f,a,b,c,d) GC_printf(f, (long)a, (long)b, (long)c, \
00843                                             (long)d, 0l, 0l)
00844 # define GC_printf5(f,a,b,c,d,e) GC_printf(f, (long)a, (long)b, (long)c, \
00845                                               (long)d, (long)e, 0l)
00846 # define GC_printf6(f,a,b,c,d,e,g) GC_printf(f, (long)a, (long)b, (long)c, \
00847                                                 (long)d, (long)e, (long)g)
00848 
00849 void GC_err_printf(/* format, a, b, c, d, e, f */);
00850 # define GC_err_printf0(f) GC_err_puts(f)
00851 # define GC_err_printf1(f,a) GC_err_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l)
00852 # define GC_err_printf2(f,a,b) GC_err_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l)
00853 # define GC_err_printf3(f,a,b,c) GC_err_printf(f, (long)a, (long)b, (long)c, \
00854                                                   0l, 0l, 0l)
00855 # define GC_err_printf4(f,a,b,c,d) GC_err_printf(f, (long)a, (long)b, \
00856                                                     (long)c, (long)d, 0l, 0l)
00857 # define GC_err_printf5(f,a,b,c,d,e) GC_err_printf(f, (long)a, (long)b, \
00858                                                       (long)c, (long)d, \
00859                                                       (long)e, 0l)
00860 # define GC_err_printf6(f,a,b,c,d,e,g) GC_err_printf(f, (long)a, (long)b, \
00861                                                         (long)c, (long)d, \
00862                                                         (long)e, (long)g)
00863                         /* Ditto, writes to stderr.                     */
00864                         
00865 void GC_err_puts(/* char *s */);
00866                         /* Write s to stderr, don't buffer, don't add   */
00867                         /* newlines, don't ...                          */
00868 
00869 # endif /* GC_PRIVATE_H */

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