diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2019-01-03 23:19:02 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2019-01-03 23:19:02 +0000 |
commit | 5aafa8723044f96031ff7626357c5843c1280012 (patch) | |
tree | 923e32bf5fcbb0a051297b317d9b245e1633f2a5 /compiler-rt | |
parent | 19f326bb8b2b46ffd6be3a0e99bb088380c59f1d (diff) |
[hwasan] Switch to 64 allocator with a dense size class map.
Summary:
Replace the 32-bit allocator with a 64-bit one with a non-constant
base address, and reduce both the number of size classes and the maximum
size of per-thread caches.
As measured on [1], this reduces average weighted memory overhead
(MaxRSS) from 26% to 12% over stock android allocator. These numbers
include overhead from code instrumentation and hwasan shadow (i.e. not a
pure allocator benchmark).
This switch also enables release-to-OS functionality, which is not
implemented in the 32-bit allocator. I have not seen any effect from
that on the benchmark.
[1] https://android.googlesource.com/platform/system/extras/+/master/memory_replay/
Reviewers: vitalybuka, kcc
Subscribers: kubamracek, cryptoad, llvm-commits
Differential Revision: https://reviews.llvm.org/D56239
Diffstat (limited to 'compiler-rt')
5 files changed, 11 insertions, 15 deletions
diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.h b/compiler-rt/lib/hwasan/hwasan_allocator.h index b3f2d6c8491..785a80625b1 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.h +++ b/compiler-rt/lib/hwasan/hwasan_allocator.h @@ -45,28 +45,22 @@ struct HwasanMapUnmapCallback { }; static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G -static const uptr kRegionSizeLog = 20; -static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; -typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; -struct AP32 { - static const uptr kSpaceBeg = 0; - static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; +struct AP64 { + static const uptr kSpaceBeg = ~0ULL; + static const uptr kSpaceSize = 0x2000000000ULL; static const uptr kMetadataSize = sizeof(Metadata); - typedef __sanitizer::CompactSizeClassMap SizeClassMap; - static const uptr kRegionSizeLog = __hwasan::kRegionSizeLog; + typedef __sanitizer::VeryDenseSizeClassMap SizeClassMap; using AddressSpaceView = LocalAddressSpaceView; - using ByteMap = __hwasan::ByteMap; typedef HwasanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32<AP32> PrimaryAllocator; +typedef SizeClassAllocator64<AP64> PrimaryAllocator; typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache; typedef LargeMmapAllocator<HwasanMapUnmapCallback> SecondaryAllocator; typedef CombinedAllocator<PrimaryAllocator, AllocatorCache, SecondaryAllocator> Allocator; - void AllocatorSwallowThreadLocalCache(AllocatorCache *cache); class HwasanChunkView { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h index 91e46847f57..fcc4469c98c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_combined.h @@ -34,15 +34,15 @@ class CombinedAllocator { "SecondaryAllocator is using wrong AddressSpaceView"); void InitLinkerInitialized(s32 release_to_os_interval_ms) { + stats_.InitLinkerInitialized(); primary_.Init(release_to_os_interval_ms); secondary_.InitLinkerInitialized(); - stats_.InitLinkerInitialized(); } void Init(s32 release_to_os_interval_ms) { + stats_.Init(); primary_.Init(release_to_os_interval_ms); secondary_.Init(); - stats_.Init(); } void *Allocate(AllocatorCache *cache, uptr size, uptr alignment) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_size_class_map.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_size_class_map.h index 07958424c7d..1c05fb8ff06 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_size_class_map.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_size_class_map.h @@ -237,3 +237,6 @@ typedef SizeClassMap<2, 5, 9, 16, 64, 14> VeryCompactSizeClassMap; // allowing for denser per-class arrays, smaller memory footprint and usually // better performances in threaded environments. typedef SizeClassMap<3, 4, 8, 17, 8, 10> DenseSizeClassMap; +// Similar to VeryCompact map above, this one has a small number of different +// size classes, and also reduced thread-local caches. +typedef SizeClassMap<2, 5, 9, 16, 8, 10> VeryDenseSizeClassMap; diff --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c index bff39d293d8..9f605b3208d 100644 --- a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c +++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c @@ -43,7 +43,6 @@ int main(int argc, char **argv) { // CHECK80-RIGHT: allocated heap chunk; size: 32 offset: // CHECK80-RIGHT: is located 50 bytes to the right of 30-byte region // -// CHECKm30: allocated heap chunk; size: 32 offset: 2 // CHECKm30: is located 30 bytes to the left of 30-byte region // // CHECKMm30: is a large allocated heap chunk; size: 1003520 offset: -30 diff --git a/compiler-rt/test/hwasan/TestCases/use-after-free.c b/compiler-rt/test/hwasan/TestCases/use-after-free.c index fcdd0771c37..03a1771c1b8 100644 --- a/compiler-rt/test/hwasan/TestCases/use-after-free.c +++ b/compiler-rt/test/hwasan/TestCases/use-after-free.c @@ -23,7 +23,7 @@ int main() { // CHECK: [[TYPE]] of size 1 at {{.*}} tags: [[PTR_TAG:[0-9a-f][0-9a-f]]]/[[MEM_TAG:[0-9a-f][0-9a-f]]] (ptr/mem) // CHECK: #0 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]] // Offset is 5 or 11 depending on left/right alignment. - // CHECK: is a small unallocated heap chunk; size: 16 offset: {{5|11}} + // CHECK: is a small unallocated heap chunk; size: 32 offset: {{5|11}} // CHECK: is located 5 bytes inside of 10-byte region // // CHECK: freed by thread {{.*}} here: |