Back to index

plt-scheme  4.2.1
gc_priv.h
Go to the documentation of this file.
00001 /* 
00002  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
00003  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
00004  * Copyright (c) 1996-1999 by Silicon Graphics.  All rights reserved.
00005  * Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved.
00006  *
00007  *
00008  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00009  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00010  *
00011  * Permission is hereby granted to use or copy this program
00012  * for any purpose,  provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  */
00017  
00018 
00019 # ifndef GC_PRIVATE_H
00020 # define GC_PRIVATE_H
00021 
00022 #if defined(mips) && defined(SYSTYPE_BSD) && defined(sony_news)
00023     /* sony RISC NEWS, NEWSOS 4 */
00024 #   define BSD_TIME
00025 /*    typedef long ptrdiff_t;   -- necessary on some really old systems      */
00026 #endif
00027 
00028 #if defined(mips) && defined(SYSTYPE_BSD43)
00029     /* MIPS RISCOS 4 */
00030 #   define BSD_TIME
00031 #endif
00032 
00033 #ifdef DGUX
00034 #   include <sys/types.h>
00035 #   include <sys/time.h>
00036 #   include <sys/resource.h>
00037 #endif /* DGUX */
00038 
00039 #ifdef BSD_TIME
00040 #   include <sys/types.h>
00041 #   include <sys/time.h>
00042 #   include <sys/resource.h>
00043 #endif /* BSD_TIME */
00044 
00045 # ifndef _GC_H
00046 #   include "../gc.h"
00047 # endif
00048 
00049 # ifndef GC_MARK_H
00050 #   include "../gc_mark.h"
00051 # endif
00052 
00053 typedef GC_word word;
00054 typedef GC_signed_word signed_word;
00055 
00056 typedef int GC_bool;
00057 # define TRUE 1
00058 # define FALSE 0
00059 
00060 typedef char * ptr_t;       /* A generic pointer to which we can add  */
00061                      /* byte displacements.                           */
00062                      /* Preferably identical to caddr_t, if it        */
00063                      /* exists.                                */
00064                      
00065 # ifndef GCCONFIG_H
00066 #   include "gcconfig.h"
00067 # endif
00068 
00069 # ifndef HEADERS_H
00070 #   include "gc_hdrs.h"
00071 # endif
00072 
00073 #if defined(__STDC__)
00074 #   include <stdlib.h>
00075 #   if !(defined( sony_news ) )
00076 #       include <stddef.h>
00077 #   endif
00078 #   define VOLATILE volatile
00079 #else
00080 #   ifdef MSWIN32
00081 #      include <stdlib.h>
00082 #   endif
00083 #   define VOLATILE
00084 #endif
00085 
00086 #if 0 /* defined(__GNUC__) doesn't work yet */
00087 # define EXPECT(expr, outcome) __builtin_expect(expr,outcome)
00088   /* Equivalent to (expr), but predict that usually (expr)==outcome. */
00089 #else
00090 # define EXPECT(expr, outcome) (expr)
00091 #endif /* __GNUC__ */
00092 
00093 # ifndef GC_LOCKS_H
00094 #   include "gc_locks.h"
00095 # endif
00096 
00097 # ifdef STACK_GROWS_DOWN
00098 #   define COOLER_THAN >
00099 #   define HOTTER_THAN <
00100 #   define MAKE_COOLER(x,y) if ((word)(x)+(y) > (word)(x)) {(x) += (y);} \
00101                          else {(x) = (word)ONES;}
00102 #   define MAKE_HOTTER(x,y) (x) -= (y)
00103 # else
00104 #   define COOLER_THAN <
00105 #   define HOTTER_THAN >
00106 #   define MAKE_COOLER(x,y) if ((word)(x)-(y) < (word)(x)) {(x) -= (y);} else {(x) = 0;}
00107 #   define MAKE_HOTTER(x,y) (x) += (y)
00108 # endif
00109 
00110 #if defined(AMIGA) && defined(__SASC)
00111 #   define GC_FAR __far
00112 #else
00113 #   define GC_FAR
00114 #endif
00115 
00116 
00117 /*********************************/
00118 /*                               */
00119 /* Definitions for conservative  */
00120 /* collector                     */
00121 /*                               */
00122 /*********************************/
00123 
00124 /*********************************/
00125 /*                               */
00126 /* Easily changeable parameters  */
00127 /*                               */
00128 /*********************************/
00129 
00130 /* #define STUBBORN_ALLOC */
00131                   /* Enable stubborm allocation, and thus a limited   */
00132                   /* form of incremental collection w/o dirty bits.   */
00133 
00134 /* #define ALL_INTERIOR_POINTERS */
00135                   /* Forces all pointers into the interior of an      */
00136                   /* object to be considered valid.  Also causes the  */
00137                   /* sizes of all objects to be inflated by at least  */
00138                   /* one byte.  This should suffice to guarantee      */
00139                   /* that in the presence of a compiler that does     */
00140                   /* not perform garbage-collector-unsafe             */
00141                   /* optimizations, all portable, strictly ANSI       */
00142                   /* conforming C programs should be safely usable    */
00143                   /* with malloc replaced by GC_malloc and free       */
00144                   /* calls removed.  There are several disadvantages: */
00145                   /* 1. There are probably no interesting, portable,  */
00146                   /*    strictly ANSI     conforming C programs.             */
00147                   /* 2. This option makes it hard for the collector   */
00148                   /*    to allocate space that is not ``pointed to''  */
00149                   /*    by integers, etc.  Under SunOS 4.X with a     */
00150                   /*    statically linked libc, we empiricaly         */
00151                   /*    observed that it would be difficult to        */
00152                   /*   allocate individual objects larger than 100K.  */
00153                   /*          Even if only smaller objects are allocated,    */
00154                   /*    more swap space is likely to be needed.       */
00155                   /*    Fortunately, much of this will never be       */
00156                   /*    touched.                               */
00157                   /* If you can easily avoid using this option, do.   */
00158                   /* If not, try to keep individual objects small.    */
00159                   /* This is now really controlled at startup, */
00160                   /* through GC_all_interior_pointers.         */
00161                   
00162 #define PRINTSTATS  /* Print garbage collection statistics            */
00163                   /* For less verbose output, undefine in reclaim.c   */
00164 
00165 #define PRINTTIMES  /* Print the amount of time consumed by each garbage   */
00166                   /* collection.                                         */
00167 
00168 #define PRINTBLOCKS /* Print object sizes associated with heap blocks,     */
00169                   /* whether the objects are atomic or composite, and    */
00170                   /* whether or not the block was found to be empty      */
00171                   /* during the reclaim phase.  Typically generates       */
00172                   /* about one screenful per garbage collection.         */
00173 #undef PRINTBLOCKS
00174 
00175 #ifdef SILENT
00176 #  ifdef PRINTSTATS
00177 #    undef PRINTSTATS
00178 #  endif
00179 #  ifdef PRINTTIMES
00180 #    undef PRINTTIMES
00181 #  endif
00182 #  ifdef PRINTNBLOCKS
00183 #    undef PRINTNBLOCKS
00184 #  endif
00185 #endif
00186 
00187 #if defined(PRINTSTATS) && !defined(GATHERSTATS)
00188 #   define GATHERSTATS
00189 #endif
00190 
00191 #if defined(PRINTSTATS) || !defined(SMALL_CONFIG)
00192 #   define CONDPRINT  /* Print some things if GC_print_stats is set */
00193 #endif
00194 
00195 #define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers()
00196 
00197 #define MERGE_SIZES /* Round up some object sizes, so that fewer distinct */
00198                   /* free lists are actually maintained.  This applies  */
00199                   /* only to the top level routines in misc.c, not to   */
00200                   /* user generated code that calls GC_allocobj and     */
00201                   /* GC_allocaobj directly.                             */
00202                   /* Slows down average programs slightly.  May however */
00203                   /* substantially reduce fragmentation if allocation   */
00204                   /* request sizes are widely scattered.                */
00205                   /* May save significant amounts of space for obj_map  */
00206                   /* entries.                                           */
00207 
00208 #if defined(USE_MARK_BYTES) && !defined(ALIGN_DOUBLE)
00209 #  define ALIGN_DOUBLE
00210    /* We use one byte for every 2 words, which doesn't allow for      */
00211    /* odd numbered words to have mark bits.                           */
00212 #endif
00213 
00214 #if defined(GC_GCJ_SUPPORT) && ALIGNMENT < 8 && !defined(ALIGN_DOUBLE)
00215    /* GCJ's Hashtable synchronization code requires 64-bit alignment.  */
00216 #  define ALIGN_DOUBLE
00217 #endif
00218 
00219 /* ALIGN_DOUBLE requires MERGE_SIZES at present. */
00220 # if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES)
00221 #   define MERGE_SIZES
00222 # endif
00223 
00224 #if !defined(DONT_ADD_BYTE_AT_END)
00225 # define EXTRA_BYTES GC_all_interior_pointers
00226 #else
00227 # define EXTRA_BYTES 0
00228 #endif
00229 
00230 
00231 # ifndef LARGE_CONFIG
00232 #   define MINHINCR 16       /* Minimum heap increment, in blocks of HBLKSIZE  */
00233                       /* Must be multiple of largest page size.          */
00234 #   define MAXHINCR 2048 /* Maximum heap increment, in blocks              */
00235 # else
00236 #   define MINHINCR 64
00237 #   define MAXHINCR 4096
00238 # endif
00239 
00240 # define TIME_LIMIT 50         /* We try to keep pause times from exceeding   */
00241                         /* this by much. In milliseconds.              */
00242 
00243 # define BL_LIMIT GC_black_list_spacing
00244                         /* If we need a block of N bytes, and we have */
00245                         /* a block of N + BL_LIMIT bytes available,    */
00246                         /* and N > BL_LIMIT,                           */
00247                         /* but all possible positions in it are        */
00248                         /* blacklisted, we just use it anyway (and     */
00249                         /* print a warning, if warnings are enabled). */
00250                         /* This risks subsequently leaking the block   */
00251                         /* due to a false reference.  But not using    */
00252                         /* the block risks unreasonable immediate      */
00253                         /* heap growth.                         */
00254 
00255 /*********************************/
00256 /*                               */
00257 /* Stack saving for debugging       */
00258 /*                               */
00259 /*********************************/
00260 
00261 #ifdef NEED_CALLINFO
00262     struct callinfo {
00263        word ci_pc;   /* Caller, not callee, pc   */
00264 #      if NARGS > 0
00265            word ci_arg[NARGS];     /* bit-wise complement to avoid retention */
00266 #      endif
00267 #      if defined(ALIGN_DOUBLE) && (NFRAMES * (NARGS + 1)) % 2 == 1
00268            /* Likely alignment problem. */
00269            word ci_dummy;
00270 #      endif
00271     };
00272 #endif
00273 
00274 #ifdef SAVE_CALL_CHAIN
00275 
00276 /* Fill in the pc and argument information for up to NFRAMES of my    */
00277 /* callers.  Ignore my frame and my callers frame.                    */
00278 void GC_save_callers GC_PROTO((struct callinfo info[NFRAMES]));
00279   
00280 void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES]));
00281 
00282 #endif
00283 
00284 
00285 /*********************************/
00286 /*                               */
00287 /* OS interface routines     */
00288 /*                               */
00289 /*********************************/
00290 
00291 #ifdef BSD_TIME
00292 #   undef CLOCK_TYPE
00293 #   undef GET_TIME
00294 #   undef MS_TIME_DIFF
00295 #   define CLOCK_TYPE struct timeval
00296 #   define GET_TIME(x) { struct rusage rusage; \
00297                       getrusage (RUSAGE_SELF,  &rusage); \
00298                       x = rusage.ru_utime; }
00299 #   define MS_TIME_DIFF(a,b) ((double) (a.tv_sec - b.tv_sec) * 1000.0 \
00300                                + (double) (a.tv_usec - b.tv_usec) / 1000.0)
00301 #else /* !BSD_TIME */
00302 # if defined(MSWIN32) || defined(MSWINCE)
00303 #   include <windows.h>
00304 #   include <winbase.h>
00305 #   define CLOCK_TYPE DWORD
00306 #   define GET_TIME(x) x = GetTickCount()
00307 #   define MS_TIME_DIFF(a,b) ((long)((a)-(b)))
00308 # else /* !MSWIN32, !MSWINCE, !BSD_TIME */
00309 #   include <time.h>
00310 #   if !defined(__STDC__) && defined(SPARC) && defined(SUNOS4)
00311       clock_t clock();      /* Not in time.h, where it belongs */
00312 #   endif
00313 #   if defined(FREEBSD) && !defined(CLOCKS_PER_SEC)
00314 #     include <machine/limits.h>
00315 #     define CLOCKS_PER_SEC CLK_TCK
00316 #   endif
00317 #   if !defined(CLOCKS_PER_SEC)
00318 #     define CLOCKS_PER_SEC 1000000
00319 /*
00320  * This is technically a bug in the implementation.  ANSI requires that
00321  * CLOCKS_PER_SEC be defined.  But at least under SunOS4.1.1, it isn't.
00322  * Also note that the combination of ANSI C and POSIX is incredibly gross
00323  * here. The type clock_t is used by both clock() and times().  But on
00324  * some machines these use different notions of a clock tick,  CLOCKS_PER_SEC
00325  * seems to apply only to clock.  Hence we use it here.  On many machines,
00326  * including SunOS, clock actually uses units of microseconds (which are
00327  * not really clock ticks).
00328  */
00329 #   endif
00330 #   define CLOCK_TYPE clock_t
00331 #   define GET_TIME(x) x = clock()
00332 #   define MS_TIME_DIFF(a,b) ((unsigned long) \
00333               (1000.0*(double)((a)-(b))/(double)CLOCKS_PER_SEC))
00334 # endif /* !MSWIN32 */
00335 #endif /* !BSD_TIME */
00336 
00337 /* We use bzero and bcopy internally.  They may not be available.     */
00338 # if defined(SPARC) && defined(SUNOS4)
00339 #   define BCOPY_EXISTS
00340 # endif
00341 # if defined(M68K) && defined(AMIGA)
00342 #   define BCOPY_EXISTS
00343 # endif
00344 # if defined(M68K) && defined(NEXT)
00345 #   define BCOPY_EXISTS
00346 # endif
00347 # if defined(VAX)
00348 #   define BCOPY_EXISTS
00349 # endif
00350 # if defined(AMIGA)
00351 #   include <string.h>
00352 #   define BCOPY_EXISTS
00353 # endif
00354 # if defined(DARWIN)
00355 #   include <string.h>
00356 #   define BCOPY_EXISTS
00357 # endif
00358 
00359 # ifndef BCOPY_EXISTS
00360 #   include <string.h>
00361 #   define BCOPY(x,y,n) memcpy(y, x, (size_t)(n))
00362 #   define BZERO(x,n)  memset(x, 0, (size_t)(n))
00363 # else
00364 #   define BCOPY(x,y,n) bcopy((char *)(x),(char *)(y),(int)(n))
00365 #   define BZERO(x,n) bzero((char *)(x),(int)(n))
00366 # endif
00367 
00368 /* Delay any interrupts or signals that may abort this thread.  Data  */
00369 /* structures are in a consistent state outside this pair of calls.   */
00370 /* ANSI C allows both to be empty (though the standard isn't very     */
00371 /* clear on that point).  Standard malloc implementations are usually */
00372 /* neither interruptable nor thread-safe, and thus correspond to      */
00373 /* empty definitions.                                                 */
00374 /* It probably doesn't make any sense to declare these to be nonempty */
00375 /* if the code is being optimized, since signal safety relies on some */
00376 /* ordering constraints that are typically not obeyed by optimizing   */
00377 /* compilers.                                                  */
00378 # ifdef PCR
00379 #   define DISABLE_SIGNALS() \
00380                PCR_Th_SetSigMask(PCR_allSigsBlocked,&GC_old_sig_mask)
00381 #   define ENABLE_SIGNALS() \
00382               PCR_Th_SetSigMask(&GC_old_sig_mask, NIL)
00383 # else
00384 #   if defined(THREADS) || defined(AMIGA)  \
00385        || defined(MSWIN32) || defined(MSWINCE) || defined(MACOS) \
00386        || defined(DJGPP) || defined(NO_SIGNALS) 
00387                      /* Also useful for debugging.             */
00388        /* Should probably use thr_sigsetmask for GC_SOLARIS_THREADS. */
00389 #     define DISABLE_SIGNALS()
00390 #     define ENABLE_SIGNALS()
00391 #   else
00392 #     define DISABLE_SIGNALS() GC_disable_signals()
00393        void GC_disable_signals();
00394 #     define ENABLE_SIGNALS() GC_enable_signals()
00395        void GC_enable_signals();
00396 #   endif
00397 # endif
00398 
00399 /*
00400  * Stop and restart mutator threads.
00401  */
00402 # ifdef PCR
00403 #     include "th/PCR_ThCtl.h"
00404 #     define STOP_WORLD() \
00405        PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_stopNormal, \
00406                                PCR_allSigsBlocked, \
00407                                PCR_waitForever)
00408 #     define START_WORLD() \
00409        PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_null, \
00410                                PCR_allSigsBlocked, \
00411                                PCR_waitForever);
00412 # else
00413 #   if defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) \
00414        || defined(GC_PTHREADS)
00415       void GC_stop_world();
00416       void GC_start_world();
00417 #     define STOP_WORLD() GC_stop_world()
00418 #     define START_WORLD() GC_start_world()
00419 #   else
00420 #     define STOP_WORLD()
00421 #     define START_WORLD()
00422 #   endif
00423 # endif
00424 
00425 /* Abandon ship */
00426 # ifdef PCR
00427 #   define ABORT(s) PCR_Base_Panic(s)
00428 # else
00429 #   ifdef SMALL_CONFIG
00430 #      define ABORT(msg) abort();
00431 #   else
00432        GC_API void GC_abort GC_PROTO((GC_CONST char * msg));
00433 #       define ABORT(msg) GC_abort(msg);
00434 #   endif
00435 # endif
00436 
00437 /* Exit abnormally, but without making a mess (e.g. out of memory) */
00438 # ifdef PCR
00439 #   define EXIT() PCR_Base_Exit(1,PCR_waitForever)
00440 # else
00441 #   define EXIT() (void)exit(1)
00442 # endif
00443 
00444 /* Print warning message, e.g. almost out of memory.    */
00445 # define WARN(msg,arg) (*GC_current_warn_proc)("GC Warning: " msg, (GC_word)(arg))
00446 extern GC_warn_proc GC_current_warn_proc;
00447 
00448 /* Get environment entry */
00449 #if !defined(NO_GETENV)
00450 #   if defined(EMPTY_GETENV_RESULTS)
00451        /* Workaround for a reputed Wine bug.     */
00452        static inline char * fixed_getenv(const char *name)
00453        {
00454          char * tmp = getenv(name);
00455          if (tmp == 0 || strlen(tmp) == 0)
00456            return 0;
00457          return tmp;
00458        }
00459 #       define GETENV(name) fixed_getenv(name)
00460 #   else
00461 #       define GETENV(name) getenv(name)
00462 #   endif
00463 #else
00464 #   define GETENV(name) 0
00465 #endif
00466 
00467 /*********************************/
00468 /*                               */
00469 /* Word-size-dependent defines   */
00470 /*                               */
00471 /*********************************/
00472 
00473 #if CPP_WORDSZ == 32
00474 #  define WORDS_TO_BYTES(x)   ((x)<<2)
00475 #  define BYTES_TO_WORDS(x)   ((x)>>2)
00476 #  define LOGWL               ((word)5)    /* log[2] of CPP_WORDSZ */
00477 #  define modWORDSZ(n) ((n) & 0x1f)        /* n mod size of word          */
00478 #  if ALIGNMENT != 4
00479 #      define UNALIGNED
00480 #  endif
00481 #endif
00482 
00483 #if CPP_WORDSZ == 64
00484 #  define WORDS_TO_BYTES(x)   ((x)<<3)
00485 #  define BYTES_TO_WORDS(x)   ((x)>>3)
00486 #  define LOGWL               ((word)6)    /* log[2] of CPP_WORDSZ */
00487 #  define modWORDSZ(n) ((n) & 0x3f)        /* n mod size of word          */
00488 #  if ALIGNMENT != 8
00489 #      define UNALIGNED
00490 #  endif
00491 #endif
00492 
00493 #define WORDSZ ((word)CPP_WORDSZ)
00494 #define SIGNB  ((word)1 << (WORDSZ-1))
00495 #define BYTES_PER_WORD      ((word)(sizeof (word)))
00496 #define ONES                ((word)(signed_word)(-1))
00497 #define divWORDSZ(n) ((n) >> LOGWL)          /* divide n by size of word      */
00498 
00499 /*********************/
00500 /*                   */
00501 /*  Size Parameters  */
00502 /*                   */
00503 /*********************/
00504 
00505 /*  heap block size, bytes. Should be power of 2 */
00506 
00507 #ifndef HBLKSIZE
00508 # ifdef SMALL_CONFIG
00509 #   define CPP_LOG_HBLKSIZE 10
00510 # else
00511 #   if (CPP_WORDSZ == 32) || (defined(HPUX) && defined(HP_PA))
00512       /* HPUX/PA seems to use 4K pages with the 64 bit ABI */
00513 #     define CPP_LOG_HBLKSIZE 12
00514 #   else
00515 #     define CPP_LOG_HBLKSIZE 13
00516 #   endif
00517 # endif
00518 #else
00519 # if HBLKSIZE == 512
00520 #   define CPP_LOG_HBLKSIZE 9
00521 # endif
00522 # if HBLKSIZE == 1024
00523 #   define CPP_LOG_HBLKSIZE 10
00524 # endif
00525 # if HBLKSIZE == 2048
00526 #   define CPP_LOG_HBLKSIZE 11
00527 # endif
00528 # if HBLKSIZE == 4096
00529 #   define CPP_LOG_HBLKSIZE 12
00530 # endif
00531 # if HBLKSIZE == 8192
00532 #   define CPP_LOG_HBLKSIZE 13
00533 # endif
00534 # if HBLKSIZE == 16384
00535 #   define CPP_LOG_HBLKSIZE 14
00536 # endif
00537 # ifndef CPP_LOG_HBLKSIZE
00538     --> fix HBLKSIZE
00539 # endif
00540 # undef HBLKSIZE
00541 #endif
00542 # define CPP_HBLKSIZE (1 << CPP_LOG_HBLKSIZE)
00543 # define LOG_HBLKSIZE   ((word)CPP_LOG_HBLKSIZE)
00544 # define HBLKSIZE ((word)CPP_HBLKSIZE)
00545 
00546 
00547 /*  max size objects supported by freelist (larger objects may be   */
00548 /*  allocated, but less efficiently)                                */
00549 
00550 #define CPP_MAXOBJBYTES (CPP_HBLKSIZE/2)
00551 #define MAXOBJBYTES ((word)CPP_MAXOBJBYTES)
00552 #define CPP_MAXOBJSZ    BYTES_TO_WORDS(CPP_MAXOBJBYTES)
00553 #define MAXOBJSZ ((word)CPP_MAXOBJSZ)
00554               
00555 # define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE)
00556 
00557 # define HBLK_PTR_DIFF(p,q) divHBLKSZ((ptr_t)p - (ptr_t)q)
00558        /* Equivalent to subtracting 2 hblk pointers.    */
00559        /* We do it this way because a compiler should   */
00560        /* find it hard to use an integer division       */
00561        /* instead of a shift.  The bundled SunOS 4.1    */
00562        /* o.w. sometimes pessimizes the subtraction to  */
00563        /* involve a call to .div.                */
00564  
00565 # define modHBLKSZ(n) ((n) & (HBLKSIZE-1))
00566  
00567 # define HBLKPTR(objptr) ((struct hblk *)(((word) (objptr)) & ~(HBLKSIZE-1)))
00568 
00569 # define HBLKDISPL(objptr) (((word) (objptr)) & (HBLKSIZE-1))
00570 
00571 /* Round up byte allocation requests to integral number of words, etc. */
00572 # define ROUNDED_UP_WORDS(n) \
00573        BYTES_TO_WORDS((n) + (WORDS_TO_BYTES(1) - 1 + EXTRA_BYTES))
00574 # ifdef ALIGN_DOUBLE
00575 #       define ALIGNED_WORDS(n) \
00576            (BYTES_TO_WORDS((n) + WORDS_TO_BYTES(2) - 1 + EXTRA_BYTES) & ~1)
00577 # else
00578 #       define ALIGNED_WORDS(n) ROUNDED_UP_WORDS(n)
00579 # endif
00580 # define SMALL_OBJ(bytes) ((bytes) <= (MAXOBJBYTES - EXTRA_BYTES))
00581 # define ADD_SLOP(bytes) ((bytes) + EXTRA_BYTES)
00582 # ifndef MIN_WORDS
00583     /* MIN_WORDS is the size of the smallest allocated object. */
00584     /* 1 and 2 are the only valid values.               */
00585     /* 2 must be used if:                               */
00586     /* - GC_gcj_malloc can be used for objects of requested    */
00587     /*   size  smaller than 2 words, or                        */
00588     /* - USE_MARK_BYTES is defined.                            */
00589 #   if defined(USE_MARK_BYTES) || defined(GC_GCJ_SUPPORT)
00590 #     define MIN_WORDS 2    /* Smallest allocated object.      */
00591 #   else
00592 #     define MIN_WORDS 1
00593 #   endif
00594 # endif
00595 
00596 
00597 /*
00598  * Hash table representation of sets of pages.  This assumes it is
00599  * OK to add spurious entries to sets.
00600  * Used by black-listing code, and perhaps by dirty bit maintenance code.
00601  */
00602  
00603 # ifdef LARGE_CONFIG
00604 #   define LOG_PHT_ENTRIES  20  /* Collisions likely at 1M blocks,    */
00605                             /* which is >= 4GB.  Each table takes     */
00606                             /* 128KB, some of which may never be      */
00607                             /* touched.                        */
00608 # else
00609 #   ifdef SMALL_CONFIG
00610 #     define LOG_PHT_ENTRIES  14 /* Collisions are likely if heap grows      */
00611                              /* to more than 16K hblks = 64MB. */
00612                              /* Each hash table occupies 2K bytes.   */
00613 #   else /* default "medium" configuration */
00614 #     define LOG_PHT_ENTRIES  16 /* Collisions are likely if heap grows      */
00615                              /* to more than 64K hblks >= 256MB.      */
00616                              /* Each hash table occupies 8K bytes.  */
00617                              /* Even for somewhat smaller heaps,      */
00618                              /* say half that, collisions may be an   */
00619                              /* issue because we blacklist            */
00620                              /* addresses outside the heap.           */
00621 #   endif
00622 # endif
00623 # define PHT_ENTRIES ((word)1 << LOG_PHT_ENTRIES)
00624 # define PHT_SIZE (PHT_ENTRIES >> LOGWL)
00625 typedef word page_hash_table[PHT_SIZE];
00626 
00627 # define PHT_HASH(addr) ((((word)(addr)) >> LOG_HBLKSIZE) & (PHT_ENTRIES - 1))
00628 
00629 # define get_pht_entry_from_index(bl, index) \
00630               (((bl)[divWORDSZ(index)] >> modWORDSZ(index)) & 1)
00631 # define set_pht_entry_from_index(bl, index) \
00632               (bl)[divWORDSZ(index)] |= (word)1 << modWORDSZ(index)
00633 # define clear_pht_entry_from_index(bl, index) \
00634               (bl)[divWORDSZ(index)] &= ~((word)1 << modWORDSZ(index))
00635 /* And a dumb but thread-safe version of set_pht_entry_from_index.    */
00636 /* This sets (many) extra bits.                                       */
00637 # define set_pht_entry_from_index_safe(bl, index) \
00638               (bl)[divWORDSZ(index)] = ONES
00639        
00640 
00641 
00642 /********************************************/
00643 /*                                          */
00644 /*    H e a p   B l o c k s                 */
00645 /*                                          */
00646 /********************************************/
00647 
00648 /*  heap block header */
00649 #define HBLKMASK   (HBLKSIZE-1)
00650 
00651 #define BITS_PER_HBLK (CPP_HBLKSIZE * 8)
00652 
00653 #define MARK_BITS_PER_HBLK (BITS_PER_HBLK/CPP_WORDSZ)
00654           /* upper bound                                    */
00655           /* We allocate 1 bit/word, unless USE_MARK_BYTES  */
00656           /* is defined.  Only the first word         */
00657           /* in each object is actually marked.             */
00658 
00659 # ifdef USE_MARK_BYTES
00660 #   define MARK_BITS_SZ (MARK_BITS_PER_HBLK/2)
00661        /* Unlike the other case, this is in units of bytes.           */
00662        /* We actually allocate only every second mark bit, since we   */
00663        /* force all objects to be doubleword aligned.                 */
00664        /* However, each mark bit is allocated as a byte.              */
00665 # else
00666 #   define MARK_BITS_SZ (MARK_BITS_PER_HBLK/CPP_WORDSZ)
00667 # endif
00668 
00669 /* We maintain layout maps for heap blocks containing objects of a given */
00670 /* size.  Each entry in this map describes a byte offset and has the   */
00671 /* following type.                                              */
00672 typedef unsigned char map_entry_type;
00673 
00674 struct hblkhdr {
00675     word hb_sz;  /* If in use, size in words, of objects in the block. */
00676                /* if free, the size in bytes of the whole block      */
00677     struct hblk * hb_next;  /* Link field for hblk free list    */
00678                             /* and for lists of chunks waiting to be */
00679                             /* reclaimed.                       */
00680     struct hblk * hb_prev;  /* Backwards link for free list.   */
00681     word hb_descr;                 /* object descriptor for marking.  See    */
00682                             /* mark.h.                         */
00683     map_entry_type * hb_map;       
00684                      /* A pointer to a pointer validity map of the block. */
00685                      /* See GC_obj_map.                             */
00686                      /* Valid for all blocks with headers.                 */
00687                      /* Free blocks point to GC_invalid_map.               */
00688     unsigned char hb_obj_kind;
00689                       /* Kind of objects in the block.  Each kind     */
00690                       /* identifies a mark procedure and a set of     */
00691                       /* list headers.  Sometimes called regions.     */
00692     unsigned char hb_flags;
00693 #      define IGNORE_OFF_PAGE      1      /* Ignore pointers that do not     */
00694                                    /* point to the first page of      */
00695                                    /* this object.                    */
00696 #      define WAS_UNMAPPED 2       /* This is a free block, which has */
00697                             /* been unmapped from the address  */
00698                             /* space.                          */
00699                             /* GC_remap must be invoked on it  */
00700                             /* before it can be reallocated.   */
00701                             /* Only set with USE_MUNMAP.              */
00702     unsigned short hb_last_reclaimed;
00703                             /* Value of GC_gc_no when block was       */
00704                             /* last allocated or swept. May wrap.   */
00705                             /* For a free block, this is maintained */
00706                             /* only for USE_MUNMAP, and indicates     */
00707                             /* when the header was allocated, or      */
00708                             /* when the size of the block last */
00709                             /* changed.                        */
00710 #   ifdef USE_MARK_BYTES
00711       union {
00712         char _hb_marks[MARK_BITS_SZ];
00713                          /* The i'th byte is 1 if the object   */
00714                          /* starting at word 2i is marked, 0 o.w.     */
00715        word dummy;   /* Force word alignment of mark bytes. */
00716       } _mark_byte_union;
00717 #     define hb_marks _mark_byte_union._hb_marks
00718 #   else
00719       word hb_marks[MARK_BITS_SZ];
00720                          /* Bit i in the array refers to the             */
00721                          /* object starting at the ith word (header      */
00722                          /* INCLUDED) in the heap block.                 */
00723                          /* The lsb of word 0 is numbered 0.              */
00724                          /* Unused bits are invalid, and are       */
00725                          /* occasionally set, e.g for uncollectable       */
00726                          /* objects.                                      */
00727 #   endif /* !USE_MARK_BYTES */
00728 };
00729 
00730 /*  heap block body */
00731 
00732 # define BODY_SZ (HBLKSIZE/sizeof(word))
00733 
00734 struct hblk {
00735     word hb_body[BODY_SZ];
00736 };
00737 
00738 # define HBLK_IS_FREE(hdr) ((hdr) -> hb_map == GC_invalid_map)
00739 
00740 # define OBJ_SZ_TO_BLOCKS(sz) \
00741     divHBLKSZ(WORDS_TO_BYTES(sz) + HBLKSIZE-1)
00742     /* Size of block (in units of HBLKSIZE) needed to hold objects of */
00743     /* given sz (in words).                                    */
00744 
00745 /* Object free list link */
00746 # define obj_link(p) (*(ptr_t *)(p))
00747 
00748 # define LOG_MAX_MARK_PROCS 6
00749 # define MAX_MARK_PROCS (1 << LOG_MAX_MARK_PROCS)
00750 
00751 /* Root sets.  Logically private to mark_rts.c.  But we don't want the       */
00752 /* tables scanned, so we put them here.                               */
00753 /* MAX_ROOT_SETS is the maximum number of ranges that can be   */
00754 /* registered as static roots.                                 */
00755 # ifdef LARGE_CONFIG
00756 #   define MAX_ROOT_SETS 4096
00757 # else
00758     /* GCJ LOCAL: MAX_ROOT_SETS increased to permit more shared */
00759     /* libraries to be loaded.                                  */ 
00760 #   define MAX_ROOT_SETS 1024
00761 # endif
00762 
00763 # define MAX_EXCLUSIONS (MAX_ROOT_SETS/4)
00764 /* Maximum number of segments that can be excluded from root sets.    */
00765 
00766 /*
00767  * Data structure for excluded static roots.
00768  */
00769 struct exclusion {
00770     ptr_t e_start;
00771     ptr_t e_end;
00772 };
00773 
00774 /* Data structure for list of root sets.                       */
00775 /* We keep a hash table, so that we can filter out duplicate additions.      */
00776 /* Under Win32, we need to do a better job of filtering overlaps, so  */
00777 /* we resort to sequential search, and pay the price.                 */
00778 struct roots {
00779        ptr_t r_start;
00780        ptr_t r_end;
00781 #      if !defined(MSWIN32) && !defined(MSWINCE)
00782          struct roots * r_next;
00783 #      endif
00784        GC_bool r_tmp;
00785               /* Delete before registering new dynamic libraries */
00786 };
00787 
00788 #if !defined(MSWIN32) && !defined(MSWINCE)
00789     /* Size of hash table index to roots. */
00790 #   define LOG_RT_SIZE 6
00791 #   define RT_SIZE (1 << LOG_RT_SIZE) /* Power of 2, may be != MAX_ROOT_SETS */
00792 #endif
00793 
00794 /* Lists of all heap blocks and free lists       */
00795 /* as well as other random data structures       */
00796 /* that should not be scanned by the             */
00797 /* collector.                             */
00798 /* These are grouped together in a struct */
00799 /* so that they can be easily skipped by the     */
00800 /* GC_mark routine.                       */
00801 /* The ordering is weird to make GC_malloc       */
00802 /* faster by keeping the important fields */
00803 /* sufficiently close together that a            */
00804 /* single load of a base register will do.       */
00805 /* Scalars that could easily appear to           */
00806 /* be pointers are also put here.         */
00807 /* The main fields should precede any            */
00808 /* conditionally included fields, so that */
00809 /* gc_inl.h will work even if a different set    */
00810 /* of macros is defined when the client is       */
00811 /* compiled.                              */
00812 
00813 struct _GC_arrays {
00814   word _heapsize;
00815   word _max_heapsize;
00816   word _requested_heapsize; /* Heap size due to explicit expansion */
00817   ptr_t _last_heap_addr;
00818   ptr_t _prev_heap_addr;
00819   word _large_free_bytes;
00820        /* Total bytes contained in blocks on large object free */
00821        /* list.                                         */
00822   word _large_allocd_bytes;
00823        /* Total number of bytes in allocated large objects blocks.    */
00824        /* For the purposes of this counter and the next one only, a   */
00825        /* large object is one that occupies a block of at least       */
00826        /* 2*HBLKSIZE.                                                 */
00827   word _max_large_allocd_bytes;
00828        /* Maximum number of bytes that were ever allocated in         */
00829        /* large object blocks.  This is used to help decide when it   */
00830        /* is safe to split up a large block.                          */
00831   word _words_allocd_before_gc;
00832               /* Number of words allocated before this  */
00833               /* collection cycle.                      */
00834 # ifndef SEPARATE_GLOBALS
00835     word _words_allocd;
00836        /* Number of words allocated during this collection cycle */
00837 # endif
00838   word _words_wasted;
00839        /* Number of words wasted due to internal fragmentation */
00840        /* in large objects, or due to dropping blacklisted     */
00841        /* blocks, since last gc.  Approximate.                 */
00842   word _words_finalized;
00843        /* Approximate number of words in objects (and headers) */
00844        /* That became ready for finalization in the last       */
00845        /* collection.                                          */
00846   word _non_gc_bytes_at_gc;
00847        /* Number of explicitly managed bytes of storage        */
00848        /* at last collection.                                  */
00849   word _mem_freed;
00850        /* Number of explicitly deallocated words of memory     */
00851        /* since last collection.                        */
00852   word _finalizer_mem_freed;
00853        /* Words of memory explicitly deallocated while  */
00854        /* finalizers were running.  Used to approximate mem.   */
00855        /* explicitly deallocated by finalizers.         */
00856   ptr_t _scratch_end_ptr;
00857   ptr_t _scratch_last_end_ptr;
00858        /* Used by headers.c, and can easily appear to point to */
00859        /* heap.                                         */
00860   GC_mark_proc _mark_procs[MAX_MARK_PROCS];
00861        /* Table of user-defined mark procedures.  There is     */
00862        /* a small number of these, which can be referenced     */
00863        /* by DS_PROC mark descriptors.  See gc_mark.h.         */
00864 
00865 # ifndef SEPARATE_GLOBALS
00866     ptr_t _objfreelist[MAXOBJSZ+1];
00867                        /* free list for objects */
00868     ptr_t _aobjfreelist[MAXOBJSZ+1];
00869                        /* free list for atomic objs     */
00870 # endif
00871 
00872   ptr_t _uobjfreelist[MAXOBJSZ+1];
00873                        /* uncollectable but traced objs        */
00874                        /* objects on this and auobjfreelist  */
00875                        /* are always marked, except during   */
00876                        /* garbage collections.          */
00877 # ifdef ATOMIC_UNCOLLECTABLE
00878     ptr_t _auobjfreelist[MAXOBJSZ+1];
00879 # endif
00880                        /* uncollectable but traced objs        */
00881 
00882 # ifdef GATHERSTATS
00883     word _composite_in_use;
00884               /* Number of words in accessible composite       */
00885               /* objects.                               */
00886     word _atomic_in_use;
00887               /* Number of words in accessible atomic          */
00888               /* objects.                               */
00889 # endif
00890 # ifdef USE_MUNMAP
00891     word _unmapped_bytes;
00892 # endif
00893 # ifdef MERGE_SIZES
00894     unsigned _size_map[WORDS_TO_BYTES(MAXOBJSZ+1)];
00895        /* Number of words to allocate for a given allocation request in */
00896        /* bytes.                                                */
00897 # endif 
00898 
00899 # ifdef STUBBORN_ALLOC
00900     ptr_t _sobjfreelist[MAXOBJSZ+1];
00901 # endif
00902                        /* free list for immutable objects      */
00903   map_entry_type * _obj_map[MAXOBJSZ+1];
00904                        /* If not NIL, then a pointer to a map of valid  */
00905                      /* object addresses. _obj_map[sz][i] is j if the */
00906                      /* address block_start+i is a valid pointer      */
00907                      /* to an object at block_start +                 */
00908                      /* WORDS_TO_BYTES(BYTES_TO_WORDS(i) - j)         */
00909                      /* I.e. j is a word displacement from the */
00910                      /* object beginning.                      */
00911                      /* The entry is OBJ_INVALID if the corresponding */
00912                      /* address is not a valid pointer.  It is        */
00913                      /* OFFSET_TOO_BIG if the value j would be too    */
00914                      /* large to fit in the entry.  (Note that the    */
00915                      /* size of these entries matters, both for       */
00916                      /* space consumption and for cache utilization.) */
00917 #   define OFFSET_TOO_BIG 0xfe
00918 #   define OBJ_INVALID 0xff
00919 #   define MAP_ENTRY(map, bytes) (map)[bytes]
00920 #   define MAP_ENTRIES HBLKSIZE
00921 #   define MAP_SIZE MAP_ENTRIES
00922 #   define CPP_MAX_OFFSET (OFFSET_TOO_BIG - 1)   
00923 #   define MAX_OFFSET ((word)CPP_MAX_OFFSET)
00924     /* The following are used only if GC_all_interior_ptrs != 0 */
00925 #      define VALID_OFFSET_SZ \
00926          (CPP_MAX_OFFSET > WORDS_TO_BYTES(CPP_MAXOBJSZ)? \
00927           CPP_MAX_OFFSET+1 \
00928           : WORDS_TO_BYTES(CPP_MAXOBJSZ)+1)
00929        char _valid_offsets[VALID_OFFSET_SZ];
00930                             /* GC_valid_offsets[i] == TRUE ==> i      */
00931                             /* is registered as a displacement.       */
00932        char _modws_valid_offsets[sizeof(word)];
00933                             /* GC_valid_offsets[i] ==>           */
00934                             /* GC_modws_valid_offsets[i%sizeof(word)] */
00935 #   define OFFSET_VALID(displ) \
00936          (GC_all_interior_pointers || GC_valid_offsets[displ])
00937 # ifdef STUBBORN_ALLOC
00938     page_hash_table _changed_pages;
00939         /* Stubborn object pages that were changes since last call to */
00940        /* GC_read_changed.                                     */
00941     page_hash_table _prev_changed_pages;
00942         /* Stubborn object pages that were changes before last call to       */
00943        /* GC_read_changed.                                     */
00944 # endif
00945 # if defined(PROC_VDB) || defined(MPROTECT_VDB)
00946     page_hash_table _grungy_pages; /* Pages that were dirty at last      */
00947                                  /* GC_read_dirty.                       */
00948 # endif
00949 # ifdef MPROTECT_VDB
00950     VOLATILE page_hash_table _dirty_pages;       
00951                      /* Pages dirtied since last GC_read_dirty. */
00952 # endif
00953 # ifdef PROC_VDB
00954     page_hash_table _written_pages;       /* Pages ever dirtied       */
00955 # endif
00956 # ifdef LARGE_CONFIG
00957 #   if CPP_WORDSZ > 32
00958 #     define MAX_HEAP_SECTS 4096   /* overflows at roughly 64 GB         */
00959 #   else
00960 #     define MAX_HEAP_SECTS 768           /* Separately added heap sections. */
00961 #   endif
00962 # else
00963 #   ifdef SMALL_CONFIG
00964 #     define MAX_HEAP_SECTS 128           /* Roughly 256MB (128*2048*1K)     */
00965 #   else
00966 #     define MAX_HEAP_SECTS 384           /* Roughly 3GB                     */
00967 #   endif
00968 # endif
00969   struct HeapSect {
00970       ptr_t hs_start; word hs_bytes;
00971   } _heap_sects[MAX_HEAP_SECTS];
00972 # if defined(MSWIN32) || defined(MSWINCE)
00973     ptr_t _heap_bases[MAX_HEAP_SECTS];
00974               /* Start address of memory regions obtained from kernel. */
00975 # endif
00976 # ifdef MSWINCE
00977     word _heap_lengths[MAX_HEAP_SECTS];
00978               /* Commited lengths of memory regions obtained from kernel. */
00979 # endif
00980   struct roots _static_roots[MAX_ROOT_SETS];
00981 # if !defined(MSWIN32) && !defined(MSWINCE)
00982     struct roots * _root_index[RT_SIZE];
00983 # endif
00984   struct exclusion _excl_table[MAX_EXCLUSIONS];
00985   /* Block header index; see gc_headers.h */
00986   bottom_index * _all_nils;
00987   bottom_index * _top_index [TOP_SZ];
00988 #ifdef SAVE_CALL_CHAIN
00989   struct callinfo _last_stack[NFRAMES];   /* Stack at last garbage collection.*/
00990                                    /* Useful for debugging     mysterious  */
00991                                    /* object disappearances.       */
00992                                    /* In the multithreaded case, we    */
00993                                    /* currently only save the calling  */
00994                                    /* stack.                       */
00995 #endif
00996 };
00997 
00998 GC_API GC_FAR struct _GC_arrays GC_arrays; 
00999 
01000 # ifndef SEPARATE_GLOBALS
01001 #   define GC_objfreelist GC_arrays._objfreelist
01002 #   define GC_aobjfreelist GC_arrays._aobjfreelist
01003 #   define GC_words_allocd GC_arrays._words_allocd
01004 # endif
01005 # define GC_uobjfreelist GC_arrays._uobjfreelist
01006 # ifdef ATOMIC_UNCOLLECTABLE
01007 #   define GC_auobjfreelist GC_arrays._auobjfreelist
01008 # endif
01009 # define GC_sobjfreelist GC_arrays._sobjfreelist
01010 # define GC_valid_offsets GC_arrays._valid_offsets
01011 # define GC_modws_valid_offsets GC_arrays._modws_valid_offsets
01012 # ifdef STUBBORN_ALLOC
01013 #    define GC_changed_pages GC_arrays._changed_pages
01014 #    define GC_prev_changed_pages GC_arrays._prev_changed_pages
01015 # endif
01016 # define GC_obj_map GC_arrays._obj_map
01017 # define GC_last_heap_addr GC_arrays._last_heap_addr
01018 # define GC_prev_heap_addr GC_arrays._prev_heap_addr
01019 # define GC_words_wasted GC_arrays._words_wasted
01020 # define GC_large_free_bytes GC_arrays._large_free_bytes
01021 # define GC_large_allocd_bytes GC_arrays._large_allocd_bytes
01022 # define GC_max_large_allocd_bytes GC_arrays._max_large_allocd_bytes
01023 # define GC_words_finalized GC_arrays._words_finalized
01024 # define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc
01025 # define GC_mem_freed GC_arrays._mem_freed
01026 # define GC_finalizer_mem_freed GC_arrays._finalizer_mem_freed
01027 # define GC_scratch_end_ptr GC_arrays._scratch_end_ptr
01028 # define GC_scratch_last_end_ptr GC_arrays._scratch_last_end_ptr
01029 # define GC_mark_procs GC_arrays._mark_procs
01030 # define GC_heapsize GC_arrays._heapsize
01031 # define GC_max_heapsize GC_arrays._max_heapsize
01032 # define GC_requested_heapsize GC_arrays._requested_heapsize
01033 # define GC_words_allocd_before_gc GC_arrays._words_allocd_before_gc
01034 # define GC_heap_sects GC_arrays._heap_sects
01035 # define GC_last_stack GC_arrays._last_stack
01036 # ifdef USE_MUNMAP
01037 #   define GC_unmapped_bytes GC_arrays._unmapped_bytes
01038 # endif
01039 # if defined(MSWIN32) || defined(MSWINCE)
01040 #   define GC_heap_bases GC_arrays._heap_bases
01041 # endif
01042 # ifdef MSWINCE
01043 #   define GC_heap_lengths GC_arrays._heap_lengths
01044 # endif
01045 # define GC_static_roots GC_arrays._static_roots
01046 # define GC_root_index GC_arrays._root_index
01047 # define GC_excl_table GC_arrays._excl_table
01048 # define GC_all_nils GC_arrays._all_nils
01049 # define GC_top_index GC_arrays._top_index
01050 # if defined(PROC_VDB) || defined(MPROTECT_VDB)
01051 #   define GC_grungy_pages GC_arrays._grungy_pages
01052 # endif
01053 # ifdef MPROTECT_VDB
01054 #   define GC_dirty_pages GC_arrays._dirty_pages
01055 # endif
01056 # ifdef PROC_VDB
01057 #   define GC_written_pages GC_arrays._written_pages
01058 # endif
01059 # ifdef GATHERSTATS
01060 #   define GC_composite_in_use GC_arrays._composite_in_use
01061 #   define GC_atomic_in_use GC_arrays._atomic_in_use
01062 # endif
01063 # ifdef MERGE_SIZES
01064 #   define GC_size_map GC_arrays._size_map
01065 # endif
01066 
01067 # define beginGC_arrays ((ptr_t)(&GC_arrays))
01068 # define endGC_arrays (((ptr_t)(&GC_arrays)) + (sizeof GC_arrays))
01069 
01070 #define USED_HEAP_SIZE (GC_heapsize - GC_large_free_bytes)
01071 
01072 /* Object kinds: */
01073 # define MAXOBJKINDS 16
01074 
01075 extern struct obj_kind {
01076    ptr_t *ok_freelist;      /* Array of free listheaders for this kind of object */
01077                      /* Point either to GC_arrays or to storage allocated */
01078                      /* with GC_scratch_alloc.                      */
01079    struct hblk **ok_reclaim_list;
01080                      /* List headers for lists of blocks waiting to be */
01081                      /* swept.                                   */
01082    word ok_descriptor;  /* Descriptor template for objects in this    */
01083                      /* block.                                 */
01084    GC_bool ok_relocate_descr;
01085                      /* Add object size in bytes to descriptor        */
01086                      /* template to obtain descriptor.  Otherwise     */
01087                      /* template is used as is.                */
01088    GC_bool ok_init;   /* Clear objects before putting them on the free list. */
01089 } GC_obj_kinds[MAXOBJKINDS];
01090 
01091 # define beginGC_obj_kinds ((ptr_t)(&GC_obj_kinds))
01092 # define endGC_obj_kinds (beginGC_obj_kinds + (sizeof GC_obj_kinds))
01093 
01094 /* Variables that used to be in GC_arrays, but need to be accessed by        */
01095 /* inline allocation code.  If they were in GC_arrays, the inlined    */
01096 /* allocation code would include GC_arrays offsets (as it did), which */
01097 /* introduce maintenance problems.                             */
01098 
01099 #ifdef SEPARATE_GLOBALS
01100   word GC_words_allocd;
01101        /* Number of words allocated during this collection cycle */
01102   ptr_t GC_objfreelist[MAXOBJSZ+1];
01103                        /* free list for NORMAL objects */
01104 # define beginGC_objfreelist ((ptr_t)(&GC_objfreelist))
01105 # define endGC_objfreelist (beginGC_objfreelist + sizeof(GC_objfreelist))
01106 
01107   ptr_t GC_aobjfreelist[MAXOBJSZ+1];
01108                        /* free list for atomic (PTRFREE) objs  */
01109 # define beginGC_aobjfreelist ((ptr_t)(&GC_aobjfreelist))
01110 # define endGC_aobjfreelist (beginGC_aobjfreelist + sizeof(GC_aobjfreelist))
01111 #endif
01112 
01113 /* Predefined kinds: */
01114 # define PTRFREE 0
01115 # define NORMAL  1
01116 # define UNCOLLECTABLE 2
01117 # ifdef ATOMIC_UNCOLLECTABLE
01118 #   define AUNCOLLECTABLE 3
01119 #   define STUBBORN 4
01120 #   define IS_UNCOLLECTABLE(k) (((k) & ~1) == UNCOLLECTABLE)
01121 # else
01122 #   define STUBBORN 3
01123 #   define IS_UNCOLLECTABLE(k) ((k) == UNCOLLECTABLE)
01124 # endif
01125 
01126 extern int GC_n_kinds;
01127 
01128 GC_API word GC_fo_entries;
01129 
01130 extern word GC_n_heap_sects;       /* Number of separately added heap */
01131                             /* sections.                       */
01132 
01133 extern word GC_page_size;
01134 
01135 # if defined(MSWIN32) || defined(MSWINCE)
01136   struct _SYSTEM_INFO;
01137   extern struct _SYSTEM_INFO GC_sysinfo;
01138   extern word GC_n_heap_bases;     /* See GC_heap_bases.       */
01139 # endif
01140 
01141 extern word GC_total_stack_black_listed;
01142                      /* Number of bytes on stack blacklist.    */
01143 
01144 extern word GC_black_list_spacing;
01145                      /* Average number of bytes between blacklisted   */
01146                      /* blocks. Approximate.                          */
01147                      /* Counts only blocks that are                   */
01148                      /* "stack-blacklisted", i.e. that are            */
01149                      /* problematic in the interior of an object.     */
01150 
01151 extern map_entry_type * GC_invalid_map;
01152                      /* Pointer to the nowhere valid hblk map */
01153                      /* Blocks pointing to this map are free. */
01154 
01155 extern struct hblk * GC_hblkfreelist[];
01156                             /* List of completely empty heap blocks   */
01157                             /* Linked through hb_next field of        */
01158                             /* header structure associated with       */
01159                             /* block.                          */
01160 
01161 extern GC_bool GC_objects_are_marked;     /* There are marked objects in  */
01162                                    /* the heap.                */
01163 
01164 #ifndef SMALL_CONFIG
01165   extern GC_bool GC_incremental;
01166                      /* Using incremental/generational collection. */
01167 # define TRUE_INCREMENTAL \
01168        (GC_incremental && GC_time_limit != GC_TIME_UNLIMITED)
01169        /* True incremental, not just generational, mode */
01170 #else
01171 # define GC_incremental FALSE
01172                      /* Hopefully allow optimizer to remove some code. */
01173 # define TRUE_INCREMENTAL FALSE
01174 #endif
01175 
01176 extern GC_bool GC_dirty_maintained;
01177                             /* Dirty bits are being maintained,       */
01178                             /* either for incremental collection,     */
01179                             /* or to limit the root set.              */
01180 
01181 extern word GC_root_size;   /* Total size of registered root sections */
01182 
01183 extern GC_bool GC_debugging_started;      /* GC_debug_malloc has been called. */ 
01184 
01185 extern long GC_large_alloc_warn_interval;
01186        /* Interval between unsuppressed warnings.       */
01187 
01188 extern long GC_large_alloc_warn_suppressed;
01189        /* Number of warnings suppressed so far.  */
01190 
01191 #ifdef THREADS
01192   extern GC_bool GC_world_stopped;
01193 #endif
01194 
01195 /* Operations */
01196 # ifndef abs
01197 #   define abs(x)  ((x) < 0? (-(x)) : (x))
01198 # endif
01199 
01200 
01201 /*  Marks are in a reserved area in                          */
01202 /*  each heap block.  Each word has one mark bit associated  */
01203 /*  with it. Only those corresponding to the beginning of an */
01204 /*  object are used.                                         */
01205 
01206 /* Set mark bit correctly, even if mark bits may be concurrently      */
01207 /* accessed.                                                   */
01208 #ifdef PARALLEL_MARK
01209 # define OR_WORD(addr, bits) \
01210        { word old; \
01211          do { \
01212            old = *((volatile word *)addr); \
01213          } while (!GC_compare_and_exchange((addr), old, old | (bits))); \
01214        }
01215 # define OR_WORD_EXIT_IF_SET(addr, bits, exit_label) \
01216        { word old; \
01217          word my_bits = (bits); \
01218          do { \
01219            old = *((volatile word *)addr); \
01220            if (old & my_bits) goto exit_label; \
01221          } while (!GC_compare_and_exchange((addr), old, old | my_bits)); \
01222        }
01223 #else
01224 # define OR_WORD(addr, bits) *(addr) |= (bits)
01225 # define OR_WORD_EXIT_IF_SET(addr, bits, exit_label) \
01226        { \
01227          word old = *(addr); \
01228          word my_bits = (bits); \
01229          if (old & my_bits) goto exit_label; \
01230          *(addr) = (old | my_bits); \
01231        }
01232 #endif
01233 
01234 /* Mark bit operations */
01235 
01236 /*
01237  * Retrieve, set, clear the mark bit corresponding
01238  * to the nth word in a given heap block.
01239  *
01240  * (Recall that bit n corresponds to object beginning at word n
01241  * relative to the beginning of the block, including unused words)
01242  */
01243 
01244 #ifdef USE_MARK_BYTES
01245 # define mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n) >> 1])
01246 # define set_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n)>>1]) = 1
01247 # define clear_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n)>>1]) = 0
01248 #else /* !USE_MARK_BYTES */
01249 # define mark_bit_from_hdr(hhdr,n) (((hhdr)->hb_marks[divWORDSZ(n)] \
01250                          >> (modWORDSZ(n))) & (word)1)
01251 # define set_mark_bit_from_hdr(hhdr,n) \
01252                          OR_WORD((hhdr)->hb_marks+divWORDSZ(n), \
01253                                 (word)1 << modWORDSZ(n))
01254 # define clear_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \
01255                             &= ~((word)1 << modWORDSZ(n))
01256 #endif /* !USE_MARK_BYTES */
01257 
01258 /* Important internal collector routines */
01259 
01260 ptr_t GC_approx_sp GC_PROTO((void));
01261   
01262 GC_bool GC_should_collect GC_PROTO((void));
01263   
01264 void GC_apply_to_all_blocks GC_PROTO(( \
01265     void (*fn) GC_PROTO((struct hblk *h, word client_data)), \
01266     word client_data));
01267                      /* Invoke fn(hbp, client_data) for each   */
01268                      /* allocated heap block.                  */
01269 struct hblk * GC_next_used_block GC_PROTO((struct hblk * h));
01270                      /* Return first in-use block >= h  */
01271 struct hblk * GC_prev_block GC_PROTO((struct hblk * h));
01272                      /* Return last block <= h.  Returned block       */
01273                      /* is managed by GC, but may or may not be in    */
01274                      /* use.                                          */
01275 void GC_mark_init GC_PROTO((void));
01276 void GC_clear_marks GC_PROTO((void));     /* Clear mark bits for all heap objects. */
01277 void GC_invalidate_mark_state GC_PROTO((void));
01278                                    /* Tell the marker that     marked           */
01279                                    /* objects may point to     unmarked   */
01280                                    /* ones, and roots may point to       */
01281                                    /* unmarked objects.           */
01282                                    /* Reset mark stack.           */
01283 GC_bool GC_mark_stack_empty GC_PROTO((void));
01284 GC_bool GC_mark_some GC_PROTO((ptr_t cold_gc_frame));
01285                      /* Perform about one pages worth of marking      */
01286                      /* work of whatever kind is needed.  Returns     */
01287                      /* quickly if no collection is in progress.      */
01288                      /* Return TRUE if mark phase finished.           */
01289 void GC_initiate_gc GC_PROTO((void));
01290                             /* initiate collection.                   */
01291                             /* If the mark state is invalid, this     */
01292                             /* becomes full colleection.  Otherwise */
01293                             /* it's partial.                   */
01294 void GC_push_all GC_PROTO((ptr_t bottom, ptr_t top));
01295                             /* Push everything in a range             */
01296                             /* onto mark stack.                */
01297 void GC_push_selected GC_PROTO(( \
01298     ptr_t bottom, \
01299     ptr_t top, \
01300     int (*dirty_fn) GC_PROTO((struct hblk *h)), \
01301     void (*push_fn) GC_PROTO((ptr_t bottom, ptr_t top)) ));
01302                               /* Push all pages h in [b,t) s.t.       */
01303                               /* select_fn(h) != 0 onto mark stack. */
01304 #ifndef SMALL_CONFIG
01305   void GC_push_conditional GC_PROTO((ptr_t b, ptr_t t, GC_bool all));
01306 #else
01307 # define GC_push_conditional(b, t, all) GC_push_all(b, t)
01308 #endif
01309                                 /* Do either of the above, depending  */
01310                             /* on the third arg.               */
01311 /* PLTSCHEME: GC_API */
01312 GC_API void GC_push_all_stack GC_PROTO((ptr_t b, ptr_t t));
01313                                 /* As above, but consider             */
01314                                 /*  interior pointers as valid        */
01315 void GC_push_all_eager GC_PROTO((ptr_t b, ptr_t t));
01316                                 /* Same as GC_push_all_stack, but   */
01317                                 /* ensures that stack is scanned      */
01318                                 /* immediately, not just scheduled  */
01319                                 /* for scanning.               */
01320 #ifndef THREADS
01321   void GC_push_all_stack_partially_eager GC_PROTO(( \
01322       ptr_t bottom, ptr_t top, ptr_t cold_gc_frame ));
01323                      /* Similar to GC_push_all_eager, but only the    */
01324                      /* part hotter than cold_gc_frame is scanned     */
01325                      /* immediately.  Needed to ensure that callee-   */
01326                      /* save registers are not missed.         */
01327 #else
01328   /* In the threads case, we push part of the current thread stack    */
01329   /* with GC_push_all_eager when we push the registers.  This gets the  */
01330   /* callee-save registers that may disappear.  The remainder of the  */
01331   /* stacks are scheduled for scanning in *GC_push_other_roots, which */
01332   /* is thread-package-specific.                               */
01333 #endif
01334 void GC_push_current_stack GC_PROTO((ptr_t cold_gc_frame));
01335                      /* Push enough of the current stack eagerly to   */
01336                      /* ensure that callee-save registers saved in    */
01337                      /* GC frames are scanned.                 */
01338                      /* In the non-threads case, schedule entire      */
01339                      /* stack for scanning.                           */
01340 void GC_push_roots GC_PROTO((GC_bool all, ptr_t cold_gc_frame));
01341                      /* Push all or dirty roots. */
01342 /* PLTSCHEME: GC_API */
01343 GC_API void (*GC_push_other_roots) GC_PROTO((void));
01344                      /* Push system or application specific roots     */
01345                      /* onto the mark stack.  In some environments    */
01346                      /* (e.g. threads environments) this is           */
01347                      /* predfined to be non-zero.  A client supplied */
01348                      /* replacement should also call the original     */
01349                      /* function.                              */
01350 extern void GC_push_gc_structures GC_PROTO((void));
01351                      /* Push GC internal roots.  These are normally   */
01352                      /* included in the static data segment, and      */
01353                      /* Thus implicitly pushed.  But we must do this  */
01354                      /* explicitly if normal root processing is       */
01355                      /* disabled.  Calls the following:        */
01356 /* PLTSCHEME: GC_API */
01357        GC_API void GC_push_finalizer_structures GC_PROTO((void));
01358        GC_API void GC_push_stubborn_structures GC_PROTO((void));
01359 #      ifdef THREADS
01360          extern void GC_push_thread_structures GC_PROTO((void));
01361 #      endif
01362 extern void (*GC_start_call_back) GC_PROTO((void));
01363                      /* Called at start of full collections.          */
01364                      /* Not called if 0.  Called with allocation      */
01365                      /* lock held.                             */
01366                      /* 0 by default.                          */
01367 # if defined(USE_GENERIC_PUSH_REGS)
01368   void GC_generic_push_regs GC_PROTO((ptr_t cold_gc_frame));
01369 # else
01370   void GC_push_regs GC_PROTO((void));
01371 # endif
01372 # if defined(SPARC) || defined(IA64)
01373   /* Cause all stacked registers to be saved in memory.  Return a     */
01374   /* pointer to the top of the corresponding memory stack.            */
01375   word GC_save_regs_in_stack GC_PROTO((void));
01376 # endif
01377                      /* Push register contents onto mark stack.       */
01378                      /* If NURSERY is defined, the default push       */
01379                      /* action can be overridden with GC_push_proc    */
01380 
01381 # ifdef NURSERY
01382     extern void (*GC_push_proc)(ptr_t);
01383 # endif
01384 # if defined(MSWIN32) || defined(MSWINCE)
01385   void __cdecl GC_push_one GC_PROTO((word p));
01386 # else
01387   void GC_push_one GC_PROTO((word p));
01388                            /* If p points to an object, mark it    */
01389                               /* and push contents on the mark stack  */
01390                            /* Pointer recognition test always      */
01391                            /* accepts interior pointers, i.e. this */
01392                            /* is appropriate for pointers found on */
01393                            /* stack.                                 */
01394 # endif
01395 # if defined(PRINT_BLACK_LIST) || defined(KEEP_BACK_PTRS)
01396   void GC_mark_and_push_stack GC_PROTO((word p, ptr_t source));
01397                             /* Ditto, omits plausibility test  */
01398 # else
01399   void GC_mark_and_push_stack GC_PROTO((word p));
01400 # endif
01401 void GC_push_marked GC_PROTO((struct hblk * h, hdr * hhdr));
01402               /* Push contents of all marked objects in h onto */
01403               /* mark stack.                                          */
01404 #ifdef SMALL_CONFIG
01405 # define GC_push_next_marked_dirty(h) GC_push_next_marked(h)
01406 #else
01407   struct hblk * GC_push_next_marked_dirty GC_PROTO((struct hblk * h));
01408               /* Invoke GC_push_marked on next dirty block above h.   */
01409               /* Return a pointer just past the end of this block.    */
01410 #endif /* !SMALL_CONFIG */
01411 struct hblk * GC_push_next_marked GC_PROTO((struct hblk * h));
01412               /* Ditto, but also mark from clean pages. */
01413 struct hblk * GC_push_next_marked_uncollectable GC_PROTO((struct hblk * h));
01414               /* Ditto, but mark only from uncollectable pages.       */
01415 GC_bool GC_stopped_mark GC_PROTO((GC_stop_func stop_func));
01416                      /* Stop world and mark from all roots     */
01417                      /* and rescuers.                   */
01418 void GC_clear_hdr_marks GC_PROTO((hdr * hhdr));
01419                                 /* Clear the mark bits in a header */
01420 void GC_set_hdr_marks GC_PROTO((hdr * hhdr));
01421                                 /* Set the mark bits in a header */
01422 void GC_set_fl_marks GC_PROTO((ptr_t p));
01423                                 /* Set all mark bits associated with */
01424                                 /* a free list.                 */
01425 void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp));
01426 void GC_remove_roots_inner GC_PROTO((char * b, char * e));
01427 GC_bool GC_is_static_root GC_PROTO((ptr_t p));
01428               /* Is the address p in one of the registered static     */
01429               /* root sections?                                */
01430 # if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION)
01431 GC_bool GC_is_tmp_root GC_PROTO((ptr_t p));
01432               /* Is the address p in one of the temporary static      */
01433               /* root sections?                                */
01434 # endif
01435 void GC_register_dynamic_libraries GC_PROTO((void));
01436               /* Add dynamic library data sections to the root set. */
01437 
01438 GC_bool GC_register_main_static_data GC_PROTO((void));
01439               /* We need to register the main data segment.  Returns  */
01440               /* TRUE unless this is done implicitly as part of       */
01441               /* dynamic library registration.                 */
01442   
01443 /* Machine dependent startup routines */
01444 /* PLTSCHEME: GC_API (IA64, too) */
01445 GC_API ptr_t GC_get_stack_base GC_PROTO((void)); /* Cold end of stack */
01446 #ifdef IA64
01447   GC_API ptr_t GC_get_register_stack_base GC_PROTO((void));
01448                                    /* Cold end of register stack.     */
01449 #endif
01450 void GC_register_data_segments GC_PROTO((void));
01451   
01452 /* Black listing: */
01453 void GC_bl_init GC_PROTO((void));
01454 # ifdef PRINT_BLACK_LIST
01455       void GC_add_to_black_list_normal GC_PROTO((word p, ptr_t source));
01456                      /* Register bits as a possible future false      */
01457                      /* reference from the heap or static data */
01458 #     define GC_ADD_TO_BLACK_LIST_NORMAL(bits, source) \
01459               if (GC_all_interior_pointers) { \
01460                 GC_add_to_black_list_stack(bits, (ptr_t)(source)); \
01461               } else { \
01462                 GC_add_to_black_list_normal(bits, (ptr_t)(source)); \
01463               }
01464 # else
01465       void GC_add_to_black_list_normal GC_PROTO((word p));
01466 #     define GC_ADD_TO_BLACK_LIST_NORMAL(bits, source) \
01467               if (GC_all_interior_pointers) { \
01468                 GC_add_to_black_list_stack(bits); \
01469               } else { \
01470                 GC_add_to_black_list_normal(bits); \
01471               }
01472 # endif
01473 
01474 # ifdef PRINT_BLACK_LIST
01475     void GC_add_to_black_list_stack GC_PROTO((word p, ptr_t source));
01476 # else
01477     void GC_add_to_black_list_stack GC_PROTO((word p));
01478 # endif
01479 struct hblk * GC_is_black_listed GC_PROTO((struct hblk * h, word len));
01480                      /* If there are likely to be false references    */
01481                      /* to a block starting at h of the indicated    */
01482                      /* length, then return the next plausible */
01483                      /* starting location for h that might avoid      */
01484                      /* these false references.                */
01485 void GC_promote_black_lists GC_PROTO((void));
01486                      /* Declare an end to a black listing phase.      */
01487 void GC_unpromote_black_lists GC_PROTO((void));
01488                      /* Approximately undo the effect of the above.   */
01489                      /* This actually loses some information, but     */
01490                      /* only in a reasonably safe way.         */
01491 word GC_number_stack_black_listed GC_PROTO(( \
01492        struct hblk *start, struct hblk *endp1));
01493                      /* Return the number of (stack) blacklisted      */
01494                      /* blocks in the range for statistical           */
01495                      /* purposes.                              */
01496                      
01497 ptr_t GC_scratch_alloc GC_PROTO((word bytes));
01498                             /* GC internal memory allocation for      */
01499                             /* small objects.  Deallocation is not  */
01500                             /* possible.                       */
01501        
01502 /* Heap block layout maps: */                    
01503 void GC_invalidate_map GC_PROTO((hdr * hhdr));
01504                             /* Remove the object map associated       */
01505                             /* with the block.  This identifies       */
01506                             /* the block as invalid to the mark       */
01507                             /* routines.                       */
01508 GC_bool GC_add_map_entry GC_PROTO((word sz));
01509                             /* Add a heap block map for objects of    */
01510                             /* size sz to obj_map.                    */
01511                             /* Return FALSE on failure.        */
01512 void GC_register_displacement_inner GC_PROTO((word offset));
01513                             /* Version of GC_register_displacement    */
01514                             /* that assumes lock is already held      */
01515                             /* and signals are already disabled.      */
01516   
01517 /*  hblk allocation: */            
01518 void GC_new_hblk GC_PROTO((word size_in_words, int kind));
01519                             /* Allocate a new heap block, and build */
01520                             /* a free list in it.                     */                          
01521 
01522 ptr_t GC_build_fl GC_PROTO((struct hblk *h, word sz,
01523                         GC_bool clear,  ptr_t list));
01524                             /* Build a free list for objects of       */
01525                             /* size sz in block h.  Append list to    */
01526                             /* end of the free lists.  Possibly       */
01527                             /* clear objects on the list.  Normally   */
01528                             /* called by GC_new_hblk, but also */
01529                             /* called explicitly without GC lock.     */
01530 
01531 struct hblk * GC_allochblk GC_PROTO(( \
01532        word size_in_words, int kind, unsigned flags));
01533                             /* Allocate a heap block, inform   */
01534                             /* the marker that block is valid  */
01535                             /* for objects of indicated size.  */
01536 
01537 ptr_t GC_alloc_large GC_PROTO((word lw, int k, unsigned flags));
01538                      /* Allocate a large block of size lw words.      */
01539                      /* The block is not cleared.                     */
01540                      /* Flags is 0 or IGNORE_OFF_PAGE.         */
01541                      /* Calls GC_allchblk to do the actual            */
01542                      /* allocation, but also triggers GC and/or       */
01543                      /* heap expansion as appropriate.         */
01544                      /* Does not update GC_words_allocd, but does     */
01545                      /* other accounting.                      */
01546 
01547 ptr_t GC_alloc_large_and_clear GC_PROTO((word lw, int k, unsigned flags));
01548                      /* As above, but clear block if appropriate      */
01549                      /* for kind k.                                   */
01550 
01551 void GC_freehblk GC_PROTO((struct hblk * p));
01552                             /* Deallocate a heap block and mark it  */
01553                             /* as invalid.                            */
01554                             
01555 /*  Misc GC: */
01556 void GC_init_inner GC_PROTO((void));
01557 GC_bool GC_expand_hp_inner GC_PROTO((word n));
01558 void GC_start_reclaim GC_PROTO((int abort_if_found));
01559                             /* Restore unmarked objects to free       */
01560                             /* lists, or (if abort_if_found is */
01561                             /* TRUE) report them.                     */
01562                             /* Sweeping of small object pages is      */
01563                             /* largely deferred.               */
01564 void GC_continue_reclaim GC_PROTO((word sz, int kind));
01565                             /* Sweep pages of the given size and      */
01566                             /* kind, as long as possible, and  */
01567                             /* as long as the corr. free list is    */
01568                             /* empty.                          */
01569 void GC_reclaim_or_delete_all GC_PROTO((void));
01570                             /* Arrange for all reclaim lists to be    */
01571                             /* empty.  Judiciously choose between     */
01572                             /* sweeping and discarding each page.     */
01573 GC_bool GC_reclaim_all GC_PROTO((GC_stop_func stop_func, GC_bool ignore_old));
01574                             /* Reclaim all blocks.  Abort (in a       */
01575                             /* consistent state) if f returns TRUE. */
01576 GC_bool GC_block_empty GC_PROTO((hdr * hhdr));
01577                             /* Block completely unmarked?      */
01578 GC_bool GC_never_stop_func GC_PROTO((void));
01579                             /* Returns FALSE.           */
01580 GC_bool GC_try_to_collect_inner GC_PROTO((GC_stop_func f));
01581 
01582                             /* Collect; caller must have acquired     */
01583                             /* lock and disabled signals.             */
01584                             /* Collection is aborted if f returns     */
01585                             /* TRUE.  Returns TRUE if it completes    */
01586                             /* successfully.                   */
01587 # define GC_gcollect_inner() \
01588        (void) GC_try_to_collect_inner(GC_never_stop_func)
01589 void GC_finish_collection GC_PROTO((void));
01590                             /* Finish collection.  Mark bits are      */
01591                             /* consistent and lock is still held.     */
01592 GC_bool GC_collect_or_expand GC_PROTO(( \
01593        word needed_blocks, GC_bool ignore_off_page));
01594                             /* Collect or expand heap in an attempt */
01595                             /* make the indicated number of free      */
01596                             /* blocks available.  Should be called    */
01597                             /* until the blocks are available or      */
01598                             /* until it fails by returning FALSE.     */
01599 
01600 extern GC_bool GC_is_initialized;  /* GC_init() has been run.  */
01601 
01602 #if defined(MSWIN32) || defined(MSWINCE)
01603   void GC_deinit GC_PROTO((void));
01604                                 /* Free any resources allocated by      */
01605                                 /* GC_init                              */
01606 #endif
01607 
01608 void GC_collect_a_little_inner GC_PROTO((int n));
01609                             /* Do n units worth of garbage            */
01610                             /* collection work, if appropriate.       */
01611                             /* A unit is an amount appropriate for  */
01612                             /* HBLKSIZE bytes of allocation.   */
01613 /* ptr_t GC_generic_malloc GC_PROTO((word lb, int k)); */
01614                             /* Allocate an object of the given */
01615                             /* kind.  By default, there are only      */
01616                             /* a few kinds: composite(pointerfree), */
01617                             /* atomic, uncollectable, etc.            */
01618                             /* We claim it's possible for clever      */
01619                             /* client code that understands GC */
01620                             /* internals to add more, e.g. to  */
01621                             /* communicate object layout info  */
01622                             /* to the collector.               */
01623                             /* The actual decl is in gc_mark.h.       */
01624 ptr_t GC_generic_malloc_ignore_off_page GC_PROTO((size_t b, int k));
01625                             /* As above, but pointers past the        */
01626                             /* first page of the resulting object     */
01627                             /* are ignored.                           */
01628 ptr_t GC_generic_malloc_inner GC_PROTO((word lb, int k));
01629                             /* Ditto, but I already hold lock, etc.   */
01630 ptr_t GC_generic_malloc_words_small_inner GC_PROTO((word lw, int k));
01631                             /* Analogous to the above, but assumes    */
01632                             /* a small object size, and bypasses      */
01633                             /* MERGE_SIZES mechanism.          */
01634 ptr_t GC_generic_malloc_words_small GC_PROTO((size_t lw, int k));
01635                             /* As above, but size in units of words */
01636                             /* Bypasses MERGE_SIZES.  Assumes  */
01637                             /* words <= MAXOBJSZ.                     */
01638 ptr_t GC_generic_malloc_inner_ignore_off_page GC_PROTO((size_t lb, int k));
01639                             /* Allocate an object, where              */
01640                             /* the client guarantees that there       */
01641                             /* will always be a pointer to the        */
01642                             /* beginning of the object while the      */
01643                             /* object is live.                 */
01644 ptr_t GC_allocobj GC_PROTO((word sz, int kind));
01645                             /* Make the indicated                     */
01646                             /* free list nonempty, and return its     */
01647                             /* head.                           */
01648 
01649 void GC_free_inner(GC_PTR p);
01650   
01651 void GC_init_headers GC_PROTO((void));
01652 struct hblkhdr * GC_install_header GC_PROTO((struct hblk *h));
01653                             /* Install a header for block h.   */
01654                             /* Return 0 on failure, or the header     */
01655                             /* otherwise.                      */
01656 GC_bool GC_install_counts GC_PROTO((struct hblk * h, word sz));
01657                             /* Set up forwarding counts for block     */
01658                             /* h of size sz.                   */
01659                             /* Return FALSE on failure.        */
01660 void GC_remove_header GC_PROTO((struct hblk * h));
01661                             /* Remove the header for block h.  */
01662 void GC_remove_counts GC_PROTO((struct hblk * h, word sz));
01663                             /* Remove forwarding counts for h. */
01664 hdr * GC_find_header GC_PROTO((ptr_t h)); /* Debugging only.          */
01665   
01666 void GC_finalize GC_PROTO((void));
01667                      /* Perform all indicated finalization actions    */
01668                      /* on unmarked objects.                          */
01669                      /* Unreachable finalizable objects are enqueued  */
01670                      /* for processing by GC_invoke_finalizers.       */
01671                      /* Invoked with lock.                            */
01672 
01673 void GC_notify_or_invoke_finalizers GC_PROTO((void));
01674                      /* If GC_finalize_on_demand is not set, invoke   */
01675                      /* eligible finalizers. Otherwise:        */
01676                      /* Call *GC_finalizer_notifier if there are      */
01677                      /* finalizers to be run, and we haven't called   */
01678                      /* this procedure yet this GC cycle.             */
01679 
01680 GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data));
01681 GC_API void GC_debug_invoke_finalizer GC_PROTO((GC_PTR obj, GC_PTR data));
01682                      /* Auxiliary fns to make finalization work       */
01683                      /* correctly with displaced pointers introduced  */
01684                      /* by the debugging allocators.                  */
01685                      
01686 void GC_add_to_heap GC_PROTO((struct hblk *p, word bytes));
01687                      /* Add a HBLKSIZE aligned chunk to the heap.     */
01688   
01689 void GC_print_obj GC_PROTO((ptr_t p));
01690                      /* P points to somewhere inside an object with   */
01691                      /* debugging info.  Print a human readable       */
01692                      /* description of the object to stderr.          */
01693 extern void (*GC_check_heap) GC_PROTO((void));
01694                      /* Check that all objects in the heap with       */
01695                      /* debugging info are intact.                    */
01696                      /* Add any that are not to GC_smashed list.      */
01697 extern void (*GC_print_all_smashed) GC_PROTO((void));
01698                      /* Print GC_smashed if it's not empty.           */
01699                      /* Clear GC_smashed list.                 */
01700 extern void GC_print_all_errors GC_PROTO((void));
01701                      /* Print smashed and leaked objects, if any.     */
01702                      /* Clear the lists of such objects.              */
01703 extern void (*GC_print_heap_obj) GC_PROTO((ptr_t p));
01704                      /* If possible print s followed by a more */
01705                      /* detailed description of the object            */
01706                      /* referred to by p.                      */
01707 #if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG)
01708   void GC_print_address_map GC_PROTO((void));
01709                      /* Print an address map of the process.          */
01710 #endif
01711 
01712 extern GC_bool GC_have_errors;  /* We saw a smashed or leaked object. */
01713                             /* Call error printing routine            */
01714                             /* occasionally.                   */
01715 extern GC_bool GC_print_stats;     /* Produce at least some logging output   */
01716                             /* Set from environment variable.  */
01717 
01718 #ifndef NO_DEBUGGING
01719   extern GC_bool GC_dump_regularly;  /* Generate regular debugging dumps. */
01720 # define COND_DUMP if (GC_dump_regularly) GC_dump();
01721 #else
01722 # define COND_DUMP
01723 #endif
01724 
01725 #ifdef KEEP_BACK_PTRS
01726   extern long GC_backtraces;
01727   void GC_generate_random_backtrace_no_gc(void);
01728 #endif
01729 
01730 extern GC_bool GC_print_back_height;
01731 
01732 #ifdef MAKE_BACK_GRAPH
01733   void GC_print_back_graph_stats(void);
01734 #endif
01735 
01736 /* Macros used for collector internal allocation.       */
01737 /* These assume the collector lock is held.             */
01738 #ifdef DBG_HDRS_ALL
01739     extern GC_PTR GC_debug_generic_malloc_inner(size_t lb, int k);
01740     extern GC_PTR GC_debug_generic_malloc_inner_ignore_off_page(size_t lb,
01741                                                         int k);
01742 #   define GC_INTERNAL_MALLOC GC_debug_generic_malloc_inner
01743 #   define GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE \
01744                GC_debug_generic_malloc_inner_ignore_off_page
01745 #   ifdef THREADS
01746 #       define GC_INTERNAL_FREE GC_debug_free_inner
01747 #   else
01748 #       define GC_INTERNAL_FREE GC_debug_free
01749 #   endif
01750 #else
01751 #   define GC_INTERNAL_MALLOC GC_generic_malloc_inner
01752 #   define GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE \
01753                GC_generic_malloc_inner_ignore_off_page
01754 #   ifdef THREADS
01755 #       define GC_INTERNAL_FREE GC_free_inner
01756 #   else
01757 #       define GC_INTERNAL_FREE GC_free
01758 #   endif
01759 #endif
01760 
01761 /* Memory unmapping: */
01762 #ifdef USE_MUNMAP
01763   void GC_unmap_old(void);
01764   void GC_merge_unmapped(void);
01765   void GC_unmap(ptr_t start, word bytes);
01766   void GC_remap(ptr_t start, word bytes);
01767   void GC_unmap_gap(ptr_t start1, word bytes1, ptr_t start2, word bytes2);
01768 #endif
01769 
01770 /* Virtual dirty bit implementation:             */
01771 /* Each implementation exports the following:    */
01772 void GC_read_dirty GC_PROTO((void));
01773                      /* Retrieve dirty bits.     */
01774 GC_bool GC_page_was_dirty GC_PROTO((struct hblk *h));
01775                      /* Read retrieved dirty bits.      */
01776 GC_bool GC_page_was_ever_dirty GC_PROTO((struct hblk *h));
01777                      /* Could the page contain valid heap pointers?   */
01778 void GC_is_fresh GC_PROTO((struct hblk *h, word n));
01779                      /* Assert the region currently contains no       */
01780                      /* valid pointers.                        */
01781 void GC_remove_protection GC_PROTO((struct hblk *h, word nblocks,
01782                                 GC_bool pointerfree));
01783                      /* h is about to be writteni or allocated.  Ensure  */
01784                      /* that it's not write protected by the virtual      */
01785                      /* dirty bit implementation.                         */
01786                      
01787 void GC_dirty_init GC_PROTO((void));
01788   
01789 /* Slow/general mark bit manipulation: */
01790 GC_API GC_bool GC_is_marked GC_PROTO((ptr_t p));
01791 void GC_clear_mark_bit GC_PROTO((ptr_t p));
01792 void GC_set_mark_bit GC_PROTO((ptr_t p));
01793   
01794 /* Stubborn objects: */
01795 void GC_read_changed GC_PROTO((void));    /* Analogous to GC_read_dirty */
01796 GC_bool GC_page_was_changed GC_PROTO((struct hblk * h));
01797                             /* Analogous to GC_page_was_dirty */
01798 void GC_clean_changing_list GC_PROTO((void));
01799                             /* Collect obsolete changing list entries */
01800 void GC_stubborn_init GC_PROTO((void));
01801   
01802 /* Debugging print routines: */
01803 void GC_print_block_list GC_PROTO((void));
01804 void GC_print_hblkfreelist GC_PROTO((void));
01805 void GC_print_heap_sects GC_PROTO((void));
01806 void GC_print_static_roots GC_PROTO((void));
01807 void GC_print_finalization_stats GC_PROTO((void));
01808 /* PLTSCHEME: GC_API */
01809 GC_API void GC_dump GC_PROTO((void));
01810 
01811 #ifdef KEEP_BACK_PTRS
01812    void GC_store_back_pointer(ptr_t source, ptr_t dest);
01813    void GC_marked_for_finalization(ptr_t dest);
01814 #  define GC_STORE_BACK_PTR(source, dest) GC_store_back_pointer(source, dest)
01815 #  define GC_MARKED_FOR_FINALIZATION(dest) GC_marked_for_finalization(dest)
01816 #else
01817 #  define GC_STORE_BACK_PTR(source, dest) 
01818 #  define GC_MARKED_FOR_FINALIZATION(dest)
01819 #endif
01820 
01821 /* Make arguments appear live to compiler */
01822 # ifdef __WATCOMC__
01823     void GC_noop(void*, ...);
01824 # else
01825 #   ifdef __DMC__
01826       GC_API void GC_noop(...);
01827 #   else
01828       GC_API void GC_noop();
01829 #   endif
01830 # endif
01831 
01832 void GC_noop1 GC_PROTO((word));
01833 
01834 /* Logging and diagnostic output:  */
01835 GC_API void GC_printf GC_PROTO((GC_CONST char * format, long, long, long, long, long, long));
01836                      /* A version of printf that doesn't allocate,    */
01837                      /* is restricted to long arguments, and          */
01838                      /* (unfortunately) doesn't use varargs for       */
01839                      /* portability.  Restricted to 6 args and */
01840                      /* 1K total output length.                */
01841                      /* (We use sprintf.  Hopefully that doesn't      */
01842                      /* allocate for long arguments.)          */
01843 # define GC_printf0(f) GC_printf(f, 0l, 0l, 0l, 0l, 0l, 0l)
01844 # define GC_printf1(f,a) GC_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l)
01845 # define GC_printf2(f,a,b) GC_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l)
01846 # define GC_printf3(f,a,b,c) GC_printf(f, (long)a, (long)b, (long)c, 0l, 0l, 0l)
01847 # define GC_printf4(f,a,b,c,d) GC_printf(f, (long)a, (long)b, (long)c, \
01848                                        (long)d, 0l, 0l)
01849 # define GC_printf5(f,a,b,c,d,e) GC_printf(f, (long)a, (long)b, (long)c, \
01850                                          (long)d, (long)e, 0l)
01851 # define GC_printf6(f,a,b,c,d,e,g) GC_printf(f, (long)a, (long)b, (long)c, \
01852                                           (long)d, (long)e, (long)g)
01853 
01854 GC_API void GC_err_printf GC_PROTO((GC_CONST char * format, long, long, long, long, long, long));
01855 # define GC_err_printf0(f) GC_err_puts(f)
01856 # define GC_err_printf1(f,a) GC_err_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l)
01857 # define GC_err_printf2(f,a,b) GC_err_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l)
01858 # define GC_err_printf3(f,a,b,c) GC_err_printf(f, (long)a, (long)b, (long)c, \
01859                                             0l, 0l, 0l)
01860 # define GC_err_printf4(f,a,b,c,d) GC_err_printf(f, (long)a, (long)b, \
01861                                               (long)c, (long)d, 0l, 0l)
01862 # define GC_err_printf5(f,a,b,c,d,e) GC_err_printf(f, (long)a, (long)b, \
01863                                                 (long)c, (long)d, \
01864                                                 (long)e, 0l)
01865 # define GC_err_printf6(f,a,b,c,d,e,g) GC_err_printf(f, (long)a, (long)b, \
01866                                                  (long)c, (long)d, \
01867                                                  (long)e, (long)g)
01868                      /* Ditto, writes to stderr.               */
01869                      
01870 void GC_err_puts GC_PROTO((GC_CONST char *s));
01871                      /* Write s to stderr, don't buffer, don't add    */
01872                      /* newlines, don't ...                           */
01873 
01874 #if defined(LINUX) && !defined(SMALL_CONFIG)
01875   void GC_err_write GC_PROTO((GC_CONST char *buf, size_t len));
01876                      /* Write buf to stderr, don't buffer, don't add  */
01877                      /* newlines, don't ...                           */
01878 #endif
01879 
01880 
01881 # ifdef GC_ASSERTIONS
01882 #      define GC_ASSERT(expr) if(!(expr)) {\
01883               GC_err_printf2("Assertion failure: %s:%ld\n", \
01884                             __FILE__, (unsigned long)__LINE__); \
01885               ABORT("assertion failure"); }
01886 # else 
01887 #      define GC_ASSERT(expr)
01888 # endif
01889 
01890 /* Check a compile time assertion at compile time.  The error  */
01891 /* message for failure is a bit baroque, but ...        */
01892 #if defined(mips) && !defined(__GNUC__)
01893 /* DOB: MIPSPro C gets an internal error taking the sizeof an array type. 
01894    This code works correctly (ugliness is to avoid "unused var" warnings) */
01895 # define GC_STATIC_ASSERT(expr) do { if (0) { char j[(expr)? 1 : -1]; j[0]='\0'; j[0]=j[0]; } } while(0)
01896 #else
01897 # define GC_STATIC_ASSERT(expr) sizeof(char[(expr)? 1 : -1])
01898 #endif
01899 
01900 # if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
01901     /* We need additional synchronization facilities from the thread  */
01902     /* support.  We believe these are less performance critical              */
01903     /* than the main garbage collector lock; standard pthreads-based  */
01904     /* implementations should be sufficient.                          */
01905 
01906     /* The mark lock and condition variable.  If the GC lock is also  */
01907     /* acquired, the GC lock must be acquired first.  The mark lock is       */
01908     /* used to both protect some variables used by the parallel              */
01909     /* marker, and to protect GC_fl_builder_count, below.             */
01910     /* GC_notify_all_marker() is called when                          */ 
01911     /* the state of the parallel marker changes                       */
01912     /* in some significant way (see gc_mark.h for details).  The      */
01913     /* latter set of events includes incrementing GC_mark_no.         */
01914     /* GC_notify_all_builder() is called when GC_fl_builder_count     */
01915     /* reaches 0.                                              */
01916 
01917      extern void GC_acquire_mark_lock();
01918      extern void GC_release_mark_lock();
01919      extern void GC_notify_all_builder();
01920      /* extern void GC_wait_builder(); */
01921      extern void GC_wait_for_reclaim();
01922 
01923      extern word GC_fl_builder_count;     /* Protected by mark lock.  */
01924 # endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */
01925 # ifdef PARALLEL_MARK
01926      extern void GC_notify_all_marker();
01927      extern void GC_wait_marker();
01928      extern word GC_mark_no;              /* Protected by mark lock.  */
01929 
01930      extern void GC_help_marker(word my_mark_no);
01931               /* Try to help out parallel marker for mark cycle       */
01932               /* my_mark_no.  Returns if the mark cycle finishes or   */
01933               /* was already done, or there was nothing to do for     */
01934               /* some other reason.                                   */
01935 # endif /* PARALLEL_MARK */
01936 
01937 # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS)
01938   /* We define the thread suspension signal here, so that we can refer       */
01939   /* to it in the dirty bit implementation, if necessary.  Ideally we */
01940   /* would allocate a (real-time ?) signal using the standard mechanism.*/
01941   /* unfortunately, there is no standard mechanism.  (There is one    */
01942   /* in Linux glibc, but it's not exported.)  Thus we continue to use */
01943   /* the same hard-coded signals we've always used.                   */
01944 #  if !defined(SIG_SUSPEND)
01945 #   if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)
01946 #    if defined(SPARC) && !defined(SIGPWR)
01947        /* SPARC/Linux doesn't properly define SIGPWR in <signal.h>.
01948         * It is aliased to SIGLOST in asm/signal.h, though.           */
01949 #      define SIG_SUSPEND SIGLOST
01950 #    else
01951        /* Linuxthreads itself uses SIGUSR1 and SIGUSR2.               */
01952 #      define SIG_SUSPEND SIGPWR
01953 #    endif
01954 #   else  /* !GC_LINUX_THREADS */
01955 #     if defined(_SIGRTMIN)
01956 #       define SIG_SUSPEND _SIGRTMIN + 6
01957 #     else
01958 #       define SIG_SUSPEND SIGRTMIN + 6
01959 #     endif       
01960 #   endif
01961 #  endif /* !SIG_SUSPEND */
01962   
01963 # endif
01964 
01965 # endif /* GC_PRIVATE_H */