/* 
 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
 * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
 * Copyright (c) 1996 by Silicon Graphics.  All rights reserved.
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 * Permission is hereby granted to use or copy this program
 * for any purpose,  provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 */
 
/*
 * This implements:
 * 1. allocation of heap block headers
 * 2. A map from addresses to heap block addresses to heap block headers
 *
 * Access speed is crucial.  We implement an index structure based on a 2
 * level tree.
 */
 
# 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)
ptr_t h;
{
#   ifdef HASH_TL
	register hdr * result;
	GET_HDR(h, result);
	return(result);
#   else
	return(HDR_INNER(h));
#   endif
}
 
/* Routines to dynamically allocate collector data structures that will */
/* never be freed.							 */
 
static ptr_t scratch_free_ptr = 0;
 
/* 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;

#   ifdef ALIGN_DOUBLE
#	define GRANULARITY (2 * sizeof(word))
#   else
#	define GRANULARITY sizeof(word)
#   endif
    bytes += GRANULARITY-1;
    bytes &= ~(GRANULARITY-1);
    scratch_free_ptr += bytes;
    if (scratch_free_ptr <= GC_scratch_end_ptr) {
        return(result);
    }
    {
        word bytes_to_get = MINHINCR * HBLKSIZE;
         
        if (bytes_to_get <= bytes) {
          /* Undo the damage, and get memory directly */
	    bytes_to_get = bytes;
#	    ifdef USE_MMAP
		bytes_to_get += GC_page_size - 1;
		bytes_to_get &= ~(GC_page_size - 1);
#	    endif
   	    result = (ptr_t)GET_MEM(bytes_to_get);
            scratch_free_ptr -= bytes;
	    GC_scratch_last_end_ptr = result + bytes;
            return(result);
        }
        result = (ptr_t)GET_MEM(bytes_to_get);
        if (result == 0) {
#	    ifdef PRINTSTATS
                GC_printf0("Out of memory - trying to allocate less\n");
#	    endif
            scratch_free_ptr -= bytes;
	    bytes_to_get = bytes;
#	    ifdef USE_MMAP
		bytes_to_get += GC_page_size - 1;
		bytes_to_get &= ~(GC_page_size - 1);
#	    endif
            return((ptr_t)GET_MEM(bytes_to_get));
        }
        scratch_free_ptr = result;
        GC_scratch_end_ptr = scratch_free_ptr + bytes_to_get;
        GC_scratch_last_end_ptr = GC_scratch_end_ptr;
        return(GC_scratch_alloc(bytes));
    }
}

static hdr * hdr_free_list = 0;

/* Return an uninitialized header */
static hdr * alloc_hdr()
{
    register hdr * result;
    
    if (hdr_free_list == 0) {
        result = (hdr *) GC_scratch_alloc((word)(sizeof(hdr)));
    } else {
        result = hdr_free_list;
        hdr_free_list = (hdr *) (result -> hb_next);
    }
    return(result);
}

static void free_hdr(hhdr)
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 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)
word addr;
{
    word hi = (word)(addr) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE);
    bottom_index * r;
    bottom_index * p;
    bottom_index ** prev;
    bottom_index *pi;
    
#   ifdef HASH_TL
      unsigned i = TL_HASH(hi);
      bottom_index * old;
      
      old = p = GC_top_index[i];
      while(p != GC_all_nils) {
          if (p -> key == hi) return(TRUE);
          p = p -> hash_link;
      }
      r = (bottom_index*)GC_scratch_alloc((word)(sizeof (bottom_index)));
      if (r == 0) return(FALSE);
      BZERO(r, sizeof (bottom_index));
      r -> hash_link = old;
      GC_top_index[i] = r;
#   else
      if (GC_top_index[hi] != GC_all_nils) return(TRUE);
      r = (bottom_index*)GC_scratch_alloc((word)(sizeof (bottom_index)));
      if (r == 0) return(FALSE);
      GC_top_index[hi] = r;
      BZERO(r, sizeof (bottom_index));
#   endif
    r -> key = hi;
    /* Add it to the list of bottom indices */
      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 the header or 0 on failure.	*/
struct hblkhdr * GC_install_header(h)
register struct hblk * h;
{
    hdr * result;
    
    if (!get_index((word) h)) return(0);
    result = alloc_hdr();
    SET_HDR(h, result);
#   ifdef USE_MUNMAP
	result -> hb_last_reclaimed = GC_gc_no;
#   endif
    return(result);
}

/* Set up forwarding counts for block h of size sz */
GC_bool GC_install_counts(h, sz)
register struct hblk * h;
register word sz; /* bytes */
{
    register struct hblk * hbp;
    register int i;
    
    for (hbp = h; (char *)hbp < (char *)h + sz; hbp += BOTTOM_SZ) {
        if (!get_index((word) hbp)) return(FALSE);
    }
    if (!get_index((word)h + sz - 1)) return(FALSE);
    for (hbp = h + 1; (char *)hbp < (char *)h + sz; hbp += 1) {
        i = HBLK_PTR_DIFF(hbp, h);
        SET_HDR(hbp, (hdr *)(i > MAX_JUMP? MAX_JUMP : i));
    }
    return(TRUE);
}

/* Remove the header for block h */
void GC_remove_header(h)
register struct hblk * h;
{
    hdr ** ha;
    
    GET_HDR_ADDR(h, ha);
    free_hdr(*ha);
    *ha = 0;
}

/* Remove forwarding counts for h */
void GC_remove_counts(h, sz)
register struct hblk * h;
register word sz; /* bytes */
{
    register struct hblk * hbp;
    
    for (hbp = h+1; (char *)hbp < (char *)h + sz; hbp += 1) {
        SET_HDR(hbp, 0);
    }
}

/* Apply fn to all allocated blocks */
/*VARARGS1*/
void GC_apply_to_all_blocks(fn, client_data)
void (*fn) GC_PROTO((struct hblk *h, word client_data));
word client_data;
{
    register int j;
    register bottom_index * index_p;
    
    for (index_p = GC_all_bottom_indices; index_p != 0;
         index_p = index_p -> asc_link) {
        for (j = BOTTOM_SZ-1; j >= 0;) {
            if (!IS_FORWARDING_ADDR_OR_NIL(index_p->index[j])) {
                if (index_p->index[j]->hb_map != GC_invalid_map) {
                    (*fn)(((struct hblk *)
                  	      (((index_p->key << LOG_BOTTOM_SZ) + (word)j)
                  	       << LOG_HBLKSIZE)),
                          client_data);
                }
                j--;
             } else if (index_p->index[j] == 0) {
                j--;
             } else {
                j -= (word)(index_p->index[j]);
             }
         }
     }
}

/* Get the next valid block whose address is at least h	*/
/* Return 0 if there is none.				*/
struct hblk * GC_next_used_block(h)
struct hblk * h;
{
    register bottom_index * bi;
    register 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;
        while (bi != 0 && bi -> key < hi) bi = bi -> asc_link;
        j = 0;
    }
    while(bi != 0) {
        while (j < BOTTOM_SZ) {
	    hdr * hhdr = bi -> index[j];
            if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
                j++;
            } else {
                if (hhdr->hb_map != GC_invalid_map) {
                    return((struct hblk *)
                  	      (((bi -> key << LOG_BOTTOM_SZ) + j)
                  	       << LOG_HBLKSIZE));
                } else {
                    j += divHBLKSZ(hhdr -> hb_sz);
                }
            }
        }
        j = 0;
        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);
}
