Index: head/libexec/rtld-elf/rtld_malloc.c =================================================================== --- head/libexec/rtld-elf/rtld_malloc.c +++ head/libexec/rtld-elf/rtld_malloc.c @@ -85,7 +85,6 @@ static void morecore(int bucket); static int morepages(int n); -static int findbucket(union overhead *freep, int srchlen); #define MAGIC 0xef /* magic # on accounting info */ @@ -248,19 +247,6 @@ nextf[size] = op; } -/* - * When a program attempts "storage compaction" as mentioned in the - * old malloc man page, it realloc's an already freed block. Usually - * this is the last block it freed; occasionally it might be farther - * back. We have to search all the free lists for the block in order - * to determine its bucket: 1st we make one pass through the lists - * checking only the first block in each; if that fails we search - * ``realloc_srchlen'' blocks in each list for a match (the variable - * is extern so the caller can modify it). If that fails we just copy - * however many bytes was given to realloc() and hope it's not huge. - */ -static int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ - void * __crt_realloc(void *cp, size_t nbytes) { @@ -268,78 +254,33 @@ int i; union overhead *op; char *res; - int was_alloced = 0; if (cp == NULL) return (__crt_malloc(nbytes)); op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); - if (op->ov_magic == MAGIC) { - was_alloced++; - i = op->ov_index; - } else { - /* - * Already free, doing "compaction". - * - * Search for the old block of memory on the - * free list. First, check the most common - * case (last element free'd), then (this failing) - * the last ``realloc_srchlen'' items free'd. - * If all lookups fail, then assume the size of - * the memory block being realloc'd is the - * largest possible (so that all "nbytes" of new - * memory are copied into). Note that this could cause - * a memory fault if the old area was tiny, and the moon - * is gibbous. However, that is very unlikely. - */ - if ((i = findbucket(op, 1)) < 0 && - (i = findbucket(op, realloc_srchlen)) < 0) - i = NBUCKETS; - } + if (op->ov_magic != MAGIC) + return (NULL); /* Double-free or bad argument */ + i = op->ov_index; onb = 1 << (i + 3); if (onb < (u_int)pagesz) onb -= sizeof(*op); else onb += pagesz - sizeof(*op); /* avoid the copy if same size block */ - if (was_alloced) { - if (i) { - i = 1 << (i + 2); - if (i < pagesz) - i -= sizeof(*op); - else - i += pagesz - sizeof(*op); - } - if (nbytes <= onb && nbytes > (size_t)i) - return (cp); - __crt_free(cp); + if (i != 0) { + i = 1 << (i + 2); + if (i < pagesz) + i -= sizeof(*op); + else + i += pagesz - sizeof(*op); } + if (nbytes <= onb && nbytes > (size_t)i) + return (cp); if ((res = __crt_malloc(nbytes)) == NULL) return (NULL); - if (cp != res) /* common optimization if "compacting" */ - bcopy(cp, res, (nbytes < onb) ? nbytes : onb); + bcopy(cp, res, (nbytes < onb) ? nbytes : onb); + __crt_free(cp); return (res); -} - -/* - * Search ``srchlen'' elements of each free list for a block whose - * header starts at ``freep''. If srchlen is -1 search the whole list. - * Return bucket number, or -1 if not found. - */ -static int -findbucket(union overhead *freep, int srchlen) -{ - union overhead *p; - int i, j; - - for (i = 0; i < NBUCKETS; i++) { - j = 0; - for (p = nextf[i]; p && j != srchlen; p = p->ov_next) { - if (p == freep) - return (i); - j++; - } - } - return (-1); } static int