BlockAllocator.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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/Heap/BlockAllocator.h>
  9. #include <LibJS/Heap/HeapBlock.h>
  10. #include <sys/mman.h>
  11. #ifdef HAS_ADDRESS_SANITIZER
  12. # include <sanitizer/asan_interface.h>
  13. #endif
  14. namespace JS {
  15. BlockAllocator::BlockAllocator()
  16. {
  17. }
  18. BlockAllocator::~BlockAllocator()
  19. {
  20. for (auto* block : m_blocks) {
  21. ASAN_UNPOISON_MEMORY_REGION(block, HeapBlock::block_size);
  22. #ifdef __serenity__
  23. if (munmap(block, HeapBlock::block_size) < 0) {
  24. perror("munmap");
  25. VERIFY_NOT_REACHED();
  26. }
  27. #else
  28. free(block);
  29. #endif
  30. }
  31. }
  32. void* BlockAllocator::allocate_block([[maybe_unused]] char const* name)
  33. {
  34. if (!m_blocks.is_empty()) {
  35. auto* block = m_blocks.take_last();
  36. ASAN_UNPOISON_MEMORY_REGION(block, HeapBlock::block_size);
  37. #ifdef __serenity__
  38. if (set_mmap_name(block, HeapBlock::block_size, name) < 0) {
  39. perror("set_mmap_name");
  40. VERIFY_NOT_REACHED();
  41. }
  42. #endif
  43. return block;
  44. }
  45. #ifdef __serenity__
  46. 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);
  47. VERIFY(block != MAP_FAILED);
  48. #else
  49. auto* block = (HeapBlock*)aligned_alloc(HeapBlock::block_size, HeapBlock::block_size);
  50. VERIFY(block);
  51. #endif
  52. return block;
  53. }
  54. void BlockAllocator::deallocate_block(void* block)
  55. {
  56. VERIFY(block);
  57. if (m_blocks.size() >= max_cached_blocks) {
  58. #ifdef __serenity__
  59. if (munmap(block, HeapBlock::block_size) < 0) {
  60. perror("munmap");
  61. VERIFY_NOT_REACHED();
  62. }
  63. #else
  64. free(block);
  65. #endif
  66. return;
  67. }
  68. ASAN_POISON_MEMORY_REGION(block, HeapBlock::block_size);
  69. m_blocks.append(block);
  70. }
  71. }