Index: lib/asan/asan_allocator.h =================================================================== --- lib/asan/asan_allocator.h +++ lib/asan/asan_allocator.h @@ -162,22 +162,28 @@ static const uptr kRegionSizeLog = 20; static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; # if SANITIZER_WORDSIZE == 32 -typedef FlatByteMap ByteMap; +template +using ByteMap = FlatByteMap; # elif SANITIZER_WORDSIZE == 64 -typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; +template +using ByteMap = TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>; # endif typedef CompactSizeClassMap SizeClassMap; +template 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::ByteMap; typedef AsanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32 PrimaryAllocator; +template +using PrimaryAllocatorT = SizeClassAllocator32 >; +using PrimaryAllocator = PrimaryAllocatorT; #endif // SANITIZER_CAN_USE_ALLOCATOR64 static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses; Index: lib/hwasan/hwasan_allocator.h =================================================================== --- lib/hwasan/hwasan_allocator.h +++ lib/hwasan/hwasan_allocator.h @@ -47,19 +47,24 @@ 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; +template +using ByteMap = TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>; +template struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = sizeof(Metadata); typedef __sanitizer::CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = __hwasan::kRegionSizeLog; - typedef __hwasan::ByteMap ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = __hwasan::ByteMap; typedef HwasanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32 PrimaryAllocator; +template +using PrimaryAllocatorT = SizeClassAllocator32>; +using PrimaryAllocator = PrimaryAllocatorT; typedef SizeClassAllocatorLocalCache AllocatorCache; typedef LargeMmapAllocator SecondaryAllocator; typedef CombinedAllocator> kRegionSizeLog; -typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; +template +using ByteMap = TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>; +template 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::ByteMap; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32 PrimaryAllocator; +template +using PrimaryAllocatorT = SizeClassAllocator32>; +using PrimaryAllocator = PrimaryAllocatorT; #elif defined(__x86_64__) || defined(__powerpc64__) # if defined(__powerpc64__) const uptr kAllocatorSpace = 0xa0000000000ULL; Index: lib/msan/msan_allocator.cc =================================================================== --- lib/msan/msan_allocator.cc +++ lib/msan/msan_allocator.cc @@ -49,19 +49,25 @@ static const uptr kMaxAllowedMallocSize = 2UL << 30; static const uptr kRegionSizeLog = 20; static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; - typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; + template + using ByteMap = + TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>; + template struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = sizeof(Metadata); typedef __sanitizer::CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = __msan::kRegionSizeLog; - typedef __msan::ByteMap ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = __msan::ByteMap; typedef MsanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; - typedef SizeClassAllocator32 PrimaryAllocator; + template + using PrimaryAllocatorT = SizeClassAllocator32>; + using PrimaryAllocator = PrimaryAllocatorT; #elif defined(__x86_64__) #if SANITIZER_NETBSD || \ (SANITIZER_LINUX && !defined(MSAN_LINUX_X86_64_OLD_MAPPING)) @@ -99,19 +105,25 @@ 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; + template + using ByteMap = + TwoLevelByteMap<(kNumRegions >> 12), 1 << 12, AddressSpaceView>; + template struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = sizeof(Metadata); typedef __sanitizer::CompactSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = __msan::kRegionSizeLog; - typedef __msan::ByteMap ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = __msan::ByteMap; typedef MsanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; - typedef SizeClassAllocator32 PrimaryAllocator; + template + using PrimaryAllocatorT = SizeClassAllocator32>; + using PrimaryAllocator = PrimaryAllocatorT; #endif typedef SizeClassAllocatorLocalCache AllocatorCache; typedef LargeMmapAllocator SecondaryAllocator; Index: lib/sanitizer_common/sanitizer_allocator.h =================================================================== --- lib/sanitizer_common/sanitizer_allocator.h +++ 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 { Index: lib/sanitizer_common/sanitizer_allocator_bytemap.h =================================================================== --- lib/sanitizer_common/sanitizer_allocator_bytemap.h +++ lib/sanitizer_common/sanitizer_allocator_bytemap.h @@ -15,9 +15,10 @@ #endif // Maps integers in rage [0, kSize) to u8 values. -template +template class FlatByteMap { public: + using AddressSpaceView = AddressSpaceViewTy; void Init() { internal_memset(map_, 0, sizeof(map_)); } @@ -41,9 +42,12 @@ // 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 +template class TwoLevelByteMap { public: + using AddressSpaceView = AddressSpaceViewTy; void Init() { internal_memset(map1_, 0, sizeof(map1_)); mu_.Init(); @@ -72,8 +76,10 @@ u8 operator[] (uptr idx) const { CHECK_LT(idx, kSize1 * kSize2); u8 *map2 = Get(idx / kSize2); - if (!map2) return 0; - return map2[idx % kSize2]; + if (!map2) + return 0; + auto value_ptr = AddressSpaceView::Load(&map2[idx % kSize2]); + return *value_ptr; } private: Index: lib/sanitizer_common/sanitizer_allocator_internal.h =================================================================== --- lib/sanitizer_common/sanitizer_allocator_internal.h +++ lib/sanitizer_common/sanitizer_allocator_internal.h @@ -27,21 +27,29 @@ static const uptr kInternalAllocatorNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kInternalAllocatorRegionSizeLog; #if SANITIZER_WORDSIZE == 32 -typedef FlatByteMap ByteMap; +template +using ByteMap = FlatByteMap; #else -typedef TwoLevelByteMap<(kInternalAllocatorNumRegions >> 12), 1 << 12> ByteMap; +template +using ByteMap = TwoLevelByteMap<(kInternalAllocatorNumRegions >> 12), 1 << 12, + AddressSpaceView>; #endif +template struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = 0; typedef InternalSizeClassMap SizeClassMap; static const uptr kRegionSizeLog = kInternalAllocatorRegionSizeLog; - typedef __sanitizer::ByteMap ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + typedef __sanitizer::ByteMap ByteMap; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32 PrimaryInternalAllocator; +template +using PrimaryInternalAllocatorT = SizeClassAllocator32>; +using PrimaryInternalAllocator = + PrimaryInternalAllocatorT; typedef SizeClassAllocatorLocalCache InternalAllocatorCache; @@ -51,7 +59,8 @@ SecondaryInternalAllocator; typedef CombinedAllocator InternalAllocator; + SecondaryInternalAllocator> + InternalAllocator; void *InternalAlloc(uptr size, InternalAllocatorCache *cache = nullptr, uptr alignment = 0); Index: lib/sanitizer_common/sanitizer_allocator_primary32.h =================================================================== --- lib/sanitizer_common/sanitizer_allocator_primary32.h +++ lib/sanitizer_common/sanitizer_allocator_primary32.h @@ -48,6 +48,7 @@ template 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 @@ typedef SizeClassAllocator32LocalCache AllocatorCache; void Init(s32 release_to_os_interval_ms) { + static_assert( + is_same::value, + "AddressSpaceView type mismatch"); possible_regions.Init(); internal_memset(size_class_info_array, 0, sizeof(size_class_info_array)); } @@ -236,9 +240,10 @@ // Iterate over all existing chunks. // The allocator must be locked when calling this function. void ForEachChunk(ForEachChunkCallback callback, void *arg) { - for (uptr region = 0; region < kNumPossibleRegions; region++) - if (possible_regions[region]) { - uptr chunk_size = ClassIdToSize(possible_regions[region]); + for (uptr region = 0; region < kNumPossibleRegions; region++) { + uptr class_id = possible_regions[region]; + if (class_id) { + uptr chunk_size = ClassIdToSize(class_id); uptr max_chunks_in_region = kRegionSize / (chunk_size + kMetadataSize); uptr region_beg = region * kRegionSize; for (uptr chunk = region_beg; @@ -248,6 +253,7 @@ callback(chunk, arg); } } + } } void PrintStats() {} Index: lib/sanitizer_common/sanitizer_type_traits.h =================================================================== --- /dev/null +++ lib/sanitizer_common/sanitizer_type_traits.h @@ -0,0 +1,44 @@ +//===-- sanitizer_type_traits.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implements a subset of C++ type traits. This is so we can avoid depending +// on system C++ headers. +// +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_TYPE_TRAITS_H +#define SANITIZER_TYPE_TRAITS_H + +namespace __sanitizer { + +struct true_type { + static const bool value = true; +}; + +struct false_type { + static const bool value = false; +}; + +// is_same +// +// Type trait to compare if types are the same. +// E.g. +// +// ``` +// is_same::value - True +// is_same::value - False +// ``` +template +struct is_same : public false_type {}; + +template +struct is_same : public true_type {}; + +}; // namespace __sanitizer + +#endif Index: lib/sanitizer_common/tests/CMakeLists.txt =================================================================== --- lib/sanitizer_common/tests/CMakeLists.txt +++ lib/sanitizer_common/tests/CMakeLists.txt @@ -36,6 +36,7 @@ sanitizer_symbolizer_test.cc sanitizer_test_main.cc sanitizer_thread_registry_test.cc + sanitizer_type_traits_test.cc sanitizer_vector_test.cc) set(SANITIZER_TEST_HEADERS Index: lib/sanitizer_common/tests/sanitizer_allocator_test.cc =================================================================== --- lib/sanitizer_common/tests/sanitizer_allocator_test.cc +++ lib/sanitizer_common/tests/sanitizer_allocator_test.cc @@ -118,17 +118,21 @@ static const uptr kRegionSizeLog = FIRST_32_SECOND_64(20, 24); static const uptr kFlatByteMapSize = kAddressSpaceSize >> kRegionSizeLog; +template 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 ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = FlatByteMap; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32 Allocator32Compact; +template +using Allocator32CompactT = SizeClassAllocator32>; +using Allocator32Compact = Allocator32CompactT; template void TestSizeClassMap() { @@ -259,18 +263,24 @@ TestSizeClassAllocator(); } +template 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 ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = FlatByteMap; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch; }; -typedef SizeClassAllocator32 Allocator32SeparateBatches; +template +using Allocator32SeparateBatchesT = + SizeClassAllocator32>; +using Allocator32SeparateBatches = + Allocator32SeparateBatchesT; TEST(SanitizerCommon, SizeClassAllocator32SeparateBatches) { TestSizeClassAllocator(); @@ -426,13 +436,15 @@ #endif #endif +template 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 ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = FlatByteMap; typedef TestMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; @@ -440,7 +452,7 @@ TEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) { TestMapUnmapCallback::map_count = 0; TestMapUnmapCallback::unmap_count = 0; - typedef SizeClassAllocator32 Allocator32WithCallBack; + typedef SizeClassAllocator32> Allocator32WithCallBack; Allocator32WithCallBack *a = new Allocator32WithCallBack; a->Init(kReleaseToOSIntervalNever); EXPECT_EQ(TestMapUnmapCallback::map_count, 0); @@ -1321,8 +1333,10 @@ m.TestOnlyUnmap(); } - -typedef TwoLevelByteMap<1 << 12, 1 << 13, TestMapUnmapCallback> TestByteMap; +template +using TestByteMapT = + TwoLevelByteMap<1 << 12, 1 << 13, AddressSpaceView, TestMapUnmapCallback>; +using TestByteMap = TestByteMapT; struct TestByteMapParam { TestByteMap *m; Index: lib/sanitizer_common/tests/sanitizer_type_traits_test.cc =================================================================== --- /dev/null +++ lib/sanitizer_common/tests/sanitizer_type_traits_test.cc @@ -0,0 +1,28 @@ +//===-- sanitizer_type_traits_test.cc -------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of ThreadSanitizer/AddressSanitizer runtime. +// +//===----------------------------------------------------------------------===// +#include "sanitizer_common/sanitizer_type_traits.h" +#include "gtest/gtest.h" +#include "sanitizer_common/sanitizer_internal_defs.h" + +using namespace __sanitizer; + +TEST(SanitizerCommon, IsSame) { + ASSERT_TRUE((is_same::value)); + ASSERT_TRUE((is_same::value)); + ASSERT_TRUE((is_same::value)); + ASSERT_TRUE((is_same::value)); + + ASSERT_FALSE((is_same::value)); + ASSERT_FALSE((is_same::value)); + ASSERT_FALSE((is_same::value)); +} Index: lib/scudo/scudo_allocator.h =================================================================== --- lib/scudo/scudo_allocator.h +++ lib/scudo/scudo_allocator.h @@ -86,23 +86,26 @@ #else static const uptr NumRegions = SANITIZER_MMAP_RANGE_SIZE >> RegionSizeLog; # if SANITIZER_WORDSIZE == 32 -typedef FlatByteMap ByteMap; +template +using ByteMap = FlatByteMap; # elif SANITIZER_WORDSIZE == 64 -typedef TwoLevelByteMap<(NumRegions >> 12), 1 << 12> ByteMap; +template +using ByteMap = TwoLevelByteMap<(NumRegions >> 12), 1 << 12, AddressSpaceView>; # endif // SANITIZER_WORDSIZE -struct AP32 { +template struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = 0; typedef __scudo::SizeClassMap SizeClassMap; static const uptr kRegionSizeLog = RegionSizeLog; - typedef __scudo::ByteMap ByteMap; + using AddressSpaceView = AddressSpaceViewTy; + using ByteMap = __scudo::ByteMap; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = SizeClassAllocator32FlagMasks::kRandomShuffleChunks | SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch; }; -typedef SizeClassAllocator32 PrimaryT; +typedef SizeClassAllocator32> PrimaryT; #endif // SANITIZER_CAN_USE_ALLOCATOR64 #include "scudo_allocator_secondary.h" Index: lib/tsan/rtl/tsan_rtl.h =================================================================== --- lib/tsan/rtl/tsan_rtl.h +++ lib/tsan/rtl/tsan_rtl.h @@ -59,19 +59,24 @@ static const uptr kAllocatorRegionSizeLog = 20; static const uptr kAllocatorNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kAllocatorRegionSizeLog; -typedef TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12, - MapUnmapCallback> ByteMap; +template +using ByteMap = TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12, + AddressSpaceView, MapUnmapCallback>; +template 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 = AddressSpaceViewTy; + using ByteMap = __tsan::ByteMap; typedef __tsan::MapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32 PrimaryAllocator; +template +using PrimaryAllocatorT = SizeClassAllocator32>; +using PrimaryAllocator = PrimaryAllocatorT; #else struct AP64 { // Allocator64 parameters. Deliberately using a short name. static const uptr kSpaceBeg = Mapping::kHeapMemBeg;