diff options
author | Kostya Kortchinsky <kostyak@google.com> | 2018-02-12 16:59:17 +0000 |
---|---|---|
committer | Kostya Kortchinsky <kostyak@google.com> | 2018-02-12 16:59:17 +0000 |
commit | 5603ad4d9ba1b0c030ac7dd72306b7dbaf256f1b (patch) | |
tree | 3bd2795dddc7a8a60ddb0dc5acb0a468fbf8900c /lib/sanitizer_common/sanitizer_allocator_primary32.h | |
parent | 2d44375c5ff703160001a171c16b1105764a425e (diff) | |
download | compiler-rt-5603ad4d9ba1b0c030ac7dd72306b7dbaf256f1b.tar.gz |
[sanitizer] Size class map & local cache improvements
Summary:
- Reland rL324263, this time allowing for a compile-time decision as to whether
or not use the 32-bit division. A single test is using a class map covering
a maximum size greater than 4GB, this can be checked via the template
parameters, and allows SizeClassAllocator64PopulateFreeListOOM to pass;
- `MaxCachedHint` is always called on a class id for which we have already
computed the size, but we still recompute `Size(class_id)`. Change the
prototype of the function to work on sizes instead of class ids. This also
allows us to get rid of the `kBatchClassID` special case. Update the callers
accordingly;
- `InitCache` and `Drain` will start iterating at index 1: index 0 contents are
unused and can safely be left to be 0. Plus we do not pay the cost of going
through an `UNLIKELY` in `MaxCachedHint`, and touching memory that is
otherwise not used;
- `const` some variables in the areas modified;
- Remove an spurious extra line at the end of a file.
Reviewers: alekseyshl, tl0gic, dberris
Reviewed By: alekseyshl, dberris
Subscribers: dberris, kubamracek, delcypher, llvm-commits, #sanitizers
Differential Revision: https://reviews.llvm.org/D43088
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@324906 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_allocator_primary32.h')
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator_primary32.h | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/lib/sanitizer_common/sanitizer_allocator_primary32.h b/lib/sanitizer_common/sanitizer_allocator_primary32.h index 6c682aff6..4e87bd7fe 100644 --- a/lib/sanitizer_common/sanitizer_allocator_primary32.h +++ b/lib/sanitizer_common/sanitizer_allocator_primary32.h @@ -84,8 +84,8 @@ class SizeClassAllocator32 { static uptr AllocationSizeRequiredForNElements(uptr n) { return sizeof(uptr) * 2 + sizeof(void *) * n; } - static uptr MaxCached(uptr class_id) { - return Min(kMaxNumCached, SizeClassMap::MaxCachedHint(class_id)); + static uptr MaxCached(uptr size) { + return Min(kMaxNumCached, SizeClassMap::MaxCachedHint(size)); } TransferBatch *next; @@ -156,10 +156,11 @@ class SizeClassAllocator32 { CHECK_LT(class_id, kNumClasses); SizeClassInfo *sci = GetSizeClassInfo(class_id); SpinMutexLock l(&sci->mutex); - if (sci->free_list.empty() && - UNLIKELY(!PopulateFreeList(stat, c, sci, class_id))) - return nullptr; - CHECK(!sci->free_list.empty()); + if (sci->free_list.empty()) { + if (UNLIKELY(!PopulateFreeList(stat, c, sci, class_id))) + return nullptr; + DCHECK(!sci->free_list.empty()); + } TransferBatch *b = sci->free_list.front(); sci->free_list.pop_front(); return b; @@ -275,7 +276,7 @@ class SizeClassAllocator32 { COMPILER_CHECK(sizeof(SizeClassInfo) == kCacheLineSize); uptr ComputeRegionId(uptr mem) { - uptr res = mem >> kRegionSizeLog; + const uptr res = mem >> kRegionSizeLog; CHECK_LT(res, kNumPossibleRegions); return res; } @@ -329,22 +330,22 @@ class SizeClassAllocator32 { bool PopulateFreeList(AllocatorStats *stat, AllocatorCache *c, SizeClassInfo *sci, uptr class_id) { - uptr size = ClassIdToSize(class_id); - uptr reg = AllocateRegion(stat, class_id); - if (UNLIKELY(!reg)) + const uptr region = AllocateRegion(stat, class_id); + if (UNLIKELY(!region)) return false; if (kRandomShuffleChunks) if (UNLIKELY(sci->rand_state == 0)) // The random state is initialized from ASLR (PIE) and time. sci->rand_state = reinterpret_cast<uptr>(sci) ^ NanoTime(); - uptr n_chunks = kRegionSize / (size + kMetadataSize); - uptr max_count = TransferBatch::MaxCached(class_id); - CHECK_GT(max_count, 0); + const uptr size = ClassIdToSize(class_id); + const uptr n_chunks = kRegionSize / (size + kMetadataSize); + const uptr max_count = TransferBatch::MaxCached(size); + DCHECK_GT(max_count, 0); TransferBatch *b = nullptr; - const uptr kShuffleArraySize = 48; + constexpr uptr kShuffleArraySize = 48; uptr shuffle_array[kShuffleArraySize]; uptr count = 0; - for (uptr i = reg; i < reg + n_chunks * size; i += size) { + for (uptr i = region; i < region + n_chunks * size; i += size) { shuffle_array[count++] = i; if (count == kShuffleArraySize) { if (UNLIKELY(!PopulateBatches(c, sci, class_id, &b, max_count, |