emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [patch] mem_node shrink #2


From: Dmitry Antipov
Subject: Re: [patch] mem_node shrink #2
Date: Thu, 29 Nov 2007 18:43:19 +0300
User-agent: Thunderbird 2.0.0.9 (X11/20071115)

Richard Stallman wrote:
It looks good to me, except that here

    +  /* Size of allocated region.  */
    +  unsigned size : MEM_NODE_SIZE_WIDTH;

The comment should explain WHY it is defined that way.

OK. BTW, is there a (supported) system where gmalloc.c is still used ?

Dmitry
Index: alloc.c
===================================================================
RCS file: /sources/emacs/emacs/src/alloc.c,v
retrieving revision 1.432
diff -u -r1.432 alloc.c
--- alloc.c     16 Nov 2007 21:24:59 -0000      1.432
+++ alloc.c     29 Nov 2007 15:39:56 -0000
@@ -430,6 +430,19 @@
    description of red-black trees.  Any book worth its salt should
    describe them.  */
 
+#ifdef GC_MALLOC_CHECK
+/* If this is defined, xmalloc and xrealloc calls mem_insert.  On 64-bit
+   system, if neither USE_MMAP_FOR_BUFFERS nor REL_ALLOC are used, xmalloc
+   or xrealloc may allocate buffer text which size fits into integer, but
+   not into BITS_PER_INT - 4 bits wide bit field.  */
+#define MEM_NODE_SIZE_WIDTH (BITS_PER_EMACS_INT - 4)
+#else
+/* Otherwise, every region which is passed to mem_insert is never larger
+   than 256M, so it's size fits into BITS_PER_INT - 4 bits wide bit field.  */
+#define MEM_NODE_SIZE_WIDTH (BITS_PER_INT - 4)
+#endif
+#define MEM_NODE_SIZE_MAX ((1 << MEM_NODE_SIZE_WIDTH) - 1)
+
 struct mem_node
 {
   /* Children of this node.  These pointers are never NULL.  When there
@@ -439,14 +452,20 @@
   /* The parent of this node.  In the root node, this is NULL.  */
   struct mem_node *parent;
 
-  /* Start and end of allocated region.  */
-  void *start, *end;
+  /* Start of allocated region.  */
+  void *start;
+
+  /* Size of allocated region.  It's defined in such a way to pack the
+     rest of mem_node data within single integer, but still provide
+     the space enough to hold any acceptable size value.  */
+  unsigned size : MEM_NODE_SIZE_WIDTH;
 
   /* Node color.  */
-  enum {MEM_BLACK, MEM_RED} color;
+  enum {MEM_BLACK, MEM_RED} color : 1;
 
-  /* Memory type.  */
-  enum mem_type type;
+  /* Memory type.  The width of this bitfield should be
+     enough to hold any possible mem_type value.  */
+  enum mem_type type : 3;
 };
 
 /* Base address of stack.  Set in main.  */
@@ -480,7 +499,7 @@
 static void mark_maybe_object P_ ((Lisp_Object));
 static void mark_memory P_ ((void *, void *, int));
 static void mem_init P_ ((void));
-static struct mem_node *mem_insert P_ ((void *, void *, enum mem_type));
+static struct mem_node *mem_insert P_ ((void *, size_t, enum mem_type));
 static void mem_insert_fixup P_ ((struct mem_node *));
 static void mem_rotate_left P_ ((struct mem_node *));
 static void mem_rotate_right P_ ((struct mem_node *));
@@ -781,9 +800,16 @@
   register POINTER_TYPE *val;
 
   MALLOC_BLOCK_INPUT;
+  /* Some mallocs returns valid pointer even if SIZE is 0.
+     We're just doing free (PTR) here.  */
+  if (size == 0)
+    {
+      free (block);
+      val = NULL;
+    }
   /* We must call malloc explicitly when BLOCK is 0, since some
      reallocs don't do this.  */
-  if (! block)
+  else if (! block)
     val = (POINTER_TYPE *) malloc (size);
   else
     val = (POINTER_TYPE *) realloc (block, size);
@@ -880,7 +906,7 @@
 
 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK
   if (val && type != MEM_TYPE_NON_LISP)
-    mem_insert (val, (char *) val + nbytes, type);
+    mem_insert (val, nbytes, type);
 #endif
 
   MALLOC_UNBLOCK_INPUT;
@@ -1090,7 +1116,7 @@
 
 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK
   if (val && type != MEM_TYPE_NON_LISP)
-    mem_insert (val, (char *) val + nbytes, type);
+    mem_insert (val, nbytes, type);
 #endif
 
   MALLOC_UNBLOCK_INPUT;
@@ -1263,14 +1289,13 @@
        fprintf (stderr, "Malloc returned %p which is already in use\n",
                 value);
        fprintf (stderr, "Region in use is %p...%p, %u bytes, type %d\n",
-                m->start, m->end, (char *) m->end - (char *) m->start,
-                m->type);
+                m->start, m->start + m->size, m->size, m->type);
        abort ();
       }
 
     if (!dont_register_blocks)
       {
-       mem_insert (value, (char *) value + max (1, size), allocated_mem_type);
+       mem_insert (value, size, allocated_mem_type);
        allocated_mem_type = MEM_TYPE_NON_LISP;
       }
   }
@@ -1330,9 +1355,7 @@
        fprintf (stderr, "Realloc returns memory that is already in use\n");
        abort ();
       }
-
-    /* Can't handle zero size regions in the red-black tree.  */
-    mem_insert (value, (char *) value + max (size, 1), MEM_TYPE_NON_LISP);
+    mem_insert (value, size, MEM_TYPE_NON_LISP);
   }
 
   /* fprintf (stderr, "%p <- realloc\n", value); */
@@ -3543,7 +3566,8 @@
   mem_z.left = mem_z.right = MEM_NIL;
   mem_z.parent = NULL;
   mem_z.color = MEM_BLACK;
-  mem_z.start = mem_z.end = NULL;
+  mem_z.start = NULL;
+  mem_z.size = 0;
   mem_root = MEM_NIL;
 }
 
@@ -3562,10 +3586,10 @@
 
   /* Make the search always successful to speed up the loop below.  */
   mem_z.start = start;
-  mem_z.end = (char *) start + 1;
+  mem_z.size = 1;
 
   p = mem_root;
-  while (start < p->start || start >= p->end)
+  while (start < p->start || start >= p->start + p->size)
     p = start < p->start ? p->left : p->right;
   return p;
 }
@@ -3576,16 +3600,20 @@
    pointer to the node that was inserted.  */
 
 static struct mem_node *
-mem_insert (start, end, type)
-     void *start, *end;
+mem_insert (start, size, type)
+     void *start;
+     size_t size;
      enum mem_type type;
 {
   struct mem_node *c, *parent, *x;
 
+  if (size == 0 || size > MEM_NODE_SIZE_MAX)
+    abort ();
+
   if (min_heap_address == NULL || start < min_heap_address)
     min_heap_address = start;
-  if (max_heap_address == NULL || end > max_heap_address)
-    max_heap_address = end;
+  if (max_heap_address == NULL || start + size > max_heap_address)
+    max_heap_address = start + size;
 
   /* See where in the tree a node for START belongs.  In this
      particular application, it shouldn't happen that a node is already
@@ -3597,7 +3625,7 @@
 
   while (c != MEM_NIL)
     {
-      if (start >= c->start && start < c->end)
+      if (start >= c->start && start < c->start + c->size)
        abort ();
       parent = c;
       c = start < c->start ? c->left : c->right;
@@ -3622,7 +3650,7 @@
   x = (struct mem_node *) xmalloc (sizeof *x);
 #endif
   x->start = start;
-  x->end = end;
+  x->size = size;
   x->type = type;
   x->parent = parent;
   x->left = x->right = MEM_NIL;
@@ -3835,7 +3863,7 @@
   if (y != z)
     {
       z->start = y->start;
-      z->end = y->end;
+      z->size = y->size;
       z->type = y->type;
     }
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]