[BACK]Return to gc_mark.h CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gc

Annotation of OpenXM_contrib/gc/gc_mark.h, Revision 1.1.1.2

1.1       maekawa     1: /*
                      2:  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
                      3:  *
                      4:  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
                      5:  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
                      6:  *
                      7:  * Permission is hereby granted to use or copy this program
                      8:  * for any purpose,  provided the above notices are retained on all copies.
                      9:  * Permission to modify the code and to distribute modified code is granted,
                     10:  * provided the above notices are retained, and a notice that the code was
                     11:  * modified is included with the above copyright notice.
                     12:  *
                     13:  */
                     14: /* Boehm, November 7, 1994 4:56 pm PST */
                     15:
                     16: /*
                     17:  * Declarations of mark stack.  Needed by marker and client supplied mark
                     18:  * routines.  To be included after gc_priv.h.
                     19:  */
                     20: #ifndef GC_MARK_H
                     21: # define GC_MARK_H
                     22:
                     23: /* A client supplied mark procedure.  Returns new mark stack pointer.  */
                     24: /* Primary effect should be to push new entries on the mark stack.     */
                     25: /* Mark stack pointer values are passed and returned explicitly.       */
                     26: /* Global variables decribing mark stack are not necessarily valid.    */
                     27: /* (This usually saves a few cycles by keeping things in registers.)   */
                     28: /* Assumed to scan about PROC_BYTES on average.  If it needs to do     */
                     29: /* much more work than that, it should do it in smaller pieces by      */
                     30: /* pushing itself back on the mark stack.                              */
                     31: /* Note that it should always do some work (defined as marking some    */
                     32: /* objects) before pushing more than one entry on the mark stack.      */
                     33: /* This is required to ensure termination in the event of mark stack   */
                     34: /* overflows.                                                          */
                     35: /* This procedure is always called with at least one empty entry on the */
                     36: /* mark stack.                                                         */
                     37: /* Currently we require that mark procedures look for pointers in a    */
                     38: /* subset of the places the conservative marker would.  It must be safe        */
                     39: /* to invoke the normal mark procedure instead.                                */
                     40: # define PROC_BYTES 100
                     41: /* The real declarations of the following are in gc_priv.h, so that    */
                     42: /* we can avoid scanning the following table.                          */
                     43: /*
                     44: typedef struct ms_entry * (*mark_proc)(   word * addr, mark_stack_ptr,
                     45:                                          mark_stack_limit, env   );
                     46:
                     47: # define LOG_MAX_MARK_PROCS 6
                     48: # define MAX_MARK_PROCS (1 << LOG_MAX_MARK_PROCS)
                     49: extern mark_proc GC_mark_procs[MAX_MARK_PROCS];
                     50: */
                     51:
                     52: extern word GC_n_mark_procs;
                     53:
                     54: /* Object descriptors on mark stack or in objects.  Low order two      */
                     55: /* bits are tags distinguishing among the following 4 possibilities    */
                     56: /* for the high order 30 bits.                                         */
                     57: #define DS_TAG_BITS 2
                     58: #define DS_TAGS   ((1 << DS_TAG_BITS) - 1)
                     59: #define DS_LENGTH 0    /* The entire word is a length in bytes that    */
                     60:                        /* must be a multiple of 4.                     */
                     61: #define DS_BITMAP 1    /* 30 bits are a bitmap describing pointer      */
                     62:                        /* fields.  The msb is 1 iff the first word     */
                     63:                        /* is a pointer.                                */
                     64:                        /* (This unconventional ordering sometimes      */
                     65:                        /* makes the marker slightly faster.)           */
                     66:                        /* Zeroes indicate definite nonpointers.  Ones  */
                     67:                        /* indicate possible pointers.                  */
                     68:                        /* Only usable if pointers are word aligned.    */
                     69: #   define BITMAP_BITS (WORDSZ - DS_TAG_BITS)
                     70: #define DS_PROC   2
                     71:                        /* The objects referenced by this object can be */
                     72:                        /* pushed on the mark stack by invoking         */
                     73:                        /* PROC(descr).  ENV(descr) is passed as the    */
                     74:                        /* last argument.                               */
                     75: #   define PROC(descr) \
                     76:                (GC_mark_procs[((descr) >> DS_TAG_BITS) & (MAX_MARK_PROCS-1)])
                     77: #   define ENV(descr) \
                     78:                ((descr) >> (DS_TAG_BITS + LOG_MAX_MARK_PROCS))
                     79: #   define MAX_ENV \
                     80:              (((word)1 << (WORDSZ - DS_TAG_BITS - LOG_MAX_MARK_PROCS)) - 1)
                     81: #   define MAKE_PROC(proc_index, env) \
                     82:            (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
                     83:            | DS_PROC)
                     84: #define DS_PER_OBJECT 3        /* The real descriptor is at the                */
                     85:                        /* byte displacement from the beginning of the  */
                     86:                        /* object given by descr & ~DS_TAGS             */
                     87:
                     88: typedef struct ms_entry {
                     89:     word * mse_start;   /* First word of object */
                     90:     word mse_descr;    /* Descriptor; low order two bits are tags,     */
                     91:                        /* identifying the upper 30 bits as one of the  */
                     92:                        /* following:                                   */
                     93: } mse;
                     94:
                     95: extern word GC_mark_stack_size;
                     96:
                     97: extern mse * GC_mark_stack_top;
                     98:
                     99: extern mse * GC_mark_stack;
                    100:
                    101: word GC_find_start();
                    102:
                    103: mse * GC_signal_mark_stack_overflow();
                    104:
                    105: # ifdef GATHERSTATS
                    106: #   define ADD_TO_ATOMIC(sz) GC_atomic_in_use += (sz)
                    107: #   define ADD_TO_COMPOSITE(sz) GC_composite_in_use += (sz)
                    108: # else
                    109: #   define ADD_TO_ATOMIC(sz)
                    110: #   define ADD_TO_COMPOSITE(sz)
                    111: # endif
                    112:
                    113: /* Push the object obj with corresponding heap block header hhdr onto  */
                    114: /* the mark stack.                                                     */
                    115: # define PUSH_OBJ(obj, hhdr, mark_stack_top, mark_stack_limit) \
                    116: { \
                    117:     register word _descr = (hhdr) -> hb_descr; \
                    118:         \
                    119:     if (_descr == 0) { \
                    120:        ADD_TO_ATOMIC((hhdr) -> hb_sz); \
                    121:     } else { \
                    122:         ADD_TO_COMPOSITE((hhdr) -> hb_sz); \
                    123:         mark_stack_top++; \
                    124:         if (mark_stack_top >= mark_stack_limit) { \
                    125:           mark_stack_top = GC_signal_mark_stack_overflow(mark_stack_top); \
                    126:         } \
                    127:         mark_stack_top -> mse_start = (obj); \
                    128:         mark_stack_top -> mse_descr = _descr; \
                    129:     } \
                    130: }
                    131:
                    132: #ifdef PRINT_BLACK_LIST
                    133: #   define GC_FIND_START(current, hhdr, source) \
                    134:        GC_find_start(current, hhdr, source)
                    135: #else
                    136: #   define GC_FIND_START(current, hhdr, source) \
                    137:        GC_find_start(current, hhdr)
                    138: #endif
                    139:
                    140: /* Push the contents of current onto the mark stack if it is a valid   */
                    141: /* ptr to a currently unmarked object.  Mark it.                       */
                    142: /* If we assumed a standard-conforming compiler, we could probably     */
                    143: /* generate the exit_label transparently.                              */
                    144: # define PUSH_CONTENTS(current, mark_stack_top, mark_stack_limit, \
                    145:                       source, exit_label) \
                    146: { \
                    147:     register int displ;  /* Displacement in block; first bytes, then words */ \
                    148:     register hdr * hhdr; \
                    149:     register map_entry_type map_entry; \
                    150:     \
                    151:     GET_HDR(current,hhdr); \
                    152:     if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \
                    153:          current = GC_FIND_START(current, hhdr, (word)source); \
                    154:          if (current == 0) goto exit_label; \
                    155:          hhdr = HDR(current); \
                    156:     } \
                    157:     displ = HBLKDISPL(current); \
                    158:     map_entry = MAP_ENTRY((hhdr -> hb_map), displ); \
                    159:     if (map_entry == OBJ_INVALID) { \
                    160:         GC_ADD_TO_BLACK_LIST_NORMAL(current, source); goto exit_label; \
                    161:     } \
                    162:     displ = BYTES_TO_WORDS(displ); \
                    163:     displ -= map_entry; \
                    164:        \
                    165:     { \
                    166:         register word * mark_word_addr = hhdr -> hb_marks + divWORDSZ(displ); \
                    167:         register word mark_word = *mark_word_addr; \
                    168:         register word mark_bit = (word)1 << modWORDSZ(displ); \
                    169:           \
                    170:         if (mark_word & mark_bit) { \
                    171:              /* Mark bit is already set */ \
                    172:              goto exit_label; \
                    173:         } \
1.1.1.2 ! maekawa   174:         GC_STORE_BACK_PTR((ptr_t)source, (ptr_t)HBLKPTR(current) \
        !           175:                                      + WORDS_TO_BYTES(displ)); \
1.1       maekawa   176:         *mark_word_addr = mark_word | mark_bit; \
                    177:     } \
                    178:     PUSH_OBJ(((word *)(HBLKPTR(current)) + displ), hhdr, \
                    179:             mark_stack_top, mark_stack_limit) \
                    180:   exit_label: ; \
                    181: }
                    182:
                    183: #ifdef PRINT_BLACK_LIST
                    184: #   define PUSH_ONE_CHECKED(p, ip, source) \
                    185:        GC_push_one_checked(p, ip, (ptr_t)(source))
                    186: #else
                    187: #   define PUSH_ONE_CHECKED(p, ip, source) \
                    188:        GC_push_one_checked(p, ip)
                    189: #endif
                    190:
                    191: /*
                    192:  * Push a single value onto mark stack. Mark from the object pointed to by p.
                    193:  * P is considered valid even if it is an interior pointer.
                    194:  * Previously marked objects are not pushed.  Hence we make progress even
                    195:  * if the mark stack overflows.
                    196:  */
                    197: # define GC_PUSH_ONE_STACK(p, source) \
                    198:     if ((ptr_t)(p) >= GC_least_plausible_heap_addr     \
                    199:         && (ptr_t)(p) < GC_greatest_plausible_heap_addr) {     \
                    200:         PUSH_ONE_CHECKED(p, TRUE, source);     \
                    201:     }
                    202:
                    203: /*
                    204:  * As above, but interior pointer recognition as for
                    205:  * normal for heap pointers.
                    206:  */
                    207: # ifdef ALL_INTERIOR_POINTERS
                    208: #   define AIP TRUE
                    209: # else
                    210: #   define AIP FALSE
                    211: # endif
                    212: # define GC_PUSH_ONE_HEAP(p,source) \
                    213:     if ((ptr_t)(p) >= GC_least_plausible_heap_addr     \
                    214:         && (ptr_t)(p) < GC_greatest_plausible_heap_addr) {     \
                    215:         PUSH_ONE_CHECKED(p,AIP,source);        \
                    216:     }
                    217:
                    218: /*
                    219:  * Mark from one finalizable object using the specified
                    220:  * mark proc. May not mark the object pointed to by
                    221:  * real_ptr. That is the job of the caller, if appropriate
                    222:  */
                    223: # define GC_MARK_FO(real_ptr, mark_proc) \
                    224: { \
                    225:     (*(mark_proc))(real_ptr); \
                    226:     while (!GC_mark_stack_empty()) GC_mark_from_mark_stack(); \
                    227:     if (GC_mark_state != MS_NONE) { \
                    228:         GC_set_mark_bit(real_ptr); \
                    229:         while (!GC_mark_some((ptr_t)0)); \
                    230:     } \
                    231: }
                    232:
                    233: extern GC_bool GC_mark_stack_too_small;
                    234:                                /* We need a larger mark stack.  May be */
                    235:                                /* set by client supplied mark routines.*/
                    236:
                    237: typedef int mark_state_t;      /* Current state of marking, as follows:*/
                    238:                                /* Used to remember where we are during */
                    239:                                /* concurrent marking.                  */
                    240:
                    241:                                /* We say something is dirty if it was  */
                    242:                                /* written since the last time we       */
                    243:                                /* retrieved dirty bits.  We say it's   */
                    244:                                /* grungy if it was marked dirty in the */
                    245:                                /* last set of bits we retrieved.       */
                    246:
                    247:                                /* Invariant I: all roots and marked    */
                    248:                                /* objects p are either dirty, or point */
                    249:                                /* to objects q that are either marked  */
                    250:                                /* or a pointer to q appears in a range */
                    251:                                /* on the mark stack.                   */
                    252:
                    253: # define MS_NONE 0             /* No marking in progress. I holds.     */
                    254:                                /* Mark stack is empty.                 */
                    255:
                    256: # define MS_PUSH_RESCUERS 1    /* Rescuing objects are currently       */
                    257:                                /* being pushed.  I holds, except       */
                    258:                                /* that grungy roots may point to       */
                    259:                                /* unmarked objects, as may marked      */
                    260:                                /* grungy objects above scan_ptr.       */
                    261:
                    262: # define MS_PUSH_UNCOLLECTABLE 2
                    263:                                /* I holds, except that marked          */
                    264:                                /* uncollectable objects above scan_ptr */
                    265:                                /* may point to unmarked objects.       */
                    266:                                /* Roots may point to unmarked objects  */
                    267:
                    268: # define MS_ROOTS_PUSHED 3     /* I holds, mark stack may be nonempty  */
                    269:
                    270: # define MS_PARTIALLY_INVALID 4        /* I may not hold, e.g. because of M.S. */
                    271:                                /* overflow.  However marked heap       */
                    272:                                /* objects below scan_ptr point to      */
                    273:                                /* marked or stacked objects.           */
                    274:
                    275: # define MS_INVALID 5          /* I may not hold.                      */
                    276:
                    277: extern mark_state_t GC_mark_state;
                    278:
                    279: #endif  /* GC_MARK_H */
                    280:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>