[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.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:         } \
        !           174:         *mark_word_addr = mark_word | mark_bit; \
        !           175:     } \
        !           176:     PUSH_OBJ(((word *)(HBLKPTR(current)) + displ), hhdr, \
        !           177:             mark_stack_top, mark_stack_limit) \
        !           178:   exit_label: ; \
        !           179: }
        !           180:
        !           181: #ifdef PRINT_BLACK_LIST
        !           182: #   define PUSH_ONE_CHECKED(p, ip, source) \
        !           183:        GC_push_one_checked(p, ip, (ptr_t)(source))
        !           184: #else
        !           185: #   define PUSH_ONE_CHECKED(p, ip, source) \
        !           186:        GC_push_one_checked(p, ip)
        !           187: #endif
        !           188:
        !           189: /*
        !           190:  * Push a single value onto mark stack. Mark from the object pointed to by p.
        !           191:  * P is considered valid even if it is an interior pointer.
        !           192:  * Previously marked objects are not pushed.  Hence we make progress even
        !           193:  * if the mark stack overflows.
        !           194:  */
        !           195: # define GC_PUSH_ONE_STACK(p, source) \
        !           196:     if ((ptr_t)(p) >= GC_least_plausible_heap_addr     \
        !           197:         && (ptr_t)(p) < GC_greatest_plausible_heap_addr) {     \
        !           198:         PUSH_ONE_CHECKED(p, TRUE, source);     \
        !           199:     }
        !           200:
        !           201: /*
        !           202:  * As above, but interior pointer recognition as for
        !           203:  * normal for heap pointers.
        !           204:  */
        !           205: # ifdef ALL_INTERIOR_POINTERS
        !           206: #   define AIP TRUE
        !           207: # else
        !           208: #   define AIP FALSE
        !           209: # endif
        !           210: # define GC_PUSH_ONE_HEAP(p,source) \
        !           211:     if ((ptr_t)(p) >= GC_least_plausible_heap_addr     \
        !           212:         && (ptr_t)(p) < GC_greatest_plausible_heap_addr) {     \
        !           213:         PUSH_ONE_CHECKED(p,AIP,source);        \
        !           214:     }
        !           215:
        !           216: /*
        !           217:  * Mark from one finalizable object using the specified
        !           218:  * mark proc. May not mark the object pointed to by
        !           219:  * real_ptr. That is the job of the caller, if appropriate
        !           220:  */
        !           221: # define GC_MARK_FO(real_ptr, mark_proc) \
        !           222: { \
        !           223:     (*(mark_proc))(real_ptr); \
        !           224:     while (!GC_mark_stack_empty()) GC_mark_from_mark_stack(); \
        !           225:     if (GC_mark_state != MS_NONE) { \
        !           226:         GC_set_mark_bit(real_ptr); \
        !           227:         while (!GC_mark_some((ptr_t)0)); \
        !           228:     } \
        !           229: }
        !           230:
        !           231: extern GC_bool GC_mark_stack_too_small;
        !           232:                                /* We need a larger mark stack.  May be */
        !           233:                                /* set by client supplied mark routines.*/
        !           234:
        !           235: typedef int mark_state_t;      /* Current state of marking, as follows:*/
        !           236:                                /* Used to remember where we are during */
        !           237:                                /* concurrent marking.                  */
        !           238:
        !           239:                                /* We say something is dirty if it was  */
        !           240:                                /* written since the last time we       */
        !           241:                                /* retrieved dirty bits.  We say it's   */
        !           242:                                /* grungy if it was marked dirty in the */
        !           243:                                /* last set of bits we retrieved.       */
        !           244:
        !           245:                                /* Invariant I: all roots and marked    */
        !           246:                                /* objects p are either dirty, or point */
        !           247:                                /* to objects q that are either marked  */
        !           248:                                /* or a pointer to q appears in a range */
        !           249:                                /* on the mark stack.                   */
        !           250:
        !           251: # define MS_NONE 0             /* No marking in progress. I holds.     */
        !           252:                                /* Mark stack is empty.                 */
        !           253:
        !           254: # define MS_PUSH_RESCUERS 1    /* Rescuing objects are currently       */
        !           255:                                /* being pushed.  I holds, except       */
        !           256:                                /* that grungy roots may point to       */
        !           257:                                /* unmarked objects, as may marked      */
        !           258:                                /* grungy objects above scan_ptr.       */
        !           259:
        !           260: # define MS_PUSH_UNCOLLECTABLE 2
        !           261:                                /* I holds, except that marked          */
        !           262:                                /* uncollectable objects above scan_ptr */
        !           263:                                /* may point to unmarked objects.       */
        !           264:                                /* Roots may point to unmarked objects  */
        !           265:
        !           266: # define MS_ROOTS_PUSHED 3     /* I holds, mark stack may be nonempty  */
        !           267:
        !           268: # define MS_PARTIALLY_INVALID 4        /* I may not hold, e.g. because of M.S. */
        !           269:                                /* overflow.  However marked heap       */
        !           270:                                /* objects below scan_ptr point to      */
        !           271:                                /* marked or stacked objects.           */
        !           272:
        !           273: # define MS_INVALID 5          /* I may not hold.                      */
        !           274:
        !           275: extern mark_state_t GC_mark_state;
        !           276:
        !           277: #endif  /* GC_MARK_H */
        !           278:

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