| version 1.1.1.2, 2000/04/14 11:08:00 |
version 1.1.1.3, 2000/12/01 14:48:26 |
|
|
| #ifndef GC_MARK_H |
#ifndef GC_MARK_H |
| # define GC_MARK_H |
# define GC_MARK_H |
| |
|
| |
# ifdef KEEP_BACK_PTRS |
| |
# include "dbg_mlc.h" |
| |
# endif |
| |
|
| /* A client supplied mark procedure. Returns new mark stack pointer. */ |
/* A client supplied mark procedure. Returns new mark stack pointer. */ |
| /* Primary effect should be to push new entries on the mark stack. */ |
/* Primary effect should be to push new entries on the mark stack. */ |
| /* Mark stack pointer values are passed and returned explicitly. */ |
/* Mark stack pointer values are passed and returned explicitly. */ |
|
|
| /* The real declarations of the following are in gc_priv.h, so that */ |
/* The real declarations of the following are in gc_priv.h, so that */ |
| /* we can avoid scanning the following table. */ |
/* we can avoid scanning the following table. */ |
| /* |
/* |
| typedef struct ms_entry * (*mark_proc)( word * addr, mark_stack_ptr, |
typedef struct ms_entry * (*mark_proc)( word * addr, |
| mark_stack_limit, env ); |
struct ms_entry *mark_stack_ptr, |
| |
struct ms_entry *mark_stack_limit, |
| |
word env ); |
| |
|
| # define LOG_MAX_MARK_PROCS 6 |
# define LOG_MAX_MARK_PROCS 6 |
| # define MAX_MARK_PROCS (1 << LOG_MAX_MARK_PROCS) |
# define MAX_MARK_PROCS (1 << LOG_MAX_MARK_PROCS) |
| Line 51 extern mark_proc GC_mark_procs[MAX_MARK_PROCS]; |
|
| Line 57 extern mark_proc GC_mark_procs[MAX_MARK_PROCS]; |
|
| |
|
| extern word GC_n_mark_procs; |
extern word GC_n_mark_procs; |
| |
|
| |
/* In a few cases it's necessary to assign statically known indices to */ |
| |
/* certain mark procs. Thus we reserve a few for well known clients. */ |
| |
/* (This is necessary if mark descriptors are compiler generated.) */ |
| |
#define GC_RESERVED_MARK_PROCS 8 |
| |
# define GCJ_RESERVED_MARK_PROC_INDEX 0 |
| |
|
| /* Object descriptors on mark stack or in objects. Low order two */ |
/* Object descriptors on mark stack or in objects. Low order two */ |
| /* bits are tags distinguishing among the following 4 possibilities */ |
/* bits are tags distinguishing among the following 4 possibilities */ |
| /* for the high order 30 bits. */ |
/* for the high order 30 bits. */ |
| Line 84 extern word GC_n_mark_procs; |
|
| Line 96 extern word GC_n_mark_procs; |
|
| #define DS_PER_OBJECT 3 /* The real descriptor is at the */ |
#define DS_PER_OBJECT 3 /* The real descriptor is at the */ |
| /* byte displacement from the beginning of the */ |
/* byte displacement from the beginning of the */ |
| /* object given by descr & ~DS_TAGS */ |
/* object given by descr & ~DS_TAGS */ |
| |
/* If the descriptor is negative, the real */ |
| |
/* descriptor is at (*<object_start>) - */ |
| |
/* (descr & ~DS_TAGS) - INDIR_PER_OBJ_BIAS */ |
| |
/* The latter alternative can be used if each */ |
| |
/* object contains a type descriptor in the */ |
| |
/* first word. */ |
| |
#define INDIR_PER_OBJ_BIAS 0x10 |
| |
|
| typedef struct ms_entry { |
typedef struct ms_entry { |
| word * mse_start; /* First word of object */ |
word * mse_start; /* First word of object */ |
| Line 98 extern mse * GC_mark_stack_top; |
|
| Line 117 extern mse * GC_mark_stack_top; |
|
| |
|
| extern mse * GC_mark_stack; |
extern mse * GC_mark_stack; |
| |
|
| word GC_find_start(); |
ptr_t GC_find_start(); |
| |
|
| mse * GC_signal_mark_stack_overflow(); |
mse * GC_signal_mark_stack_overflow(); |
| |
|
| Line 144 mse * GC_signal_mark_stack_overflow(); |
|
| Line 163 mse * GC_signal_mark_stack_overflow(); |
|
| # define PUSH_CONTENTS(current, mark_stack_top, mark_stack_limit, \ |
# define PUSH_CONTENTS(current, mark_stack_top, mark_stack_limit, \ |
| source, exit_label) \ |
source, exit_label) \ |
| { \ |
{ \ |
| register int displ; /* Displacement in block; first bytes, then words */ \ |
hdr * my_hhdr; \ |
| register hdr * hhdr; \ |
ptr_t my_current = current; \ |
| register map_entry_type map_entry; \ |
\ |
| \ |
GET_HDR(my_current, my_hhdr); \ |
| GET_HDR(current,hhdr); \ |
if (IS_FORWARDING_ADDR_OR_NIL(my_hhdr)) { \ |
| if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ |
my_current = GC_FIND_START(my_current, my_hhdr, (word)source); \ |
| current = GC_FIND_START(current, hhdr, (word)source); \ |
if (my_current == 0) goto exit_label; \ |
| if (current == 0) goto exit_label; \ |
my_hhdr = GC_find_header(my_current); \ |
| hhdr = HDR(current); \ |
|
| } \ |
} \ |
| |
PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \ |
| |
source, exit_label, my_hhdr); \ |
| |
exit_label: ; \ |
| |
} |
| |
|
| |
/* As above, but use header cache for header lookup. */ |
| |
# define HC_PUSH_CONTENTS(current, mark_stack_top, mark_stack_limit, \ |
| |
source, exit_label) \ |
| |
{ \ |
| |
hdr * my_hhdr; \ |
| |
ptr_t my_current = current; \ |
| |
\ |
| |
HC_GET_HDR(my_current, my_hhdr, source); \ |
| |
PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \ |
| |
source, exit_label, my_hhdr); \ |
| |
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: ; \ |
| |
} |
| |
|
| |
# define PUSH_CONTENTS_HDR(current, mark_stack_top, mark_stack_limit, \ |
| |
source, exit_label, hhdr) \ |
| |
{ \ |
| |
int displ; /* Displacement in block; first bytes, then words */ \ |
| |
map_entry_type map_entry; \ |
| |
\ |
| displ = HBLKDISPL(current); \ |
displ = HBLKDISPL(current); \ |
| map_entry = MAP_ENTRY((hhdr -> hb_map), displ); \ |
map_entry = MAP_ENTRY((hhdr -> hb_map), displ); \ |
| if (map_entry == OBJ_INVALID) { \ |
if (map_entry == OBJ_INVALID) { \ |
| Line 177 mse * GC_signal_mark_stack_overflow(); |
|
| Line 240 mse * GC_signal_mark_stack_overflow(); |
|
| } \ |
} \ |
| PUSH_OBJ(((word *)(HBLKPTR(current)) + displ), hhdr, \ |
PUSH_OBJ(((word *)(HBLKPTR(current)) + displ), hhdr, \ |
| mark_stack_top, mark_stack_limit) \ |
mark_stack_top, mark_stack_limit) \ |
| exit_label: ; \ |
|
| } |
} |
| |
|
| #ifdef PRINT_BLACK_LIST |
#if defined(PRINT_BLACK_LIST) || defined(KEEP_BACK_PTRS) |
| # define PUSH_ONE_CHECKED(p, ip, source) \ |
# define PUSH_ONE_CHECKED(p, ip, source) \ |
| GC_push_one_checked(p, ip, (ptr_t)(source)) |
GC_push_one_checked(p, ip, (ptr_t)(source)) |
| #else |
#else |