Newer
Older
/*
* 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.
*
* 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>
#if defined(MSWIN32) && defined(__GNUC__)
# include <excpt.h>
#endif
/* We put this here to minimize the risk of inlining. */
/*VARARGS*/
#ifdef __WATCOMC__
void GC_noop(void *p, ...) {}
#else
void GC_noop() {}
#endif
/* 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;
/* 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, /* Adjusted in GC_init_inner for EXTRA_BYTES */
TRUE /* add length to descr */, TRUE },
/* UNCOLLECTABLE */
{ &GC_uobjfreelist[0], 0,
0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE },
# ifdef ATOMIC_UNCOLLECTABLE
/* AUNCOLLECTABLE */
{ &GC_auobjfreelist[0], 0,
0 | GC_DS_LENGTH, FALSE /* add length to descr */, FALSE },
# endif
# ifdef STUBBORN_ALLOC
/*STUBBORN*/ { &GC_sobjfreelist[0], 0,
0 | GC_DS_LENGTH, TRUE /* add length to descr */, TRUE },
# 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. */
# 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;
#ifdef PARALLEL_MARK
mse * VOLATILE GC_mark_stack_top;
#else
mse * GC_mark_stack_top;
#endif
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. */
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
}
/* 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
}
}
/*
* 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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
{
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...