summaryrefslogtreecommitdiff
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;