AK+LibC: Implement malloc_good_size() and use it for Vector/HashTable

This implements the macOS API malloc_good_size() which returns the
true allocation size for a given requested allocation size. This
allows us to make use of all the available memory in a malloc chunk.

For example, for a malloc request of 35 bytes our malloc would
internally use a chunk of size 64, however the remaining 29 bytes
would be unused.

Knowing the true allocation size allows us to request more usable
memory that would otherwise be wasted and make that available for
Vector, HashTable and potentially other callers in the future.
This commit is contained in:
Gunnar Beutner 2021-05-15 10:06:41 +02:00 committed by Andreas Kling
parent 4ab9d8736b
commit f89e8fb71a
7 changed files with 24 additions and 1 deletions

View file

@ -258,6 +258,7 @@ private:
void rehash(size_t new_capacity)
{
new_capacity = max(new_capacity, static_cast<size_t>(4));
new_capacity = kmalloc_good_size(new_capacity * sizeof(Bucket)) / sizeof(Bucket);
auto* old_buckets = m_buckets;
auto old_capacity = m_capacity;

View file

@ -563,7 +563,7 @@ public:
{
if (m_capacity >= needed_capacity)
return true;
size_t new_capacity = needed_capacity;
size_t new_capacity = kmalloc_good_size(needed_capacity * sizeof(T)) / sizeof(T);
auto* new_buffer = (T*)kmalloc(new_capacity * sizeof(T));
if (new_buffer == nullptr)
return false;

View file

@ -8,6 +8,12 @@
#ifndef __serenity__
# include <new>
# ifndef AK_OS_MACOS
inline size_t malloc_good_size(size_t size) { return size; }
# else
# include <malloc/malloc.h>
# endif
#endif
#ifdef KERNEL
@ -27,6 +33,7 @@
# define kcalloc calloc
# define kmalloc malloc
# define kmalloc_good_size malloc_good_size
# define kfree free
# define krealloc realloc

View file

@ -277,6 +277,11 @@ void* krealloc(void* ptr, size_t new_size)
return g_kmalloc_global->m_heap.reallocate(ptr, new_size);
}
size_t kmalloc_good_size(size_t size)
{
return size;
}
void* operator new(size_t size) noexcept
{
return kmalloc(size);

View file

@ -66,4 +66,6 @@ inline void kfree_aligned(void* ptr)
kfree((u8*)ptr - ((const ptrdiff_t*)ptr)[-1]);
}
size_t kmalloc_good_size(size_t);
void kmalloc_enable_expand();

View file

@ -392,6 +392,13 @@ size_t malloc_size(void* ptr)
return size;
}
size_t malloc_good_size(size_t size)
{
size_t good_size;
allocator_for_size(size, good_size);
return good_size;
}
void* realloc(void* ptr, size_t size)
{
if (!ptr)

View file

@ -21,6 +21,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*);
size_t malloc_good_size(size_t);
void serenity_dump_malloc_stats(void);
void free(void*);
__attribute__((alloc_size(2))) void* realloc(void* ptr, size_t);