X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=boehm-gc%2Fheaders.c;h=b7be1d84930be9fb4d54fd59b70572815deb8eda;hb=43217ce91110f35e448c42647e969093efc4e8e9;hp=b5cc1af8a8da8087b31353cdc3ad04b97289aec6;hpb=4eac4b716a6e15c801da6aa27c301a092871ab02;p=pf3gnuchains%2Fgcc-fork.git diff --git a/boehm-gc/headers.c b/boehm-gc/headers.c index b5cc1af8a8d..b7be1d84930 100644 --- a/boehm-gc/headers.c +++ b/boehm-gc/headers.c @@ -22,9 +22,15 @@ * level tree. */ -# include "gc_priv.h" +# include "private/gc_priv.h" 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 */ hdr * GC_find_header(h) @@ -44,16 +50,13 @@ ptr_t h; static ptr_t scratch_free_ptr = 0; -ptr_t GC_scratch_end_ptr = 0; - -ptr_t GC_scratch_last_end_ptr = 0; - /* End point of last obtained scratch area */ +/* GC_scratch_last_end_ptr is end point of last obtained scratch area. */ +/* GC_scratch_end_ptr is end point of current scratch area. */ ptr_t GC_scratch_alloc(bytes) register word bytes; { register ptr_t result = scratch_free_ptr; - register word bytes_needed = bytes; # ifdef ALIGN_DOUBLE # define GRANULARITY (2 * sizeof(word)) @@ -90,7 +93,7 @@ register word bytes; bytes_to_get = bytes; # ifdef USE_MMAP bytes_to_get += GC_page_size - 1; - bytes_to_get &= (GC_page_size - 1); + bytes_to_get &= ~(GC_page_size - 1); # endif return((ptr_t)GET_MEM(bytes_to_get)); } @@ -123,31 +126,41 @@ hdr * hhdr; hhdr -> hb_next = (struct hblk *) hdr_free_list; hdr_free_list = hhdr; } + +hdr * GC_invalid_header; + +#ifdef USE_HDR_CACHE + word GC_hdr_cache_hits = 0; + word GC_hdr_cache_misses = 0; +#endif void GC_init_headers() { - register int i; + register unsigned i; GC_all_nils = (bottom_index *)GC_scratch_alloc((word)sizeof(bottom_index)); BZERO(GC_all_nils, sizeof(bottom_index)); for (i = 0; i < TOP_SZ; i++) { GC_top_index[i] = GC_all_nils; } + GC_invalid_header = alloc_hdr(); + GC_invalidate_map(GC_invalid_header); } /* Make sure that there is a bottom level index block for address addr */ /* Return FALSE on failure. */ static GC_bool get_index(addr) -register word addr; +word addr; { - register word hi = - (word)(addr) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); - register bottom_index * r; - register bottom_index * p; - register bottom_index ** prev; + word hi = (word)(addr) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); + bottom_index * r; + bottom_index * p; + bottom_index ** prev; + bottom_index *pi; + # ifdef HASH_TL - register unsigned i = TL_HASH(hi); - register bottom_index * old; + unsigned i = TL_HASH(hi); + bottom_index * old; old = p = GC_top_index[i]; while(p != GC_all_nils) { @@ -165,28 +178,41 @@ register word addr; if (r == 0) return(FALSE); GC_top_index[hi] = r; BZERO(r, sizeof (bottom_index)); -# endif +# endif r -> key = hi; /* Add it to the list of bottom indices */ - prev = &GC_all_bottom_indices; - while ((p = *prev) != 0 && p -> key < hi) prev = &(p -> asc_link); + prev = &GC_all_bottom_indices; /* pointer to p */ + 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; *prev = r; return(TRUE); } -/* Install a header for block h. */ -/* The header is uninitialized. */ -/* Returns FALSE on failure. */ -GC_bool GC_install_header(h) +/* Install a header for block h. */ +/* The header is uninitialized. */ +/* Returns the header or 0 on failure. */ +struct hblkhdr * GC_install_header(h) register struct hblk * h; { hdr * result; - if (!get_index((word) h)) return(FALSE); + if (!get_index((word) h)) return(0); result = alloc_hdr(); SET_HDR(h, result); - return(result != 0); +# ifdef USE_MUNMAP + result -> hb_last_reclaimed = GC_gc_no; +# endif + return(result); } /* Set up forwarding counts for block h of size sz */ @@ -234,7 +260,7 @@ register word sz; /* bytes */ /* Apply fn to all allocated blocks */ /*VARARGS1*/ void GC_apply_to_all_blocks(fn, client_data) -void (*fn)(/* struct hblk *h, word client_data */); +void (*fn) GC_PROTO((struct hblk *h, word client_data)); word client_data; { register int j; @@ -262,7 +288,7 @@ word client_data; /* Get the next valid block whose address is at least h */ /* Return 0 if there is none. */ -struct hblk * GC_next_block(h) +struct hblk * GC_next_used_block(h) struct hblk * h; { register bottom_index * bi; @@ -277,15 +303,16 @@ struct hblk * h; } while(bi != 0) { 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++; } else { - if (bi->index[j]->hb_map != GC_invalid_map) { + if (hhdr->hb_map != GC_invalid_map) { return((struct hblk *) (((bi -> key << LOG_BOTTOM_SZ) + j) << LOG_HBLKSIZE)); } else { - j += divHBLKSZ(bi->index[j] -> hb_sz); + j += divHBLKSZ(hhdr -> hb_sz); } } } @@ -294,3 +321,38 @@ struct hblk * h; } 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); +}