BlockAllocator.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Platform.h>
  7. #include <AK/Vector.h>
  8. #include <LibJS/Forward.h>
  9. #include <LibJS/Heap/BlockAllocator.h>
  10. #include <LibJS/Heap/HeapBlock.h>
  11. #include <stdlib.h>
  12. #include <sys/mman.h>
  13. #ifdef HAS_ADDRESS_SANITIZER
  14. # include <sanitizer/asan_interface.h>
  15. #endif
  16. namespace JS {
  17. BlockAllocator::BlockAllocator()
  18. {
  19. }
  20. BlockAllocator::~BlockAllocator()
  21. {
  22. for (auto* block : m_blocks) {
  23. ASAN_UNPOISON_MEMORY_REGION(block, HeapBlock::block_size);
  24. #ifdef __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. void* BlockAllocator::allocate_block([[maybe_unused]] char const* name)
  35. {
  36. if (!m_blocks.is_empty()) {
  37. auto* block = m_blocks.take_last();
  38. ASAN_UNPOISON_MEMORY_REGION(block, HeapBlock::block_size);
  39. #ifdef __serenity__
  40. if (set_mmap_name(block, HeapBlock::block_size, name) < 0) {
  41. perror("set_mmap_name");
  42. VERIFY_NOT_REACHED();
  43. }
  44. #endif
  45. return block;
  46. }
  47. #ifdef __serenity__
  48. 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);
  49. VERIFY(block != MAP_FAILED);
  50. #else
  51. auto* block = (HeapBlock*)aligned_alloc(HeapBlock::block_size, HeapBlock::block_size);
  52. VERIFY(block);
  53. #endif
  54. return block;
  55. }
  56. void BlockAllocator::deallocate_block(void* block)
  57. {
  58. VERIFY(block);
  59. if (m_blocks.size() >= max_cached_blocks) {
  60. #ifdef __serenity__
  61. if (munmap(block, HeapBlock::block_size) < 0) {
  62. perror("munmap");
  63. VERIFY_NOT_REACHED();
  64. }
  65. #else
  66. free(block);
  67. #endif
  68. return;
  69. }
  70. ASAN_POISON_MEMORY_REGION(block, HeapBlock::block_size);
  71. m_blocks.append(block);
  72. }
  73. }