[llvm-commits] [compiler-rt] r172521 - /compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
Kostya Serebryany
kcc at google.com
Tue Jan 15 02:37:59 PST 2013
This triggers an assert:
==12750== AddressSanitizer CHECK failed:
compiler-rt/lib/asan/asan_allocator2.cc:82 "((sizeof(AllocatorCache))) <=
((sizeof(ms->allocator2_cache)))" (0x61610, 0x2000)
--kcc
On Tue, Jan 15, 2013 at 1:02 PM, Dmitry Vyukov <dvyukov at google.com> wrote:
> Author: dvyukov
> Date: Tue Jan 15 03:02:20 2013
> New Revision: 172521
>
> URL: http://llvm.org/viewvc/llvm-project?rev=172521&view=rev
> Log:
> asan: faster thead-local cache for memory allocator
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h?rev=172521&r1=172520&r2=172521&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h Tue Jan
> 15 03:02:20 2013
> @@ -65,7 +65,7 @@
> // c32 => s: 512 diff: +32 06% l 9 cached: 64 32768; id 32
>
>
> -template <uptr kMaxSizeLog, uptr kMaxNumCached, uptr kMaxBytesCachedLog,
> +template <uptr kMaxSizeLog, uptr kMaxNumCachedT, uptr kMaxBytesCachedLog,
> uptr kMinBatchClassT>
> class SizeClassMap {
> static const uptr kMinSizeLog = 3;
> @@ -77,6 +77,7 @@
> static const uptr M = (1 << S) - 1;
>
> public:
> + static const uptr kMaxNumCached = kMaxNumCachedT;
> struct TransferBatch {
> TransferBatch *next;
> uptr count;
> @@ -598,6 +599,7 @@
> uptr size = SizeClassMap::Size(class_id);
> uptr reg = AllocateRegion(class_id);
> uptr n_chunks = kRegionSize / (size + kMetadataSize);
> + uptr max_count = SizeClassMap::MaxCached(class_id);
> Batch *b = 0;
> for (uptr i = reg; i < reg + n_chunks * size; i += size) {
> if (b == 0) {
> @@ -608,7 +610,7 @@
> b->count = 0;
> }
> b->batch[b->count++] = (void*)i;
> - if (b->count == SizeClassMap::MaxCached(class_id)) {
> + if (b->count == max_count) {
> sci->free_list.push_back(b);
> b = 0;
> }
> @@ -631,6 +633,7 @@
> struct SizeClassAllocatorLocalCache {
> typedef SizeClassAllocator Allocator;
> static const uptr kNumClasses = SizeClassAllocator::kNumClasses;
> +
> // Don't need to call Init if the object is a global (i.e.
> zero-initialized).
> void Init() {
> internal_memset(this, 0, sizeof(*this));
> @@ -640,18 +643,10 @@
> CHECK_NE(class_id, 0UL);
> CHECK_LT(class_id, kNumClasses);
> PerClass *c = &per_class_[class_id];
> - if (c->cur == 0) {
> - DCHECK_EQ(c->old, 0);
> - c->cur = allocator->AllocateBatch(this, class_id);
> - }
> - DCHECK_GT(c->cur->count, 0);
> - void *res = c->cur->batch[--c->cur->count];
> - if (c->cur->count == 0) {
> - if (class_id < SizeClassMap::kMinBatchClass)
> - Deallocate(allocator, SizeClassMap::ClassID(sizeof(Batch)),
> c->cur);
> - c->cur = c->old;
> - c->old = 0;
> - }
> + if (UNLIKELY(c->count == 0))
> + Refill(allocator, class_id);
> + void *res = c->batch[--c->count];
> + PREFETCH(c->batch[c->count - 1]);
> return res;
> }
>
> @@ -659,31 +654,16 @@
> CHECK_NE(class_id, 0UL);
> CHECK_LT(class_id, kNumClasses);
> PerClass *c = &per_class_[class_id];
> - if (c->cur == 0 || c->cur->count ==
> SizeClassMap::MaxCached(class_id)) {
> - if (c->old)
> - allocator->DeallocateBatch(class_id, c->old);
> - c->old = c->cur;
> - if (class_id < SizeClassMap::kMinBatchClass)
> - c->cur = (Batch*)Allocate(allocator,
> - SizeClassMap::ClassID(sizeof(Batch)));
> - else
> - c->cur = (Batch*)p;
> - c->cur->count = 0;
> - }
> - c->cur->batch[c->cur->count++] = p;
> + if (UNLIKELY(c->count == c->max_count))
> + Drain(allocator, class_id);
> + c->batch[c->count++] = p;
> }
>
> void Drain(SizeClassAllocator *allocator) {
> - for (uptr i = 0; i < kNumClasses; i++) {
> - PerClass *c = &per_class_[i];
> - if (c->cur) {
> - allocator->DeallocateBatch(i, c->cur);
> - c->cur = 0;
> - }
> - if (c->old) {
> - allocator->DeallocateBatch(i, c->old);
> - c->old = 0;
> - }
> + for (uptr class_id = 0; class_id < kNumClasses; class_id++) {
> + PerClass *c = &per_class_[class_id];
> + while (c->count > 0)
> + Drain(allocator, class_id);
> }
> }
>
> @@ -691,10 +671,49 @@
> typedef typename SizeClassAllocator::SizeClassMapT SizeClassMap;
> typedef typename SizeClassMap::TransferBatch Batch;
> struct PerClass {
> - Batch *cur;
> - Batch *old;
> + uptr count;
> + uptr max_count;
> + void *batch[2 * SizeClassMap::kMaxNumCached];
> };
> PerClass per_class_[kNumClasses];
> +
> + void InitCache() {
> + if (per_class_[0].max_count)
> + return;
> + for (uptr i = 0; i < kNumClasses; i++) {
> + PerClass *c = &per_class_[i];
> + c->max_count = 2 * SizeClassMap::MaxCached(i);
> + }
> + }
> +
> + void NOINLINE Refill(SizeClassAllocator *allocator, uptr class_id) {
> + InitCache();
> + PerClass *c = &per_class_[class_id];
> + Batch *b = allocator->AllocateBatch(this, class_id);
> + for (uptr i = 0; i < b->count; i++)
> + c->batch[i] = b->batch[i];
> + c->count = b->count;
> + if (class_id < SizeClassMap::kMinBatchClass)
> + Deallocate(allocator, SizeClassMap::ClassID(sizeof(Batch)), b);
> + }
> +
> + void NOINLINE Drain(SizeClassAllocator *allocator, uptr class_id) {
> + InitCache();
> + PerClass *c = &per_class_[class_id];
> + Batch *b;
> + if (class_id < SizeClassMap::kMinBatchClass)
> + b = (Batch*)Allocate(allocator,
> SizeClassMap::ClassID(sizeof(Batch)));
> + else
> + b = (Batch*)c->batch[0];
> + uptr cnt = Min(c->max_count / 2, c->count);
> + for (uptr i = 0; i < cnt; i++) {
> + b->batch[i] = c->batch[i];
> + c->batch[i] = c->batch[i + c->max_count / 2];
> + }
> + b->count = cnt;
> + c->count -= cnt;
> + allocator->DeallocateBatch(class_id, b);
> + }
> };
>
> // This class can (de)allocate only large chunks of memory using
> mmap/unmap.
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130115/c8133dc6/attachment.html>
More information about the llvm-commits
mailing list