diff options
author | Dan Liew <dan@su-root.co.uk> | 2018-12-14 09:03:18 +0000 |
---|---|---|
committer | Dan Liew <dan@su-root.co.uk> | 2018-12-14 09:03:18 +0000 |
commit | e9af121746eeee7e5984bae7845177d97609e3b8 (patch) | |
tree | 1d926581001f448b8f5ca66f7fee60ac5dd145a0 | |
parent | 72553161017479d64a67316c7a9c9bb592dbe326 (diff) |
Introduce `AddressSpaceView` template parameter to `SizeClassAllocator32`, `FlatByteMap`, and `TwoLevelByteMap`.
Summary:
This is a follow up patch to r346956 for the `SizeClassAllocator32`
allocator.
This patch makes `AddressSpaceView` a template parameter both to the
`ByteMap` implementations (but makes `LocalAddressSpaceView` the
default), some `AP32` implementations and is used in `SizeClassAllocator32`.
The actual changes to `ByteMap` implementations and
`SizeClassAllocator32` are very simple. However the patch is large
because it requires changing all the `AP32` definitions, and users of
those definitions.
For ASan and LSan we make `AP32` and `ByteMap` templateds type that take
a single `AddressSpaceView` argument. This has been done because we will
instantiate the allocator with a type that isn't `LocalAddressSpaceView`
in the future patches. For the allocators used in the other sanitizers
(i.e. HWAsan, MSan, Scudo, and TSan) use of `LocalAddressSpaceView` is
hard coded because we do not intend to instantiate the allocators with
any other type.
In the cases where untemplated types have become templated on a single
`AddressSpaceView` parameter (e.g. `PrimaryAllocator`) their name has
been changed to have a `ASVT` suffix (Address Space View Type) to
indicate they are templated. The only exception to this are the `AP32`
types due to the desire to keep the type name as short as possible.
In order to check that template is instantiated in the correct a way a
`static_assert(...)` has been added that checks that the
`AddressSpaceView` type used by `Params::ByteMap::AddressSpaceView` matches
the `Params::AddressSpaceView`. This uses the new `sanitizer_type_traits.h`
header.
rdar://problem/45284065
Reviewers: kcc, dvyukov, vitalybuka, cryptoad, eugenis, kubamracek, george.karpenkov
Subscribers: mgorny, llvm-commits, #sanitizers
Differential Revision: https://reviews.llvm.org/D54904
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@349138 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/asan/asan_allocator.h | 15 | ||||
-rw-r--r-- | lib/hwasan/hwasan_allocator.h | 3 | ||||
-rw-r--r-- | lib/lsan/lsan_allocator.h | 12 | ||||
-rw-r--r-- | lib/msan/msan_allocator.cc | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator.h | 1 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator_bytemap.h | 11 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator_internal.h | 3 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator_primary32.h | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/tests/sanitizer_allocator_test.cc | 31 | ||||
-rw-r--r-- | lib/scudo/scudo_allocator.h | 3 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.h | 7 |
11 files changed, 70 insertions, 26 deletions
diff --git a/lib/asan/asan_allocator.h b/lib/asan/asan_allocator.h index 93d6f29c5..51fba254a 100644 --- a/lib/asan/asan_allocator.h +++ b/lib/asan/asan_allocator.h @@ -162,22 +162,29 @@ typedef SizeClassAllocator64<AP64> PrimaryAllocator; static const uptr kRegionSizeLog = 20; static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; # if SANITIZER_WORDSIZE == 32 -typedef FlatByteMap<kNumRegions> ByteMap; +template <typename AddressSpaceView> +using ByteMapASVT = FlatByteMap<kNumRegions, AddressSpaceView>; # elif SANITIZER_WORDSIZE == 64 -typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; +template <typename AddressSpaceView> +using ByteMapASVT = + TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>; # endif typedef CompactSizeClassMap SizeClassMap; +template <typename AddressSpaceViewTy> struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = 16; typedef __asan::SizeClassMap SizeClassMap; static const uptr kRegionSizeLog = __asan::kRegionSizeLog; - typedef __asan::ByteMap ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = __asan::ByteMapASVT<AddressSpaceView>; typedef AsanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32<AP32> PrimaryAllocator; +template <typename AddressSpaceView> +using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView> >; +using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>; #endif // SANITIZER_CAN_USE_ALLOCATOR64 static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses; diff --git a/lib/hwasan/hwasan_allocator.h b/lib/hwasan/hwasan_allocator.h index 06f563a96..b3f2d6c84 100644 --- a/lib/hwasan/hwasan_allocator.h +++ b/lib/hwasan/hwasan_allocator.h @@ -55,7 +55,8 @@ struct AP32 { static const uptr kMetadataSize = sizeof(Metadata); typedef __sanitizer::CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = __hwasan::kRegionSizeLog; - typedef __hwasan::ByteMap ByteMap; + using AddressSpaceView = LocalAddressSpaceView; + using ByteMap = __hwasan::ByteMap; typedef HwasanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; diff --git a/lib/lsan/lsan_allocator.h b/lib/lsan/lsan_allocator.h index 7c70bb6d9..23ebc11f6 100644 --- a/lib/lsan/lsan_allocator.h +++ b/lib/lsan/lsan_allocator.h @@ -54,19 +54,25 @@ struct ChunkMetadata { defined(__arm__) static const uptr kRegionSizeLog = 20; static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; -typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; +template <typename AddressSpaceView> +using ByteMapASVT = + TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>; +template <typename AddressSpaceViewTy> struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = sizeof(ChunkMetadata); typedef __sanitizer::CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = __lsan::kRegionSizeLog; - typedef __lsan::ByteMap ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = __lsan::ByteMapASVT<AddressSpaceView>; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32<AP32> PrimaryAllocator; +template <typename AddressSpaceView> +using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView>>; +using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>; #elif defined(__x86_64__) || defined(__powerpc64__) # if defined(__powerpc64__) const uptr kAllocatorSpace = 0xa0000000000ULL; diff --git a/lib/msan/msan_allocator.cc b/lib/msan/msan_allocator.cc index 36f0497a9..8b9fa6506 100644 --- a/lib/msan/msan_allocator.cc +++ b/lib/msan/msan_allocator.cc @@ -57,7 +57,8 @@ struct MsanMapUnmapCallback { static const uptr kMetadataSize = sizeof(Metadata); typedef __sanitizer::CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = __msan::kRegionSizeLog; - typedef __msan::ByteMap ByteMap; + using AddressSpaceView = LocalAddressSpaceView; + using ByteMap = __msan::ByteMap; typedef MsanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; @@ -107,7 +108,8 @@ struct MsanMapUnmapCallback { static const uptr kMetadataSize = sizeof(Metadata); typedef __sanitizer::CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = __msan::kRegionSizeLog; - typedef __msan::ByteMap ByteMap; + using AddressSpaceView = LocalAddressSpaceView; + using ByteMap = __msan::ByteMap; typedef MsanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; diff --git a/lib/sanitizer_common/sanitizer_allocator.h b/lib/sanitizer_common/sanitizer_allocator.h index 7d81bef3b..88017160a 100644 --- a/lib/sanitizer_common/sanitizer_allocator.h +++ b/lib/sanitizer_common/sanitizer_allocator.h @@ -22,6 +22,7 @@ #include "sanitizer_local_address_space_view.h" #include "sanitizer_mutex.h" #include "sanitizer_procmaps.h" +#include "sanitizer_type_traits.h" namespace __sanitizer { diff --git a/lib/sanitizer_common/sanitizer_allocator_bytemap.h b/lib/sanitizer_common/sanitizer_allocator_bytemap.h index 7df3e4097..ef26941fe 100644 --- a/lib/sanitizer_common/sanitizer_allocator_bytemap.h +++ b/lib/sanitizer_common/sanitizer_allocator_bytemap.h @@ -15,9 +15,10 @@ #endif // Maps integers in rage [0, kSize) to u8 values. -template<u64 kSize> +template <u64 kSize, typename AddressSpaceViewTy = LocalAddressSpaceView> class FlatByteMap { public: + using AddressSpaceView = AddressSpaceViewTy; void Init() { internal_memset(map_, 0, sizeof(map_)); } @@ -41,9 +42,12 @@ class FlatByteMap { // to kSize2-byte arrays. The secondary arrays are mmaped on demand. // Each value is initially zero and can be set to something else only once. // Setting and getting values from multiple threads is safe w/o extra locking. -template <u64 kSize1, u64 kSize2, class MapUnmapCallback = NoOpMapUnmapCallback> +template <u64 kSize1, u64 kSize2, + typename AddressSpaceViewTy = LocalAddressSpaceView, + class MapUnmapCallback = NoOpMapUnmapCallback> class TwoLevelByteMap { public: + using AddressSpaceView = AddressSpaceViewTy; void Init() { internal_memset(map1_, 0, sizeof(map1_)); mu_.Init(); @@ -73,7 +77,8 @@ class TwoLevelByteMap { CHECK_LT(idx, kSize1 * kSize2); u8 *map2 = Get(idx / kSize2); if (!map2) return 0; - return map2[idx % kSize2]; + auto value_ptr = AddressSpaceView::Load(&map2[idx % kSize2]); + return *value_ptr; } private: diff --git a/lib/sanitizer_common/sanitizer_allocator_internal.h b/lib/sanitizer_common/sanitizer_allocator_internal.h index c0c03d3f4..30fc7042b 100644 --- a/lib/sanitizer_common/sanitizer_allocator_internal.h +++ b/lib/sanitizer_common/sanitizer_allocator_internal.h @@ -37,7 +37,8 @@ struct AP32 { static const uptr kMetadataSize = 0; typedef InternalSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = kInternalAllocatorRegionSizeLog; - typedef __sanitizer::ByteMap ByteMap; + using AddressSpaceView = LocalAddressSpaceView; + using ByteMap = __sanitizer::ByteMap; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; diff --git a/lib/sanitizer_common/sanitizer_allocator_primary32.h b/lib/sanitizer_common/sanitizer_allocator_primary32.h index 67970e95b..e5d637665 100644 --- a/lib/sanitizer_common/sanitizer_allocator_primary32.h +++ b/lib/sanitizer_common/sanitizer_allocator_primary32.h @@ -48,6 +48,7 @@ struct SizeClassAllocator32FlagMasks { // Bit masks. template <class Params> class SizeClassAllocator32 { public: + using AddressSpaceView = typename Params::AddressSpaceView; static const uptr kSpaceBeg = Params::kSpaceBeg; static const u64 kSpaceSize = Params::kSpaceSize; static const uptr kMetadataSize = Params::kMetadataSize; @@ -108,6 +109,9 @@ class SizeClassAllocator32 { typedef SizeClassAllocator32LocalCache<ThisT> AllocatorCache; void Init(s32 release_to_os_interval_ms) { + static_assert( + is_same<typename ByteMap::AddressSpaceView, AddressSpaceView>::value, + "AddressSpaceView type mismatch"); possible_regions.Init(); internal_memset(size_class_info_array, 0, sizeof(size_class_info_array)); } diff --git a/lib/sanitizer_common/tests/sanitizer_allocator_test.cc b/lib/sanitizer_common/tests/sanitizer_allocator_test.cc index c13da36ce..f12b70e7b 100644 --- a/lib/sanitizer_common/tests/sanitizer_allocator_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_allocator_test.cc @@ -118,17 +118,22 @@ static const u64 kAddressSpaceSize = 1ULL << 32; static const uptr kRegionSizeLog = FIRST_32_SECOND_64(20, 24); static const uptr kFlatByteMapSize = kAddressSpaceSize >> kRegionSizeLog; +template <typename AddressSpaceViewTy> struct AP32Compact { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = kAddressSpaceSize; static const uptr kMetadataSize = 16; typedef CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = ::kRegionSizeLog; - typedef FlatByteMap<kFlatByteMapSize> ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = FlatByteMap<kFlatByteMapSize, AddressSpaceView>; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32<AP32Compact> Allocator32Compact; +template <typename AddressSpaceView> +using Allocator32CompactASVT = + SizeClassAllocator32<AP32Compact<AddressSpaceView>>; +using Allocator32Compact = Allocator32CompactASVT<LocalAddressSpaceView>; template <class SizeClassMap> void TestSizeClassMap() { @@ -259,18 +264,24 @@ TEST(SanitizerCommon, SizeClassAllocator32Compact) { TestSizeClassAllocator<Allocator32Compact>(); } +template <typename AddressSpaceViewTy> struct AP32SeparateBatches { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = kAddressSpaceSize; static const uptr kMetadataSize = 16; typedef DefaultSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = ::kRegionSizeLog; - typedef FlatByteMap<kFlatByteMapSize> ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = FlatByteMap<kFlatByteMapSize, AddressSpaceView>; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch; }; -typedef SizeClassAllocator32<AP32SeparateBatches> Allocator32SeparateBatches; +template <typename AddressSpaceView> +using Allocator32SeparateBatchesASVT = + SizeClassAllocator32<AP32SeparateBatches<AddressSpaceView>>; +using Allocator32SeparateBatches = + Allocator32SeparateBatchesASVT<LocalAddressSpaceView>; TEST(SanitizerCommon, SizeClassAllocator32SeparateBatches) { TestSizeClassAllocator<Allocator32SeparateBatches>(); @@ -426,13 +437,15 @@ TEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) { #endif #endif +template <typename AddressSpaceViewTy = LocalAddressSpaceView> struct AP32WithCallback { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = kAddressSpaceSize; static const uptr kMetadataSize = 16; typedef CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = ::kRegionSizeLog; - typedef FlatByteMap<kFlatByteMapSize> ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = FlatByteMap<kFlatByteMapSize, AddressSpaceView>; typedef TestMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; @@ -440,7 +453,7 @@ struct AP32WithCallback { TEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) { TestMapUnmapCallback::map_count = 0; TestMapUnmapCallback::unmap_count = 0; - typedef SizeClassAllocator32<AP32WithCallback> Allocator32WithCallBack; + typedef SizeClassAllocator32<AP32WithCallback<>> Allocator32WithCallBack; Allocator32WithCallBack *a = new Allocator32WithCallBack; a->Init(kReleaseToOSIntervalNever); EXPECT_EQ(TestMapUnmapCallback::map_count, 0); @@ -1337,8 +1350,10 @@ TEST(SanitizerCommon, TwoLevelByteMap) { m.TestOnlyUnmap(); } - -typedef TwoLevelByteMap<1 << 12, 1 << 13, TestMapUnmapCallback> TestByteMap; +template <typename AddressSpaceView> +using TestByteMapASVT = + TwoLevelByteMap<1 << 12, 1 << 13, AddressSpaceView, TestMapUnmapCallback>; +using TestByteMap = TestByteMapASVT<LocalAddressSpaceView>; struct TestByteMapParam { TestByteMap *m; diff --git a/lib/scudo/scudo_allocator.h b/lib/scudo/scudo_allocator.h index 0002b4a44..869e74a5e 100644 --- a/lib/scudo/scudo_allocator.h +++ b/lib/scudo/scudo_allocator.h @@ -96,7 +96,8 @@ struct AP32 { static const uptr kMetadataSize = 0; typedef __scudo::SizeClassMap SizeClassMap; static const uptr kRegionSizeLog = RegionSizeLog; - typedef __scudo::ByteMap ByteMap; + using AddressSpaceView = LocalAddressSpaceView; + using ByteMap = __scudo::ByteMap; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = SizeClassAllocator32FlagMasks::kRandomShuffleChunks | diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h index 7d4c53ec2..60e6f82f7 100644 --- a/lib/tsan/rtl/tsan_rtl.h +++ b/lib/tsan/rtl/tsan_rtl.h @@ -59,15 +59,16 @@ struct MapUnmapCallback; static const uptr kAllocatorRegionSizeLog = 20; static const uptr kAllocatorNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kAllocatorRegionSizeLog; -typedef TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12, - MapUnmapCallback> ByteMap; +using ByteMap = TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12, + LocalAddressSpaceView, MapUnmapCallback>; struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = 0; typedef __sanitizer::CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = kAllocatorRegionSizeLog; - typedef __tsan::ByteMap ByteMap; + using AddressSpaceView = LocalAddressSpaceView; + using ByteMap = __tsan::ByteMap; typedef __tsan::MapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; |