Skip to content
Snippets Groups Projects
mark.c 54.6 KiB
Newer Older
tromey's avatar
tromey committed

/*
 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
 * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.
 * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
tromey's avatar
tromey committed
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 * Permission is hereby granted to use or copy this program
 * for any purpose,  provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 *
 */


# include <stdio.h>
# include "private/gc_pmark.h"
tromey's avatar
tromey committed

jsturm's avatar
jsturm committed
#if defined(MSWIN32) && defined(__GNUC__)
# include <excpt.h>
#endif

tromey's avatar
tromey committed
/* We put this here to minimize the risk of inlining. */
/*VARARGS*/
#ifdef __WATCOMC__
  void GC_noop(void *p, ...) {}
#else
  void GC_noop() {}
#endif
tromey's avatar
tromey committed

/* Single argument version, robust against whole program analysis. */
void GC_noop1(x)
word x;
{
    static VOLATILE word sink;

    sink = x;
}

/* mark_proc GC_mark_procs[MAX_MARK_PROCS] = {0} -- declared in gc_priv.h */

word GC_n_mark_procs = GC_RESERVED_MARK_PROCS;
tromey's avatar
tromey committed

/* Initialize GC_obj_kinds properly and standard free lists properly.  	*/
/* This must be done statically since they may be accessed before 	*/
/* GC_init is called.							*/
/* It's done here, since we need to deal with mark descriptors.		*/
struct obj_kind GC_obj_kinds[MAXOBJKINDS] = {
/* PTRFREE */ { &GC_aobjfreelist[0], 0 /* filled in dynamically */,
		0 | GC_DS_LENGTH, FALSE, FALSE },
tromey's avatar
tromey committed
/* NORMAL  */ { &GC_objfreelist[0], 0,
		0 | GC_DS_LENGTH,  /* Adjusted in GC_init_inner for EXTRA_BYTES */
tromey's avatar
tromey committed
		TRUE /* add length to descr */, TRUE },
/* UNCOLLECTABLE */
	      { &GC_uobjfreelist[0], 0,
		0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE },
tromey's avatar
tromey committed
# ifdef ATOMIC_UNCOLLECTABLE
   /* AUNCOLLECTABLE */
	      { &GC_auobjfreelist[0], 0,
		0 | GC_DS_LENGTH, FALSE /* add length to descr */, FALSE },
tromey's avatar
tromey committed
# endif
# ifdef STUBBORN_ALLOC
/*STUBBORN*/ { &GC_sobjfreelist[0], 0,
		0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE },
tromey's avatar
tromey committed
# endif
};

# ifdef ATOMIC_UNCOLLECTABLE
#   ifdef STUBBORN_ALLOC
      int GC_n_kinds = 5;
#   else
      int GC_n_kinds = 4;
#   endif
# else
#   ifdef STUBBORN_ALLOC
      int GC_n_kinds = 4;
#   else
      int GC_n_kinds = 3;
#   endif
# endif


# ifndef INITIAL_MARK_STACK_SIZE
#   define INITIAL_MARK_STACK_SIZE (1*HBLKSIZE)
		/* INITIAL_MARK_STACK_SIZE * sizeof(mse) should be a 	*/
		/* multiple of HBLKSIZE.				*/
		/* The incremental collector actually likes a larger	*/
		/* size, since it want to push all marked dirty objs	*/
		/* before marking anything new.  Currently we let it	*/
		/* grow dynamically.					*/
tromey's avatar
tromey committed
# endif

/*
 * Limits of stack for GC_mark routine.
 * All ranges between GC_mark_stack(incl.) and GC_mark_stack_top(incl.) still
 * need to be marked from.
 */

word GC_n_rescuing_pages;	/* Number of dirty pages we marked from */
				/* excludes ptrfree pages, etc.		*/

mse * GC_mark_stack;

mse * GC_mark_stack_limit;

tromey's avatar
tromey committed
word GC_mark_stack_size = 0;
 
#ifdef PARALLEL_MARK
  mse * VOLATILE GC_mark_stack_top;
#else
  mse * GC_mark_stack_top;
#endif
tromey's avatar
tromey committed

static struct hblk * scan_ptr;

mark_state_t GC_mark_state = MS_NONE;

GC_bool GC_mark_stack_too_small = FALSE;

GC_bool GC_objects_are_marked = FALSE;	/* Are there collectable marked	*/
					/* objects in the heap?		*/

/* Is a collection in progress?  Note that this can return true in the	*/
/* nonincremental case, if a collection has been abandoned and the	*/
/* mark state is now MS_INVALID.					*/
tromey's avatar
tromey committed
GC_bool GC_collection_in_progress()
{
    return(GC_mark_state != MS_NONE);
}

/* clear all mark bits in the header */
void GC_clear_hdr_marks(hhdr)
register hdr * hhdr;
{
#   ifdef USE_MARK_BYTES
      BZERO(hhdr -> hb_marks, MARK_BITS_SZ);
#   else
      BZERO(hhdr -> hb_marks, MARK_BITS_SZ*sizeof(word));
#   endif
tromey's avatar
tromey committed
}

/* Set all mark bits in the header.  Used for uncollectable blocks. */
void GC_set_hdr_marks(hhdr)
register hdr * hhdr;
{
    register int i;

    for (i = 0; i < MARK_BITS_SZ; ++i) {
#     ifdef USE_MARK_BYTES
    	hhdr -> hb_marks[i] = 1;
#     else
tromey's avatar
tromey committed
    	hhdr -> hb_marks[i] = ONES;
#     endif
tromey's avatar
tromey committed
    }
}

/*
 * Clear all mark bits associated with block h.
 */
/*ARGSUSED*/
# if defined(__STDC__) || defined(__cplusplus)
    static void clear_marks_for_block(struct hblk *h, word dummy)
# else
    static void clear_marks_for_block(h, dummy)
    struct hblk *h;
    word dummy;
# endif
tromey's avatar
tromey committed
{
    register hdr * hhdr = HDR(h);
    
    if (IS_UNCOLLECTABLE(hhdr -> hb_obj_kind)) return;
        /* Mark bit for these is cleared only once the object is 	*/
        /* explicitly deallocated.  This either frees the block, or	*/
        /* the bit is cleared once the object is on the free list.	*/
    GC_clear_hdr_marks(hhdr);
}

/* Slow but general routines for setting/clearing/asking about mark bits */
void GC_set_mark_bit(p)
ptr_t p;
{
    register struct hblk *h = HBLKPTR(p);
    register hdr * hhdr = HDR(h);
    register int word_no = (word *)p - (word *)h;
    
    set_mark_bit_from_hdr(hhdr, word_no);
}

void GC_clear_mark_bit(p)
ptr_t p;
{
    register struct hblk *h = HBLKPTR(p);
    register hdr * hhdr = HDR(h);
    register int word_no = (word *)p - (word *)h;
    
    clear_mark_bit_from_hdr(hhdr, word_no);
}
Loading
Loading full blame...