page_heap.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #pragma once
  2. #define PTR_TO_LV0(ptr) (ptr) >> 25
  3. #define PTR_TO_LV1(ptr) ((ptr) >> 15 & 0x3FF)
  4. #define PTR_TO_LV2(ptr) ((ptr) & 0x7FFF)
  5. namespace bg
  6. {
  7. namespace detail
  8. {
  9. struct Span
  10. {
  11. Span() = default;
  12. Span(size_t start_page, size_t page_count) : m_start_page(start_page), m_page_count(page_count) {}
  13. void RemoveNextSpan()
  14. {
  15. auto next_span = m_next;
  16. m_next = next_span->m_next;
  17. next_span->m_next->m_prev = next_span->m_prev;
  18. next_span->m_prev = nullptr;
  19. next_span->m_next = nullptr;
  20. }
  21. void InstertNextSpan(Span* span)
  22. {
  23. span->m_prev = m_next->m_prev;
  24. span->m_next = m_next;
  25. m_next->m_prev = span;
  26. m_next = span;
  27. }
  28. bool m_in_use{};
  29. unsigned char m_size_class{255};
  30. size_t m_used_count{};
  31. size_t m_start_page{};
  32. size_t m_page_count{};
  33. Span* m_prev{this};
  34. Span* m_next{this};
  35. void* m_chunk_list{};
  36. };
  37. template<size_t size0, size_t size1, size_t size2>
  38. struct RadixTree
  39. {
  40. struct NodeV2
  41. {
  42. Span* lv2[1 << size2]{0};
  43. };
  44. struct NodeV1
  45. {
  46. NodeV2* lv1[1 << size1]{0};
  47. };
  48. NodeV1* lv0[1 << size0]{0};
  49. };
  50. template<typename T>
  51. struct MetadataAllocator
  52. {
  53. void* m_free_list{};
  54. char* m_free_area{};
  55. size_t m_free_left{};
  56. };
  57. class PageHeap
  58. {
  59. public:
  60. PageHeap();
  61. bg::detail::Span* GetSpanMap(size_t start_page);
  62. bool SetSpanMap(size_t page, bg::detail::Span* span);
  63. void DeallocateSpan(bg::detail::Span* s);
  64. void RegisterSpan(bg::detail::Span* s);
  65. bool GrowHeap(size_t page_count);
  66. bg::detail::Span* AllocateSpan(size_t page_count);
  67. bg::detail::Span* GetNewSpan();
  68. bg::detail::Span* GetLastSpan(size_t page_count);
  69. using RadixTree = RadixTree<10ul, 10ul, 15ul>;
  70. RadixTree m_span_map;
  71. MetadataAllocator<bg::detail::Span> m_span_allocator;
  72. Span m_free_lists[128]{};
  73. Span m_large_list{};
  74. };
  75. }
  76. }