diff options
| author | otto <> | 2023-10-26 17:59:16 +0000 |
|---|---|---|
| committer | otto <> | 2023-10-26 17:59:16 +0000 |
| commit | 1d0513e3429bb2c7d03ecaa05238a76da6ebc5dd (patch) | |
| tree | 6261f26e62b4cd93a77b200e9584f1f66dda556b /src/lib/libc | |
| parent | 67cb76e74e33486ee4b670235412c0727b4b4023 (diff) | |
| download | openbsd-1d0513e3429bb2c7d03ecaa05238a76da6ebc5dd.tar.gz openbsd-1d0513e3429bb2c7d03ecaa05238a76da6ebc5dd.tar.bz2 openbsd-1d0513e3429bb2c7d03ecaa05238a76da6ebc5dd.zip | |
A few micro-optimizations; ok asou@
Diffstat (limited to 'src/lib/libc')
| -rw-r--r-- | src/lib/libc/stdlib/malloc.c | 35 |
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); | |||
| 209 | struct chunk_info { | 205 | struct 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) | |||
| 1129 | static void * | 1130 | static void * |
| 1130 | malloc_bytes(struct dir_info *d, size_t size) | 1131 | malloc_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 | ||
| 1231 | static uint32_t | 1231 | static inline uint32_t |
| 1232 | find_chunknum(struct dir_info *d, struct chunk_info *info, void *ptr, int check) | 1232 | find_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); |
