diff options
author | Kostya Kortchinsky <kostyak@google.com> | 2017-06-14 15:32:17 +0000 |
---|---|---|
committer | Kostya Kortchinsky <kostyak@google.com> | 2017-06-14 15:32:17 +0000 |
commit | fccfd4523bbad39dfaf5e1a9dbf7491abbc80a22 (patch) | |
tree | accaf126b266380aec4b9b8ecb56f88e813229f3 /lib/sanitizer_common/tests | |
parent | 2716b49e6801990c55b0dcbfcfbed120f6a364d8 (diff) |
[sanitizer] MmapAlignedOrDie changes to reduce fragmentation
Summary:
The reasoning behind this change is explained in D33454, which unfortunately
broke the Windows version (due to the platform not supporting partial unmapping
of a memory region).
This new approach changes `MmapAlignedOrDie` to allow for the specification of
a `padding_chunk`. If non-null, and the initial allocation is aligned, this
padding chunk will hold the address of the extra memory (of `alignment` bytes).
This allows `AllocateRegion` to get 2 regions if the memory is aligned
properly, and thus help reduce fragmentation (and saves on unmapping
operations). As with the initial D33454, we use a stash in the 32-bit Primary
to hold those extra regions and return them on the fast-path.
The Windows version of `MmapAlignedOrDie` will always return a 0
`padding_chunk` if one was requested.
Reviewers: alekseyshl, dvyukov, kcc
Reviewed By: alekseyshl
Subscribers: llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D34152
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@305391 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/tests')
-rw-r--r-- | lib/sanitizer_common/tests/sanitizer_common_test.cc | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/lib/sanitizer_common/tests/sanitizer_common_test.cc b/lib/sanitizer_common/tests/sanitizer_common_test.cc index ebc885db7..c1077e628 100644 --- a/lib/sanitizer_common/tests/sanitizer_common_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_common_test.cc @@ -77,8 +77,8 @@ TEST(SanitizerCommon, MmapAlignedOrDie) { for (uptr size = 1; size <= 32; size *= 2) { for (uptr alignment = 1; alignment <= 32; alignment *= 2) { for (int iter = 0; iter < 100; iter++) { - uptr res = (uptr)MmapAlignedOrDie( - size * PageSize, alignment * PageSize, "MmapAlignedOrDieTest"); + uptr res = (uptr)MmapAlignedOrDie(size * PageSize, alignment * PageSize, + "MmapAlignedOrDieTest", nullptr); EXPECT_EQ(0U, res % (alignment * PageSize)); internal_memset((void*)res, 1, size * PageSize); UnmapOrDie((void*)res, size * PageSize); @@ -87,6 +87,37 @@ TEST(SanitizerCommon, MmapAlignedOrDie) { } } +TEST(SanitizerCommon, MmapAlignedOrDiePaddingChunk) { + uptr PageSize = GetPageSizeCached(); + for (uptr size = 1; size <= 32; size *= 2) { + for (uptr alignment = 1; alignment <= 32; alignment *= 2) { + for (int iter = 0; iter < 100; iter++) { + uptr padding_chunk; + uptr res = (uptr)MmapAlignedOrDie(size * PageSize, alignment * PageSize, + "MmapAlignedOrDiePaddingChunkTest", &padding_chunk); + EXPECT_EQ(0U, res % (alignment * PageSize)); + internal_memset((void*)res, 1, size * PageSize); + UnmapOrDie((void*)res, size * PageSize); + if (SANITIZER_WINDOWS || (size != alignment)) { + // Not supported on Windows or for different size and alignment. + EXPECT_EQ(0U, padding_chunk); + continue; + } + if (size == 1 && alignment == 1) { + // mmap returns PageSize aligned chunks, so this is a specific case + // where we can check that padding_chunk will never be 0. + EXPECT_NE(0U, padding_chunk); + } + if (padding_chunk) { + EXPECT_EQ(res + size * PageSize, padding_chunk); + internal_memset((void*)padding_chunk, 1, alignment * PageSize); + UnmapOrDie((void*)padding_chunk, alignment * PageSize); + } + } + } + } +} + #if SANITIZER_LINUX TEST(SanitizerCommon, SanitizerSetThreadName) { const char *names[] = { |