summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorotto <>2018-01-08 12:20:23 +0000
committerotto <>2018-01-08 12:20:23 +0000
commit7bf3aa14de4848bd18b9e7cce77ac9a6d79600e9 (patch)
treeb0f164e8972236d8d1109369da0e774eaf603282
parentb5565d9f20514e6aee34a8beb128ad836d739bf9 (diff)
downloadopenbsd-7bf3aa14de4848bd18b9e7cce77ac9a6d79600e9.tar.gz
openbsd-7bf3aa14de4848bd18b9e7cce77ac9a6d79600e9.tar.bz2
openbsd-7bf3aa14de4848bd18b9e7cce77ac9a6d79600e9.zip
optimization and some cleanup; mostly from kshe (except the unmap() part)
-rw-r--r--src/lib/libc/stdlib/malloc.c118
1 files changed, 51 insertions, 67 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 02349d9ef9..b0083cb91e 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.238 2018/01/01 12:41:48 otto Exp $ */ 1/* $OpenBSD: malloc.c,v 1.239 2018/01/08 12:20:23 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> 4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -376,12 +376,11 @@ omalloc_parseopt(char opt)
376 case 'X': 376 case 'X':
377 mopts.malloc_xmalloc = 1; 377 mopts.malloc_xmalloc = 1;
378 break; 378 break;
379 default: { 379 default:
380 dprintf(STDERR_FILENO, "malloc() warning: " 380 dprintf(STDERR_FILENO, "malloc() warning: "
381 "unknown char in MALLOC_OPTIONS\n"); 381 "unknown char in MALLOC_OPTIONS\n");
382 break; 382 break;
383 } 383 }
384 }
385} 384}
386 385
387static void 386static void
@@ -448,9 +447,6 @@ omalloc_init(void)
448 ; 447 ;
449} 448}
450 449
451/*
452 * Initialize a dir_info, which should have been cleared by caller
453 */
454static void 450static void
455omalloc_poolinit(struct dir_info **dp) 451omalloc_poolinit(struct dir_info **dp)
456{ 452{
@@ -502,7 +498,7 @@ omalloc_grow(struct dir_info *d)
502 size_t i; 498 size_t i;
503 struct region_info *p; 499 struct region_info *p;
504 500
505 if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2 ) 501 if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2)
506 return 1; 502 return 1;
507 503
508 newtotal = d->regions_total * 2; 504 newtotal = d->regions_total * 2;
@@ -641,9 +637,9 @@ static void
641unmap(struct dir_info *d, void *p, size_t sz, int clear) 637unmap(struct dir_info *d, void *p, size_t sz, int clear)
642{ 638{
643 size_t psz = sz >> MALLOC_PAGESHIFT; 639 size_t psz = sz >> MALLOC_PAGESHIFT;
644 size_t rsz, tounmap; 640 size_t rsz;
645 struct region_info *r; 641 struct region_info *r;
646 u_int i, offset; 642 u_int i, offset, mask;
647 643
648 if (sz != PAGEROUND(sz)) 644 if (sz != PAGEROUND(sz))
649 wrterror(d, "munmap round"); 645 wrterror(d, "munmap round");
@@ -662,30 +658,34 @@ unmap(struct dir_info *d, void *p, size_t sz, int clear)
662 STATS_SUB(d->malloc_used, sz); 658 STATS_SUB(d->malloc_used, sz);
663 return; 659 return;
664 } 660 }
665 tounmap = 0;
666 if (psz > rsz)
667 tounmap = psz - rsz;
668 offset = getrbyte(d); 661 offset = getrbyte(d);
669 for (i = 0; tounmap > 0 && i < mopts.malloc_cache; i++) { 662 mask = mopts.malloc_cache - 1;
670 r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; 663 if (psz > rsz) {
671 if (r->p != NULL) { 664 size_t tounmap = psz - rsz;
672 rsz = r->size << MALLOC_PAGESHIFT; 665 i = 0;
673 if (munmap(r->p, rsz)) 666 for (;;) {
674 wrterror(d, "munmap %p", r->p); 667 r = &d->free_regions[(i + offset) & mask];
675 r->p = NULL; 668 if (r->p != NULL) {
676 if (tounmap > r->size) 669 rsz = r->size << MALLOC_PAGESHIFT;
677 tounmap -= r->size; 670 if (munmap(r->p, rsz))
678 else 671 wrterror(d, "munmap %p", r->p);
679 tounmap = 0; 672 r->p = NULL;
680 d->free_regions_size -= r->size; 673 if (tounmap > r->size)
681 r->size = 0; 674 tounmap -= r->size;
682 STATS_SUB(d->malloc_used, rsz); 675 else
676 tounmap = 0;
677 d->free_regions_size -= r->size;
678 STATS_SUB(d->malloc_used, rsz);
679 if (tounmap == 0) {
680 offset = i;
681 break;
682 }
683 }
684 i++;
683 } 685 }
684 } 686 }
685 if (tounmap > 0) 687 for (i = 0; ; i++) {
686 wrterror(d, "malloc cache underflow"); 688 r = &d->free_regions[(i + offset) & mask];
687 for (i = 0; i < mopts.malloc_cache; i++) {
688 r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)];
689 if (r->p == NULL) { 689 if (r->p == NULL) {
690 if (clear) 690 if (clear)
691 memset(p, 0, sz - mopts.malloc_guard); 691 memset(p, 0, sz - mopts.malloc_guard);
@@ -702,8 +702,6 @@ unmap(struct dir_info *d, void *p, size_t sz, int clear)
702 break; 702 break;
703 } 703 }
704 } 704 }
705 if (i == mopts.malloc_cache)
706 wrterror(d, "malloc free slot lost");
707 if (d->free_regions_size > mopts.malloc_cache) 705 if (d->free_regions_size > mopts.malloc_cache)
708 wrterror(d, "malloc cache overflow"); 706 wrterror(d, "malloc cache overflow");
709} 707}
@@ -723,7 +721,6 @@ zapcacheregion(struct dir_info *d, void *p, size_t len)
723 wrterror(d, "munmap %p", r->p); 721 wrterror(d, "munmap %p", r->p);
724 r->p = NULL; 722 r->p = NULL;
725 d->free_regions_size -= r->size; 723 d->free_regions_size -= r->size;
726 r->size = 0;
727 STATS_SUB(d->malloc_used, rsz); 724 STATS_SUB(d->malloc_used, rsz);
728 } 725 }
729 } 726 }
@@ -760,7 +757,6 @@ map(struct dir_info *d, void *hint, size_t sz, int zero_fill)
760 if (r->size == psz) { 757 if (r->size == psz) {
761 p = r->p; 758 p = r->p;
762 r->p = NULL; 759 r->p = NULL;
763 r->size = 0;
764 d->free_regions_size -= psz; 760 d->free_regions_size -= psz;
765 if (mopts.malloc_freeunmap) 761 if (mopts.malloc_freeunmap)
766 mprotect(p, sz, PROT_READ | PROT_WRITE); 762 mprotect(p, sz, PROT_READ | PROT_WRITE);
@@ -808,10 +804,7 @@ init_chunk_info(struct dir_info *d, struct chunk_info *p, int bits)
808 int i; 804 int i;
809 805
810 if (bits == 0) { 806 if (bits == 0) {
811 p->shift = 1; 807 p->shift = MALLOC_MINSHIFT;
812 i = MALLOC_MINSIZE - 1;
813 while (i >>= 1)
814 p->shift++;
815 p->total = p->free = MALLOC_PAGESIZE >> p->shift; 808 p->total = p->free = MALLOC_PAGESIZE >> p->shift;
816 p->size = 0; 809 p->size = 0;
817 p->offset = 0xdead; 810 p->offset = 0xdead;
@@ -824,13 +817,9 @@ init_chunk_info(struct dir_info *d, struct chunk_info *p, int bits)
824 p->canary = (u_short)d->canary1; 817 p->canary = (u_short)d->canary1;
825 818
826 /* set all valid bits in the bitmap */ 819 /* set all valid bits in the bitmap */
827 for (i = 0; p->total - i >= MALLOC_BITS; i += MALLOC_BITS) 820 i = p->total - 1;
828 p->bits[i / MALLOC_BITS] = (u_short)~0U; 821 memset(p->bits, 0xff, sizeof(p->bits[0]) * (i / MALLOC_BITS));
829 822 p->bits[i / MALLOC_BITS] = (2U << (i % MALLOC_BITS)) - 1;
830 if (i < p->total)
831 p->bits[i / MALLOC_BITS] = 0;
832 for (; i < p->total; i++)
833 p->bits[i / MALLOC_BITS] |= (u_short)1U << (i % MALLOC_BITS);
834} 823}
835 824
836static struct chunk_info * 825static struct chunk_info *
@@ -907,23 +896,20 @@ err:
907static int 896static int
908find_chunksize(size_t size) 897find_chunksize(size_t size)
909{ 898{
910 int i, j; 899 int r;
911 900
912 /* Don't bother with anything less than this */ 901 /* malloc(0) is special */
913 /* unless we have a malloc(0) requests */ 902 if (size == 0)
914 if (size != 0 && size < MALLOC_MINSIZE) 903 return 0;
904
905 if (size < MALLOC_MINSIZE)
915 size = MALLOC_MINSIZE; 906 size = MALLOC_MINSIZE;
907 size--;
916 908
917 /* Find the right bucket */ 909 r = MALLOC_MINSHIFT;
918 if (size == 0) 910 while (size >> r)
919 j = 0; 911 r++;
920 else { 912 return r;
921 j = MALLOC_MINSHIFT;
922 i = (size - 1) >> (MALLOC_MINSHIFT - 1);
923 while (i >>= 1)
924 j++;
925 }
926 return j;
927} 913}
928 914
929static void 915static void
@@ -1013,7 +999,7 @@ found:
1013 *lp ^= u; 999 *lp ^= u;
1014 1000
1015 /* If there are no more free, remove from free-list */ 1001 /* If there are no more free, remove from free-list */
1016 if (!--bp->free) 1002 if (--bp->free == 0)
1017 LIST_REMOVE(bp, entries); 1003 LIST_REMOVE(bp, entries);
1018 1004
1019 /* Adjust to the real offset of that chunk */ 1005 /* Adjust to the real offset of that chunk */
@@ -1048,8 +1034,8 @@ validate_canary(struct dir_info *d, u_char *ptr, size_t sz, size_t allocated)
1048 while (p < q) { 1034 while (p < q) {
1049 if (*p != SOME_JUNK) { 1035 if (*p != SOME_JUNK) {
1050 wrterror(d, "chunk canary corrupted %p %#tx@%#zx%s", 1036 wrterror(d, "chunk canary corrupted %p %#tx@%#zx%s",
1051 ptr, p - ptr, sz, *p == SOME_FREEJUNK ? 1037 ptr, p - ptr, sz,
1052 " (double free?)" : ""); 1038 *p == SOME_FREEJUNK ? " (double free?)" : "");
1053 } 1039 }
1054 p++; 1040 p++;
1055 } 1041 }
@@ -1173,8 +1159,7 @@ omalloc(struct dir_info *pool, size_t sz, int zero_fill, void *f)
1173 else 1159 else
1174 memset(p, SOME_JUNK, 1160 memset(p, SOME_JUNK,
1175 psz - mopts.malloc_guard); 1161 psz - mopts.malloc_guard);
1176 } 1162 } else if (mopts.chunk_canaries)
1177 else if (mopts.chunk_canaries)
1178 fill_canary(p, sz - mopts.malloc_guard, 1163 fill_canary(p, sz - mopts.malloc_guard,
1179 psz - mopts.malloc_guard); 1164 psz - mopts.malloc_guard);
1180 } 1165 }
@@ -1225,7 +1210,7 @@ _malloc_init(int from_rthreads)
1225 max = from_rthreads ? _MALLOC_MUTEXES : 1; 1210 max = from_rthreads ? _MALLOC_MUTEXES : 1;
1226 if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0) 1211 if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0)
1227 mprotect(&malloc_readonly, sizeof(malloc_readonly), 1212 mprotect(&malloc_readonly, sizeof(malloc_readonly),
1228 PROT_READ | PROT_WRITE); 1213 PROT_READ | PROT_WRITE);
1229 for (i = 0; i < max; i++) { 1214 for (i = 0; i < max; i++) {
1230 if (mopts.malloc_pool[i]) 1215 if (mopts.malloc_pool[i])
1231 continue; 1216 continue;
@@ -2030,8 +2015,7 @@ omemalign(struct dir_info *pool, size_t alignment, size_t sz, int zero_fill,
2030 SOME_JUNK, psz - sz); 2015 SOME_JUNK, psz - sz);
2031 else 2016 else
2032 memset(p, SOME_JUNK, psz - mopts.malloc_guard); 2017 memset(p, SOME_JUNK, psz - mopts.malloc_guard);
2033 } 2018 } else if (mopts.chunk_canaries)
2034 else if (mopts.chunk_canaries)
2035 fill_canary(p, sz - mopts.malloc_guard, 2019 fill_canary(p, sz - mopts.malloc_guard,
2036 psz - mopts.malloc_guard); 2020 psz - mopts.malloc_guard);
2037 2021