[Commit] nickle ChangeLog, 1.79, 1.80 mem.c, 1.19, 1.20 mem.h, 1.14, 1.15 memp.h, 1.6, 1.7

Keith Packard commit at keithp.com
Tue Aug 10 10:45:43 PDT 2004


Committed by: keithp

Update of /local/src/CVS/nickle
In directory home.keithp.com:/tmp/cvs-serv11467

Modified Files:
	ChangeLog mem.c mem.h memp.h 
Log Message:
2004-08-10  Keith Packard  <keithp at keithp.com>

	* mem.c: (newBlock), (MemAllocateHunk), (MemAllocateHuge),
	(activeReference), (activeReset), (MemInitialize), (MemAddRoot),
	(MemReference), (MemReferenceNoRecurse), (mark), (sweep),
	(MemCollect):
	* mem.h:
	* memp.h:
	Clean up new allocator implementation.


Index: ChangeLog
===================================================================
RCS file: /local/src/CVS/nickle/ChangeLog,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -d -r1.79 -r1.80
--- ChangeLog	10 Aug 2004 07:39:55 -0000	1.79
+++ ChangeLog	10 Aug 2004 17:45:40 -0000	1.80
@@ -1,4 +1,14 @@
 2004-08-10  Keith Packard  <keithp at keithp.com>
+
+	* mem.c: (newBlock), (MemAllocateHunk), (MemAllocateHuge),
+	(activeReference), (activeReset), (MemInitialize), (MemAddRoot),
+	(MemReference), (MemReferenceNoRecurse), (mark), (sweep),
+	(MemCollect):
+	* mem.h:
+	* memp.h:
+	Clean up new allocator implementation.
+
+2004-08-10  Keith Packard  <keithp at keithp.com>
 version 2.43
 
 	* Makefile.am:

Index: mem.c
===================================================================
RCS file: /local/src/CVS/nickle/mem.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- mem.c	10 Aug 2004 07:39:55 -0000	1.19
+++ mem.c	10 Aug 2004 17:45:40 -0000	1.20
@@ -15,148 +15,129 @@
  *			- returns a hunk of at least "size" bytes
  * void MemReference (void *object)
  *			- marks the indicated object as referenced
- * DataType *MemType (void *object)
- *			- returns the type of the indicated object
  * void MemAddRoot (void *object)
  *			- adds the indicated object as a root
  * void MemCollect (void)
  *			- sweeps the entire heap freeing unused storage
  *
- * local routines:
- *
- * gimmeBlock()		- calls iGarbageCollect (if it is time) or malloc
- * allocBlock()		- calls malloc
- * disposeBlock()	- calls free
- *
- * tossFree()		- erases the free lists
- * checkRef()		- puts unreferenced hunks on free lists
- * checkBlockRef(b)	- puts unreferenced hunks in a block on free lists
  */
 
 #include	<config.h>
 
 #include	<memory.h>
-#define MEM_NEED_ALLOCATE
+#define MEM_NEED_ALLOCATE 1
 #include	"mem.h"
 #include	"memp.h"
 #include	<stdlib.h>
 
-#if HAVE_STDINT_H
-#include	<stdint.h>
-#define PtrToInt(p)	((int) (intptr_t) (p))
-#else
-#define PtrToInt(p)	((int) (p))
-#endif
-
-int		GarbageTime;
+static struct block *head;
+struct bfree	    *freeList[NUMSIZES];
 
-void		*TemporaryData;
+static int	    garbageTime;
+static int	    sinceGarbage;
 
-#undef DEBUG
+StackObject	    *MemStack;
+void		    *TemporaryData;
+static void	    **Roots;
+static int	    RootCount;
+static int	    RootSize;
 
 #ifdef DEBUG
-int	GCdebug;
+int		    GCdebug;
+int		    totalBytesFree;
+int		    totalBytesUsed;
+int		    totalObjectsFree;
+int		    totalObjectsUsed;
+int		    useMap[NUMSIZES+1];
 #endif
 
-StackObject *MemStack;
-
-struct bfree *freeList[NUMSIZES];
-
-int	sinceGarbage;
-
-static void **Roots;
-static int  RootCount;
-
-struct bfree		*lastFree[NUMSIZES];
-
-static struct block	*head;
-
-int	totalBytesFree;
-int	totalBytesUsed;
-int	totalObjectsFree;
-int	totalObjectsUsed;
-int	useMap[NUMSIZES+1];
+/*
+ * Allocate a new block
+ */
 
 static struct block *
-MemNewBlock (unsigned size, int sizeIndex)
+newBlock (int sizeIndex)
 {
     struct block    *b;
-    if (++sinceGarbage >= GarbageTime)
+    int		    size;
+    
+    if (sizeIndex < NUMSIZES)
+	size = BLOCKSIZE;
+    else
+	size = sizeIndex + HEADSIZE;
+
+    if (++sinceGarbage >= garbageTime)
     {
 	MemCollect ();
-	if (sizeIndex >= 0 && freeList[sizeIndex])
+	if (sizeIndex < NUMSIZES && freeList[sizeIndex])
 	    return 0;
     }
     b = (struct block *) malloc (size);
     if (!b)
     {
 	MemCollect ();
-	if (sizeIndex >= 0 && freeList[sizeIndex])
+	if (sizeIndex < NUMSIZES && freeList[sizeIndex])
 	    return 0;
 	b = (struct block *) malloc (size);
 	if (!b)
 	    panic (0, "out of memory - quiting\n");
     }
+    b->sizeIndex = sizeIndex;
+    b->next = head;
+    head = b; 
     return b;
 }
 
-void *
-MemHunkMore (int sizeIndex)
+/*
+ * Allocate a small block of memory
+ */
+
+struct bfree *
+MemAllocateHunk (int sizeIndex)
 {
-    unsigned char	*new;
     struct block	*b;
-    int			n;
-
-    b = MemNewBlock ((unsigned) BLOCKSIZE, sizeIndex);
-    if (!b)
-	return freeList[sizeIndex];
-    /*
-     * fill in per-block data fields
-     */
-    b->sizeIndex = sizeIndex;
-    b->next = head;
-    head = b; 
+    struct bfree    	*new;
 
-    /*
-     * put it's contents on the free list
-     */
-    new = HUNKS(b);
-    n = NUMHUNK(sizeIndex) - 1;
-    while (n--)
+    b = newBlock (sizeIndex);
+    if (b)
     {
-	unsigned char	*next = new + HUNKSIZE(sizeIndex);
-	((struct bfree *) new)->type = 0;
-	((struct bfree *) new)->next = (struct bfree *) next;
-	new = next;
+	unsigned char	*data = HUNKS (b);
+	int		n = NUMHUNK(sizeIndex);
+	/*
+	 * put the contents on the free list
+	 */
+	while (--n)
+	{
+	    unsigned char	*next = data + HUNKSIZE(sizeIndex);
+	    
+	    ((struct bfree *) data)->type = 0;
+	    ((struct bfree *) data)->next = (struct bfree *) next;
+	    data = next;
+	}
+	((struct bfree *) data)->type = 0;
+	((struct bfree *) data)->next = freeList[sizeIndex];
+	freeList[sizeIndex] = (struct bfree *) HUNKS(b);
     }
-    ((struct bfree *) new)->type = 0;
-    ((struct bfree *) new)->next = freeList[sizeIndex];
-    return freeList[sizeIndex] = (struct bfree *) HUNKS(b);
+    new = freeList[sizeIndex];
+    freeList[sizeIndex] = new->next;
+    return new;
 }
 
 /*
- * take care of giant requests
+ * Allocate a large block of memory
  */
 
-void *
-MemAllocateHuge (DataType *type, int size)
+struct bfree *
+MemAllocateHuge (int size)
 {
-    struct block	*b;
-    unsigned char	*data;
-
-    b = MemNewBlock ((unsigned) (size + HEADSIZE), -1);
-    
-    b->sizeIndex = size;
-    b->next = head;
-    head = b;
-
-    data = HUNKS(b);
-    *((DataType **) data) = type;
-    return data;
+    return (struct bfree *) HUNKS (newBlock (size));
 }
 
 #ifdef MEM_TRACE
-DataType	*allDataTypes;
+/*
+ * Allocation tracing.  Track usage of each type of object
+ */
+static DataType	*allDataTypes;
 
 void
 MemAddType (DataType *type)
@@ -172,14 +153,14 @@
 }
 
 static void
-MemActiveReference (DataType *type, int size)
+activeReference (DataType *type, int size)
 {
     type->active++;
     type->active_bytes += size;
 }
 
 static void
-MemActiveReset (void)
+activeReset (void)
 {
     DataType	*type;
 
@@ -205,28 +186,116 @@
 	       type->active, type->active_bytes);
     }
 }
+#endif
 
+/*
+ * Initialize the allocator
+ */
+
+void
+MemInitialize (void)
+{
+#ifdef DEBUG
+    if (getenv ("NICKLE_MEM_DEBUG"))
+	GCdebug=1;
 #endif
+    if (!MemStack)
+    {
+	MemStack = StackCreate ();
+	MemAddRoot (MemStack);
+    }
+    garbageTime = GARBAGETIME;
+}
 
 /*
- * garbage collection scheme
+ * Add a root to the memory system, objects
+ * referenced through this will be marked as busy
  */
 
-#define isReferenced(a)	    (*((PtrInt *)(a)) & 1)
-#define clrReference(a)	    (*((PtrInt *)(a)) &= ~1)
-#define setReference(a)	    (*((PtrInt *)(a)) |= 1)
+void
+MemAddRoot (void *object)
+{
+    void    **roots;
+
+    if (RootCount == RootSize)
+    {
+	if (RootSize == 0)
+	    RootSize = 128;
+	else
+	    RootSize *= 2;
+	roots = malloc (sizeof (void *) * RootSize);
+	if (!roots)
+	    panic ("out of memory");
+	memcpy (roots, Roots, RootCount * sizeof (void *));
+	if (Roots)
+	    free (Roots);
+	Roots = roots;
+    }
+    Roots[RootCount++] = object;
+}
 
 /*
- * eliminate any remaining free list
+ * Mark an object as referenced, recurse through
+ * the Mark routine for the type to mark referenced objects
+ */
+
+void
+MemReference (void *object)
+{
+    DataType	*type;
+
+    if (!object)
+	return;
+    if (PtrToInt(object) & 3)
+	return;
+    if (!isReferenced (object))
+    {
+	type = TYPE(object);
+	setReference(object);
+	if (type && type->Mark)
+	    (*type->Mark) (object);
+    }
+}
+
+/*
+ * Mark an object but don't recurse, returning
+ * whether the object was previously referenced or not
+ */
+
+int
+MemReferenceNoRecurse (void *object)
+{
+    if (!object)
+	return 1;
+    if (PtrToInt (object) & 3)
+	return 1;
+    if (isReferenced (object))
+	return 1;
+    setReference (object);
+    return 0;
+}
+
+/*
+ * mark: walk roots marking referenced memory
  */
 
 static void
-tossFree (void)
+mark (void)
 {
-    memset (freeList, '\0', NUMSIZES * sizeof(freeList[0]));
+    int	    rootCount = RootCount;
+    void    **roots = Roots;
+    
+    while (rootCount--)
+	MemReference (*roots++);
+    if (TemporaryData)
+	MemReference (TemporaryData);
 }
 
+#if HAVE_C_INLINE
+static inline int
+#else
 static int
+#endif
 busy (unsigned char *data)
 {
     DataType	*type;
@@ -243,218 +312,132 @@
     return 1;
 }
 
-static int
-checkBlockRef (struct block *b)
+/*
+ * sweep: rebuild the free lists from unused data
+ */
+
+static void
+sweep (void)
 {
-    int		    sizeIndex = b->sizeIndex;
-    unsigned char   *data = HUNKS(b);
-    
-    if (sizeIndex >= NUMSIZES)
-    {
-	if (busy (data))
-	{
-	    clrReference(HUNKS(b));
-	    totalObjectsUsed++;
-	    totalBytesUsed += sizeIndex;
-	    useMap[NUMSIZES]++;
-#ifdef MEM_TRACE
-	    MemActiveReference (TYPE(data), b->sizeIndex);
-#endif
-	    return 1;
-	}
-	else
-	{
-	    totalBytesFree += sizeIndex;
-	    totalObjectsFree++;
-	    return 0;
-	}
-    }
-    else
+    struct block    *b, **p;
+
+    /* Erase free list */
+    memset (freeList, '\0', NUMSIZES * sizeof(freeList[0]));
+    /*
+     * Walk all blocks
+     */
+    for (p = &head; (b = *p); )
     {
-	struct bfree	*first = 0;
+	int		sizeIndex = b->sizeIndex;
+	int		n = NUMHUNK_ALL(sizeIndex);
+	int		size = HUNKSIZE_ALL(sizeIndex);
+	unsigned char   *data = HUNKS(b);
+	struct bfree    *first = 0;
 	struct bfree    **prev = &first;
-	int		n = NUMHUNK(sizeIndex);
 	int		anybusy = 0;
-	int		size = HUNKSIZE(sizeIndex);
 
 	while (n--)
 	{
 	    if (busy (data))
 	    {
 		clrReference(data);
+		anybusy = 1;
 #ifdef MEM_TRACE
-		MemActiveReference (TYPE(data), size);
+		activeReference (TYPE(data), size);
 #endif
+#ifdef DEBUG
 		totalObjectsUsed++;
 		useMap[sizeIndex]++;
 		totalBytesUsed += size;
-		anybusy = 1;
+#endif
 	    }
 	    else
 	    {
 		TYPE(data) = 0;
 		*prev = (struct bfree *) data;
 		prev = &((struct bfree *) data)->next;
+#ifdef DEBUG
 		totalBytesFree += size;
 		totalObjectsFree++;
+#endif
 	    }
 	    data += size;
 	}
 	if (anybusy)
 	{
-	    *prev = freeList[sizeIndex];
-	    freeList[sizeIndex] = first;
-	    return 1;
-	}
-	else
-	{
-	    return 0;
-	}
-    }
-}
-
-/*
- * checkRef: rebuild the free lists from unused data
- */
-
-static void
-checkRef (void)
-{
-    int	i;
-    struct block    *b, **p;
-
-    for (i = 0; i < NUMSIZES; i++)
-	lastFree[i] = 0;
-    for (p = &head; (b = *p); )
-    {
-	if (checkBlockRef (b))
+	    if (sizeIndex < NUMSIZES)
+	    {
+		*prev = freeList[sizeIndex];
+		freeList[sizeIndex] = first;
+	    }
 	    p = &b->next;
+	}
 	else
 	{
 	    *p = b->next;
 	    free (b);
 	}
     }
-    GarbageTime = GARBAGETIME/* - (totalBytesFree / BLOCKSIZE) */;
-    if (GarbageTime < 10)
-	GarbageTime = 10;
-#ifdef DEBUG
-    if (GCdebug) {
-	debug ("GC: used: bytes %7d objects %7d\n",
-	       totalBytesUsed, totalObjectsUsed);
-	debug ("GC: free: bytes %7d objects %7d\n",
-	       totalBytesFree, totalObjectsFree);
-	for (i = 0; i <= NUMSIZES; i++)
-	    debug ("used %5d: %7d\n",
-		   i == NUMSIZES ? 0 : HUNKSIZE(i), useMap[i]);
-	debug ("GC: GarbageTime set to %d\n", GarbageTime);
-    }
-#endif
-}
-
-void
-MemInitialize (void)
-{
-#ifdef DEBUG
-    if (getenv ("NICKLE_MEM_DEBUG"))
-	GCdebug=1;
-#endif
-    if (!MemStack)
-    {
-	MemStack = StackCreate ();
-	MemAddRoot (MemStack);
-    }
-    GarbageTime = GARBAGETIME;
-}
-
-void
-MemReference (void *object)
-{
-    DataType	*type;
-
-    if (!object)
-	return;
-    if (PtrToInt(object) & 3)
-	return;
-    if (!isReferenced (object))
-    {
-	type = TYPE(object);
-	setReference(object);
-	if (type && type->Mark)
-	    (*type->Mark) (object);
-    }
 }
 
 /*
- * Mark an object but don't recurse, returning
- * whether the object was previously referenced or not
+ * Garbage collect
  */
 
-int
-MemReferenceNoRecurse (void *object)
-{
-    if (!object)
-	return 1;
-    if (PtrToInt (object) & 3)
-	return 1;
-    if (isReferenced (object))
-	return 1;
-    setReference (object);
-    return 0;
-}
-
-DataType *
-MemType (void *object)
-{
-    return TYPE (object);
-}
-
-void
-MemAddRoot (void *object)
-{
-    void    **roots;
-
-    roots = malloc (sizeof (void *) * (RootCount + 1));
-    if (!roots)
-	panic ("out of memory");
-    if (RootCount)
-	memcpy (roots, Roots, RootCount * sizeof (void *));
-    if (Roots)
-	free (Roots);
-    Roots = roots;
-    Roots[RootCount++] = object;
-}
-
-
 void
 MemCollect (void)
 {
-    void    	**roots;
-    int		rootCount;
-
 #ifdef DEBUG
     if (GCdebug)
 	debug ("GC:\n");
-#endif
     memset (useMap, '\0', sizeof useMap);
     totalBytesFree = 0;
     totalObjectsFree = 0;
     totalBytesUsed = 0;
     totalObjectsUsed = 0;
+#endif
     sinceGarbage = 0;
+    
 #ifdef MEM_TRACE
-    MemActiveReset ();
+    activeReset ();
 #endif
-    tossFree ();
+    
+    /*
+     * Mark
+     */
 #ifdef DEBUG
     if (GCdebug)
-	debug ("GC: reference objects\n");
+	debug ("GC: mark objects\n");
+#endif
+    mark ();
+    
+    /*
+     * Sweep
+     */
+#ifdef DEBUG
+    if (GCdebug)
+	debug ("GC: sweep objects\n");
+#endif
+    sweep ();
+    
+    /*
+     * Set the garbage collection time
+     */
+    garbageTime = GARBAGETIME/* - (totalBytesFree / BLOCKSIZE) */;
+    if (garbageTime < 10)
+	garbageTime = 10;
+
+#ifdef DEBUG
+    if (GCdebug) {
+	debug ("GC: used: bytes %7d objects %7d\n",
+	       totalBytesUsed, totalObjectsUsed);
+	debug ("GC: free: bytes %7d objects %7d\n",
+	       totalBytesFree, totalObjectsFree);
+	for (i = 0; i <= NUMSIZES; i++)
+	    debug ("used %5d: %7d\n",
+		   i == NUMSIZES ? 0 : HUNKSIZE(i), useMap[i]);
+	debug ("GC: garbageTime set to %d\n", garbageTime);
+    }
 #endif
-    rootCount = RootCount;
-    roots = Roots;
-    while (rootCount--)
-	MemReference (*roots++);
-    if (TemporaryData)
-	MemReference (TemporaryData);
-    checkRef ();
 }
+

Index: mem.h
===================================================================
RCS file: /local/src/CVS/nickle/mem.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mem.h	10 Aug 2004 07:39:55 -0000	1.14
+++ mem.h	10 Aug 2004 17:45:40 -0000	1.15
@@ -16,14 +16,14 @@
 #include	<strings.h>
 #endif
 
-#undef MEM_TRACE
-
-#ifndef MEM_TRACE
-typedef const struct _DataType DataType;
-#else
+#ifdef MEM_TRACE
 typedef struct _DataType DataType;
+#else
+typedef const struct _DataType DataType;
 #endif
 
+#include	"stack.h"
+
 struct _DataType {
     void    (*Mark) (void *);
     int	    (*Free) (void *);
@@ -61,39 +61,61 @@
 # define NUMSIZES	12
 # define HUNKSIZE(i)	(MINHUNK << (i))
 # define MAXHUNK	HUNKSIZE(NUMSIZES-1)
+# define HEADSIZE	(sizeof (union block_round))
+# define HUNKS(b)	((unsigned char *) (b) + HEADSIZE)
 
 #if HAVE_C_INLINE
 #define USE_C_INLINE 1
 #endif
 
-extern void	MemInitialize (void);
+struct bfree *
+MemAllocateHunk (int sizeIndex);
+
+struct bfree *
+MemAllocateHuge (int size);
+
 #ifndef USE_C_INLINE
-extern void	*MemAllocate (DataType *type, int size);
-extern void	*MemAllocateRef (DataType *type, int size);
+void
+*MemAllocate (DataType *type, int size);
+
+void
+*MemAllocateRef (DataType *type, int size);
 #endif
-extern void	MemFree (void *object, int size);
-extern void	*MemAllocateHuge (DataType *type, int size);
-extern void	*MemHunkMore (int sizeIndex);
-extern void	MemReference (void *object);
-extern int	MemReferenceNoRecurse (void *object);
-extern DataType	*MemType (void *object);
-extern void	MemAddRoot (void *object);
-extern void	MemCollect (void);
-extern void	MemCheckPointer (void *base, void *address, int size);
+
 #ifdef MEM_TRACE
-extern void	MemAddType (DataType *type);
-extern void	MemActiveDump (void);
+void
+MemAddType (DataType *type);
+
+void
+MemActiveDump (void);
 #endif
 
-extern void	debug (char *, ...);
-extern void	panic (char *, ...);
+void
+MemInitialize (void);
 
-extern int	GCdebug;
+void
+MemAddRoot (void *object);
 
-#include	"stack.h"
+void
+MemReference (void *object);
 
-extern	StackObject *MemStack;
+int
+MemReferenceNoRecurse (void *object);
 
+void
+MemCollect (void);
+    
+/*
+ * These are used by the mem system and defined externally
+ */
+
+void
+debug (char *, ...);
+
+void
+panic (char *, ...);
+
+extern StackObject  *MemStack;
 extern void	    *TemporaryData;
 
 extern struct bfree *freeList[NUMSIZES];
@@ -105,13 +127,13 @@
 #define RETURN(r)	    return (STACK_RETURN (MemStack, __stackPointer, (r)))
 #define NOREFRETURN(r)	    return (EXIT(), (r))
 
-#if defined(USE_C_INLINE) || defined(MEM_NEED_ALLOCATE)
+#if USE_C_INLINE || MEM_NEED_ALLOCATE
 
 /*
  * Allocator entry point
  */
 
-#ifdef USE_C_INLINE
+#if USE_C_INLINE
 static inline struct bfree *
 #else
 static struct bfree *
@@ -121,7 +143,7 @@
     int	sizeIndex = 0;
     struct bfree    *new;
     
-#if NUMSIZES > 16
+#if NUMSIZES > 15    
     bad NUMSIZES
 #endif
 #ifdef MEM_TRACE
@@ -142,16 +164,15 @@
 	sizeIndex += 1;
     
     if (sizeIndex >= NUMSIZES)
-	return MemAllocateHuge (type, size);
-    
-    new = freeList[sizeIndex];
-    if (!new)
-	new = MemHunkMore (sizeIndex);
-    freeList[sizeIndex] = new->next;
+	new = MemAllocateHuge (size);
+    else if ((new = freeList[sizeIndex]))
+	freeList[sizeIndex] = new->next;
+    else
+	new = MemAllocateHunk (sizeIndex);
     return new;
 }
 
-#ifdef USE_C_INLINE
+#if USE_C_INLINE
 static inline void *
 #else
 void *
@@ -166,7 +187,7 @@
     return (void *) new;
 }
 
-#ifdef USE_C_INLINE
+#if USE_C_INLINE
 static inline void *
 #else
 void *
@@ -179,6 +200,6 @@
     return (void *) new;
 }
 
-#endif
+#endif	/* USE_C_INLINE */
 
 #endif /* _MEM_H_ */

Index: memp.h
===================================================================
RCS file: /local/src/CVS/nickle/memp.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- memp.h	10 Aug 2004 07:39:55 -0000	1.6
+++ memp.h	10 Aug 2004 17:45:40 -0000	1.7
@@ -6,21 +6,45 @@
  * for licensing information.
  */
 
+#ifndef _MEMP_H_
+#define _MEMP_H_
+
 /*
- * mem.h
+ * memp.h
  *
  * definitions for the memory manager
  */
 
-# define TYPE(o)	(*((DataType **) (o)))
-# define HEADSIZE	(sizeof (union block_round))
-# define MINBLOCKSIZE	(MAXHUNK + MINHUNK + HEADSIZE)
-# define GOODBLOCKSIZE	(0x2000)
-# define BLOCKSIZE	(GOODBLOCKSIZE < MINBLOCKSIZE ? \
-			 MINBLOCKSIZE : GOODBLOCKSIZE)
-# define DATASIZE	(BLOCKSIZE - HEADSIZE)
-# define NUMHUNK(i)	((i) >= NUMSIZES ? 1 : (DATASIZE / HUNKSIZE(i)))
-
-# define HUNKS(b)	((unsigned char *) (b) + HEADSIZE)
+# define TYPE(o)	    (*((DataType **) (o)))
+# define MINBLOCKSIZE	    (MAXHUNK + MINHUNK + HEADSIZE)
+# define GOODBLOCKSIZE	    (0x2000)
+# define BLOCKSIZE	    (GOODBLOCKSIZE < MINBLOCKSIZE ? \
+			     MINBLOCKSIZE : GOODBLOCKSIZE)
+# define DATASIZE	    (BLOCKSIZE - HEADSIZE)
+# define NUMHUNK(i)	    (DATASIZE / HUNKSIZE(i))
+# define NUMHUNK_ALL(i)	    ((i) >= NUMSIZES ? 1 : NUMHUNK(i))
+# define HUNKSIZE_ALL(i)    ((i) >= NUMSIZES ? (i) : HUNKSIZE(i))
 
 # define GARBAGETIME	1000
+
+#if HAVE_STDINT_H
+#include	<stdint.h>
+#define PtrToInt(p)	((int) (intptr_t) (p))
+typedef intptr_t	IntPtr;
+#else
+#define PtrToInt(p)	((int) (p))
+typedef int		IntPtr;
+#endif
+
+/*
+ * Reference bits are stored in the low bit of the DataType pointer
+ * which exists at the head of each object
+ */
+
+#define fetchRefInt(a)	    ((IntPtr) (*(DataType **) (a)))
+#define storeRefInt(a,v)    ((*(DataType **) (a)) = (DataType *) (v))
+#define isReferenced(a)	    (fetchRefInt(a) & 1)
+#define clrReference(a)	    (storeRefInt(a,fetchRefInt(a) & ~1))
+#define setReference(a)	    (storeRefInt(a,fetchRefInt(a) | 1))
+
+#endif /* _MEMP_H_ */




More information about the Commit mailing list