From b160677e9e766b50a89210b6b645a8ba1cd1b7bd Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 30 May 2019 02:37:40 +0200 Subject: [PATCH] LibC: Add malloc_size() to tell you how big an allocation might be. It can't be 100% precise but it doesn't really matter. Use this to implement realloc() nicely. This also fixes a bug in realloc() where we didn't take the size of the allocation metadata into account when computing the size of an allocation backed by a BigAllocationBlock. --- LibC/malloc.cpp | 27 ++++++++++++++++----------- LibC/stdlib.h | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/LibC/malloc.cpp b/LibC/malloc.cpp index 6f456140b9..21021ba03d 100644 --- a/LibC/malloc.cpp +++ b/LibC/malloc.cpp @@ -155,9 +155,7 @@ void* malloc(size_t size) } } #endif - char buffer[64]; - snprintf(buffer, sizeof(buffer), "malloc: BigAllocationBlock(%u)", real_size); - auto* block = (BigAllocationBlock*)os_alloc(real_size, buffer); + auto* block = (BigAllocationBlock*)os_alloc(real_size, "malloc: BigAllocationBlock"); new (block) BigAllocationBlock(real_size); return &block->m_slot[0]; } @@ -277,20 +275,27 @@ void* calloc(size_t count, size_t size) return ptr; } +size_t malloc_size(void* ptr) +{ + if (!ptr) + return 0; + void* page_base = (void*)((uintptr_t)ptr & (uintptr_t)~0xfff); + auto* header = (const CommonHeader*)page_base; + auto size = header->m_size; + if (header->m_magic == MAGIC_BIGALLOC_HEADER) + size -= sizeof(CommonHeader); + return size; +} + void* realloc(void* ptr, size_t size) { if (!ptr) return malloc(size); - - size_t old_size = 0; - void* page_base = (void*)((uintptr_t)ptr & (uintptr_t)~0xfff); - auto* header = (const CommonHeader*)page_base; - old_size = header->m_size; - - if (malloc_good_size(size) == old_size) + auto existing_allocation_size = malloc_size(ptr); + if (size <= existing_allocation_size) return ptr; auto* new_ptr = malloc(size); - memcpy(new_ptr, ptr, min(old_size, size)); + memcpy(new_ptr, ptr, min(existing_allocation_size, size)); free(ptr); return new_ptr; } diff --git a/LibC/stdlib.h b/LibC/stdlib.h index 22493e5e98..946a1d8274 100644 --- a/LibC/stdlib.h +++ b/LibC/stdlib.h @@ -12,6 +12,7 @@ __BEGIN_DECLS __attribute__((malloc)) __attribute__((alloc_size(1))) void* malloc(size_t); __attribute__((malloc)) __attribute__((alloc_size(1, 2))) void* calloc(size_t nmemb, size_t); +size_t malloc_size(void*); void free(void*); void* realloc(void* ptr, size_t); char* getenv(const char* name);