aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-11-01 12:18:34 -0500
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-11-01 12:18:34 -0500
commit09d1315f16b8dfdd1758f2bc263ae7b7dee0f82a (patch)
tree2551e1b155c6bc70242591a3a0f1710964c8676e /src
parent6bde8c20d1f7c020a920e59a989c03822a08445d (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')
-rw-r--r--src/common/sparse_large_vector.cpp7
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);