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_WINDOWS + /* 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) { + MmapFixedOrDie(region_beg, region->mapped_user, + "SizeClassAllocator: region data"); + 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,8 +334,13 @@ } void ReleaseMemoryPagesToOS(uptr beg, uptr end) { - // This is almost useless on 32-bits. - // FIXME: add madvise-analog when we move to 64-bits. + uptr beg_aligned, end_aligned; + beg_aligned = RoundDownTo(beg, GetPageSizeCached()); + end_aligned = RoundDownTo(end, GetPageSizeCached()); + CHECK(beg < end); // make sure the region is sane + if (beg_aligned == end_aligned) // make sure we're freeing at least 1 page; + return; + UnmapOrDie((void *)beg, end_aligned - beg_aligned); } void SetShadowRegionHugePageMode(uptr addr, uptr size) { Index: compiler-rt/test/asan/TestCases/Windows/sanitizer_purge.cpp =================================================================== --- /dev/null +++ compiler-rt/test/asan/TestCases/Windows/sanitizer_purge.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +// RUN: %clang_cl_asan -Od %s -Fe%t +// RUN: %t +// REQUIRES: asan-64-bits + +size_t GetRSS() { + PROCESS_MEMORY_COUNTERS counters; + if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters))) + return 0; + return counters.WorkingSetSize; +} + +int main(){ + for (int i = 0; i < 1000; i++) { + void* a = malloc(1000); + free(a); + } + size_t rss_pre = GetRSS(); + __sanitizer_purge_allocator(); + size_t rss_post = GetRSS(); + + if (rss_pre <= rss_post){ + return -1; + } + + return 0; +} \ No newline at end of file