page.h 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. bool m_in_use{};
  12. unsigned char m_size_class{255};
  13. size_t m_used_count{};
  14. size_t m_start_page{};
  15. size_t m_page_count{};
  16. Span* m_prev{this};
  17. Span* m_next{this};
  18. void* m_chunk_list{};
  19. };
  20. template<size_t size0, size_t size1, size_t size2>
  21. struct RadixTree
  22. {
  23. struct NodeV2
  24. {
  25. Span* lv2[1 << size2]{0};
  26. };
  27. struct NodeV1
  28. {
  29. NodeV2* lv1[1 << size1]{0};
  30. };
  31. NodeV1* lv0[1 << size0]{0};
  32. };
  33. template<typename T>
  34. struct MetadataAllocator
  35. {
  36. void* m_free_list{};
  37. char* m_free_area{};
  38. size_t m_free_left{};
  39. };
  40. class PageHeap
  41. {
  42. public:
  43. PageHeap();
  44. void DeallocateSpan(bg::detail::Span* s);
  45. void RegisterSpan(bg::detail::Span* s);
  46. bool GrowHeap(size_t page_count);
  47. bg::detail::Span* AllocateSpan(size_t page_count);
  48. using RadixTree = RadixTree<10ul, 10ul, 15ul>;
  49. RadixTree m_span_map;
  50. MetadataAllocator<bg::detail::Span> m_span_allocator;
  51. Span m_free_lists[128]{};
  52. Span m_large_list{};
  53. };
  54. }
  55. }