[sanitizer] Align & pad the allocator structures to the cacheline size v2

Summary:
This is a new version of D44261, which broke some builds with older gcc, as
they can't align on a constexpr, but rather require an integer (see
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859) among others.

We introduce `SANITIZER_CACHE_LINE_SIZE` in `sanitizer_platform.h` to be
used in `ALIGNED` attributes instead of using directly `kCacheLineSize`.

Reviewers: alekseyshl, thakis

Reviewed By: alekseyshl

Subscribers: kubamracek, delcypher, #sanitizers, llvm-commits

Differential Revision: https://reviews.llvm.org/D44326

llvm-svn: 327297
This commit is contained in:
Kostya Kortchinsky 2018-03-12 17:18:26 +00:00
parent deface9c73
commit 85ecac5f3f
4 changed files with 18 additions and 15 deletions

View File

@ -266,14 +266,12 @@ class SizeClassAllocator32 {
static const uptr kRegionSize = 1 << kRegionSizeLog; static const uptr kRegionSize = 1 << kRegionSizeLog;
static const uptr kNumPossibleRegions = kSpaceSize / kRegionSize; static const uptr kNumPossibleRegions = kSpaceSize / kRegionSize;
struct SizeClassInfo { struct ALIGNED(SANITIZER_CACHE_LINE_SIZE) SizeClassInfo {
SpinMutex mutex; SpinMutex mutex;
IntrusiveList<TransferBatch> free_list; IntrusiveList<TransferBatch> free_list;
u32 rand_state; u32 rand_state;
char padding[kCacheLineSize - 2 * sizeof(uptr) -
sizeof(IntrusiveList<TransferBatch>)];
}; };
COMPILER_CHECK(sizeof(SizeClassInfo) == kCacheLineSize); COMPILER_CHECK(sizeof(SizeClassInfo) % kCacheLineSize == 0);
uptr ComputeRegionId(uptr mem) { uptr ComputeRegionId(uptr mem) {
const uptr res = mem >> kRegionSizeLog; const uptr res = mem >> kRegionSizeLog;
@ -299,7 +297,7 @@ class SizeClassAllocator32 {
} }
SizeClassInfo *GetSizeClassInfo(uptr class_id) { SizeClassInfo *GetSizeClassInfo(uptr class_id) {
CHECK_LT(class_id, kNumClasses); DCHECK_LT(class_id, kNumClasses);
return &size_class_info_array[class_id]; return &size_class_info_array[class_id];
} }

View File

@ -80,6 +80,8 @@ class SizeClassAllocator64 {
} }
SetReleaseToOSIntervalMs(release_to_os_interval_ms); SetReleaseToOSIntervalMs(release_to_os_interval_ms);
MapWithCallbackOrDie(SpaceEnd(), AdditionalSize()); MapWithCallbackOrDie(SpaceEnd(), AdditionalSize());
// Check that the RegionInfo array is aligned on the CacheLine size.
DCHECK_EQ(SpaceEnd() % kCacheLineSize, 0);
} }
s32 ReleaseToOSIntervalMs() const { s32 ReleaseToOSIntervalMs() const {
@ -584,7 +586,7 @@ class SizeClassAllocator64 {
u64 last_released_bytes; u64 last_released_bytes;
}; };
struct RegionInfo { struct ALIGNED(SANITIZER_CACHE_LINE_SIZE) RegionInfo {
BlockingMutex mutex; BlockingMutex mutex;
uptr num_freed_chunks; // Number of elements in the freearray. uptr num_freed_chunks; // Number of elements in the freearray.
uptr mapped_free_array; // Bytes mapped for freearray. uptr mapped_free_array; // Bytes mapped for freearray.
@ -597,12 +599,11 @@ class SizeClassAllocator64 {
Stats stats; Stats stats;
ReleaseToOsInfo rtoi; ReleaseToOsInfo rtoi;
}; };
COMPILER_CHECK(sizeof(RegionInfo) >= kCacheLineSize); COMPILER_CHECK(sizeof(RegionInfo) % kCacheLineSize == 0);
RegionInfo *GetRegionInfo(uptr class_id) const { RegionInfo *GetRegionInfo(uptr class_id) const {
CHECK_LT(class_id, kNumClasses); DCHECK_LT(class_id, kNumClasses);
RegionInfo *regions = RegionInfo *regions = reinterpret_cast<RegionInfo *>(SpaceEnd());
reinterpret_cast<RegionInfo *>(SpaceBeg() + kSpaceSize);
return &regions[class_id]; return &regions[class_id];
} }

View File

@ -39,11 +39,7 @@ struct StackTrace;
const uptr kWordSize = SANITIZER_WORDSIZE / 8; const uptr kWordSize = SANITIZER_WORDSIZE / 8;
const uptr kWordSizeInBits = 8 * kWordSize; const uptr kWordSizeInBits = 8 * kWordSize;
#if defined(__powerpc__) || defined(__powerpc64__) const uptr kCacheLineSize = SANITIZER_CACHE_LINE_SIZE;
const uptr kCacheLineSize = 128;
#else
const uptr kCacheLineSize = 64;
#endif
const uptr kMaxPathLength = 4096; const uptr kMaxPathLength = 4096;

View File

@ -309,4 +309,12 @@
# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED # define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
#endif #endif
// Older gcc have issues aligning to a constexpr, and require an integer.
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others.
#if defined(__powerpc__) || defined(__powerpc64__)
# define SANITIZER_CACHE_LINE_SIZE 128
#else
# define SANITIZER_CACHE_LINE_SIZE 64
#endif
#endif // SANITIZER_PLATFORM_H #endif // SANITIZER_PLATFORM_H