Index: compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -144,6 +144,17 @@ CompactPtrT *free_array = GetFreeArray(region_beg); BlockingMutexLock l(®ion->mutex); +#if SANITIZER_WINDOWS64 + /* On Windows unmapping of memory during __sanitizer_purge_allocator is + explicit and immediate, so unmapped regions must be explicitly mapped back + in when they are accessed again. */ + if (region->rtoi.last_released_bytes > 0) { + if (!MmapFixedOrDie(region_beg, region->mapped_user, "SizeClassAllocator: region data") ) + return false; + region->rtoi.n_freed_at_last_release = 0; + region->rtoi.last_released_bytes = 0; + } +#endif if (UNLIKELY(region->num_freed_chunks < n_chunks)) { if (UNLIKELY(!PopulateFreeArray(stat, class_id, region, n_chunks - region->num_freed_chunks))) Index: compiler-rt/lib/sanitizer_common/sanitizer_win.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -334,10 +334,17 @@ } void ReleaseMemoryPagesToOS(uptr beg, uptr end) { - // This is almost useless on 32-bits. - // FIXME: add madvise-analog when we move to 64-bits. +#if SANITIZER_WINDOWS64 + uptr beg_aligned = (beg & ~0xfff), end_aligned = (end & ~0xFFF); + CHECK(beg < end); // make sure the region is sane + if (beg_aligned == end_aligned) // make sure we're freeing at least 1 page; + return; + size_t size = end_aligned - beg_aligned; + UnmapOrDie((void *)beg, size); +#endif } + void SetShadowRegionHugePageMode(uptr addr, uptr size) { // FIXME: probably similar to ReleaseMemoryToOS. }