sanitizer_allocator_test.cc revision 784935d1bbc301eaf92fd9f7d3a551eb65edcd15
1225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov//===-- sanitizer_allocator_test.cc ---------------------------------------===// 2225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov// 3225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov// The LLVM Compiler Infrastructure 4225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov// 5225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov// This file is distributed under the University of Illinois Open Source 6225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov// License. See LICENSE.TXT for details. 7225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov// 8225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov//===----------------------------------------------------------------------===// 9225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov// 10a3eca8192505f4796194dd24eb051019f402de99Dmitry Vyukov// This file is a part of ThreadSanitizer/AddressSanitizer runtime. 1172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany// Tests for sanitizer_allocator.h. 12225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov// 13225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov//===----------------------------------------------------------------------===// 1472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#include "sanitizer_common/sanitizer_allocator.h" 15225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov#include "sanitizer_common/sanitizer_common.h" 1672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 17225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov#include "gtest/gtest.h" 1872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 19225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov#include <stdlib.h> 2072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#include <algorithm> 2172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#include <vector> 2272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 2372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 2472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanystatic const uptr kAllocatorSpace = 0x700000000000ULL; 2572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanystatic const uptr kAllocatorSize = 0x010000000000ULL; // 1T. 2645595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryanystatic const u64 kAddressSpaceSize = 1ULL << 47; 2772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 2872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytypedef SizeClassAllocator64< 2972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany kAllocatorSpace, kAllocatorSize, 16, DefaultSizeClassMap> Allocator64; 3072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 3172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytypedef SizeClassAllocator64< 3272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany kAllocatorSpace, kAllocatorSize, 16, CompactSizeClassMap> Allocator64Compact; 3345595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany#else 3445595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryanystatic const u64 kAddressSpaceSize = 1ULL << 32; 3572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 3672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 3745595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryanytypedef SizeClassAllocator32< 3845595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany 0, kAddressSpaceSize, 16, CompactSizeClassMap> Allocator32Compact; 3945595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany 4072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate <class SizeClassMap> 4172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid TestSizeClassMap() { 4272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany typedef SizeClassMap SCMap; 4372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if 0 4472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < SCMap::kNumClasses; i++) { 4572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany printf("c%ld => %ld (%lx) cached=%ld(%ld)\n", 4672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany i, SCMap::Size(i), SCMap::Size(i), SCMap::MaxCached(i) * SCMap::Size(i), 4772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany SCMap::MaxCached(i)); 4872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 4972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 5072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr c = 0; c < SCMap::kNumClasses; c++) { 5172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr s = SCMap::Size(c); 5272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(SCMap::ClassID(s), c); 5372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (c != SCMap::kNumClasses - 1) 5472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(SCMap::ClassID(s + 1), c + 1); 5572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(SCMap::ClassID(s - 1), c); 5672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (c) 5772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GT(SCMap::Size(c), SCMap::Size(c-1)); 5872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 5972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(SCMap::ClassID(SCMap::kMaxSize + 1), 0); 6072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 6172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr s = 1; s <= SCMap::kMaxSize; s++) { 6272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr c = SCMap::ClassID(s); 6372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_LT(c, SCMap::kNumClasses); 6472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GE(SCMap::Size(c), s); 6572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (c > 0) 6672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_LT(SCMap::Size(c-1), s); 6772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 6872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 6972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 7072166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, DefaultSizeClassMap) { 7172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassMap<DefaultSizeClassMap>(); 7272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 7372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 7472166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, CompactSizeClassMap) { 7572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassMap<CompactSizeClassMap>(); 7672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 7772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 7872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate <class Allocator> 7972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid TestSizeClassAllocator() { 8045595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany Allocator *a = new Allocator; 8145595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany a->Init(); 8272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 8372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static const uptr sizes[] = {1, 16, 30, 40, 100, 1000, 10000, 8472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 50000, 60000, 100000, 300000, 500000, 1000000, 2000000}; 8572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 8672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany std::vector<void *> allocated; 8772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 8872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr last_total_allocated = 0; 8972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < 5; i++) { 9072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Allocate a bunch of chunks. 9145595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany for (uptr s = 0; s < ARRAY_SIZE(sizes); s++) { 9272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr size = sizes[s]; 9345595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany if (!a->CanAllocate(size, 1)) continue; 9472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // printf("s = %ld\n", size); 9572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr n_iter = std::max((uptr)2, 1000000 / size); 9672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < n_iter; i++) { 9745595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany void *x = a->Allocate(size, 1); 9872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated.push_back(x); 9945595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany CHECK(a->PointerIsMine(x)); 10045595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany CHECK_GE(a->GetActuallyAllocatedSize(x), size); 10145595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany uptr class_id = a->GetSizeClass(x); 10272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(class_id, Allocator::SizeClassMapT::ClassID(size)); 10345595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany uptr *metadata = reinterpret_cast<uptr*>(a->GetMetaData(x)); 10472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany metadata[0] = reinterpret_cast<uptr>(x) + 1; 10572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany metadata[1] = 0xABCD; 10672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 10772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 10872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Deallocate all. 10972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < allocated.size(); i++) { 11072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *x = allocated[i]; 11145595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany uptr *metadata = reinterpret_cast<uptr*>(a->GetMetaData(x)); 11272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(metadata[0], reinterpret_cast<uptr>(x) + 1); 11372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(metadata[1], 0xABCD); 11445595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany a->Deallocate(x); 11572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 11672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated.clear(); 11745595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany uptr total_allocated = a->TotalMemoryUsed(); 11872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (last_total_allocated == 0) 11972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany last_total_allocated = total_allocated; 12072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(last_total_allocated, total_allocated); 12172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 12272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 12345595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany a->TestOnlyUnmap(); 12445595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany delete a; 12572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 12672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 12772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 12872166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64) { 12972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassAllocator<Allocator64>(); 13072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 13172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 13272166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64Compact) { 13372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassAllocator<Allocator64Compact>(); 13472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 13572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 13672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 13745595ba6b77b54b8212389cba6b95dc634122145Kostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator32Compact) { 13845595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany TestSizeClassAllocator<Allocator32Compact>(); 13945595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany} 14045595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany 14172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate <class Allocator> 142784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryanyvoid SizeClassAllocatorMetadataStress() { 143784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany Allocator *a = new Allocator; 144784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany a->Init(); 14572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static volatile void *sink; 14672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 14772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr kNumAllocs = 10000; 14872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *allocated[kNumAllocs]; 14972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 15072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr size = (i % 4096) + 1; 151784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany void *x = a->Allocate(size, 1); 15272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = x; 15372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 15472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Get Metadata kNumAllocs^2 times. 15572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs * kNumAllocs; i++) { 156784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany sink = a->GetMetaData(allocated[i % kNumAllocs]); 15772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 15872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 159784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany a->Deallocate(allocated[i]); 16072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 16172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 162784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany a->TestOnlyUnmap(); 16372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany (void)sink; 164784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany delete a; 16572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 16672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 16772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 16872166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64MetadataStress) { 169784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany SizeClassAllocatorMetadataStress<Allocator64>(); 17072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 171225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov 17272166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64CompactMetadataStress) { 173784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany SizeClassAllocatorMetadataStress<Allocator64Compact>(); 17472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 17572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 176784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator32CompactMetadataStress) { 177784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany SizeClassAllocatorMetadataStress<Allocator32Compact>(); 178784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany} 17972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 18072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate<class Allocator> 18172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid FailInAssertionOnOOM() { 18272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany Allocator a; 18372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Init(); 18472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr size = 1 << 20; 18572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < 1000000; i++) { 18672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Allocate(size, 1); 18772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 18872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 18972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.TestOnlyUnmap(); 19072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 19172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 19272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 19372166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64Overflow) { 19472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany EXPECT_DEATH(FailInAssertionOnOOM<Allocator64>(), "Out of memory"); 19572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 19672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 19772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 19872166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, LargeMmapAllocator) { 19972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany LargeMmapAllocator a; 20072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Init(); 20172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 20272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static const int kNumAllocs = 100; 20372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *allocated[kNumAllocs]; 20472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static const uptr size = 1000; 20572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Allocate some. 20672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 20772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = a.Allocate(size, 1); 20872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 20972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Deallocate all. 21072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs); 21172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 21272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *p = allocated[i]; 21372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK(a.PointerIsMine(p)); 21472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Deallocate(p); 21572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 21672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Check that non left. 21772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(a.TotalMemoryUsed(), 0); 21872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 21972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Allocate some more, also add metadata. 22072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 22172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *x = a.Allocate(size, 1); 22272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GE(a.GetActuallyAllocatedSize(x), size); 22372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x)); 22472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany *meta = i; 22572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = x; 22672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 22772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs); 22872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Deallocate all in reverse order. 22972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 23072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany int idx = kNumAllocs - i - 1; 23172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *p = allocated[idx]; 23272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(p)); 23372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(*meta, idx); 23472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK(a.PointerIsMine(p)); 23572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Deallocate(p); 23672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 23772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(a.TotalMemoryUsed(), 0); 23872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr max_alignment = SANITIZER_WORDSIZE == 64 ? (1 << 28) : (1 << 24); 23972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr alignment = 8; alignment <= max_alignment; alignment *= 2) { 24072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 24172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr size = ((i % 10) + 1) * 4096; 24272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = a.Allocate(size, alignment); 24372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(0, (uptr)allocated[i] % alignment); 24472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany char *p = (char*)allocated[i]; 24572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany p[0] = p[size - 1] = 0; 24672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 24772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 24872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Deallocate(allocated[i]); 24972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 25072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 25172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 25272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 25372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate 25472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany<class PrimaryAllocator, class SecondaryAllocator, class AllocatorCache> 25572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid TestCombinedAllocator() { 25672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CombinedAllocator<PrimaryAllocator, AllocatorCache, SecondaryAllocator> a; 25772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Init(); 25872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 25972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany AllocatorCache cache; 26072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany cache.Init(); 26172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 26272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany EXPECT_EQ(a.Allocate(&cache, -1, 1), (void*)0); 26372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany EXPECT_EQ(a.Allocate(&cache, -1, 1024), (void*)0); 26472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany EXPECT_EQ(a.Allocate(&cache, (uptr)-1 - 1024, 1), (void*)0); 26572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany EXPECT_EQ(a.Allocate(&cache, (uptr)-1 - 1024, 1024), (void*)0); 26672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany EXPECT_EQ(a.Allocate(&cache, (uptr)-1 - 1023, 1024), (void*)0); 26772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 26872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr kNumAllocs = 100000; 26972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr kNumIter = 10; 27072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr iter = 0; iter < kNumIter; iter++) { 27172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany std::vector<void*> allocated; 27272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 27372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr size = (i % (1 << 14)) + 1; 27472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if ((i % 1024) == 0) 27572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany size = 1 << (10 + (i % 14)); 27672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *x = a.Allocate(&cache, size, 1); 27772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x)); 27872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(*meta, 0); 27972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany *meta = size; 28072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated.push_back(x); 28172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 28272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 28372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany random_shuffle(allocated.begin(), allocated.end()); 28472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 28572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 28672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *x = allocated[i]; 28772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x)); 28872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_NE(*meta, 0); 28972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK(a.PointerIsMine(x)); 29072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany *meta = 0; 29172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Deallocate(&cache, x); 29272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 29372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated.clear(); 29472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.SwallowCache(&cache); 29572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 29672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.TestOnlyUnmap(); 29772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 29872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 29972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 30072166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, CombinedAllocator) { 30172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestCombinedAllocator<Allocator64, 30272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany LargeMmapAllocator, 30372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany SizeClassAllocatorLocalCache<Allocator64> > (); 30472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 30572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 30672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 30772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate <class AllocatorCache> 30872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid TestSizeClassAllocatorLocalCache() { 30972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static THREADLOCAL AllocatorCache static_allocator_cache; 31072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static_allocator_cache.Init(); 31172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany AllocatorCache cache; 31272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany typename AllocatorCache::Allocator a; 31372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 31472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Init(); 31572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany cache.Init(); 31672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 31772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr kNumAllocs = 10000; 31872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const int kNumIter = 100; 31972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr saved_total = 0; 32072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumIter; i++) { 32172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *allocated[kNumAllocs]; 32272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 32372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = cache.Allocate(&a, 0); 32472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 32572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 32672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany cache.Deallocate(&a, 0, allocated[i]); 32772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 32872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany cache.Drain(&a); 32972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr total_allocated = a.TotalMemoryUsed(); 33072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (saved_total) 33172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(saved_total, total_allocated); 33272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany saved_total = total_allocated; 33372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 33472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 33572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.TestOnlyUnmap(); 33672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 33772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 33872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 33972166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64LocalCache) { 34072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassAllocatorLocalCache< 34172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany SizeClassAllocatorLocalCache<Allocator64> >(); 34272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 34372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 344225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov 345225f53194082f475a5d21780344ff79a2a387c13Dmitry VyukovTEST(Allocator, Basic) { 346225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov char *p = (char*)InternalAlloc(10); 347225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov EXPECT_NE(p, (char*)0); 348225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov char *p2 = (char*)InternalAlloc(20); 349225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov EXPECT_NE(p2, (char*)0); 350225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov EXPECT_NE(p2, p); 351225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov InternalFree(p); 352225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov InternalFree(p2); 353225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov} 354225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov 355225f53194082f475a5d21780344ff79a2a387c13Dmitry VyukovTEST(Allocator, Stress) { 356225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov const int kCount = 1000; 357225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov char *ptrs[kCount]; 358225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov unsigned rnd = 42; 359225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov for (int i = 0; i < kCount; i++) { 360225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov uptr sz = rand_r(&rnd) % 1000; 361225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov char *p = (char*)InternalAlloc(sz); 362225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov EXPECT_NE(p, (char*)0); 363225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov ptrs[i] = p; 364225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov } 365225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov for (int i = 0; i < kCount; i++) { 366225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov InternalFree(ptrs[i]); 367225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov } 368225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov} 369225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov 3706611abe0c2737a37c1c69f0527a35bb34875221dAlexey SamsonovTEST(Allocator, ScopedBuffer) { 3716611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov const int kSize = 512; 3726611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov { 3736611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov InternalScopedBuffer<int> int_buf(kSize); 3746611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov EXPECT_EQ(sizeof(int) * kSize, int_buf.size()); // NOLINT 3756611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov } 3766611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov InternalScopedBuffer<char> char_buf(kSize); 3776611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov EXPECT_EQ(sizeof(char) * kSize, char_buf.size()); // NOLINT 3786611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov memset(char_buf.data(), 'c', kSize); 3796611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov for (int i = 0; i < kSize; i++) { 3806611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov EXPECT_EQ('c', char_buf[i]); 3816611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov } 3826611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov} 383