[Memory] Add free block tracker to BaseHeap for O(log n) allocation

Replace linear page_table_ scans in AllocRange with a std::map-based
free block index that tracks contiguous free regions.

Insertions now coalesce with adjacent blocks on release and AllocFixed
uses the targeted tracker for pure reserves and falls back to a full rebuild
for mixed-state commits.

Also fixing PhysicalHeap leaking parent memory on child allocation failure,
Reset() not restoring unreserved_page_count_ and some incorrect method names
in PhysicalHeap error messages
This commit is contained in:
Herman S.
2026-04-08 12:07:50 +09:00
parent 80c6751b82
commit ea02e8d317
3 changed files with 599 additions and 79 deletions

View File

@@ -11,6 +11,7 @@
#define XENIA_MEMORY_H_
#include <cstdint>
#include <map>
#include <memory>
#include <mutex>
#include <string>
@@ -210,6 +211,15 @@ class BaseHeap {
uint32_t heap_base, uint32_t heap_size, uint32_t page_size,
uint32_t host_address_offset = 0);
// Rebuilds free_blocks_ by scanning page_table_. Used after Restore.
void RebuildFreeBlocks();
// Removes (or splits) the free block covering the given page range.
void RemoveFreeBlock(uint32_t start_page, uint32_t page_count);
// Inserts a free block and coalesces with adjacent free blocks.
void InsertFreeBlock(uint32_t start_page, uint32_t page_count);
Memory* memory_;
uint8_t* membase_;
HeapType heap_type_;
@@ -221,6 +231,10 @@ class BaseHeap {
uint32_t unreserved_page_count_;
xe::global_critical_region global_critical_region_;
std::vector<PageEntry> page_table_;
// Auxiliary free block tracker: maps start_page -> count of contiguous free
// pages. Kept in sync with page_table_ mutations. Not serialized.
std::map<uint32_t, uint32_t> free_blocks_;
};
// Normal heap allowing allocations from guest virtual address ranges.