[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
- Previous message: [Commit]
nickle ChangeLog, 1.78, 1.79 Makefile.am, 1.58, 1.59 avl.c,
1.4, NONE avl.h, 1.5, NONE mem.c, 1.18, 1.19 mem.h, 1.13,
1.14 memp.h, 1.5, 1.6
- Next message: [Commit]
jove Makefile, 1.8, 1.9 c.c, 1.5, 1.6 disp.c, 1.4, 1.5 fp.c,
1.4, 1.5 jove.h, 1.7, 1.8 move.c, 1.3, 1.4 screen.c, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
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_ */
- Previous message: [Commit]
nickle ChangeLog, 1.78, 1.79 Makefile.am, 1.58, 1.59 avl.c,
1.4, NONE avl.h, 1.5, NONE mem.c, 1.18, 1.19 mem.h, 1.13,
1.14 memp.h, 1.5, 1.6
- Next message: [Commit]
jove Makefile, 1.8, 1.9 c.c, 1.5, 1.6 disp.c, 1.4, 1.5 fp.c,
1.4, 1.5 jove.h, 1.7, 1.8 move.c, 1.3, 1.4 screen.c, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Commit
mailing list