| version 1.1.1.1, 1999/11/27 10:58:32 |
version 1.1.1.2, 2000/04/14 11:07:58 |
|
|
| # include "gc_priv.h" |
# include "gc_priv.h" |
| |
|
| bottom_index * GC_all_bottom_indices = 0; |
bottom_index * GC_all_bottom_indices = 0; |
| |
/* Pointer to first (lowest addr) */ |
| |
/* bottom_index. */ |
| |
|
| |
bottom_index * GC_all_bottom_indices_end = 0; |
| |
/* Pointer to last (highest addr) */ |
| |
/* bottom_index. */ |
| |
|
| /* Non-macro version of header location routine */ |
/* Non-macro version of header location routine */ |
| hdr * GC_find_header(h) |
hdr * GC_find_header(h) |
| Line 137 void GC_init_headers() |
|
| Line 143 void GC_init_headers() |
|
| /* Make sure that there is a bottom level index block for address addr */ |
/* Make sure that there is a bottom level index block for address addr */ |
| /* Return FALSE on failure. */ |
/* Return FALSE on failure. */ |
| static GC_bool get_index(addr) |
static GC_bool get_index(addr) |
| register word addr; |
word addr; |
| { |
{ |
| register word hi = |
word hi = (word)(addr) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); |
| (word)(addr) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); |
bottom_index * r; |
| register bottom_index * r; |
bottom_index * p; |
| register bottom_index * p; |
bottom_index ** prev; |
| register bottom_index ** prev; |
bottom_index *pi; |
| |
|
| # ifdef HASH_TL |
# ifdef HASH_TL |
| register unsigned i = TL_HASH(hi); |
unsigned i = TL_HASH(hi); |
| register bottom_index * old; |
bottom_index * old; |
| |
|
| old = p = GC_top_index[i]; |
old = p = GC_top_index[i]; |
| while(p != GC_all_nils) { |
while(p != GC_all_nils) { |
| Line 164 register word addr; |
|
| Line 171 register word addr; |
|
| if (r == 0) return(FALSE); |
if (r == 0) return(FALSE); |
| GC_top_index[hi] = r; |
GC_top_index[hi] = r; |
| BZERO(r, sizeof (bottom_index)); |
BZERO(r, sizeof (bottom_index)); |
| # endif |
# endif |
| r -> key = hi; |
r -> key = hi; |
| /* Add it to the list of bottom indices */ |
/* Add it to the list of bottom indices */ |
| prev = &GC_all_bottom_indices; |
prev = &GC_all_bottom_indices; /* pointer to p */ |
| while ((p = *prev) != 0 && p -> key < hi) prev = &(p -> asc_link); |
pi = 0; /* bottom_index preceding p */ |
| |
while ((p = *prev) != 0 && p -> key < hi) { |
| |
pi = p; |
| |
prev = &(p -> asc_link); |
| |
} |
| |
r -> desc_link = pi; |
| |
if (0 == p) { |
| |
GC_all_bottom_indices_end = r; |
| |
} else { |
| |
p -> desc_link = r; |
| |
} |
| r -> asc_link = p; |
r -> asc_link = p; |
| *prev = r; |
*prev = r; |
| return(TRUE); |
return(TRUE); |
| Line 185 register struct hblk * h; |
|
| Line 202 register struct hblk * h; |
|
| if (!get_index((word) h)) return(FALSE); |
if (!get_index((word) h)) return(FALSE); |
| result = alloc_hdr(); |
result = alloc_hdr(); |
| SET_HDR(h, result); |
SET_HDR(h, result); |
| |
# ifdef USE_MUNMAP |
| |
result -> hb_last_reclaimed = GC_gc_no; |
| |
# endif |
| return(result != 0); |
return(result != 0); |
| } |
} |
| |
|
| Line 261 word client_data; |
|
| Line 281 word client_data; |
|
| |
|
| /* Get the next valid block whose address is at least h */ |
/* Get the next valid block whose address is at least h */ |
| /* Return 0 if there is none. */ |
/* Return 0 if there is none. */ |
| struct hblk * GC_next_block(h) |
struct hblk * GC_next_used_block(h) |
| struct hblk * h; |
struct hblk * h; |
| { |
{ |
| register bottom_index * bi; |
register bottom_index * bi; |
| Line 276 struct hblk * h; |
|
| Line 296 struct hblk * h; |
|
| } |
} |
| while(bi != 0) { |
while(bi != 0) { |
| while (j < BOTTOM_SZ) { |
while (j < BOTTOM_SZ) { |
| if (IS_FORWARDING_ADDR_OR_NIL(bi -> index[j])) { |
hdr * hhdr = bi -> index[j]; |
| |
if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { |
| j++; |
j++; |
| } else { |
} else { |
| if (bi->index[j]->hb_map != GC_invalid_map) { |
if (hhdr->hb_map != GC_invalid_map) { |
| return((struct hblk *) |
return((struct hblk *) |
| (((bi -> key << LOG_BOTTOM_SZ) + j) |
(((bi -> key << LOG_BOTTOM_SZ) + j) |
| << LOG_HBLKSIZE)); |
<< LOG_HBLKSIZE)); |
| } else { |
} else { |
| j += divHBLKSZ(bi->index[j] -> hb_sz); |
j += divHBLKSZ(hhdr -> hb_sz); |
| } |
} |
| } |
} |
| } |
} |
| j = 0; |
j = 0; |
| bi = bi -> asc_link; |
bi = bi -> asc_link; |
| |
} |
| |
return(0); |
| |
} |
| |
|
| |
/* Get the last (highest address) block whose address is */ |
| |
/* at most h. Return 0 if there is none. */ |
| |
/* Unlike the above, this may return a free block. */ |
| |
struct hblk * GC_prev_block(h) |
| |
struct hblk * h; |
| |
{ |
| |
register bottom_index * bi; |
| |
register signed_word j = ((word)h >> LOG_HBLKSIZE) & (BOTTOM_SZ-1); |
| |
|
| |
GET_BI(h, bi); |
| |
if (bi == GC_all_nils) { |
| |
register word hi = (word)h >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); |
| |
bi = GC_all_bottom_indices_end; |
| |
while (bi != 0 && bi -> key > hi) bi = bi -> desc_link; |
| |
j = BOTTOM_SZ - 1; |
| |
} |
| |
while(bi != 0) { |
| |
while (j >= 0) { |
| |
hdr * hhdr = bi -> index[j]; |
| |
if (0 == hhdr) { |
| |
--j; |
| |
} else if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { |
| |
j -= (signed_word)hhdr; |
| |
} else { |
| |
return((struct hblk *) |
| |
(((bi -> key << LOG_BOTTOM_SZ) + j) |
| |
<< LOG_HBLKSIZE)); |
| |
} |
| |
} |
| |
j = BOTTOM_SZ - 1; |
| |
bi = bi -> desc_link; |
| } |
} |
| return(0); |
return(0); |
| } |
} |