forked from OSchip/llvm-project
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 llvm-svn: 349138
This commit is contained in:
parent
257ce3871e
commit
41fec1bfc5
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue