summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-08-27 04:38:05 +0000
committerUlrich Drepper <drepper@redhat.com>2006-08-27 04:38:05 +0000
commit41999a1a37a1c00864c7e390ac6c9f29ec1ae27c (patch)
tree5360f88142a35949927e64a80c537e0cee5da741
parent7166374764ceb7eb568c63e736f099b812f29a54 (diff)
downloadglibc-41999a1a37a1c00864c7e390ac6c9f29ec1ae27c.tar.gz
glibc-41999a1a37a1c00864c7e390ac6c9f29ec1ae27c.tar.xz
glibc-41999a1a37a1c00864c7e390ac6c9f29ec1ae27c.zip
* 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.
-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;