From a924e9d5dc8af8d7e3aa189a642125508735ecbe Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 14 Apr 2026 00:37:59 +0000 Subject: [PATCH] [memory] coalesce mappings of MultiPageLevel (theyre redundant) Signed-off-by: lizzie --- src/common/multi_level_page_table.inc | 43 ++++++++++----------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/src/common/multi_level_page_table.inc b/src/common/multi_level_page_table.inc index 8ac506fa0a..79125e8e0b 100644 --- a/src/common/multi_level_page_table.inc +++ b/src/common/multi_level_page_table.inc @@ -13,13 +13,13 @@ namespace Common { template -MultiLevelPageTable::MultiLevelPageTable(std::size_t address_space_bits_, - std::size_t first_level_bits_, - std::size_t page_bits_) - : address_space_bits{address_space_bits_}, - first_level_bits{first_level_bits_}, page_bits{page_bits_} { +MultiLevelPageTable::MultiLevelPageTable(std::size_t address_space_bits_, std::size_t first_level_bits_, std::size_t page_bits_) + : address_space_bits{address_space_bits_} + , first_level_bits{first_level_bits_} + , page_bits{page_bits_} +{ if (page_bits == 0) { - return; + return; } first_level_shift = address_space_bits - first_level_bits; first_level_chunk_size = (1ULL << (first_level_shift - page_bits)) * sizeof(BaseAddr); @@ -30,12 +30,9 @@ MultiLevelPageTable::MultiLevelPageTable(std::size_t address_space_bit void* base{VirtualAlloc(nullptr, alloc_size, MEM_RESERVE, PAGE_READWRITE)}; #else void* base{mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)}; - - if (base == MAP_FAILED) { + if (base == MAP_FAILED) base = nullptr; - } #endif - ASSERT(base); base_ptr = reinterpret_cast(base); } @@ -56,29 +53,21 @@ template void MultiLevelPageTable::ReserveRange(u64 start, std::size_t size) { const u64 new_start = start >> first_level_shift; const u64 new_end = (start + size) >> first_level_shift; - for (u64 i = new_start; i <= new_end; i++) { - if (!first_level_map[i]) { + for (u64 i = new_start; i <= new_end; i++) + if (!first_level_map[i]) AllocateLevel(i); - } - } } template -void MultiLevelPageTable::AllocateLevel(u64 level) { - void* ptr = reinterpret_cast(base_ptr) + level * first_level_chunk_size; +void MultiLevelPageTable::AllocateLevel(u64 index) { + void* ptr = reinterpret_cast(base_ptr) + index * first_level_chunk_size; #ifdef _WIN32 - void* base{VirtualAlloc(ptr, first_level_chunk_size, MEM_COMMIT, PAGE_READWRITE)}; -#else - void* base{mmap(ptr, first_level_chunk_size, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)}; - - if (base == MAP_FAILED) { - base = nullptr; - } -#endif + void* base = VirtualAlloc(ptr, first_level_chunk_size, MEM_COMMIT, PAGE_READWRITE); ASSERT(base); - - first_level_map[level] = base; +#else + void* base = ptr; +#endif + first_level_map[index] = base; } } // namespace Common