Serenity Operating System
1/*
2 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/Platform.h>
8#include <AK/Random.h>
9#include <AK/Vector.h>
10#include <LibJS/Heap/BlockAllocator.h>
11#include <LibJS/Heap/HeapBlock.h>
12#include <sys/mman.h>
13
14#ifdef HAS_ADDRESS_SANITIZER
15# include <sanitizer/asan_interface.h>
16#endif
17
18namespace JS {
19
20BlockAllocator::~BlockAllocator()
21{
22 for (auto* block : m_blocks) {
23 ASAN_UNPOISON_MEMORY_REGION(block, HeapBlock::block_size);
24#ifdef AK_OS_SERENITY
25 if (munmap(block, HeapBlock::block_size) < 0) {
26 perror("munmap");
27 VERIFY_NOT_REACHED();
28 }
29#else
30 free(block);
31#endif
32 }
33}
34
35void* BlockAllocator::allocate_block([[maybe_unused]] char const* name)
36{
37 if (!m_blocks.is_empty()) {
38 // To reduce predictability, take a random block from the cache.
39 size_t random_index = get_random_uniform(m_blocks.size());
40 auto* block = m_blocks.unstable_take(random_index);
41 ASAN_UNPOISON_MEMORY_REGION(block, HeapBlock::block_size);
42#ifdef AK_OS_SERENITY
43 if (set_mmap_name(block, HeapBlock::block_size, name) < 0) {
44 perror("set_mmap_name");
45 VERIFY_NOT_REACHED();
46 }
47#endif
48 return block;
49 }
50
51#ifdef AK_OS_SERENITY
52 auto* block = (HeapBlock*)serenity_mmap(nullptr, HeapBlock::block_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_RANDOMIZED | MAP_PRIVATE, 0, 0, HeapBlock::block_size, name);
53 VERIFY(block != MAP_FAILED);
54#else
55 auto* block = (HeapBlock*)aligned_alloc(HeapBlock::block_size, HeapBlock::block_size);
56 VERIFY(block);
57#endif
58 return block;
59}
60
61void BlockAllocator::deallocate_block(void* block)
62{
63 VERIFY(block);
64 if (m_blocks.size() >= max_cached_blocks) {
65#ifdef AK_OS_SERENITY
66 if (munmap(block, HeapBlock::block_size) < 0) {
67 perror("munmap");
68 VERIFY_NOT_REACHED();
69 }
70#else
71 free(block);
72#endif
73 return;
74 }
75
76 ASAN_POISON_MEMORY_REGION(block, HeapBlock::block_size);
77 m_blocks.append(block);
78}
79
80}