diff options
Diffstat (limited to 'Kernel/Heap')
-rw-r--r-- | Kernel/Heap/Heap.h | 13 | ||||
-rw-r--r-- | Kernel/Heap/kmalloc.cpp | 28 |
2 files changed, 27 insertions, 14 deletions
diff --git a/Kernel/Heap/Heap.h b/Kernel/Heap/Heap.h index 5724d7e918..1ccf4edc3a 100644 --- a/Kernel/Heap/Heap.h +++ b/Kernel/Heap/Heap.h @@ -14,6 +14,11 @@ namespace Kernel { +enum class CallerWillInitializeMemory { + No, + Yes, +}; + template<size_t CHUNK_SIZE, unsigned HEAP_SCRUB_BYTE_ALLOC = 0, unsigned HEAP_SCRUB_BYTE_FREE = 0> class Heap { AK_MAKE_NONCOPYABLE(Heap); @@ -63,7 +68,7 @@ public: return needed_chunks * CHUNK_SIZE + (needed_chunks + 7) / 8; } - void* allocate(size_t size) + void* allocate(size_t size, CallerWillInitializeMemory caller_will_initialize_memory) { // We need space for the AllocationHeader at the head of the block. size_t real_size = size + sizeof(AllocationHeader); @@ -92,8 +97,10 @@ public: m_bitmap.set_range_and_verify_that_all_bits_flip(first_chunk.value(), chunks_needed, true); m_allocated_chunks += chunks_needed; - if constexpr (HEAP_SCRUB_BYTE_ALLOC != 0) { - __builtin_memset(ptr, HEAP_SCRUB_BYTE_ALLOC, (chunks_needed * CHUNK_SIZE) - sizeof(AllocationHeader)); + if (caller_will_initialize_memory == CallerWillInitializeMemory::No) { + if constexpr (HEAP_SCRUB_BYTE_ALLOC != 0) { + __builtin_memset(ptr, HEAP_SCRUB_BYTE_ALLOC, (chunks_needed * CHUNK_SIZE) - sizeof(AllocationHeader)); + } } return ptr; } diff --git a/Kernel/Heap/kmalloc.cpp b/Kernel/Heap/kmalloc.cpp index e158ca6fc5..3258e83d89 100644 --- a/Kernel/Heap/kmalloc.cpp +++ b/Kernel/Heap/kmalloc.cpp @@ -123,7 +123,7 @@ public: size_t slab_size() const { return m_slab_size; } - void* allocate() + void* allocate(CallerWillInitializeMemory caller_will_initialize_memory) { if (m_usable_blocks.is_empty()) { // FIXME: This allocation wastes `block_size` bytes due to the implementation of kmalloc_aligned(). @@ -141,7 +141,9 @@ public: if (block->is_full()) m_full_blocks.append(*block); - memset(ptr, KMALLOC_SCRUB_BYTE, m_slab_size); + if (caller_will_initialize_memory == CallerWillInitializeMemory::No) { + memset(ptr, KMALLOC_SCRUB_BYTE, m_slab_size); + } return ptr; } @@ -220,17 +222,17 @@ struct KmallocGlobalData { subheaps.append(*subheap); } - void* allocate(size_t size) + void* allocate(size_t size, CallerWillInitializeMemory caller_will_initialize_memory) { VERIFY(!expansion_in_progress); for (auto& slabheap : slabheaps) { if (size <= slabheap.slab_size()) - return slabheap.allocate(); + return slabheap.allocate(caller_will_initialize_memory); } for (auto& subheap : subheaps) { - if (auto* ptr = subheap.allocator.allocate(size)) + if (auto* ptr = subheap.allocator.allocate(size, caller_will_initialize_memory)) return ptr; } @@ -247,14 +249,14 @@ struct KmallocGlobalData { } } if (did_purge) - return allocate(size); + return allocate(size, caller_will_initialize_memory); } if (!try_expand(size)) { PANIC("OOM when trying to expand kmalloc heap."); } - return allocate(size); + return allocate(size, caller_will_initialize_memory); } void deallocate(void* ptr, size_t size) @@ -419,7 +421,7 @@ UNMAP_AFTER_INIT void kmalloc_init() s_lock.initialize(); } -void* kmalloc(size_t size) +static void* kmalloc_impl(size_t size, CallerWillInitializeMemory caller_will_initialize_memory) { // Catch bad callers allocating under spinlock. if constexpr (KMALLOC_VERIFY_NO_SPINLOCK_HELD) { @@ -434,7 +436,7 @@ void* kmalloc(size_t size) Kernel::dump_backtrace(); } - void* ptr = g_kmalloc_global->allocate(size); + void* ptr = g_kmalloc_global->allocate(size, caller_will_initialize_memory); Thread* current_thread = Thread::current(); if (!current_thread) @@ -449,13 +451,17 @@ void* kmalloc(size_t size) return ptr; } +void* kmalloc(size_t size) +{ + return kmalloc_impl(size, CallerWillInitializeMemory::No); +} + void* kcalloc(size_t count, size_t size) { if (Checked<size_t>::multiplication_would_overflow(count, size)) return nullptr; size_t new_size = count * size; - auto* ptr = kmalloc(new_size); - // FIXME: Avoid redundantly scrubbing the memory in kmalloc() + auto* ptr = kmalloc_impl(new_size, CallerWillInitializeMemory::Yes); if (ptr) memset(ptr, 0, new_size); return ptr; |