diff options
| author | Kostya Serebryany <kcc@google.com> | 2012-07-06 14:32:00 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2012-07-06 14:32:00 +0000 |
| commit | 739b0de5b1d4ca773de8c975e6392a0889adf3a2 (patch) | |
| tree | 16f425a257a2600ef2045f5a0af72f37e33ab941 | |
| parent | 740d166c3e3ccfba8d9ae5cefc4a9a8541c109f2 (diff) | |
| download | bcm5719-llvm-739b0de5b1d4ca773de8c975e6392a0889adf3a2.tar.gz bcm5719-llvm-739b0de5b1d4ca773de8c975e6392a0889adf3a2.zip | |
[tsan] start using AllocatorCache in CombinedAllocator
llvm-svn: 159825
4 files changed, 33 insertions, 14 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator64.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator64.h index 679e07dfa63..966c128e4ec 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator64.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator64.h @@ -152,6 +152,8 @@ class SizeClassAllocator64 { return (reinterpret_cast<uptr>(p) / kRegionSize) % kNumClasses; } + uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); } + void *GetMetaData(void *p) { uptr class_id = GetSizeClass(p); uptr chunk_idx = GetChunkIdx(reinterpret_cast<uptr>(p), class_id); @@ -384,8 +386,10 @@ class LargeMmapAllocator { // internal allocators: // PrimaryAllocator is efficient, but may not allocate some sizes (alignments). // When allocating 2^x bytes it should return 2^x aligned chunk. +// PrimaryAllocator is used via a local AllocatorCache. // SecondaryAllocator can allocate anything, but is not efficient. -template <class PrimaryAllocator, class SecondaryAllocator> +template <class PrimaryAllocator, class AllocatorCache, + class SecondaryAllocator> class CombinedAllocator { public: void Init() { @@ -393,13 +397,13 @@ class CombinedAllocator { secondary_.Init(); } - void *Allocate(uptr size, uptr alignment) { + void *Allocate(AllocatorCache *cache, uptr size, uptr alignment) { CHECK_GT(size, 0); if (alignment > 8) size = RoundUpTo(size, alignment); void *res; if (primary_.CanAllocate(size, alignment)) - res = primary_.Allocate(size, alignment); + res = cache->Allocate(&primary_, primary_.ClassID(size)); else res = secondary_.Allocate(size, alignment); if (alignment > 8) @@ -407,9 +411,9 @@ class CombinedAllocator { return res; } - void Deallocate(void *p) { + void Deallocate(AllocatorCache *cache, void *p) { if (primary_.PointerIsMine(p)) - primary_.Deallocate(p); + cache->Deallocate(&primary_, primary_.GetSizeClass(p), p); else secondary_.Deallocate(p); } @@ -432,6 +436,10 @@ class CombinedAllocator { void TestOnlyUnmap() { primary_.TestOnlyUnmap(); } + void SwallowCache(AllocatorCache *cache) { + cache->Drain(&primary_); + } + private: PrimaryAllocator primary_; SecondaryAllocator secondary_; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_list.h b/compiler-rt/lib/sanitizer_common/sanitizer_list.h index 4c7ce685317..ef98eee1231 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_list.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_list.h @@ -74,8 +74,8 @@ struct IntrusiveList { CHECK_NE(this, l); if (empty()) { *this = *l; - } else { - l->last_ = first_; + } else if (!l->empty()) { + l->last_->next = first_; first_ = l->first_; size_ += l->size(); } diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc index 62b4329b08b..cbb71dbe037 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc @@ -20,6 +20,8 @@ static const uptr kAllocatorSize = 0x10000000000; // 1T. typedef DefaultSizeClassMap SCMap; typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 16, SCMap> Allocator; +typedef SizeClassAllocatorLocalCache<Allocator::kNumClasses, Allocator> + AllocatorCache; TEST(SanitizerCommon, DefaultSizeClassMap) { #if 0 @@ -182,10 +184,13 @@ TEST(SanitizerCommon, LargeMmapAllocator) { TEST(SanitizerCommon, CombinedAllocator) { typedef Allocator PrimaryAllocator; typedef LargeMmapAllocator SecondaryAllocator; - typedef CombinedAllocator<PrimaryAllocator, SecondaryAllocator> Allocator; + typedef CombinedAllocator<PrimaryAllocator, AllocatorCache, + SecondaryAllocator> Allocator; + AllocatorCache cache; Allocator a; a.Init(); + cache.Init(); const uptr kNumAllocs = 100000; const uptr kNumIter = 10; for (uptr iter = 0; iter < kNumIter; iter++) { @@ -194,7 +199,7 @@ TEST(SanitizerCommon, CombinedAllocator) { uptr size = (i % (1 << 14)) + 1; if ((i % 1024) == 0) size = 1 << (10 + (i % 14)); - void *x = a.Allocate(size, 1); + void *x = a.Allocate(&cache, size, 1); uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x)); CHECK_EQ(*meta, 0); *meta = size; @@ -209,15 +214,14 @@ TEST(SanitizerCommon, CombinedAllocator) { CHECK_NE(*meta, 0); CHECK(a.PointerIsMine(x)); *meta = 0; - a.Deallocate(x); + a.Deallocate(&cache, x); } allocated.clear(); + a.SwallowCache(&cache); } a.TestOnlyUnmap(); } -typedef SizeClassAllocatorLocalCache<Allocator::kNumClasses, Allocator> - AllocatorCache; static THREADLOCAL AllocatorCache static_allocator_cache; TEST(SanitizerCommon, SizeClassAllocatorLocalCache) { diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_list_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_list_test.cc index c2ca7e8ef77..d328fbfdf92 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_list_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_list_test.cc @@ -24,9 +24,10 @@ typedef IntrusiveList<ListItem> List; // Check that IntrusiveList can be made thread-local. static THREADLOCAL List static_list; -static void SetList(List *l, ListItem *x, ListItem *y = 0, ListItem *z = 0) { +static void SetList(List *l, ListItem *x = 0, + ListItem *y = 0, ListItem *z = 0) { l->clear(); - l->push_back(x); + if (x) l->push_back(x); if (y) l->push_back(y); if (z) l->push_back(z); } @@ -145,6 +146,12 @@ TEST(SanitizerCommon, IntrusiveList) { l1.append_back(&l2); CheckList(&l1, x, y, z, a, b, c); CHECK(l2.empty()); + + SetList(&l1, x, y); + SetList(&l2); + l1.append_front(&l2); + CheckList(&l1, x, y); + CHECK(l2.empty()); } } // namespace __sanitizer |

