version 1.2, 2002/07/24 07:46:36 |
version 1.3, 2002/07/24 08:00:20 |
|
|
#ifndef GC_PMARK_H |
#ifndef GC_PMARK_H |
# define GC_PMARK_H |
# define GC_PMARK_H |
|
|
# ifdef KEEP_BACK_PTRS |
# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) |
# include "dbg_mlc.h" |
# include "dbg_mlc.h" |
# endif |
# endif |
# ifndef GC_MARK_H |
# ifndef GC_MARK_H |
Line 132 extern mse * GC_mark_stack; |
|
Line 132 extern mse * GC_mark_stack; |
|
*/ |
*/ |
#endif /* PARALLEL_MARK */ |
#endif /* PARALLEL_MARK */ |
|
|
ptr_t GC_find_start(); |
/* Return a pointer to within 1st page of object. */ |
|
/* Set *new_hdr_p to corr. hdr. */ |
|
#ifdef __STDC__ |
|
# ifdef PRINT_BLACK_LIST |
|
ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p, |
|
word source); |
|
# else |
|
ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p); |
|
# endif |
|
#else |
|
ptr_t GC_find_start(); |
|
#endif |
|
|
mse * GC_signal_mark_stack_overflow(); |
mse * GC_signal_mark_stack_overflow GC_PROTO((mse *msp)); |
|
|
# ifdef GATHERSTATS |
# ifdef GATHERSTATS |
# define ADD_TO_ATOMIC(sz) GC_atomic_in_use += (sz) |
# define ADD_TO_ATOMIC(sz) GC_atomic_in_use += (sz) |
Line 163 mse * GC_signal_mark_stack_overflow(); |
|
Line 174 mse * GC_signal_mark_stack_overflow(); |
|
} \ |
} \ |
} |
} |
|
|
#ifdef PRINT_BLACK_LIST |
|
# define GC_FIND_START(current, hhdr, source) \ |
|
GC_find_start(current, hhdr, source) |
|
#else |
|
# define GC_FIND_START(current, hhdr, source) \ |
|
GC_find_start(current, hhdr) |
|
#endif |
|
|
|
/* Push the contents of current onto the mark stack if it is a valid */ |
/* Push the contents of current onto the mark stack if it is a valid */ |
/* ptr to a currently unmarked object. Mark it. */ |
/* ptr to a currently unmarked object. Mark it. */ |
/* If we assumed a standard-conforming compiler, we could probably */ |
/* If we assumed a standard-conforming compiler, we could probably */ |
Line 183 mse * GC_signal_mark_stack_overflow(); |
|
Line 186 mse * GC_signal_mark_stack_overflow(); |
|
\ |
\ |
GET_HDR(my_current, my_hhdr); \ |
GET_HDR(my_current, my_hhdr); \ |
if (IS_FORWARDING_ADDR_OR_NIL(my_hhdr)) { \ |
if (IS_FORWARDING_ADDR_OR_NIL(my_hhdr)) { \ |
my_current = GC_FIND_START(my_current, my_hhdr, (word)source); \ |
hdr * new_hdr = GC_invalid_header; \ |
if (my_current == 0) goto exit_label; \ |
my_current = GC_find_start(my_current, my_hhdr, &new_hdr); \ |
my_hhdr = GC_find_header(my_current); \ |
my_hhdr = new_hdr; \ |
} \ |
} \ |
PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \ |
PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \ |
source, exit_label, my_hhdr); \ |
source, exit_label, my_hhdr); \ |
|
|
exit_label: ; \ |
exit_label: ; \ |
} |
} |
|
|
/* As above, but deal with two pointers in interleaved fashion. */ |
|
# define HC_PUSH_CONTENTS2(current1, current2, mark_stack_top, \ |
|
mark_stack_limit, \ |
|
source1, source2, exit_label1, exit_label2) \ |
|
{ \ |
|
hdr * hhdr1; \ |
|
ptr_t my_current1 = current1; \ |
|
hdr * hhdr2; \ |
|
ptr_t my_current2 = current2; \ |
|
\ |
|
HC_GET_HDR2(my_current1, hhdr1, source1, my_current2, hhdr2, source2); \ |
|
PUSH_CONTENTS_HDR(my_current1, mark_stack_top, mark_stack_limit, \ |
|
source1, exit_label1, hhdr1); \ |
|
exit_label1: ; \ |
|
if (0 != hhdr2) { \ |
|
PUSH_CONTENTS_HDR(my_current2, mark_stack_top, mark_stack_limit, \ |
|
source2, exit_label2, hhdr2); \ |
|
} \ |
|
exit_label2: ; \ |
|
} |
|
|
|
/* Set mark bit, exit if it was already set. */ |
/* Set mark bit, exit if it was already set. */ |
|
|
# ifdef USE_MARK_BYTES |
# ifdef USE_MARK_BYTES |
Line 245 exit_label2: ; \ |
|
Line 227 exit_label2: ; \ |
|
# define SET_MARK_BIT_EXIT_IF_SET(hhdr,displ,exit_label) \ |
# define SET_MARK_BIT_EXIT_IF_SET(hhdr,displ,exit_label) \ |
{ \ |
{ \ |
register word * mark_word_addr = hhdr -> hb_marks + divWORDSZ(displ); \ |
register word * mark_word_addr = hhdr -> hb_marks + divWORDSZ(displ); \ |
register word mark_word = *mark_word_addr; \ |
|
\ |
\ |
OR_WORD_EXIT_IF_SET(mark_word_addr, (word)1 << modWORDSZ(displ), \ |
OR_WORD_EXIT_IF_SET(mark_word_addr, (word)1 << modWORDSZ(displ), \ |
exit_label); \ |
exit_label); \ |
Line 253 exit_label2: ; \ |
|
Line 234 exit_label2: ; \ |
|
# endif /* USE_MARK_BYTES */ |
# endif /* USE_MARK_BYTES */ |
|
|
/* If the mark bit corresponding to current is not set, set it, and */ |
/* If the mark bit corresponding to current is not set, set it, and */ |
/* push the contents of the object on the mark stack. Since we */ |
/* push the contents of the object on the mark stack. For a small */ |
/* already have the header, we only look at the low order bits of */ |
/* object we assume that current is the (possibly interior) pointer */ |
/* current. (The value of current doesn't matter if hhdr = */ |
/* to the object. For large objects we assume that current points */ |
/* GC_invalid_header.) */ |
/* to somewhere inside the first page of the object. If */ |
|
/* GC_all_interior_pointers is set, it may have been previously */ |
|
/* adjusted to make that true. */ |
# define PUSH_CONTENTS_HDR(current, mark_stack_top, mark_stack_limit, \ |
# define PUSH_CONTENTS_HDR(current, mark_stack_top, mark_stack_limit, \ |
source, exit_label, hhdr) \ |
source, exit_label, hhdr) \ |
{ \ |
{ \ |
Line 342 mse * GC_mark_from GC_PROTO((mse * top, mse * bottom, |
|
Line 325 mse * GC_mark_from GC_PROTO((mse * top, mse * bottom, |
|
while (!GC_mark_stack_empty()) MARK_FROM_MARK_STACK(); \ |
while (!GC_mark_stack_empty()) MARK_FROM_MARK_STACK(); \ |
if (GC_mark_state != MS_NONE) { \ |
if (GC_mark_state != MS_NONE) { \ |
GC_set_mark_bit(real_ptr); \ |
GC_set_mark_bit(real_ptr); \ |
while (!GC_mark_some((ptr_t)0)); \ |
while (!GC_mark_some((ptr_t)0)) {} \ |
} \ |
} \ |
} |
} |
|
|