summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorotto <>2023-10-26 17:59:16 +0000
committerotto <>2023-10-26 17:59:16 +0000
commit6921d9724fbbaf9674356178ca47d499fca8b2aa (patch)
tree6261f26e62b4cd93a77b200e9584f1f66dda556b
parent96440ea19a1b89c446ea1f11f423c7af87d21ef3 (diff)
downloadopenbsd-6921d9724fbbaf9674356178ca47d499fca8b2aa.tar.gz
openbsd-6921d9724fbbaf9674356178ca47d499fca8b2aa.tar.bz2
openbsd-6921d9724fbbaf9674356178ca47d499fca8b2aa.zip
A few micro-optimizations; ok asou@
-rw-r--r--src/lib/libc/stdlib/malloc.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index c3b2332251..81ad79dfd3 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.291 2023/10/22 12:19:26 otto Exp $ */ 1/* $OpenBSD: malloc.c,v 1.292 2023/10/26 17:59:16 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008, 2010, 2011, 2016, 2023 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008, 2010, 2011, 2016, 2023 Otto Moerbeek <otto@drijf.net>
4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> 4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -169,16 +169,12 @@ struct dir_info {
169 void *caller; 169 void *caller;
170 size_t inserts; 170 size_t inserts;
171 size_t insert_collisions; 171 size_t insert_collisions;
172 size_t finds;
173 size_t find_collisions;
174 size_t deletes; 172 size_t deletes;
175 size_t delete_moves; 173 size_t delete_moves;
176 size_t cheap_realloc_tries; 174 size_t cheap_realloc_tries;
177 size_t cheap_reallocs; 175 size_t cheap_reallocs;
178 size_t malloc_used; /* bytes allocated */ 176 size_t malloc_used; /* bytes allocated */
179 size_t malloc_guarded; /* bytes used for guards */ 177 size_t malloc_guarded; /* bytes used for guards */
180 size_t pool_searches; /* searches for pool */
181 size_t other_pool; /* searches in other pool */
182#define STATS_ADD(x,y) ((x) += (y)) 178#define STATS_ADD(x,y) ((x) += (y))
183#define STATS_SUB(x,y) ((x) -= (y)) 179#define STATS_SUB(x,y) ((x) -= (y))
184#define STATS_INC(x) ((x)++) 180#define STATS_INC(x) ((x)++)
@@ -209,12 +205,14 @@ static void unmap(struct dir_info *d, void *p, size_t sz, size_t clear);
209struct chunk_info { 205struct chunk_info {
210 LIST_ENTRY(chunk_info) entries; 206 LIST_ENTRY(chunk_info) entries;
211 void *page; /* pointer to the page */ 207 void *page; /* pointer to the page */
208 /* number of shorts should add up to 8, check alloc_chunk_info() */
212 u_short canary; 209 u_short canary;
213 u_short bucket; 210 u_short bucket;
214 u_short free; /* how many free chunks */ 211 u_short free; /* how many free chunks */
215 u_short total; /* how many chunks */ 212 u_short total; /* how many chunks */
216 u_short offset; /* requested size table offset */ 213 u_short offset; /* requested size table offset */
217 u_short bits[1]; /* which chunks are free */ 214#define CHUNK_INFO_TAIL 3
215 u_short bits[CHUNK_INFO_TAIL]; /* which chunks are free */
218}; 216};
219 217
220#define CHUNK_FREE(i, n) ((i)->bits[(n) / MALLOC_BITS] & (1U << ((n) % MALLOC_BITS))) 218#define CHUNK_FREE(i, n) ((i)->bits[(n) / MALLOC_BITS] & (1U << ((n) % MALLOC_BITS)))
@@ -656,12 +654,10 @@ find(struct dir_info *d, void *p)
656 index = hash(p) & mask; 654 index = hash(p) & mask;
657 r = d->r[index].p; 655 r = d->r[index].p;
658 q = MASK_POINTER(r); 656 q = MASK_POINTER(r);
659 STATS_INC(d->finds);
660 while (q != p && r != NULL) { 657 while (q != p && r != NULL) {
661 index = (index - 1) & mask; 658 index = (index - 1) & mask;
662 r = d->r[index].p; 659 r = d->r[index].p;
663 q = MASK_POINTER(r); 660 q = MASK_POINTER(r);
664 STATS_INC(d->find_collisions);
665 } 661 }
666 return (q == p && r != NULL) ? &d->r[index] : NULL; 662 return (q == p && r != NULL) ? &d->r[index] : NULL;
667} 663}
@@ -949,7 +945,7 @@ init_chunk_info(struct dir_info *d, struct chunk_info *p, u_int bucket)
949 945
950 p->bucket = bucket; 946 p->bucket = bucket;
951 p->total = p->free = MALLOC_PAGESIZE / B2ALLOC(bucket); 947 p->total = p->free = MALLOC_PAGESIZE / B2ALLOC(bucket);
952 p->offset = bucket == 0 ? 0xdead : howmany(p->total, MALLOC_BITS); 948 p->offset = howmany(p->total, MALLOC_BITS);
953 p->canary = (u_short)d->canary1; 949 p->canary = (u_short)d->canary1;
954 950
955 /* set all valid bits in the bitmap */ 951 /* set all valid bits in the bitmap */
@@ -971,8 +967,13 @@ alloc_chunk_info(struct dir_info *d, u_int bucket)
971 count = MALLOC_PAGESIZE / B2ALLOC(bucket); 967 count = MALLOC_PAGESIZE / B2ALLOC(bucket);
972 968
973 size = howmany(count, MALLOC_BITS); 969 size = howmany(count, MALLOC_BITS);
974 size = sizeof(struct chunk_info) + (size - 1) * sizeof(u_short); 970 /* see declaration of struct chunk_info */
975 if (mopts.chunk_canaries) 971 if (size <= CHUNK_INFO_TAIL)
972 size = 0;
973 else
974 size -= CHUNK_INFO_TAIL;
975 size = sizeof(struct chunk_info) + size * sizeof(u_short);
976 if (mopts.chunk_canaries && bucket > 0)
976 size += count * sizeof(u_short); 977 size += count * sizeof(u_short);
977 size = _ALIGN(size); 978 size = _ALIGN(size);
978 count = MALLOC_PAGESIZE / size; 979 count = MALLOC_PAGESIZE / size;
@@ -1129,8 +1130,7 @@ fill_canary(char *ptr, size_t sz, size_t allocated)
1129static void * 1130static void *
1130malloc_bytes(struct dir_info *d, size_t size) 1131malloc_bytes(struct dir_info *d, size_t size)
1131{ 1132{
1132 u_int i, r, bucket, listnum; 1133 u_int i, k, r, bucket, listnum;
1133 size_t k;
1134 u_short *lp; 1134 u_short *lp;
1135 struct chunk_info *bp; 1135 struct chunk_info *bp;
1136 void *p; 1136 void *p;
@@ -1170,7 +1170,7 @@ malloc_bytes(struct dir_info *d, size_t size)
1170 /* no bit halfway, go to next full short */ 1170 /* no bit halfway, go to next full short */
1171 i /= MALLOC_BITS; 1171 i /= MALLOC_BITS;
1172 for (;;) { 1172 for (;;) {
1173 if (++i >= howmany(bp->total, MALLOC_BITS)) 1173 if (++i >= bp->offset)
1174 i = 0; 1174 i = 0;
1175 lp = &bp->bits[i]; 1175 lp = &bp->bits[i];
1176 if (*lp) { 1176 if (*lp) {
@@ -1228,7 +1228,7 @@ validate_canary(struct dir_info *d, u_char *ptr, size_t sz, size_t allocated)
1228 } 1228 }
1229} 1229}
1230 1230
1231static uint32_t 1231static inline uint32_t
1232find_chunknum(struct dir_info *d, struct chunk_info *info, void *ptr, int check) 1232find_chunknum(struct dir_info *d, struct chunk_info *info, void *ptr, int check)
1233{ 1233{
1234 uint32_t chunknum; 1234 uint32_t chunknum;
@@ -1532,12 +1532,10 @@ findpool(void *p, struct dir_info *argpool, struct dir_info **foundpool,
1532 struct dir_info *pool = argpool; 1532 struct dir_info *pool = argpool;
1533 struct region_info *r = find(pool, p); 1533 struct region_info *r = find(pool, p);
1534 1534
1535 STATS_INC(pool->pool_searches);
1536 if (r == NULL) { 1535 if (r == NULL) {
1537 u_int i, nmutexes; 1536 u_int i, nmutexes;
1538 1537
1539 nmutexes = mopts.malloc_pool[1]->malloc_mt ? mopts.malloc_mutexes : 2; 1538 nmutexes = mopts.malloc_pool[1]->malloc_mt ? mopts.malloc_mutexes : 2;
1540 STATS_INC(pool->other_pool);
1541 for (i = 1; i < nmutexes; i++) { 1539 for (i = 1; i < nmutexes; i++) {
1542 u_int j = (argpool->mutex + i) & (nmutexes - 1); 1540 u_int j = (argpool->mutex + i) & (nmutexes - 1);
1543 1541
@@ -2581,13 +2579,10 @@ malloc_dump1(int poolno, struct dir_info *d, struct leaktree *leaks)
2581 d->mmap_flag); 2579 d->mmap_flag);
2582 ulog("Region slots free %zu/%zu\n", 2580 ulog("Region slots free %zu/%zu\n",
2583 d->regions_free, d->regions_total); 2581 d->regions_free, d->regions_total);
2584 ulog("Finds %zu/%zu\n", d->finds, d->find_collisions);
2585 ulog("Inserts %zu/%zu\n", d->inserts, d->insert_collisions); 2582 ulog("Inserts %zu/%zu\n", d->inserts, d->insert_collisions);
2586 ulog("Deletes %zu/%zu\n", d->deletes, d->delete_moves); 2583 ulog("Deletes %zu/%zu\n", d->deletes, d->delete_moves);
2587 ulog("Cheap reallocs %zu/%zu\n", 2584 ulog("Cheap reallocs %zu/%zu\n",
2588 d->cheap_reallocs, d->cheap_realloc_tries); 2585 d->cheap_reallocs, d->cheap_realloc_tries);
2589 ulog("Other pool searches %zu/%zu\n",
2590 d->other_pool, d->pool_searches);
2591 ulog("In use %zu\n", d->malloc_used); 2586 ulog("In use %zu\n", d->malloc_used);
2592 ulog("Guarded %zu\n", d->malloc_guarded); 2587 ulog("Guarded %zu\n", d->malloc_guarded);
2593 dump_free_chunk_info(d, leaks); 2588 dump_free_chunk_info(d, leaks);