diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-11-30 20:41:59 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-11-30 20:41:59 +0000 |
| commit | e109ef854a15326c4a818b42e5b6b15adfd730f5 (patch) | |
| tree | b99c728deb37a04a3edbe59d837657c0cb23da84 /compiler-rt/lib | |
| parent | 3d78d3a2aeab767590ddb6cb5d6986e6a63130ba (diff) | |
| download | bcm5719-llvm-e109ef854a15326c4a818b42e5b6b15adfd730f5.tar.gz bcm5719-llvm-e109ef854a15326c4a818b42e5b6b15adfd730f5.zip | |
Release memory to OS only when the requested range covers the entire page
Summary:
The current code was sometimes attempting to release huge chunks of
memory due to undesired RoundUp/RoundDown interaction when the requested
range is fully contained within one memory page.
Reviewers: eugenis
Subscribers: kubabrecka, llvm-commits
Patch by Aleksey Shlyapnikov.
Differential Revision: https://reviews.llvm.org/D27228
llvm-svn: 288271
Diffstat (limited to 'compiler-rt/lib')
| -rw-r--r-- | compiler-rt/lib/asan/asan_poisoning.cc | 9 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_poisoning.h | 4 | ||||
| -rw-r--r-- | compiler-rt/lib/msan/msan_allocator.cc | 9 | ||||
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h | 10 | ||||
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common.h | 4 | ||||
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc | 8 | ||||
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_win.cc | 3 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_mman.cc | 3 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.cc | 4 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc | 3 |
11 files changed, 29 insertions, 30 deletions
diff --git a/compiler-rt/lib/asan/asan_poisoning.cc b/compiler-rt/lib/asan/asan_poisoning.cc index ec61db4f2d1..abb75ab3bf9 100644 --- a/compiler-rt/lib/asan/asan_poisoning.cc +++ b/compiler-rt/lib/asan/asan_poisoning.cc @@ -64,12 +64,9 @@ struct ShadowSegmentEndpoint { }; void FlushUnneededASanShadowMemory(uptr p, uptr size) { - // Since asan's mapping is compacting, the shadow chunk may be - // not page-aligned, so we only flush the page-aligned portion. - uptr page_size = GetPageSizeCached(); - uptr shadow_beg = RoundUpTo(MemToShadow(p), page_size); - uptr shadow_end = RoundDownTo(MemToShadow(p + size), page_size); - ReleaseMemoryToOS(shadow_beg, shadow_end - shadow_beg); + // Since asan's mapping is compacting, the shadow chunk may be + // not page-aligned, so we only flush the page-aligned portion. + ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size)); } void AsanPoisonOrUnpoisonIntraObjectRedzone(uptr ptr, uptr size, bool poison) { diff --git a/compiler-rt/lib/asan/asan_poisoning.h b/compiler-rt/lib/asan/asan_poisoning.h index 35905c0265f..cc3281e08a7 100644 --- a/compiler-rt/lib/asan/asan_poisoning.h +++ b/compiler-rt/lib/asan/asan_poisoning.h @@ -86,8 +86,8 @@ ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone( } } -// Calls __sanitizer::ReleaseMemoryToOS() on -// [MemToShadow(p), MemToShadow(p+size)] with proper rounding. +// Calls __sanitizer::ReleaseMemoryPagesToOS() on +// [MemToShadow(p), MemToShadow(p+size)]. void FlushUnneededASanShadowMemory(uptr p, uptr size); } // namespace __asan diff --git a/compiler-rt/lib/msan/msan_allocator.cc b/compiler-rt/lib/msan/msan_allocator.cc index a82e89845cf..6c389f008cf 100644 --- a/compiler-rt/lib/msan/msan_allocator.cc +++ b/compiler-rt/lib/msan/msan_allocator.cc @@ -33,9 +33,12 @@ struct MsanMapUnmapCallback { // We are about to unmap a chunk of user memory. // Mark the corresponding shadow memory as not needed. - ReleaseMemoryToOS(MEM_TO_SHADOW(p), size); - if (__msan_get_track_origins()) - ReleaseMemoryToOS(MEM_TO_ORIGIN(p), size); + uptr shadow_p = MEM_TO_SHADOW(p); + ReleaseMemoryPagesToOS(shadow_p, shadow_p + size); + if (__msan_get_track_origins()) { + uptr origin_p = MEM_TO_ORIGIN(p); + ReleaseMemoryPagesToOS(origin_p, origin_p + size); + } } }; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h index 4beb109caae..f2d94a07a52 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -458,17 +458,11 @@ class SizeClassAllocator64 { } } - bool MaybeReleaseChunkRange(uptr region_beg, uptr chunk_size, + void MaybeReleaseChunkRange(uptr region_beg, uptr chunk_size, CompactPtrT first, CompactPtrT last) { uptr beg_ptr = CompactPtrToPointer(region_beg, first); uptr end_ptr = CompactPtrToPointer(region_beg, last) + chunk_size; - const uptr page_size = GetPageSizeCached(); - CHECK_GE(end_ptr - beg_ptr, page_size); - beg_ptr = RoundUpTo(beg_ptr, page_size); - end_ptr = RoundDownTo(end_ptr, page_size); - if (end_ptr == beg_ptr) return false; - ReleaseMemoryToOS(beg_ptr, end_ptr - beg_ptr); - return true; + ReleaseMemoryPagesToOS(beg_ptr, end_ptr); } // Attempts to release some RAM back to OS. The region is expected to be diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 70b10864ce1..bf66d00d6ae 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -103,7 +103,9 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding); // Used to check if we can map shadow memory to a fixed location. bool MemoryRangeIsAvailable(uptr range_start, uptr range_end); -void ReleaseMemoryToOS(uptr addr, uptr size); +// Releases memory pages entirely within the [beg, end] address range. Noop if +// the provided range does not contain at least one entire page. +void ReleaseMemoryPagesToOS(uptr beg, uptr end); void IncreaseTotalMmap(uptr size); void DecreaseTotalMmap(uptr size); uptr GetRSS(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc index 71eda4e80c2..dd62140b5e0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc @@ -56,8 +56,12 @@ uptr GetThreadSelf() { return (uptr)pthread_self(); } -void ReleaseMemoryToOS(uptr addr, uptr size) { - madvise((void*)addr, size, MADV_DONTNEED); +void ReleaseMemoryPagesToOS(uptr beg, uptr end) { + uptr page_size = GetPageSizeCached(); + uptr beg_aligned = RoundUpTo(beg, page_size); + uptr end_aligned = RoundDownTo(end, page_size); + if (beg_aligned < end_aligned) + madvise((void*)beg_aligned, end_aligned - beg_aligned, MADV_DONTNEED); } void NoHugePagesInRegion(uptr addr, uptr size) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc index 763193a78c4..0b7a38ca23e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc @@ -234,8 +234,7 @@ bool MprotectNoAccess(uptr addr, uptr size) { return VirtualProtect((LPVOID)addr, size, PAGE_NOACCESS, &old_protection); } - -void ReleaseMemoryToOS(uptr addr, uptr size) { +void ReleaseMemoryPagesToOS(uptr beg, uptr end) { // This is almost useless on 32-bits. // FIXME: add madvise-analog when we move to 64-bits. } diff --git a/compiler-rt/lib/tsan/rtl/tsan_mman.cc b/compiler-rt/lib/tsan/rtl/tsan_mman.cc index 4ca7baeef82..2dea24915e8 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_mman.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_mman.cc @@ -54,7 +54,8 @@ struct MapUnmapCallback { diff = p + size - RoundDown(p + size, kPageSize); if (diff != 0) size -= diff; - ReleaseMemoryToOS((uptr)MemToMeta(p), size / kMetaRatio); + uptr p_meta = (uptr)MemToMeta(p); + ReleaseMemoryPagesToOS(p_meta, p_meta + size / kMetaRatio); } }; diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc index 233de103fae..3313288a728 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc @@ -134,7 +134,7 @@ void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive) { void FlushShadowMemoryCallback( const SuspendedThreadsList &suspended_threads_list, void *argument) { - ReleaseMemoryToOS(ShadowBeg(), ShadowEnd() - ShadowBeg()); + ReleaseMemoryPagesToOS(ShadowBeg(), ShadowEnd()); } #endif diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc index 87a1c838ebd..804f3cf64ee 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc @@ -234,9 +234,7 @@ static void StopBackgroundThread() { #endif void DontNeedShadowFor(uptr addr, uptr size) { - uptr shadow_beg = MemToShadow(addr); - uptr shadow_end = MemToShadow(addr + size); - ReleaseMemoryToOS(shadow_beg, shadow_end - shadow_beg); + ReleaseMemoryPagesToOS(MemToShadow(addr), MemToShadow(addr + size)); } void MapShadow(uptr addr, uptr size) { diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc index 40c3b31276e..5b17dc60bcb 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc @@ -68,7 +68,8 @@ void ThreadContext::OnCreated(void *arg) { void ThreadContext::OnReset() { CHECK_EQ(sync.size(), 0); - ReleaseMemoryToOS(GetThreadTrace(tid), TraceSize() * sizeof(Event)); + uptr trace_p = GetThreadTrace(tid); + ReleaseMemoryPagesToOS(trace_p, trace_p + TraceSize() * sizeof(Event)); //!!! ReleaseMemoryToOS(GetThreadTraceHeader(tid), sizeof(Trace)); } |

