summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--malloc/malloc.c19
2 files changed, 22 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 7680f124a0..61a0696850 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2006-08-26  Ulrich Drepper  <drepper@redhat.com>
 
+	* malloc/malloc.c (bin_at): Rewrite to be more clear and to not
+	waste bins[0..1].
+	(malloc_state): Reduce bins size by 2.
+	(_int_malloc): Fix test for large enough buffer for early termination.
+	When no unsorted block matches perfectly and an exiting block has
+	to be split, use full list insert and not shortcut which assumes
+	the list is empty.
+
 	* locale/programs/ld-ctype.c (ctype_read): Better patch for read
 	failure.
 
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 6de1409c4f..5813b419c7 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2061,7 +2061,9 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 typedef struct malloc_chunk* mbinptr;
 
 /* addressing -- note that bin_at(0) does not exist */
-#define bin_at(m, i) ((mbinptr)((char*)&((m)->bins[(i)<<1]) - (SIZE_SZ<<1)))
+#define bin_at(m, i) \
+  (mbinptr) (((char *) &((m)->bins[((i) - 1) * 2]))			      \
+	     - offsetof (struct malloc_chunk, fd))
 
 /* analog of ++bin */
 #define next_bin(b)  ((mbinptr)((char*)(b) + (sizeof(mchunkptr)<<1)))
@@ -2301,7 +2303,7 @@ struct malloc_state {
   mchunkptr        last_remainder;
 
   /* Normal bins packed as described above */
-  mchunkptr        bins[NBINS * 2];
+  mchunkptr        bins[NBINS * 2 - 2];
 
   /* Bitmap of bins */
   unsigned int     binmap[BINMAPSIZE];
@@ -4168,7 +4170,7 @@ _int_malloc(mstate av, size_t bytes)
       fwd->bk = victim;
       bck->fd = victim;
 
-      if (size >= nb)
+      if (size >= nb + MINSIZE)
 	any_larger = true;
 #define MAX_ITERS	10000
       if (++iters >= MAX_ITERS)
@@ -4291,8 +4293,15 @@ _int_malloc(mstate av, size_t bytes)
         else {
           remainder = chunk_at_offset(victim, nb);
 
-          unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
-          remainder->bk = remainder->fd = unsorted_chunks(av);
+	  /* We cannot assume the unsorted list is empty and therefore
+	     have to perform a complete insert here.  */
+	  bck = unsorted_chunks(av);
+	  fwd = bck->fd;
+	  remainder->bk = bck;
+	  remainder->fd = fwd;
+	  bck->fd = remainder;
+	  fwd->bk = remainder;
+
           /* advertise as last remainder */
           if (in_smallbin_range(nb))
             av->last_remainder = remainder;