2021-06-29 17:57:27 -03:00
|
|
|
/*
|
2024-10-04 08:19:50 -03:00
|
|
|
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
2021-06-29 17:57:27 -03:00
|
|
|
* Copyright (c) 2021, Daniel Bertalan <dani@danielbertalan.dev>
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
*/
|
|
|
|
|
|
2022-10-09 18:23:23 -03:00
|
|
|
#include <AK/kmalloc.h>
|
|
|
|
|
|
2026-06-10 06:52:50 -03:00
|
|
|
#include <cstddef>
|
|
|
|
|
#include <cstring>
|
2021-06-29 17:57:27 -03:00
|
|
|
|
2026-06-10 06:52:50 -03:00
|
|
|
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
AK: Adopt mimalloc v2 as main allocator
Use mimalloc for Ladybird-owned allocations without overriding malloc().
Route kmalloc(), kcalloc(), krealloc(), and kfree() through mimalloc,
and put the embedded Rust crates on the same allocator via a shared
shim in AK/kmalloc.cpp.
This also lets us drop kfree_sized(), since it no longer used its size
argument. StringData, Utf16StringData, JS object storage, Rust error
strings, and the CoreAudio playback helpers can all free their AK-backed
storage with plain kfree().
Sanitizer builds still use the system allocator. LeakSanitizer does not
reliably trace references stored in mimalloc-managed AK containers, so
static caches and other long-lived roots can look leaked. Pass the old
size into the Rust realloc shim so aligned fallback reallocations can
move posix_memalign-backed blocks safely.
Static builds still need a little linker help. macOS app binaries need
the Rust allocator entry points forced in from liblagom-ak.a, while
static ELF links can pull in identical allocator shim definitions from
multiple Rust staticlibs. Keep the Apple -u flags and allow those
duplicate shim symbols for LibJS and LibRegex links on Linux and BSD.
2026-04-03 12:06:58 -03:00
|
|
|
// LeakSanitizer does not reliably trace references stored in mimalloc-managed
|
|
|
|
|
// AK containers, so sanitizer builds fall back to the system allocator.
|
2026-06-10 06:52:50 -03:00
|
|
|
# define AK_USE_SYSTEM_ALLOCATOR_INSTRUMENTED 1
|
|
|
|
|
#else
|
|
|
|
|
# include <mimalloc.h>
|
|
|
|
|
#endif
|
AK: Adopt mimalloc v2 as main allocator
Use mimalloc for Ladybird-owned allocations without overriding malloc().
Route kmalloc(), kcalloc(), krealloc(), and kfree() through mimalloc,
and put the embedded Rust crates on the same allocator via a shared
shim in AK/kmalloc.cpp.
This also lets us drop kfree_sized(), since it no longer used its size
argument. StringData, Utf16StringData, JS object storage, Rust error
strings, and the CoreAudio playback helpers can all free their AK-backed
storage with plain kfree().
Sanitizer builds still use the system allocator. LeakSanitizer does not
reliably trace references stored in mimalloc-managed AK containers, so
static caches and other long-lived roots can look leaked. Pass the old
size into the Rust realloc shim so aligned fallback reallocations can
move posix_memalign-backed blocks safely.
Static builds still need a little linker help. macOS app binaries need
the Rust allocator entry points forced in from liblagom-ak.a, while
static ELF links can pull in identical allocator shim definitions from
multiple Rust staticlibs. Keep the Apple -u flags and allow those
duplicate shim symbols for LibJS and LibRegex links on Linux and BSD.
2026-04-03 12:06:58 -03:00
|
|
|
|
|
|
|
|
static bool allocation_needs_explicit_alignment(size_t alignment)
|
|
|
|
|
{
|
|
|
|
|
return alignment > alignof(std::max_align_t);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-10 06:52:50 -03:00
|
|
|
#ifdef AK_USE_SYSTEM_ALLOCATOR_INSTRUMENTED
|
AK: Adopt mimalloc v2 as main allocator
Use mimalloc for Ladybird-owned allocations without overriding malloc().
Route kmalloc(), kcalloc(), krealloc(), and kfree() through mimalloc,
and put the embedded Rust crates on the same allocator via a shared
shim in AK/kmalloc.cpp.
This also lets us drop kfree_sized(), since it no longer used its size
argument. StringData, Utf16StringData, JS object storage, Rust error
strings, and the CoreAudio playback helpers can all free their AK-backed
storage with plain kfree().
Sanitizer builds still use the system allocator. LeakSanitizer does not
reliably trace references stored in mimalloc-managed AK containers, so
static caches and other long-lived roots can look leaked. Pass the old
size into the Rust realloc shim so aligned fallback reallocations can
move posix_memalign-backed blocks safely.
Static builds still need a little linker help. macOS app binaries need
the Rust allocator entry points forced in from liblagom-ak.a, while
static ELF links can pull in identical allocator shim definitions from
multiple Rust staticlibs. Keep the Apple -u flags and allow those
duplicate shim symbols for LibJS and LibRegex links on Linux and BSD.
2026-04-03 12:06:58 -03:00
|
|
|
|
|
|
|
|
static void* aligned_alloc_with_system_allocator(size_t size, size_t alignment, bool zeroed)
|
|
|
|
|
{
|
|
|
|
|
void* ptr = nullptr;
|
|
|
|
|
auto actual_size = size == 0 ? static_cast<size_t>(1) : size;
|
|
|
|
|
if (auto result = posix_memalign(&ptr, alignment, actual_size); result != 0)
|
|
|
|
|
return nullptr;
|
|
|
|
|
if (zeroed)
|
|
|
|
|
__builtin_memset(ptr, 0, actual_size);
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* ak_kcalloc(size_t count, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return calloc(count, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* ak_kmalloc(size_t size)
|
|
|
|
|
{
|
|
|
|
|
return malloc(size);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-10 06:52:50 -03:00
|
|
|
void* ak_kmalloc(HeapPartition, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return ak_kmalloc(size);
|
|
|
|
|
}
|
|
|
|
|
|
AK: Adopt mimalloc v2 as main allocator
Use mimalloc for Ladybird-owned allocations without overriding malloc().
Route kmalloc(), kcalloc(), krealloc(), and kfree() through mimalloc,
and put the embedded Rust crates on the same allocator via a shared
shim in AK/kmalloc.cpp.
This also lets us drop kfree_sized(), since it no longer used its size
argument. StringData, Utf16StringData, JS object storage, Rust error
strings, and the CoreAudio playback helpers can all free their AK-backed
storage with plain kfree().
Sanitizer builds still use the system allocator. LeakSanitizer does not
reliably trace references stored in mimalloc-managed AK containers, so
static caches and other long-lived roots can look leaked. Pass the old
size into the Rust realloc shim so aligned fallback reallocations can
move posix_memalign-backed blocks safely.
Static builds still need a little linker help. macOS app binaries need
the Rust allocator entry points forced in from liblagom-ak.a, while
static ELF links can pull in identical allocator shim definitions from
multiple Rust staticlibs. Keep the Apple -u flags and allow those
duplicate shim symbols for LibJS and LibRegex links on Linux and BSD.
2026-04-03 12:06:58 -03:00
|
|
|
void* ak_krealloc(void* ptr, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return realloc(ptr, size);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-10 06:52:50 -03:00
|
|
|
void* ak_krealloc(HeapPartition, void* ptr, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return ak_krealloc(ptr, size);
|
|
|
|
|
}
|
|
|
|
|
|
AK: Adopt mimalloc v2 as main allocator
Use mimalloc for Ladybird-owned allocations without overriding malloc().
Route kmalloc(), kcalloc(), krealloc(), and kfree() through mimalloc,
and put the embedded Rust crates on the same allocator via a shared
shim in AK/kmalloc.cpp.
This also lets us drop kfree_sized(), since it no longer used its size
argument. StringData, Utf16StringData, JS object storage, Rust error
strings, and the CoreAudio playback helpers can all free their AK-backed
storage with plain kfree().
Sanitizer builds still use the system allocator. LeakSanitizer does not
reliably trace references stored in mimalloc-managed AK containers, so
static caches and other long-lived roots can look leaked. Pass the old
size into the Rust realloc shim so aligned fallback reallocations can
move posix_memalign-backed blocks safely.
Static builds still need a little linker help. macOS app binaries need
the Rust allocator entry points forced in from liblagom-ak.a, while
static ELF links can pull in identical allocator shim definitions from
multiple Rust staticlibs. Keep the Apple -u flags and allow those
duplicate shim symbols for LibJS and LibRegex links on Linux and BSD.
2026-04-03 12:06:58 -03:00
|
|
|
size_t ak_kmalloc_good_size(size_t size)
|
|
|
|
|
{
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ak_kfree(void* ptr)
|
|
|
|
|
{
|
|
|
|
|
free(ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
void* ladybird_rust_alloc(size_t size, size_t alignment);
|
|
|
|
|
void* ladybird_rust_alloc_zeroed(size_t size, size_t alignment);
|
|
|
|
|
void ladybird_rust_dealloc(void* ptr, size_t alignment);
|
|
|
|
|
void* ladybird_rust_realloc(void* ptr, size_t old_size, size_t new_size, size_t alignment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void* ladybird_rust_alloc(size_t size, size_t alignment)
|
|
|
|
|
{
|
|
|
|
|
if (allocation_needs_explicit_alignment(alignment))
|
|
|
|
|
return aligned_alloc_with_system_allocator(size, alignment, false);
|
|
|
|
|
return malloc(size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void* ladybird_rust_alloc_zeroed(size_t size, size_t alignment)
|
|
|
|
|
{
|
|
|
|
|
if (allocation_needs_explicit_alignment(alignment))
|
|
|
|
|
return aligned_alloc_with_system_allocator(size, alignment, true);
|
|
|
|
|
return calloc(1, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void ladybird_rust_dealloc(void* ptr, size_t)
|
|
|
|
|
{
|
|
|
|
|
free(ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void* ladybird_rust_realloc(void* ptr, size_t old_size, size_t new_size, size_t alignment)
|
|
|
|
|
{
|
|
|
|
|
if (!allocation_needs_explicit_alignment(alignment))
|
|
|
|
|
return realloc(ptr, new_size);
|
|
|
|
|
|
|
|
|
|
auto* new_ptr = aligned_alloc_with_system_allocator(new_size, alignment, false);
|
|
|
|
|
if (!new_ptr)
|
|
|
|
|
return nullptr;
|
|
|
|
|
if (ptr)
|
|
|
|
|
__builtin_memcpy(new_ptr, ptr, old_size < new_size ? old_size : new_size);
|
|
|
|
|
free(ptr);
|
|
|
|
|
return new_ptr;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-10 06:52:50 -03:00
|
|
|
#else
|
AK: Adopt mimalloc v2 as main allocator
Use mimalloc for Ladybird-owned allocations without overriding malloc().
Route kmalloc(), kcalloc(), krealloc(), and kfree() through mimalloc,
and put the embedded Rust crates on the same allocator via a shared
shim in AK/kmalloc.cpp.
This also lets us drop kfree_sized(), since it no longer used its size
argument. StringData, Utf16StringData, JS object storage, Rust error
strings, and the CoreAudio playback helpers can all free their AK-backed
storage with plain kfree().
Sanitizer builds still use the system allocator. LeakSanitizer does not
reliably trace references stored in mimalloc-managed AK containers, so
static caches and other long-lived roots can look leaked. Pass the old
size into the Rust realloc shim so aligned fallback reallocations can
move posix_memalign-backed blocks safely.
Static builds still need a little linker help. macOS app binaries need
the Rust allocator entry points forced in from liblagom-ak.a, while
static ELF links can pull in identical allocator shim definitions from
multiple Rust staticlibs. Keep the Apple -u flags and allow those
duplicate shim symbols for LibJS and LibRegex links on Linux and BSD.
2026-04-03 12:06:58 -03:00
|
|
|
|
|
|
|
|
void* ak_kcalloc(size_t count, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return mi_calloc(count, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* ak_kmalloc(size_t size)
|
|
|
|
|
{
|
|
|
|
|
return mi_malloc(size);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-10 06:52:50 -03:00
|
|
|
static mi_heap_t* heap_for_partition(HeapPartition partition)
|
|
|
|
|
{
|
|
|
|
|
switch (partition) {
|
|
|
|
|
case HeapPartition::General:
|
|
|
|
|
return mi_heap_get_default();
|
2026-06-10 07:39:59 -03:00
|
|
|
case HeapPartition::ArrayBuffer:
|
|
|
|
|
static mi_heap_t* array_buffer_heap = mi_heap_new();
|
|
|
|
|
return array_buffer_heap;
|
2026-06-10 09:27:28 -03:00
|
|
|
case HeapPartition::JSObjectStorage:
|
|
|
|
|
static mi_heap_t* js_object_storage_heap = mi_heap_new();
|
|
|
|
|
return js_object_storage_heap;
|
2026-06-13 10:57:57 -03:00
|
|
|
case HeapPartition::Layout:
|
|
|
|
|
static mi_heap_t* layout_heap = mi_heap_new();
|
|
|
|
|
return layout_heap;
|
|
|
|
|
case HeapPartition::Painting:
|
|
|
|
|
static mi_heap_t* painting_heap = mi_heap_new();
|
|
|
|
|
return painting_heap;
|
2026-06-10 14:14:13 -03:00
|
|
|
case HeapPartition::String:
|
|
|
|
|
static thread_local mi_heap_t* string_heap = mi_heap_new();
|
|
|
|
|
return string_heap;
|
2026-06-10 06:52:50 -03:00
|
|
|
}
|
|
|
|
|
VERIFY_NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* ak_kmalloc(HeapPartition partition, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return mi_heap_malloc(heap_for_partition(partition), size);
|
|
|
|
|
}
|
|
|
|
|
|
AK: Adopt mimalloc v2 as main allocator
Use mimalloc for Ladybird-owned allocations without overriding malloc().
Route kmalloc(), kcalloc(), krealloc(), and kfree() through mimalloc,
and put the embedded Rust crates on the same allocator via a shared
shim in AK/kmalloc.cpp.
This also lets us drop kfree_sized(), since it no longer used its size
argument. StringData, Utf16StringData, JS object storage, Rust error
strings, and the CoreAudio playback helpers can all free their AK-backed
storage with plain kfree().
Sanitizer builds still use the system allocator. LeakSanitizer does not
reliably trace references stored in mimalloc-managed AK containers, so
static caches and other long-lived roots can look leaked. Pass the old
size into the Rust realloc shim so aligned fallback reallocations can
move posix_memalign-backed blocks safely.
Static builds still need a little linker help. macOS app binaries need
the Rust allocator entry points forced in from liblagom-ak.a, while
static ELF links can pull in identical allocator shim definitions from
multiple Rust staticlibs. Keep the Apple -u flags and allow those
duplicate shim symbols for LibJS and LibRegex links on Linux and BSD.
2026-04-03 12:06:58 -03:00
|
|
|
void* ak_krealloc(void* ptr, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return mi_realloc(ptr, size);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-10 06:52:50 -03:00
|
|
|
void* ak_krealloc(HeapPartition partition, void* ptr, size_t size)
|
|
|
|
|
{
|
|
|
|
|
return mi_heap_realloc(heap_for_partition(partition), ptr, size);
|
|
|
|
|
}
|
|
|
|
|
|
AK: Adopt mimalloc v2 as main allocator
Use mimalloc for Ladybird-owned allocations without overriding malloc().
Route kmalloc(), kcalloc(), krealloc(), and kfree() through mimalloc,
and put the embedded Rust crates on the same allocator via a shared
shim in AK/kmalloc.cpp.
This also lets us drop kfree_sized(), since it no longer used its size
argument. StringData, Utf16StringData, JS object storage, Rust error
strings, and the CoreAudio playback helpers can all free their AK-backed
storage with plain kfree().
Sanitizer builds still use the system allocator. LeakSanitizer does not
reliably trace references stored in mimalloc-managed AK containers, so
static caches and other long-lived roots can look leaked. Pass the old
size into the Rust realloc shim so aligned fallback reallocations can
move posix_memalign-backed blocks safely.
Static builds still need a little linker help. macOS app binaries need
the Rust allocator entry points forced in from liblagom-ak.a, while
static ELF links can pull in identical allocator shim definitions from
multiple Rust staticlibs. Keep the Apple -u flags and allow those
duplicate shim symbols for LibJS and LibRegex links on Linux and BSD.
2026-04-03 12:06:58 -03:00
|
|
|
size_t ak_kmalloc_good_size(size_t size)
|
|
|
|
|
{
|
|
|
|
|
return mi_good_size(size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ak_kfree(void* ptr)
|
|
|
|
|
{
|
|
|
|
|
mi_free(ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
void* ladybird_rust_alloc(size_t size, size_t alignment);
|
|
|
|
|
void* ladybird_rust_alloc_zeroed(size_t size, size_t alignment);
|
|
|
|
|
void ladybird_rust_dealloc(void* ptr, size_t alignment);
|
|
|
|
|
void* ladybird_rust_realloc(void* ptr, size_t old_size, size_t new_size, size_t alignment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void* ladybird_rust_alloc(size_t size, size_t alignment)
|
|
|
|
|
{
|
|
|
|
|
if (allocation_needs_explicit_alignment(alignment))
|
|
|
|
|
return mi_malloc_aligned(size, alignment);
|
|
|
|
|
return mi_malloc(size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void* ladybird_rust_alloc_zeroed(size_t size, size_t alignment)
|
|
|
|
|
{
|
|
|
|
|
if (allocation_needs_explicit_alignment(alignment))
|
|
|
|
|
return mi_zalloc_aligned(size, alignment);
|
|
|
|
|
return mi_zalloc(size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void ladybird_rust_dealloc(void* ptr, size_t)
|
|
|
|
|
{
|
|
|
|
|
mi_free(ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" void* ladybird_rust_realloc(void* ptr, size_t, size_t new_size, size_t alignment)
|
|
|
|
|
{
|
|
|
|
|
if (allocation_needs_explicit_alignment(alignment))
|
|
|
|
|
return mi_realloc_aligned(ptr, new_size, alignment);
|
|
|
|
|
return mi_realloc(ptr, new_size);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-29 17:57:27 -03:00
|
|
|
#endif
|