/*
 * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
 * opyright (c) 1999-2000 by Hewlett-Packard Company.  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.
 *
 */


/*
 * Some simple primitives for allocation with explicit type information.
 * Simple objects are allocated such that they contain a GC_descr at the
 * end (in the last allocated word).  This descriptor may be a procedure
 * which then examines an extended descriptor passed as its environment.
 *
 * Arrays are treated as simple objects if they have sufficiently simple
 * structure.  Otherwise they are allocated from an array kind that supplies
 * a special mark procedure.  These arrays contain a pointer to a
 * complex_descriptor as their last word.
 * This is done because the environment field is too small, and the collector
 * must trace the complex_descriptor.
 *
 * Note that descriptors inside objects may appear cleared, if we encounter a
 * false refrence to an object on a free list.  In the GC_descr case, this
 * is OK, since a 0 descriptor corresponds to examining no fields.
 * In the complex_descriptor case, we explicitly check for that case.
 *
 * MAJOR PARTS OF THIS CODE HAVE NOT BEEN TESTED AT ALL and are not testable,
 * since they are not accessible through the current interface.
 */

#include "private/gc_pmark.h"
#include "gc_typed.h"

# define TYPD_EXTRA_BYTES (sizeof(word) - EXTRA_BYTES)

GC_bool GC_explicit_typing_initialized = FALSE;

int GC_explicit_kind;	/* Object kind for objects with indirect	*/
			/* (possibly extended) descriptors.		*/

int GC_array_kind;	/* Object kind for objects with complex		*/
			/* descriptors and GC_array_mark_proc.		*/

/* Extended descriptors.  GC_typed_mark_proc understands these.	*/
/* These are used for simple objects that are larger than what	*/
/* can be described by a BITMAP_BITS sized bitmap.		*/
typedef struct {
	word ed_bitmap;	/* lsb corresponds to first word.	*/
	GC_bool ed_continued;	/* next entry is continuation.	*/
} ext_descr;

/* Array descriptors.  GC_array_mark_proc understands these.	*/
/* We may eventually need to add provisions for headers and	*/
/* trailers.  Hence we provide for tree structured descriptors, */
/* though we don't really use them currently.			*/
typedef union ComplexDescriptor {
    struct LeafDescriptor {	/* Describes simple array	*/
        word ld_tag;
#	define LEAF_TAG 1
	word ld_size;		/* bytes per element	*/
				/* multiple of ALIGNMENT	*/
	word ld_nelements;	/* Number of elements.	*/
	GC_descr ld_descriptor; /* A simple length, bitmap,	*/
				/* or procedure descriptor.	*/
    } ld;
    struct ComplexArrayDescriptor {
        word ad_tag;
#	define ARRAY_TAG 2
	word ad_nelements;
	union ComplexDescriptor * ad_element_descr;
    } ad;
    struct SequenceDescriptor {
        word sd_tag;
#	define SEQUENCE_TAG 3
	union ComplexDescriptor * sd_first;
	union ComplexDescriptor * sd_second;
    } sd;
} complex_descriptor;
#define TAG ld.ld_tag

ext_descr * GC_ext_descriptors;	/* Points to array of extended 	*/
				/* descriptors.			*/

word GC_ed_size = 0;	/* Current size of above arrays.	*/
# define ED_INITIAL_SIZE 100;

word GC_avail_descr = 0;	/* Next available slot.		*/

int GC_typed_mark_proc_index;	/* Indices of my mark		*/
int GC_array_mark_proc_index;	/* procedures.			*/

/* Add a multiword bitmap to GC_ext_descriptors arrays.  Return	*/
/* starting index.						*/
/* Returns -1 on failure.					*/
/* Caller does not hold allocation lock.			*/
signed_word GC_add_ext_descriptor(bm, nbits)
GC_bitmap bm;
word nbits;
{
    register size_t nwords = divWORDSZ(nbits + WORDSZ-1);
    register signed_word result;
    register word i;
    register word last_part;
    register int extra_bits;
    DCL_LOCK_STATE;

    DISABLE_SIGNALS();
    LOCK();
    while (GC_avail_descr + nwords >= GC_ed_size) {
    	ext_descr * new;
    	size_t new_size;
    	word ed_size = GC_ed_size;
    	
    	UNLOCK();
        ENABLE_SIGNALS();
    	if (ed_size == 0) {
    	    new_size = ED_INITIAL_SIZE;
    	} else {
    	    new_size = 2 * ed_size;
    	    if (new_size > MAX_ENV) return(-1);
    	} 
    	new = (ext_descr *) GC_malloc_atomic(new_size * sizeof(ext_descr));
    	if (new == 0) return(-1);
    	DISABLE_SIGNALS();
        LOCK();
        if (ed_size == GC_ed_size) {
            if (GC_avail_descr != 0) {
    	        BCOPY(GC_ext_descriptors, new,
    	              GC_avail_descr * sizeof(ext_descr));
    	    }
    	    GC_ed_size = new_size;
    	    GC_ext_descriptors = new;
    	}  /* else another thread already resized it in the meantime */
    }
    result = GC_avail_descr;
    for (i = 0; i < nwords-1; i++) {
        GC_ext_descriptors[result + i].ed_bitmap = bm[i];
        GC_ext_descriptors[result + i].ed_continued = TRUE;
    }
    last_part = bm[i];
    /* Clear irrelevant bits. */
    extra_bits = nwords * WORDSZ - nbits;
    last_part <<= extra_bits;
    last_part >>= extra_bits;
    GC_ext_descriptors[result + i].ed_bitmap = last_part;
    GC_ext_descriptors[result + i].ed_continued = FALSE;
    GC_avail_descr += nwords;
    UNLOCK();
    ENABLE_SIGNALS();
    return(result);
}

/* Table of bitmap descriptors for n word long all pointer objects.	*/
GC_descr GC_bm_table[WORDSZ/2];
	
/* Return a descriptor for the concatenation of 2 nwords long objects,	*/
/* each of which is described by descriptor.				*/
/* The result is known to be short enough to fit into a bitmap		*/
/* descriptor.								*/
/* Descriptor is a GC_DS_LENGTH or GC_DS_BITMAP descriptor.		*/
GC_descr GC_double_descr(descriptor, nwords)
register GC_descr descriptor;
register word nwords;
{
    if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) {
        descriptor = GC_bm_table[BYTES_TO_WORDS((word)descriptor)];
    };
    descriptor |= (descriptor & ~GC_DS_TAGS) >> nwords;
    return(descriptor);
}

complex_descriptor * GC_make_sequence_descriptor();

/* Build a descriptor for an array with nelements elements,	*/
/* each of which can be described by a simple descriptor.	*/
/* We try to optimize some common cases.			*/
/* If the result is COMPLEX, then a complex_descr* is returned  */
/* in *complex_d.							*/
/* If the result is LEAF, then we built a LeafDescriptor in	*/
/* the structure pointed to by leaf.				*/
/* The tag in the leaf structure is not set.			*/
/* If the result is SIMPLE, then a GC_descr			*/
/* is returned in *simple_d.					*/
/* If the result is NO_MEM, then				*/
/* we failed to allocate the descriptor.			*/
/* The implementation knows that GC_DS_LENGTH is 0.		*/
/* *leaf, *complex_d, and *simple_d may be used as temporaries	*/
/* during the construction.					*/
# define COMPLEX 2
# define LEAF 1
# define SIMPLE 0
# define NO_MEM (-1)
int GC_make_array_descriptor(nelements, size, descriptor,
			     simple_d, complex_d, leaf)
word size;
word nelements;
GC_descr descriptor;
GC_descr *simple_d;
complex_descriptor **complex_d;
struct LeafDescriptor * leaf;
{
#   define OPT_THRESHOLD 50
	/* For larger arrays, we try to combine descriptors of adjacent	*/
	/* descriptors to speed up marking, and to reduce the amount	*/
	/* of space needed on the mark stack.				*/
    if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) {
      if ((word)descriptor == size) {
    	*simple_d = nelements * descriptor;
    	return(SIMPLE);
      } else if ((word)descriptor == 0) {
        *simple_d = (GC_descr)0;
        return(SIMPLE);
      }
    }
    if (nelements <= OPT_THRESHOLD) {
      if (nelements <= 1) {
        if (nelements == 1) {
            *simple_d = descriptor;
            return(SIMPLE);
        } else {
            *simple_d = (GC_descr)0;
            return(SIMPLE);
        }
      }
    } else if (size <= BITMAP_BITS/2
    	       && (descriptor & GC_DS_TAGS) != GC_DS_PROC
    	       && (size & (sizeof(word)-1)) == 0) {
      int result =      
          GC_make_array_descriptor(nelements/2, 2*size,
      				   GC_double_descr(descriptor,
      				   		   BYTES_TO_WORDS(size)),
      				   simple_d, complex_d, leaf);
      if ((nelements & 1) == 0) {
          return(result);
      } else {
          struct LeafDescriptor * one_element =
              (struct LeafDescriptor *)
        	GC_malloc_atomic(sizeof(struct LeafDescriptor));
          
          if (result == NO_MEM || one_element == 0) return(NO_MEM);
          one_element -> ld_tag = LEAF_TAG;
          one_element -> ld_size = size;
          one_element -> ld_nelements = 1;
          one_element -> ld_descriptor = descriptor;
          switch(result) {
            case SIMPLE:
            {
              struct LeafDescriptor * beginning =
                (struct LeafDescriptor *)
        	  GC_malloc_atomic(sizeof(struct LeafDescriptor));
              if (beginning == 0) return(NO_MEM);
              beginning -> ld_tag = LEAF_TAG;
              beginning -> ld_size = size;
              beginning -> ld_nelements = 1;
              beginning -> ld_descriptor = *simple_d;
              *complex_d = GC_make_sequence_descriptor(
              			(complex_descriptor *)beginning,
              			(complex_descriptor *)one_element);
              break;
            }
            case LEAF:
            {
              struct LeafDescriptor * beginning =
                (struct LeafDescriptor *)
        	  GC_malloc_atomic(sizeof(struct LeafDescriptor));
              if (beginning == 0) return(NO_MEM);
              beginning -> ld_tag = LEAF_TAG;
              beginning -> ld_size = leaf -> ld_size;
              beginning -> ld_nelements = leaf -> ld_nelements;
              beginning -> ld_descriptor = leaf -> ld_descriptor;
              *complex_d = GC_make_sequence_descriptor(
              			(complex_descriptor *)beginning,
              			(complex_descriptor *)one_element);
              break;
            }
            case COMPLEX:
              *complex_d = GC_make_sequence_descriptor(
              			*complex_d,
              			(complex_descriptor *)one_element);
              break;
          }
          return(COMPLEX);
      }
    }
    {
        leaf -> ld_size = size;
        leaf -> ld_nelements = nelements;
        leaf -> ld_descriptor = descriptor;
        return(LEAF);
    }
}

complex_descriptor * GC_make_sequence_descriptor(first, second)
complex_descriptor * first;
complex_descriptor * second;
{
    struct SequenceDescriptor * result =
        (struct SequenceDescriptor *)
        	GC_malloc(sizeof(struct SequenceDescriptor));
    /* Can't result in overly conservative marking, since tags are	*/
    /* very small integers. Probably faster than maintaining type	*/
    /* info.								*/    
    if (result != 0) {
    	result -> sd_tag = SEQUENCE_TAG;
        result -> sd_first = first;
        result -> sd_second = second;
    }
    return((complex_descriptor *)result);
}

#ifdef UNDEFINED
complex_descriptor * GC_make_complex_array_descriptor(nelements, descr)
word nelements;
complex_descriptor * descr;
{
    struct ComplexArrayDescriptor * result =
        (struct ComplexArrayDescriptor *)
        	GC_malloc(sizeof(struct ComplexArrayDescriptor));
    
    if (result != 0) {
    	result -> ad_tag = ARRAY_TAG;
        result -> ad_nelements = nelements;
        result -> ad_element_descr = descr;
    }
    return((complex_descriptor *)result);
}
#endif

ptr_t * GC_eobjfreelist;

ptr_t * GC_arobjfreelist;

mse * GC_typed_mark_proc GC_PROTO((register word * addr,
				   register mse * mark_stack_ptr,
				   mse * mark_stack_limit,
				   word env));

mse * GC_array_mark_proc GC_PROTO((register word * addr,
				   register mse * mark_stack_ptr,
				   mse * mark_stack_limit,
				   word env));

GC_descr GC_generic_array_descr;

/* Caller does not hold allocation lock. */
void GC_init_explicit_typing()
{
    register int i;
    DCL_LOCK_STATE;

    
#   ifdef PRINTSTATS
     	if (sizeof(struct LeafDescriptor) % sizeof(word) != 0)
     	    ABORT("Bad leaf descriptor size");
#   endif
    DISABLE_SIGNALS();
    LOCK();
    if (GC_explicit_typing_initialized) {
      UNLOCK();
      ENABLE_SIGNALS();
      return;
    }
    GC_explicit_typing_initialized = TRUE;
    /* Set up object kind with simple indirect descriptor. */
      GC_eobjfreelist = (ptr_t *)
          GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
      if (GC_eobjfreelist == 0) ABORT("Couldn't allocate GC_eobjfreelist");
      BZERO(GC_eobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t));
      GC_explicit_kind = GC_n_kinds++;
      GC_obj_kinds[GC_explicit_kind].ok_freelist = GC_eobjfreelist;
      GC_obj_kinds[GC_explicit_kind].ok_reclaim_list = 0;
      GC_obj_kinds[GC_explicit_kind].ok_descriptor =
    		(((word)WORDS_TO_BYTES(-1)) | GC_DS_PER_OBJECT);
      GC_obj_kinds[GC_explicit_kind].ok_relocate_descr = TRUE;
      GC_obj_kinds[GC_explicit_kind].ok_init = TRUE;
    		/* Descriptors are in the last word of the object. */
      GC_typed_mark_proc_index = GC_n_mark_procs;
      GC_mark_procs[GC_typed_mark_proc_index] = GC_typed_mark_proc;
      GC_n_mark_procs++;
        /* Moving this up breaks DEC AXP compiler.      */
    /* Set up object kind with array descriptor. */
      GC_arobjfreelist = (ptr_t *)
          GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
      if (GC_arobjfreelist == 0) ABORT("Couldn't allocate GC_arobjfreelist");
      BZERO(GC_arobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t));
      if (GC_n_mark_procs >= MAX_MARK_PROCS)
      		ABORT("No slot for array mark proc");
      GC_array_mark_proc_index = GC_n_mark_procs++;
      if (GC_n_kinds >= MAXOBJKINDS)
      		ABORT("No kind available for array objects");
      GC_array_kind = GC_n_kinds++;
      GC_obj_kinds[GC_array_kind].ok_freelist = GC_arobjfreelist;
      GC_obj_kinds[GC_array_kind].ok_reclaim_list = 0;
      GC_obj_kinds[GC_array_kind].ok_descriptor =
    		GC_MAKE_PROC(GC_array_mark_proc_index, 0);;
      GC_obj_kinds[GC_array_kind].ok_relocate_descr = FALSE;
      GC_obj_kinds[GC_array_kind].ok_init = TRUE;
    		/* Descriptors are in the last word of the object. */
            GC_mark_procs[GC_array_mark_proc_index] = GC_array_mark_proc;
      for (i = 0; i < WORDSZ/2; i++) {
          GC_descr d = (((word)(-1)) >> (WORDSZ - i)) << (WORDSZ - i);
          d |= GC_DS_BITMAP;
          GC_bm_table[i] = d;
      }
      GC_generic_array_descr = GC_MAKE_PROC(GC_array_mark_proc_index, 0); 
    UNLOCK();
    ENABLE_SIGNALS();
}

# if defined(__STDC__) || defined(__cplusplus)
    mse * GC_typed_mark_proc(register word * addr,
			     register mse * mark_stack_ptr,
			     mse * mark_stack_limit,
			     word env)
# else
    mse * GC_typed_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env)
    register word * addr;
    register mse * mark_stack_ptr;
    mse * mark_stack_limit;
    word env;
# endif
{
    register word bm = GC_ext_descriptors[env].ed_bitmap;
    register word * current_p = addr;
    register word current;
    register ptr_t greatest_ha = GC_greatest_plausible_heap_addr;
    register ptr_t least_ha = GC_least_plausible_heap_addr;
    
    for (; bm != 0; bm >>= 1, current_p++) {
    	if (bm & 1) {
    	    current = *current_p;
	    FIXUP_POINTER(current);
    	    if ((ptr_t)current >= least_ha && (ptr_t)current <= greatest_ha) {
    	        PUSH_CONTENTS((ptr_t)current, mark_stack_ptr,
			      mark_stack_limit, current_p, exit1);
    	    }
    	}
    }
    if (GC_ext_descriptors[env].ed_continued) {
        /* Push an entry with the rest of the descriptor back onto the	*/
        /* stack.  Thus we never do too much work at once.  Note that	*/
        /* we also can't overflow the mark stack unless we actually 	*/
        /* mark something.						*/
        mark_stack_ptr++;
        if (mark_stack_ptr >= mark_stack_limit) {
            mark_stack_ptr = GC_signal_mark_stack_overflow(mark_stack_ptr);
        }
        mark_stack_ptr -> mse_start = addr + WORDSZ;
        mark_stack_ptr -> mse_descr =
        	GC_MAKE_PROC(GC_typed_mark_proc_index, env+1);
    }
    return(mark_stack_ptr);
}

/* Return the size of the object described by d.  It would be faster to	*/
/* store this directly, or to compute it as part of			*/
/* GC_push_complex_descriptor, but hopefully it doesn't matter.		*/
word GC_descr_obj_size(d)
register complex_descriptor *d;
{
    switch(d -> TAG) {
      case LEAF_TAG:
      	return(d -> ld.ld_nelements * d -> ld.ld_size);
      case ARRAY_TAG:
        return(d -> ad.ad_nelements
               * GC_descr_obj_size(d -> ad.ad_element_descr));
      case SEQUENCE_TAG:
        return(GC_descr_obj_size(d -> sd.sd_first)
               + GC_descr_obj_size(d -> sd.sd_second));
      default:
        ABORT("Bad complex descriptor");
        /*NOTREACHED*/ return 0; /*NOTREACHED*/
    }
}

/* Push descriptors for the object at addr with complex descriptor d	*/
/* onto the mark stack.  Return 0 if the mark stack overflowed.  	*/
mse * GC_push_complex_descriptor(addr, d, msp, msl)
word * addr;
register complex_descriptor *d;
register mse * msp;
mse * msl;
{
    register ptr_t current = (ptr_t) addr;
    register word nelements;
    register word sz;
    register word i;
    
    switch(d -> TAG) {
      case LEAF_TAG:
        {
          register GC_descr descr = d -> ld.ld_descriptor;
          
          nelements = d -> ld.ld_nelements;
          if (msl - msp <= (ptrdiff_t)nelements) return(0);
          sz = d -> ld.ld_size;
          for (i = 0; i < nelements; i++) {
              msp++;
              msp -> mse_start = (word *)current;
              msp -> mse_descr = descr;
              current += sz;
          }
          return(msp);
        }
      case ARRAY_TAG:
        {
          register complex_descriptor *descr = d -> ad.ad_element_descr;
          
          nelements = d -> ad.ad_nelements;
          sz = GC_descr_obj_size(descr);
          for (i = 0; i < nelements; i++) {
              msp = GC_push_complex_descriptor((word *)current, descr,
              					msp, msl);
              if (msp == 0) return(0);
              current += sz;
          }
          return(msp);
        }
      case SEQUENCE_TAG:
        {
          sz = GC_descr_obj_size(d -> sd.sd_first);
          msp = GC_push_complex_descriptor((word *)current, d -> sd.sd_first,
          				   msp, msl);
          if (msp == 0) return(0);
          current += sz;
          msp = GC_push_complex_descriptor((word *)current, d -> sd.sd_second,
          				   msp, msl);
          return(msp);
        }
      default:
        ABORT("Bad complex descriptor");
        /*NOTREACHED*/ return 0; /*NOTREACHED*/
   }
}

/*ARGSUSED*/
# if defined(__STDC__) || defined(__cplusplus)
    mse * GC_array_mark_proc(register word * addr,
			     register mse * mark_stack_ptr,
			     mse * mark_stack_limit,
			     word env)
# else
    mse * GC_array_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env)
    register word * addr;
    register mse * mark_stack_ptr;
    mse * mark_stack_limit;
    word env;
# endif
{
    register hdr * hhdr = HDR(addr);
    register word sz = hhdr -> hb_sz;
    register complex_descriptor * descr = (complex_descriptor *)(addr[sz-1]);
    mse * orig_mark_stack_ptr = mark_stack_ptr;
    mse * new_mark_stack_ptr;
    
    if (descr == 0) {
    	/* Found a reference to a free list entry.  Ignore it. */
    	return(orig_mark_stack_ptr);
    }
    /* In use counts were already updated when array descriptor was	*/
    /* pushed.  Here we only replace it by subobject descriptors, so 	*/
    /* no update is necessary.						*/
    new_mark_stack_ptr = GC_push_complex_descriptor(addr, descr,
    						    mark_stack_ptr,
    						    mark_stack_limit-1);
    if (new_mark_stack_ptr == 0) {
    	/* Doesn't fit.  Conservatively push the whole array as a unit	*/
    	/* and request a mark stack expansion.				*/
    	/* This cannot cause a mark stack overflow, since it replaces	*/
    	/* the original array entry.					*/
    	GC_mark_stack_too_small = TRUE;
    	new_mark_stack_ptr = orig_mark_stack_ptr + 1;
    	new_mark_stack_ptr -> mse_start = addr;
    	new_mark_stack_ptr -> mse_descr = WORDS_TO_BYTES(sz) | GC_DS_LENGTH;
    } else {
        /* Push descriptor itself */
        new_mark_stack_ptr++;
        new_mark_stack_ptr -> mse_start = addr + sz - 1;
        new_mark_stack_ptr -> mse_descr = sizeof(word) | GC_DS_LENGTH;
    }
    return(new_mark_stack_ptr);
}

#if defined(__STDC__) || defined(__cplusplus)
  GC_descr GC_make_descriptor(GC_bitmap bm, size_t len)
#else
  GC_descr GC_make_descriptor(bm, len)
  GC_bitmap bm;
  size_t len;
#endif
{
    register signed_word last_set_bit = len - 1;
    register word result;
    register int i;
#   define HIGH_BIT (((word)1) << (WORDSZ - 1))
    
    if (!GC_explicit_typing_initialized) GC_init_explicit_typing();
    while (last_set_bit >= 0 && !GC_get_bit(bm, last_set_bit)) last_set_bit --;
    if (last_set_bit < 0) return(0 /* no pointers */);
#   if ALIGNMENT == CPP_WORDSZ/8
    {
      register GC_bool all_bits_set = TRUE;
      for (i = 0; i < last_set_bit; i++) {
    	if (!GC_get_bit(bm, i)) {
    	    all_bits_set = FALSE;
    	    break;
    	}
      }
      if (all_bits_set) {
    	/* An initial section contains all pointers.  Use length descriptor. */
        return(WORDS_TO_BYTES(last_set_bit+1) | GC_DS_LENGTH);
      }
    }
#   endif
    if (last_set_bit < BITMAP_BITS) {
    	/* Hopefully the common case.			*/
    	/* Build bitmap descriptor (with bits reversed)	*/
    	result = HIGH_BIT;
    	for (i = last_set_bit - 1; i >= 0; i--) {
    	    result >>= 1;
    	    if (GC_get_bit(bm, i)) result |= HIGH_BIT;
    	}
    	result |= GC_DS_BITMAP;
    	return(result);
    } else {
    	signed_word index;
    	
    	index = GC_add_ext_descriptor(bm, (word)last_set_bit+1);
    	if (index == -1) return(WORDS_TO_BYTES(last_set_bit+1) | GC_DS_LENGTH);
    				/* Out of memory: use conservative	*/
    				/* approximation.			*/
    	result = GC_MAKE_PROC(GC_typed_mark_proc_index, (word)index);
    	return(result);
    }
}

ptr_t GC_clear_stack();

#define GENERAL_MALLOC(lb,k) \
    (GC_PTR)GC_clear_stack(GC_generic_malloc((word)lb, k))
    
#define GENERAL_MALLOC_IOP(lb,k) \
    (GC_PTR)GC_clear_stack(GC_generic_malloc_ignore_off_page(lb, k))

#if defined(__STDC__) || defined(__cplusplus)
  void * GC_malloc_explicitly_typed(size_t lb, GC_descr d)
#else
  char * GC_malloc_explicitly_typed(lb, d)
  size_t lb;
  GC_descr d;
#endif
{
register ptr_t op;
register ptr_t * opp;
register word lw;
DCL_LOCK_STATE;

    lb += TYPD_EXTRA_BYTES;
    if( SMALL_OBJ(lb) ) {
#       ifdef MERGE_SIZES
	  lw = GC_size_map[lb];
#	else
	  lw = ALIGNED_WORDS(lb);
#       endif
	opp = &(GC_eobjfreelist[lw]);
	FASTLOCK();
        if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
            FASTUNLOCK();
            op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
	    if (0 == op) return 0;
#	    ifdef MERGE_SIZES
		lw = GC_size_map[lb];	/* May have been uninitialized.	*/
#	    endif
        } else {
            *opp = obj_link(op);
	    obj_link(op) = 0;
            GC_words_allocd += lw;
            FASTUNLOCK();
        }
   } else {
       op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
       if (op != NULL)
	    lw = BYTES_TO_WORDS(GC_size(op));
   }
   if (op != NULL)
       ((word *)op)[lw - 1] = d;
   return((GC_PTR) op);
}

#if defined(__STDC__) || defined(__cplusplus)
  void * GC_malloc_explicitly_typed_ignore_off_page(size_t lb, GC_descr d)
#else
  char * GC_malloc_explicitly_typed_ignore_off_page(lb, d)
  size_t lb;
  GC_descr d;
#endif
{
register ptr_t op;
register ptr_t * opp;
register word lw;
DCL_LOCK_STATE;

    lb += TYPD_EXTRA_BYTES;
    if( SMALL_OBJ(lb) ) {
#       ifdef MERGE_SIZES
	  lw = GC_size_map[lb];
#	else
	  lw = ALIGNED_WORDS(lb);
#       endif
	opp = &(GC_eobjfreelist[lw]);
	FASTLOCK();
        if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
            FASTUNLOCK();
            op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
#	    ifdef MERGE_SIZES
		lw = GC_size_map[lb];	/* May have been uninitialized.	*/
#	    endif
        } else {
            *opp = obj_link(op);
	    obj_link(op) = 0;
            GC_words_allocd += lw;
            FASTUNLOCK();
        }
   } else {
       op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind);
       if (op != NULL)
       lw = BYTES_TO_WORDS(GC_size(op));
   }
   if (op != NULL)
       ((word *)op)[lw - 1] = d;
   return((GC_PTR) op);
}

#if defined(__STDC__) || defined(__cplusplus)
  void * GC_calloc_explicitly_typed(size_t n,
  				    size_t lb,
  				    GC_descr d)
#else
  char * GC_calloc_explicitly_typed(n, lb, d)
  size_t n;
  size_t lb;
  GC_descr d;
#endif
{
register ptr_t op;
register ptr_t * opp;
register word lw;
GC_descr simple_descr;
complex_descriptor *complex_descr;
register int descr_type;
struct LeafDescriptor leaf;
DCL_LOCK_STATE;

    descr_type = GC_make_array_descriptor((word)n, (word)lb, d,
    					  &simple_descr, &complex_descr, &leaf);
    switch(descr_type) {
    	case NO_MEM: return(0);
    	case SIMPLE: return(GC_malloc_explicitly_typed(n*lb, simple_descr));
    	case LEAF:
    	    lb *= n;
    	    lb += sizeof(struct LeafDescriptor) + TYPD_EXTRA_BYTES;
    	    break;
    	case COMPLEX:
    	    lb *= n;
    	    lb += TYPD_EXTRA_BYTES;
    	    break;
    }
    if( SMALL_OBJ(lb) ) {
#       ifdef MERGE_SIZES
	  lw = GC_size_map[lb];
#	else
	  lw = ALIGNED_WORDS(lb);
#       endif
	opp = &(GC_arobjfreelist[lw]);
	FASTLOCK();
        if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
            FASTUNLOCK();
            op = (ptr_t)GENERAL_MALLOC((word)lb, GC_array_kind);
	    if (0 == op) return(0);
#	    ifdef MERGE_SIZES
		lw = GC_size_map[lb];	/* May have been uninitialized.	*/            
#	    endif
        } else {
            *opp = obj_link(op);
	    obj_link(op) = 0;
            GC_words_allocd += lw;
            FASTUNLOCK();
        }
   } else {
       op = (ptr_t)GENERAL_MALLOC((word)lb, GC_array_kind);
       if (0 == op) return(0);
       lw = BYTES_TO_WORDS(GC_size(op));
   }
   if (descr_type == LEAF) {
       /* Set up the descriptor inside the object itself. */
       VOLATILE struct LeafDescriptor * lp =
           (struct LeafDescriptor *)
               ((word *)op
                + lw - (BYTES_TO_WORDS(sizeof(struct LeafDescriptor)) + 1));
                
       lp -> ld_tag = LEAF_TAG;
       lp -> ld_size = leaf.ld_size;
       lp -> ld_nelements = leaf.ld_nelements;
       lp -> ld_descriptor = leaf.ld_descriptor;
       ((VOLATILE word *)op)[lw - 1] = (word)lp;
   } else {
       extern unsigned GC_finalization_failures;
       unsigned ff = GC_finalization_failures;
       
       ((word *)op)[lw - 1] = (word)complex_descr;
       /* Make sure the descriptor is cleared once there is any danger	*/
       /* it may have been collected.					*/
       (void)
         GC_general_register_disappearing_link((GC_PTR *)
         					  ((word *)op+lw-1),
       					          (GC_PTR) op);
       if (ff != GC_finalization_failures) {
	   /* Couldn't register it due to lack of memory.  Punt.	*/
	   /* This will probably fail too, but gives the recovery code  */
	   /* a chance.							*/
	   return(GC_malloc(n*lb));
       }			          
   }
   return((GC_PTR) op);
}
