diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 12:18:34 -0500 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-11-01 12:18:34 -0500 |
| commit | 09d1315f16b8dfdd1758f2bc263ae7b7dee0f82a (patch) | |
| tree | 2551e1b155c6bc70242591a3a0f1710964c8676e /src/common/sparse_large_vector.cpp | |
| parent | 6bde8c20d1f7c020a920e59a989c03822a08445d (diff) | |
common: forget a sparse vector's region when it is freed
Regions are kept in host pages but were looked up by byte address when
freed, so none was ever removed, and the fault handler kept matching
faults in released address ranges (and in the page after each region,
as the end was treated as inclusive).
Diffstat (limited to 'src/common/sparse_large_vector.cpp')
| -rw-r--r-- | src/common/sparse_large_vector.cpp | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/src/common/sparse_large_vector.cpp b/src/common/sparse_large_vector.cpp index b96340999d..34aba73d78 100644 --- a/src/common/sparse_large_vector.cpp +++ b/src/common/sparse_large_vector.cpp @@ -39,12 +39,12 @@ static LONG WINAPI FakePageFaultHandler(PEXCEPTION_POINTERS info) { std::lock_guard lock(vector_regions_mutex); for (auto region: vector_regions) { auto addr_shifted = exception_addr >> HostPageBits; - if (region.first <= addr_shifted && addr_shifted <= region.second) { + if (region.first <= addr_shifted && addr_shifted < region.second) { addr = addr_shifted; } // Page-boundary accesses - if (auto addr_ = (exception_addr + 0x40) >> HostPageBits; addr_ != addr_shifted && region.first <= addr_ && addr_ <= region.second) { + if (auto addr_ = (exception_addr + 0x40) >> HostPageBits; addr_ != addr_shifted && region.first <= addr_ && addr_ < region.second) { addr2 = addr_; } @@ -164,7 +164,8 @@ void FreeMemoryPages(void* base, [[maybe_unused]] std::size_t size) noexcept { return; #ifdef _WIN32 std::lock_guard lock(vector_regions_mutex); - std::erase_if(vector_regions, [base](const auto& r) {return r.first == reinterpret_cast<u64>(base); }); + // Regions are kept in host pages. + std::erase_if(vector_regions, [base](const auto& r) {return r.first == reinterpret_cast<u64>(base) >> HostPageBits; }); ASSERT(VirtualFree(base, 0, MEM_RELEASE)); #else ASSERT(munmap(base, size) == 0); |
