#include "gc←private.h"
#include <stddef.h>

/* These are some additional routines to interface the collector to C     */
/* This is a rather special purpose interface that tries to keep down the */
/* number of collections in the presence of explicit deallocations.	  */
/* A call to this malloc effectively declares that the resulting object   */
/* will be explicitly deallocated with very high probability.		  */
/* The reduced collection frequency may interfere with object 		  */
/* coalescing.								  */
/* If you just want to rename GC←malloc and friends, this is NOT	  */
/* the right way to do it.						  */

/* This contributed by David Chase (chase@eng.sun.com) a long time	  */
/* ago. Much of its original functionality has since been absorbed	  */
/* elsewhere.								  */
/* They illustrates the use of GC←non←gc←bytes 				  */
/* Hacked by H. Boehm (11/16/89) to accomodate GC←realloc.                */
/* Further updated (2/20/92) to reflect changes in interfaces and data	  */
/* structures.								  */
/* Further updated (8/25/92) to correct previously introduced bugs and 	  */
/* make it compile with semi-modern compilers.				  */
/* Note that extern←ptr←t is either void * or char *, as appropriate.     */


/* This free routine is merely advisory -- it reduces the estimate of
   storage that won't be reclaimed in the next collection, thus
   making it more likely that the collector will run next time more
   memory is needed. */

void free(p)
extern←ptr←t p;
{
  size←t inc = GC←size(p);
  GC←non←gc←bytes -= inc;
}

/* This free routine adjusts the collector estimates of space in use,
   but also actually releases the memory for reuse.  It is thus "unsafe"
   if the programmer "frees" memory that is actually still in use.  */

void unsafe←free(p)
extern←ptr←t p;
{
  size←t inc = GC←size(p);
  GC←non←gc←bytes -= inc;
  GC←free(p);
}


/* malloc and malloc←atomic are obvious substitutes for the C library
   malloc.  Note that the storage so allocated is regarded as not likely
   to be reclaimed by the collector (until explicitly freed), and thus
   its size is added to non←gc←bytes.
*/

extern←ptr←t malloc(bytesize)
size←t bytesize;
{
  extern←ptr←t result;
  
  result = (extern←ptr←t) GC←malloc (bytesize);
  GC←non←gc←bytes += (bytesize + 3) & ~3;
  return result;
}

extern←ptr←t malloc←atomic(bytesize)
size←t bytesize;
{
  extern←ptr←t result;
  
  result = (extern←ptr←t) GC←malloc←atomic (bytesize);
  GC←non←gc←bytes += (bytesize + 3) & ~3;
  return result;
}

extern←ptr←t realloc(old,size)
extern←ptr←t old;
size←t size;
{
  int inc = GC←size(old);

  GC←non←gc←bytes += ((size + 3) & ~3) - inc;
  return(GC←realloc(old, size));
}