Increase tinymalloc granularity

This commit is contained in:
Justine Tunney 2024-05-29 18:11:18 -07:00
parent a05ce3ad9d
commit 2816df59b2
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
4 changed files with 39 additions and 36 deletions

Binary file not shown.

Binary file not shown.

View file

@ -32,7 +32,7 @@
alignas(TINYMALLOC_MAX_ALIGN) static struct { alignas(TINYMALLOC_MAX_ALIGN) static struct {
char memory[TINYMALLOC_MAX_BYTES]; char memory[TINYMALLOC_MAX_BYTES];
unsigned used, last, free; size_t used, last, free;
} heap; } heap;
static inline bool isheap(char *mem) { static inline bool isheap(char *mem) {
@ -41,12 +41,12 @@ static inline bool isheap(char *mem) {
void free(void *ptr) { void free(void *ptr) {
char *mem; char *mem;
unsigned base; size_t base;
if (ptr) { if (ptr) {
mem = (char *)ptr; mem = (char *)ptr;
unassert(isheap(mem)); unassert(isheap(mem));
base = mem - heap.memory; base = mem - heap.memory;
*(unsigned *)mem = heap.free; *(size_t *)mem = heap.free;
heap.free = base; heap.free = base;
} }
} }
@ -54,33 +54,34 @@ void free(void *ptr) {
size_t malloc_usable_size(void *ptr) { size_t malloc_usable_size(void *ptr) {
char *mem = (char *)ptr; char *mem = (char *)ptr;
unassert(isheap(mem)); unassert(isheap(mem));
return ((unsigned *)mem)[-1]; return ((size_t *)mem)[-1];
} }
void *memalign(size_t align, size_t need) { void *memalign(size_t align, size_t need) {
char *res; char *res;
unsigned next, next2, base, toto, *link, *link2; size_t next, next2, base, toto, *link, *link2;
// normalize arguments // normalize arguments
while (align & (align - 1)) while (align & (align - 1))
++align; ++align;
if (need < sizeof(unsigned)) if (need < sizeof(size_t))
need = sizeof(unsigned); need = sizeof(size_t);
if (align < sizeof(unsigned)) if (align < sizeof(size_t))
align = sizeof(unsigned); align = sizeof(size_t);
if (align > TINYMALLOC_MAX_ALIGN) if (align > TINYMALLOC_MAX_ALIGN)
goto InvalidArgument; goto InvalidArgument;
if (ckd_add(&need, need, sizeof(unsigned) - 1)) // TODO(jart): refactor append*() to not need size_t*2 granularity
if (ckd_add(&need, need, sizeof(size_t) * 2 - 1))
goto OutOfMemory; goto OutOfMemory;
need &= -sizeof(unsigned); need &= -sizeof(size_t);
// allocate from free list // allocate from free list
next = heap.free; next = heap.free;
link = &heap.free; link = &heap.free;
while (next) { while (next) {
next2 = *(unsigned *)(heap.memory + next); next2 = *(size_t *)(heap.memory + next);
link2 = (unsigned *)(heap.memory + next); link2 = (size_t *)(heap.memory + next);
if (need <= ((unsigned *)(heap.memory + next))[-1]) { if (need <= ((size_t *)(heap.memory + next))[-1]) {
*link = next2; *link = next2;
return (void *)(heap.memory + next); return (void *)(heap.memory + next);
} }
@ -90,7 +91,7 @@ void *memalign(size_t align, size_t need) {
// allocate new static memory // allocate new static memory
base = heap.used; base = heap.used;
base += sizeof(unsigned); base += sizeof(size_t);
base += align - 1; base += align - 1;
base &= -align; base &= -align;
if (ckd_add(&toto, base, need)) if (ckd_add(&toto, base, need))
@ -98,7 +99,7 @@ void *memalign(size_t align, size_t need) {
if (toto > TINYMALLOC_MAX_BYTES) if (toto > TINYMALLOC_MAX_BYTES)
goto OutOfMemory; goto OutOfMemory;
res = heap.memory + base; res = heap.memory + base;
((unsigned *)res)[-1] = need; ((size_t *)res)[-1] = need;
heap.used = toto; heap.used = toto;
heap.last = base; heap.last = base;
return res; return res;
@ -118,7 +119,7 @@ void *malloc(size_t need) {
void *calloc(size_t count, size_t size) { void *calloc(size_t count, size_t size) {
char *res; char *res;
unsigned need, used; size_t need, used;
if (ckd_mul(&need, count, size)) if (ckd_mul(&need, count, size))
need = -1; need = -1;
used = heap.used; used = heap.used;
@ -130,27 +131,27 @@ void *calloc(size_t count, size_t size) {
void *realloc(void *ptr, size_t need) { void *realloc(void *ptr, size_t need) {
char *res, *mem; char *res, *mem;
unsigned base, have, toto; size_t base, have, toto;
if (!ptr) { if (!ptr) {
res = (char *)malloc(need); res = (char *)malloc(need);
} else { } else {
mem = (char *)ptr; mem = (char *)ptr;
unassert(isheap(mem)); unassert(isheap(mem));
have = ((unsigned *)mem)[-1]; have = ((size_t *)mem)[-1];
base = mem - heap.memory; base = mem - heap.memory;
if (need < have) { if (need < have) {
res = mem; res = mem;
} else if (base == heap.last) { } else if (base == heap.last) {
if (need < sizeof(unsigned)) if (need < sizeof(size_t))
need = sizeof(unsigned); need = sizeof(size_t);
if (ckd_add(&need, need, sizeof(unsigned) - 1)) if (ckd_add(&need, need, sizeof(size_t) - 1))
goto OutOfMemory; goto OutOfMemory;
need &= -sizeof(unsigned); need &= -sizeof(size_t);
if (ckd_add(&toto, base, need)) if (ckd_add(&toto, base, need))
goto OutOfMemory; goto OutOfMemory;
if (toto > TINYMALLOC_MAX_BYTES) if (toto > TINYMALLOC_MAX_BYTES)
goto OutOfMemory; goto OutOfMemory;
((unsigned *)mem)[-1] = need; ((size_t *)mem)[-1] = need;
heap.used = toto; heap.used = toto;
res = mem; res = mem;
} else if ((res = (char *)malloc(need))) { } else if ((res = (char *)malloc(need))) {

View file

@ -214,17 +214,19 @@ const char *g_tmpout_original;
const char *const kSafeEnv[] = { const char *const kSafeEnv[] = {
"ADDR2LINE", // needed by GetAddr2linePath "ADDR2LINE", // needed by GetAddr2linePath
"BUILDLOG", // used by cosmocc
"HOME", // needed by ~/.runit.psk "HOME", // needed by ~/.runit.psk
"HOMEDRIVE", // needed by ~/.runit.psk "HOMEDRIVE", // needed by ~/.runit.psk
"HOMEPATH", // needed by ~/.runit.psk "HOMEPATH", // needed by ~/.runit.psk
"KPRINTF_LOG", // used by internals
"MAKEFLAGS", // needed by IsRunningUnderMake "MAKEFLAGS", // needed by IsRunningUnderMake
"MODE", // needed by test scripts "MODE", // needed by test scripts
"PATH", // needed by clang "PATH", // needed by clang
"PWD", // just seems plain needed "PWD", // just seems plain needed
"STRACE", // useful for troubleshooting "STRACE", // useful for troubleshooting
"SYSTEMROOT", // needed by socket()
"TERM", // needed to detect colors "TERM", // needed to detect colors
"TMPDIR", // needed by compiler "TMPDIR", // needed by compiler
"SYSTEMROOT", // needed by socket()
}; };
#include "libc/mem/tinymalloc.inc" #include "libc/mem/tinymalloc.inc"