diff --git a/AK/kmalloc.h b/AK/kmalloc.h index ad12854cbc..5807828980 100644 --- a/AK/kmalloc.h +++ b/AK/kmalloc.h @@ -41,34 +41,49 @@ inline size_t malloc_good_size(size_t size) { return size; } # ifdef __serenity__ +# include # include inline void* operator new(size_t size) +{ + void* ptr = kmalloc(size); + VERIFY(ptr); + return ptr; +} + +inline void* operator new(size_t size, const std::nothrow_t&) noexcept { return kmalloc(size); } -inline void operator delete(void* ptr) +inline void operator delete(void* ptr) noexcept { return kfree(ptr); } -inline void operator delete(void* ptr, size_t) +inline void operator delete(void* ptr, size_t) noexcept { return kfree(ptr); } inline void* operator new[](size_t size) +{ + void* ptr = kmalloc(size); + VERIFY(ptr); + return ptr; +} + +inline void* operator new[](size_t size, const std::nothrow_t&) noexcept { return kmalloc(size); } -inline void operator delete[](void* ptr) +inline void operator delete[](void* ptr) noexcept { return kfree(ptr); } -inline void operator delete[](void* ptr, size_t) +inline void operator delete[](void* ptr, size_t) noexcept { return kfree(ptr); } @@ -76,3 +91,5 @@ inline void operator delete[](void* ptr, size_t) # endif #endif + +using std::nothrow; diff --git a/Kernel/Heap/SlabAllocator.h b/Kernel/Heap/SlabAllocator.h index de826d38e7..bfaa2c99e1 100644 --- a/Kernel/Heap/SlabAllocator.h +++ b/Kernel/Heap/SlabAllocator.h @@ -19,11 +19,23 @@ void slab_dealloc(void*, size_t slab_size); void slab_alloc_init(); void slab_alloc_stats(Function); -#define MAKE_SLAB_ALLOCATED(type) \ -public: \ - [[nodiscard]] void* operator new(size_t) noexcept { return slab_alloc(sizeof(type)); } \ - void operator delete(void* ptr) noexcept { slab_dealloc(ptr, sizeof(type)); } \ - \ +#define MAKE_SLAB_ALLOCATED(type) \ +public: \ + [[nodiscard]] void* operator new(size_t) \ + { \ + void* ptr = slab_alloc(sizeof(type)); \ + VERIFY(ptr); \ + return ptr; \ + } \ + [[nodiscard]] void* operator new(size_t, const std::nothrow_t&) noexcept \ + { \ + return slab_alloc(sizeof(type)); \ + } \ + void operator delete(void* ptr) noexcept \ + { \ + slab_dealloc(ptr, sizeof(type)); \ + } \ + \ private: } diff --git a/Kernel/Heap/kmalloc.cpp b/Kernel/Heap/kmalloc.cpp index e6538cc561..68e6fa3faa 100644 --- a/Kernel/Heap/kmalloc.cpp +++ b/Kernel/Heap/kmalloc.cpp @@ -29,6 +29,10 @@ #define POOL_SIZE (2 * MiB) #define ETERNAL_RANGE_SIZE (2 * MiB) +namespace std { +const nothrow_t nothrow; +} + static RecursiveSpinLock s_lock; // needs to be recursive because of dump_backtrace() static void kmalloc_allocate_backup_memory(); @@ -300,12 +304,26 @@ size_t kmalloc_good_size(size_t size) return size; } -void* operator new(size_t size) noexcept +void* operator new(size_t size) +{ + void* ptr = kmalloc(size); + VERIFY(ptr); + return ptr; +} + +void* operator new(size_t size, const std::nothrow_t&) noexcept { return kmalloc(size); } -void* operator new[](size_t size) noexcept +void* operator new[](size_t size) +{ + void* ptr = kmalloc(size); + VERIFY(ptr); + return ptr; +} + +void* operator new[](size_t size, const std::nothrow_t&) noexcept { return kmalloc(size); } diff --git a/Kernel/Heap/kmalloc.h b/Kernel/Heap/kmalloc.h index c9db2b9285..fe35095663 100644 --- a/Kernel/Heap/kmalloc.h +++ b/Kernel/Heap/kmalloc.h @@ -13,13 +13,29 @@ #define KMALLOC_SCRUB_BYTE 0xbb #define KFREE_SCRUB_BYTE 0xaa -#define MAKE_ALIGNED_ALLOCATED(type, alignment) \ -public: \ - [[nodiscard]] void* operator new(size_t) noexcept { return kmalloc_aligned(sizeof(type)); } \ - void operator delete(void* ptr) noexcept { kfree_aligned(ptr); } \ - \ +#define MAKE_ALIGNED_ALLOCATED(type, alignment) \ +public: \ + [[nodiscard]] void* operator new(size_t) \ + { \ + void* ptr = kmalloc_aligned(sizeof(type)); \ + VERIFY(ptr); \ + return ptr; \ + } \ + [[nodiscard]] void* operator new(size_t, const std::nothrow_t&) noexcept { return kmalloc_aligned(sizeof(type)); } \ + void operator delete(void* ptr) noexcept { kfree_aligned(ptr); } \ + \ private: +// The C++ standard specifies that the nothrow allocation tag should live in the std namespace. +// Otherwise, `new (std::nothrow)` calls wouldn't get resolved. +namespace std { +struct nothrow_t { + explicit nothrow_t() = default; +}; + +extern const nothrow_t nothrow; +}; + void kmalloc_init(); [[gnu::malloc, gnu::returns_nonnull, gnu::alloc_size(1)]] void* kmalloc_impl(size_t); [[gnu::malloc, gnu::returns_nonnull, gnu::alloc_size(1)]] void* kmalloc_eternal(size_t); @@ -41,10 +57,12 @@ extern bool g_dump_kmalloc_stacks; inline void* operator new(size_t, void* p) { return p; } inline void* operator new[](size_t, void* p) { return p; } -[[nodiscard]] void* operator new(size_t size) noexcept; +[[nodiscard]] void* operator new(size_t size); +[[nodiscard]] void* operator new(size_t size, const std::nothrow_t&) noexcept; void operator delete(void* ptr) noexcept; void operator delete(void* ptr, size_t) noexcept; -[[nodiscard]] void* operator new[](size_t size) noexcept; +[[nodiscard]] void* operator new[](size_t size); +[[nodiscard]] void* operator new[](size_t size, const std::nothrow_t&) noexcept; void operator delete[](void* ptrs) noexcept; void operator delete[](void* ptr, size_t) noexcept;