mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:57:35 +00:00
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.
This commit is contained in:
parent
a906098579
commit
b160677e9e
2 changed files with 17 additions and 11 deletions
|
@ -155,9 +155,7 @@ void* malloc(size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
char buffer[64];
|
auto* block = (BigAllocationBlock*)os_alloc(real_size, "malloc: BigAllocationBlock");
|
||||||
snprintf(buffer, sizeof(buffer), "malloc: BigAllocationBlock(%u)", real_size);
|
|
||||||
auto* block = (BigAllocationBlock*)os_alloc(real_size, buffer);
|
|
||||||
new (block) BigAllocationBlock(real_size);
|
new (block) BigAllocationBlock(real_size);
|
||||||
return &block->m_slot[0];
|
return &block->m_slot[0];
|
||||||
}
|
}
|
||||||
|
@ -277,20 +275,27 @@ void* calloc(size_t count, size_t size)
|
||||||
return ptr;
|
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)
|
void* realloc(void* ptr, size_t size)
|
||||||
{
|
{
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
|
auto existing_allocation_size = malloc_size(ptr);
|
||||||
size_t old_size = 0;
|
if (size <= existing_allocation_size)
|
||||||
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)
|
|
||||||
return ptr;
|
return ptr;
|
||||||
auto* new_ptr = malloc(size);
|
auto* new_ptr = malloc(size);
|
||||||
memcpy(new_ptr, ptr, min(old_size, size));
|
memcpy(new_ptr, ptr, min(existing_allocation_size, size));
|
||||||
free(ptr);
|
free(ptr);
|
||||||
return new_ptr;
|
return new_ptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ __BEGIN_DECLS
|
||||||
|
|
||||||
__attribute__((malloc)) __attribute__((alloc_size(1))) void* malloc(size_t);
|
__attribute__((malloc)) __attribute__((alloc_size(1))) void* malloc(size_t);
|
||||||
__attribute__((malloc)) __attribute__((alloc_size(1, 2))) void* calloc(size_t nmemb, 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 free(void*);
|
||||||
void* realloc(void* ptr, size_t);
|
void* realloc(void* ptr, size_t);
|
||||||
char* getenv(const char* name);
|
char* getenv(const char* name);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue