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 |