summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortedu <>2012-06-22 01:30:17 +0000
committertedu <>2012-06-22 01:30:17 +0000
commit8ab3be999733505905c43d1c6b1e23220e85f6b5 (patch)
treecb793c8d0797100c55af7689875d24b90d9584af
parent80020aecd05f49119bfeaec130105f3890a5258a (diff)
downloadopenbsd-8ab3be999733505905c43d1c6b1e23220e85f6b5.tar.gz
openbsd-8ab3be999733505905c43d1c6b1e23220e85f6b5.tar.bz2
openbsd-8ab3be999733505905c43d1c6b1e23220e85f6b5.zip
two changes which should improve realloc. first, fix zapcacheregion to
clear out the entire requested area, not just a perfect fit. second, use mquery to check for room to avoid getting an address we don't like and having to send it back.
-rw-r--r--src/lib/libc/stdlib/malloc.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 92efd7d68b..7a48a0f2ff 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: malloc.c,v 1.143 2012/06/20 13:13:15 tedu Exp $ */ 1/* $OpenBSD: malloc.c,v 1.144 2012/06/22 01:30:17 tedu Exp $ */
2/* 2/*
3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
4 * 4 *
@@ -94,6 +94,9 @@
94#define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ 94#define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
95 MAP_ANON | MAP_PRIVATE, -1, (off_t) 0) 95 MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
96 96
97#define MQUERY(a, sz) mquery((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
98 MAP_ANON | MAP_PRIVATE, -1, (off_t)0)
99
97struct region_info { 100struct region_info {
98 void *p; /* page; low bits used to mark chunks */ 101 void *p; /* page; low bits used to mark chunks */
99 uintptr_t size; /* size for pages, or chunk_info pointer */ 102 uintptr_t size; /* size for pages, or chunk_info pointer */
@@ -356,7 +359,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
356} 359}
357 360
358static void 361static void
359zapcacheregion(struct dir_info *d, void *p) 362zapcacheregion(struct dir_info *d, void *p, size_t len)
360{ 363{
361 u_int i; 364 u_int i;
362 struct region_info *r; 365 struct region_info *r;
@@ -364,7 +367,7 @@ zapcacheregion(struct dir_info *d, void *p)
364 367
365 for (i = 0; i < mopts.malloc_cache; i++) { 368 for (i = 0; i < mopts.malloc_cache; i++) {
366 r = &d->free_regions[i]; 369 r = &d->free_regions[i];
367 if (r->p == p) { 370 if (r->p >= p && r->p <= (void *)((char *)p + len)) {
368 rsz = r->size << MALLOC_PAGESHIFT; 371 rsz = r->size << MALLOC_PAGESHIFT;
369 if (munmap(r->p, rsz)) 372 if (munmap(r->p, rsz))
370 wrterror("munmap", r->p); 373 wrterror("munmap", r->p);
@@ -1283,20 +1286,26 @@ orealloc(void *p, size_t newsz, void *f)
1283 1286
1284 if (rnewsz > roldsz) { 1287 if (rnewsz > roldsz) {
1285 if (!mopts.malloc_guard) { 1288 if (!mopts.malloc_guard) {
1289 void *hint = (char *)p + roldsz;
1290 size_t needed = rnewsz - roldsz;
1291
1286 STATS_INC(g_pool->cheap_realloc_tries); 1292 STATS_INC(g_pool->cheap_realloc_tries);
1287 zapcacheregion(g_pool, (char *)p + roldsz); 1293 zapcacheregion(g_pool, hint, needed);
1288 q = MMAPA((char *)p + roldsz, rnewsz - roldsz); 1294 q = MQUERY(hint, needed);
1289 if (q == (char *)p + roldsz) { 1295 if (q == hint)
1290 malloc_used += rnewsz - roldsz; 1296 q = MMAPA(hint, needed);
1297 else
1298 q = MAP_FAILED;
1299 if (q == hint) {
1300 malloc_used += needed;
1291 if (mopts.malloc_junk) 1301 if (mopts.malloc_junk)
1292 memset(q, SOME_JUNK, 1302 memset(q, SOME_JUNK, needed);
1293 rnewsz - roldsz);
1294 r->size = newsz; 1303 r->size = newsz;
1295 STATS_SETF(r, f); 1304 STATS_SETF(r, f);
1296 STATS_INC(g_pool->cheap_reallocs); 1305 STATS_INC(g_pool->cheap_reallocs);
1297 return p; 1306 return p;
1298 } else if (q != MAP_FAILED) { 1307 } else if (q != MAP_FAILED) {
1299 if (munmap(q, rnewsz - roldsz)) 1308 if (munmap(q, needed))
1300 wrterror("munmap", q); 1309 wrterror("munmap", q);
1301 } 1310 }
1302 } 1311 }