sanitizer_allocator_test.cc revision 68acb909db275a9d4fb16b37fab4c42b72671abb
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> 209fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany#include <pthread.h> 2172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#include <algorithm> 2272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#include <vector> 2372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 2468902f431172d101f3c6322d96a99d705a37ad95Dmitry Vyukov// Too slow for debug build 25b6bb60b0fa39efee537cc34bc200edc976df0bc4Dmitry Vyukov#if TSAN_DEBUG == 0 2668902f431172d101f3c6322d96a99d705a37ad95Dmitry Vyukov 2772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 2872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanystatic const uptr kAllocatorSpace = 0x700000000000ULL; 2972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanystatic const uptr kAllocatorSize = 0x010000000000ULL; // 1T. 3045595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryanystatic const u64 kAddressSpaceSize = 1ULL << 47; 3172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 3272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytypedef SizeClassAllocator64< 3372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany kAllocatorSpace, kAllocatorSize, 16, DefaultSizeClassMap> Allocator64; 3472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 3572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytypedef SizeClassAllocator64< 3672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany kAllocatorSpace, kAllocatorSize, 16, CompactSizeClassMap> Allocator64Compact; 3745595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany#else 3845595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryanystatic const u64 kAddressSpaceSize = 1ULL << 32; 3972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 4072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 4145595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryanytypedef SizeClassAllocator32< 4245595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany 0, kAddressSpaceSize, 16, CompactSizeClassMap> Allocator32Compact; 4345595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany 4472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate <class SizeClassMap> 4572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid TestSizeClassMap() { 4672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany typedef SizeClassMap SCMap; 4772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if 0 4872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < SCMap::kNumClasses; i++) { 4972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany printf("c%ld => %ld (%lx) cached=%ld(%ld)\n", 5072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany i, SCMap::Size(i), SCMap::Size(i), SCMap::MaxCached(i) * SCMap::Size(i), 5172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany SCMap::MaxCached(i)); 5272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 5372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 5472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr c = 0; c < SCMap::kNumClasses; c++) { 5572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr s = SCMap::Size(c); 5672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(SCMap::ClassID(s), c); 5772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (c != SCMap::kNumClasses - 1) 5872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(SCMap::ClassID(s + 1), c + 1); 5972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(SCMap::ClassID(s - 1), c); 6072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (c) 6172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GT(SCMap::Size(c), SCMap::Size(c-1)); 6272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 6372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(SCMap::ClassID(SCMap::kMaxSize + 1), 0); 6472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 6572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr s = 1; s <= SCMap::kMaxSize; s++) { 6672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr c = SCMap::ClassID(s); 6772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_LT(c, SCMap::kNumClasses); 6872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GE(SCMap::Size(c), s); 6972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (c > 0) 7072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_LT(SCMap::Size(c-1), s); 7172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 7272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 7372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 7472166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, DefaultSizeClassMap) { 7572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassMap<DefaultSizeClassMap>(); 7672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 7772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 7872166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, CompactSizeClassMap) { 7972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassMap<CompactSizeClassMap>(); 8072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 8172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 8272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate <class Allocator> 8372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid TestSizeClassAllocator() { 8445595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany Allocator *a = new Allocator; 8545595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany a->Init(); 8672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 8772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static const uptr sizes[] = {1, 16, 30, 40, 100, 1000, 10000, 8872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 50000, 60000, 100000, 300000, 500000, 1000000, 2000000}; 8972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 9072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany std::vector<void *> allocated; 9172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 9272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr last_total_allocated = 0; 9372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < 5; i++) { 9472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Allocate a bunch of chunks. 9545595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany for (uptr s = 0; s < ARRAY_SIZE(sizes); s++) { 9672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr size = sizes[s]; 9745595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany if (!a->CanAllocate(size, 1)) continue; 9872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // printf("s = %ld\n", size); 9972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr n_iter = std::max((uptr)2, 1000000 / size); 10072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < n_iter; i++) { 10145595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany void *x = a->Allocate(size, 1); 10272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated.push_back(x); 1038a41bdc963afdf3c2e14aad64a7cd3291fefd8cfKostya Serebryany CHECK_EQ(x, a->GetBlockBegin(x)); 1048a41bdc963afdf3c2e14aad64a7cd3291fefd8cfKostya Serebryany CHECK_EQ(x, a->GetBlockBegin((char*)x + size - 1)); 10545595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany CHECK(a->PointerIsMine(x)); 10645595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany CHECK_GE(a->GetActuallyAllocatedSize(x), size); 10745595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany uptr class_id = a->GetSizeClass(x); 10872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(class_id, Allocator::SizeClassMapT::ClassID(size)); 10945595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany uptr *metadata = reinterpret_cast<uptr*>(a->GetMetaData(x)); 11072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany metadata[0] = reinterpret_cast<uptr>(x) + 1; 11172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany metadata[1] = 0xABCD; 11272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 11372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 11472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Deallocate all. 11572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < allocated.size(); i++) { 11672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *x = allocated[i]; 11745595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany uptr *metadata = reinterpret_cast<uptr*>(a->GetMetaData(x)); 11872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(metadata[0], reinterpret_cast<uptr>(x) + 1); 11972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(metadata[1], 0xABCD); 12045595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany a->Deallocate(x); 12172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 12272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated.clear(); 12345595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany uptr total_allocated = a->TotalMemoryUsed(); 12472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (last_total_allocated == 0) 12572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany last_total_allocated = total_allocated; 12672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(last_total_allocated, total_allocated); 12772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 12872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 12945595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany a->TestOnlyUnmap(); 13045595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany delete a; 13172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 13272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 13372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 13472166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64) { 13572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassAllocator<Allocator64>(); 13672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 13772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 13872166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64Compact) { 13972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassAllocator<Allocator64Compact>(); 14072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 14172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 14272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 14345595ba6b77b54b8212389cba6b95dc634122145Kostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator32Compact) { 14445595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany TestSizeClassAllocator<Allocator32Compact>(); 14545595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany} 14645595ba6b77b54b8212389cba6b95dc634122145Kostya Serebryany 14772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate <class Allocator> 148784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryanyvoid SizeClassAllocatorMetadataStress() { 149784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany Allocator *a = new Allocator; 150784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany a->Init(); 15172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static volatile void *sink; 15272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 15372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr kNumAllocs = 10000; 15472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *allocated[kNumAllocs]; 15572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 15672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr size = (i % 4096) + 1; 157784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany void *x = a->Allocate(size, 1); 15872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = x; 15972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 16072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Get Metadata kNumAllocs^2 times. 16172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs * kNumAllocs; i++) { 162784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany sink = a->GetMetaData(allocated[i % kNumAllocs]); 16372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 16472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 165784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany a->Deallocate(allocated[i]); 16672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 16772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 168784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany a->TestOnlyUnmap(); 16972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany (void)sink; 170784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany delete a; 17172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 17272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 17372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 17472166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64MetadataStress) { 175784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany SizeClassAllocatorMetadataStress<Allocator64>(); 17672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 177225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov 17872166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64CompactMetadataStress) { 179784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany SizeClassAllocatorMetadataStress<Allocator64Compact>(); 18072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 18172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 182784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator32CompactMetadataStress) { 183784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany SizeClassAllocatorMetadataStress<Allocator32Compact>(); 184784935d1bbc301eaf92fd9f7d3a551eb65edcd15Kostya Serebryany} 18572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 186214621f7663896987dc509561c762460226c68c2Kostya Serebryanystruct TestMapUnmapCallback { 187214621f7663896987dc509561c762460226c68c2Kostya Serebryany static int map_count, unmap_count; 188214621f7663896987dc509561c762460226c68c2Kostya Serebryany void OnMap(uptr p, uptr size) const { map_count++; } 189214621f7663896987dc509561c762460226c68c2Kostya Serebryany void OnUnmap(uptr p, uptr size) const { unmap_count++; } 190214621f7663896987dc509561c762460226c68c2Kostya Serebryany}; 191214621f7663896987dc509561c762460226c68c2Kostya Serebryanyint TestMapUnmapCallback::map_count; 192214621f7663896987dc509561c762460226c68c2Kostya Serebryanyint TestMapUnmapCallback::unmap_count; 193214621f7663896987dc509561c762460226c68c2Kostya Serebryany 194214621f7663896987dc509561c762460226c68c2Kostya Serebryany#if SANITIZER_WORDSIZE == 64 195214621f7663896987dc509561c762460226c68c2Kostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) { 196214621f7663896987dc509561c762460226c68c2Kostya Serebryany TestMapUnmapCallback::map_count = 0; 197214621f7663896987dc509561c762460226c68c2Kostya Serebryany TestMapUnmapCallback::unmap_count = 0; 198214621f7663896987dc509561c762460226c68c2Kostya Serebryany typedef SizeClassAllocator64< 199214621f7663896987dc509561c762460226c68c2Kostya Serebryany kAllocatorSpace, kAllocatorSize, 16, DefaultSizeClassMap, 200214621f7663896987dc509561c762460226c68c2Kostya Serebryany TestMapUnmapCallback> Allocator64WithCallBack; 201214621f7663896987dc509561c762460226c68c2Kostya Serebryany Allocator64WithCallBack *a = new Allocator64WithCallBack; 202214621f7663896987dc509561c762460226c68c2Kostya Serebryany a->Init(); 203214621f7663896987dc509561c762460226c68c2Kostya Serebryany EXPECT_EQ(TestMapUnmapCallback::map_count, 1); // Allocator state. 204567ad078d73babb2c8addfbebb1ddd6cd0085c53Kostya Serebryany a->Allocate(100, 1); 205567ad078d73babb2c8addfbebb1ddd6cd0085c53Kostya Serebryany EXPECT_EQ(TestMapUnmapCallback::map_count, 3); // State + alloc + metadata. 206214621f7663896987dc509561c762460226c68c2Kostya Serebryany a->TestOnlyUnmap(); 207214621f7663896987dc509561c762460226c68c2Kostya Serebryany EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1); // The whole thing. 208214621f7663896987dc509561c762460226c68c2Kostya Serebryany delete a; 209214621f7663896987dc509561c762460226c68c2Kostya Serebryany} 210214621f7663896987dc509561c762460226c68c2Kostya Serebryany#endif 211214621f7663896987dc509561c762460226c68c2Kostya Serebryany 212214621f7663896987dc509561c762460226c68c2Kostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) { 213214621f7663896987dc509561c762460226c68c2Kostya Serebryany TestMapUnmapCallback::map_count = 0; 214214621f7663896987dc509561c762460226c68c2Kostya Serebryany TestMapUnmapCallback::unmap_count = 0; 215214621f7663896987dc509561c762460226c68c2Kostya Serebryany typedef SizeClassAllocator32< 216214621f7663896987dc509561c762460226c68c2Kostya Serebryany 0, kAddressSpaceSize, 16, CompactSizeClassMap, 217214621f7663896987dc509561c762460226c68c2Kostya Serebryany TestMapUnmapCallback> Allocator32WithCallBack; 218214621f7663896987dc509561c762460226c68c2Kostya Serebryany Allocator32WithCallBack *a = new Allocator32WithCallBack; 219214621f7663896987dc509561c762460226c68c2Kostya Serebryany a->Init(); 220214621f7663896987dc509561c762460226c68c2Kostya Serebryany EXPECT_EQ(TestMapUnmapCallback::map_count, 1); // Allocator state. 221214621f7663896987dc509561c762460226c68c2Kostya Serebryany a->Allocate(100, 1); 222214621f7663896987dc509561c762460226c68c2Kostya Serebryany EXPECT_EQ(TestMapUnmapCallback::map_count, 2); // alloc. 223214621f7663896987dc509561c762460226c68c2Kostya Serebryany a->TestOnlyUnmap(); 224214621f7663896987dc509561c762460226c68c2Kostya Serebryany EXPECT_EQ(TestMapUnmapCallback::unmap_count, 2); // The whole thing + alloc. 225214621f7663896987dc509561c762460226c68c2Kostya Serebryany delete a; 226ca661f51dbccc8b8bdeb308751f3b160501f7954Dmitry Vyukov // fprintf(stderr, "Map: %d Unmap: %d\n", 227ca661f51dbccc8b8bdeb308751f3b160501f7954Dmitry Vyukov // TestMapUnmapCallback::map_count, 228ca661f51dbccc8b8bdeb308751f3b160501f7954Dmitry Vyukov // TestMapUnmapCallback::unmap_count); 229214621f7663896987dc509561c762460226c68c2Kostya Serebryany} 230214621f7663896987dc509561c762460226c68c2Kostya Serebryany 231214621f7663896987dc509561c762460226c68c2Kostya SerebryanyTEST(SanitizerCommon, LargeMmapAllocatorMapUnmapCallback) { 232214621f7663896987dc509561c762460226c68c2Kostya Serebryany TestMapUnmapCallback::map_count = 0; 233214621f7663896987dc509561c762460226c68c2Kostya Serebryany TestMapUnmapCallback::unmap_count = 0; 234214621f7663896987dc509561c762460226c68c2Kostya Serebryany LargeMmapAllocator<TestMapUnmapCallback> a; 235214621f7663896987dc509561c762460226c68c2Kostya Serebryany a.Init(); 236214621f7663896987dc509561c762460226c68c2Kostya Serebryany void *x = a.Allocate(1 << 20, 1); 237214621f7663896987dc509561c762460226c68c2Kostya Serebryany EXPECT_EQ(TestMapUnmapCallback::map_count, 1); 238214621f7663896987dc509561c762460226c68c2Kostya Serebryany a.Deallocate(x); 239214621f7663896987dc509561c762460226c68c2Kostya Serebryany EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1); 240214621f7663896987dc509561c762460226c68c2Kostya Serebryany} 241214621f7663896987dc509561c762460226c68c2Kostya Serebryany 24272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate<class Allocator> 24372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid FailInAssertionOnOOM() { 24472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany Allocator a; 24572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Init(); 24672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr size = 1 << 20; 24772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < 1000000; i++) { 24872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Allocate(size, 1); 24972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 25072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 25172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.TestOnlyUnmap(); 25272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 25372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 25472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 25572166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64Overflow) { 25672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany EXPECT_DEATH(FailInAssertionOnOOM<Allocator64>(), "Out of memory"); 25772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 25872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 25972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 26072166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, LargeMmapAllocator) { 261214621f7663896987dc509561c762460226c68c2Kostya Serebryany LargeMmapAllocator<> a; 26272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Init(); 26372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 26472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static const int kNumAllocs = 100; 26572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *allocated[kNumAllocs]; 26672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static const uptr size = 1000; 26772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Allocate some. 26872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 26972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = a.Allocate(size, 1); 27072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 27172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Deallocate all. 27272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs); 27372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 27472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *p = allocated[i]; 27572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK(a.PointerIsMine(p)); 27672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Deallocate(p); 27772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 27872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Check that non left. 27972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(a.TotalMemoryUsed(), 0); 28072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 28172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Allocate some more, also add metadata. 28272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 28372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *x = a.Allocate(size, 1); 28472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GE(a.GetActuallyAllocatedSize(x), size); 28572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x)); 28672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany *meta = i; 28772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = x; 28872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 28972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs); 29072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany // Deallocate all in reverse order. 29172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 29272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany int idx = kNumAllocs - i - 1; 29372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *p = allocated[idx]; 29472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(p)); 29572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(*meta, idx); 29672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK(a.PointerIsMine(p)); 29772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Deallocate(p); 29872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 29972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(a.TotalMemoryUsed(), 0); 30072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr max_alignment = SANITIZER_WORDSIZE == 64 ? (1 << 28) : (1 << 24); 30172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr alignment = 8; alignment <= max_alignment; alignment *= 2) { 30272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 30372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr size = ((i % 10) + 1) * 4096; 30472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated[i] = a.Allocate(size, alignment); 30572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(0, (uptr)allocated[i] % alignment); 30672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany char *p = (char*)allocated[i]; 30772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany p[0] = p[size - 1] = 0; 30872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 30972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumAllocs; i++) { 31072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany a.Deallocate(allocated[i]); 31172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 31272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 31372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 31472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 31572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate 31672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany<class PrimaryAllocator, class SecondaryAllocator, class AllocatorCache> 31772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid TestCombinedAllocator() { 318674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany typedef 319674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany CombinedAllocator<PrimaryAllocator, AllocatorCache, SecondaryAllocator> 320674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany Allocator; 321674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany Allocator *a = new Allocator; 322674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany a->Init(); 32372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 32472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany AllocatorCache cache; 32572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany cache.Init(); 32672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 327674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany EXPECT_EQ(a->Allocate(&cache, -1, 1), (void*)0); 328674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany EXPECT_EQ(a->Allocate(&cache, -1, 1024), (void*)0); 329674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1024, 1), (void*)0); 330674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1024, 1024), (void*)0); 331674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1023, 1024), (void*)0); 33272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 33372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr kNumAllocs = 100000; 33472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr kNumIter = 10; 33572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr iter = 0; iter < kNumIter; iter++) { 33672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany std::vector<void*> allocated; 33772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 33872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr size = (i % (1 << 14)) + 1; 33972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if ((i % 1024) == 0) 34072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany size = 1 << (10 + (i % 14)); 341674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany void *x = a->Allocate(&cache, size, 1); 342674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany uptr *meta = reinterpret_cast<uptr*>(a->GetMetaData(x)); 34372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(*meta, 0); 34472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany *meta = size; 34572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated.push_back(x); 34672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 34772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 34872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany random_shuffle(allocated.begin(), allocated.end()); 34972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 35072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 35172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *x = allocated[i]; 352674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany uptr *meta = reinterpret_cast<uptr*>(a->GetMetaData(x)); 35372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_NE(*meta, 0); 354674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany CHECK(a->PointerIsMine(x)); 35572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany *meta = 0; 356674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany a->Deallocate(&cache, x); 35772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 35872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany allocated.clear(); 359674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany a->SwallowCache(&cache); 36072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 361674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany a->TestOnlyUnmap(); 36272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 36372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 36472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 365674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya SerebryanyTEST(SanitizerCommon, CombinedAllocator64) { 36672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestCombinedAllocator<Allocator64, 367214621f7663896987dc509561c762460226c68c2Kostya Serebryany LargeMmapAllocator<>, 36872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany SizeClassAllocatorLocalCache<Allocator64> > (); 36972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 370674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany 371674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya SerebryanyTEST(SanitizerCommon, CombinedAllocator64Compact) { 372674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany TestCombinedAllocator<Allocator64Compact, 373214621f7663896987dc509561c762460226c68c2Kostya Serebryany LargeMmapAllocator<>, 374674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany SizeClassAllocatorLocalCache<Allocator64Compact> > (); 375674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany} 37672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 37772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 378674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya SerebryanyTEST(SanitizerCommon, CombinedAllocator32Compact) { 379674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany TestCombinedAllocator<Allocator32Compact, 380214621f7663896987dc509561c762460226c68c2Kostya Serebryany LargeMmapAllocator<>, 381674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany SizeClassAllocatorLocalCache<Allocator32Compact> > (); 382674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany} 383674d05c15d3cfcd2e9f0e9fde47d25cd69af924bKostya Serebryany 38472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanytemplate <class AllocatorCache> 38572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryanyvoid TestSizeClassAllocatorLocalCache() { 38672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static THREADLOCAL AllocatorCache static_allocator_cache; 38772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany static_allocator_cache.Init(); 38872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany AllocatorCache cache; 389e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany typedef typename AllocatorCache::Allocator Allocator; 390e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany Allocator *a = new Allocator(); 39172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 392e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany a->Init(); 39372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany cache.Init(); 39472166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 39572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const uptr kNumAllocs = 10000; 39672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany const int kNumIter = 100; 39772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany uptr saved_total = 0; 39872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (int i = 0; i < kNumIter; i++) { 39972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany void *allocated[kNumAllocs]; 40072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 401e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany allocated[i] = cache.Allocate(a, 0); 40272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 40372166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany for (uptr i = 0; i < kNumAllocs; i++) { 404e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany cache.Deallocate(a, 0, allocated[i]); 40572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 406e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany cache.Drain(a); 407e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany uptr total_allocated = a->TotalMemoryUsed(); 40872166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany if (saved_total) 40972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany CHECK_EQ(saved_total, total_allocated); 41072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany saved_total = total_allocated; 41172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany } 41272166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 413e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany a->TestOnlyUnmap(); 414e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany delete a; 41572166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 41672166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany 41772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#if SANITIZER_WORDSIZE == 64 41872166ca99c2f8898a7a540e60aac3959cbd959bfKostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64LocalCache) { 41972166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany TestSizeClassAllocatorLocalCache< 42072166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany SizeClassAllocatorLocalCache<Allocator64> >(); 42172166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany} 422e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany 423e280ce59d37a67bee14da56a22e205d6562530b0Kostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator64CompactLocalCache) { 424e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany TestSizeClassAllocatorLocalCache< 425e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany SizeClassAllocatorLocalCache<Allocator64Compact> >(); 426e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany} 42772166ca99c2f8898a7a540e60aac3959cbd959bfKostya Serebryany#endif 428225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov 429e280ce59d37a67bee14da56a22e205d6562530b0Kostya SerebryanyTEST(SanitizerCommon, SizeClassAllocator32CompactLocalCache) { 430e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany TestSizeClassAllocatorLocalCache< 431e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany SizeClassAllocatorLocalCache<Allocator32Compact> >(); 432e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany} 433e280ce59d37a67bee14da56a22e205d6562530b0Kostya Serebryany 4349fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany#if SANITIZER_WORDSIZE == 64 4359fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryanytypedef SizeClassAllocatorLocalCache<Allocator64> AllocatorCache; 4369fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryanystatic THREADLOCAL AllocatorCache static_allocator_cache; 4379fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany 4389fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryanyvoid *AllocatorLeakTestWorker(void *arg) { 4399fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany typedef AllocatorCache::Allocator Allocator; 4409fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany Allocator *a = (Allocator*)(arg); 4419fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany static_allocator_cache.Allocate(a, 10); 4429fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany static_allocator_cache.Drain(a); 4439fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany return 0; 4449fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany} 4459fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany 4469fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya SerebryanyTEST(SanitizerCommon, AllocatorLeakTest) { 44768acb909db275a9d4fb16b37fab4c42b72671abbAlexey Samsonov typedef AllocatorCache::Allocator Allocator; 4489fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany Allocator a; 4499fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany a.Init(); 4509fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany uptr total_used_memory = 0; 4519fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany for (int i = 0; i < 100; i++) { 4529fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany pthread_t t; 4539fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany EXPECT_EQ(0, pthread_create(&t, 0, AllocatorLeakTestWorker, &a)); 4549fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany EXPECT_EQ(0, pthread_join(t, 0)); 4559fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany if (i == 0) 4569fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany total_used_memory = a.TotalMemoryUsed(); 4579fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany EXPECT_EQ(a.TotalMemoryUsed(), total_used_memory); 4589fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany } 4599fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany 4609fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany a.TestOnlyUnmap(); 4619fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany} 4629fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany#endif 4639fc1f27f55a4bb3d54858cfd3c32d0bb11002db2Kostya Serebryany 464225f53194082f475a5d21780344ff79a2a387c13Dmitry VyukovTEST(Allocator, Basic) { 465225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov char *p = (char*)InternalAlloc(10); 466225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov EXPECT_NE(p, (char*)0); 467225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov char *p2 = (char*)InternalAlloc(20); 468225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov EXPECT_NE(p2, (char*)0); 469225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov EXPECT_NE(p2, p); 470225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov InternalFree(p); 471225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov InternalFree(p2); 472225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov} 473225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov 474225f53194082f475a5d21780344ff79a2a387c13Dmitry VyukovTEST(Allocator, Stress) { 475225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov const int kCount = 1000; 476225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov char *ptrs[kCount]; 477225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov unsigned rnd = 42; 478225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov for (int i = 0; i < kCount; i++) { 479225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov uptr sz = rand_r(&rnd) % 1000; 480225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov char *p = (char*)InternalAlloc(sz); 481225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov EXPECT_NE(p, (char*)0); 482225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov ptrs[i] = p; 483225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov } 484225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov for (int i = 0; i < kCount; i++) { 485225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov InternalFree(ptrs[i]); 486225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov } 487225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov} 488225f53194082f475a5d21780344ff79a2a387c13Dmitry Vyukov 4896611abe0c2737a37c1c69f0527a35bb34875221dAlexey SamsonovTEST(Allocator, ScopedBuffer) { 4906611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov const int kSize = 512; 4916611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov { 4926611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov InternalScopedBuffer<int> int_buf(kSize); 4936611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov EXPECT_EQ(sizeof(int) * kSize, int_buf.size()); // NOLINT 4946611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov } 4956611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov InternalScopedBuffer<char> char_buf(kSize); 4966611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov EXPECT_EQ(sizeof(char) * kSize, char_buf.size()); // NOLINT 4970bb6e5ddbb11565dfe0a71b0936f0dd76251ea78Kostya Serebryany internal_memset(char_buf.data(), 'c', kSize); 4986611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov for (int i = 0; i < kSize; i++) { 4996611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov EXPECT_EQ('c', char_buf[i]); 5006611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov } 5016611abe0c2737a37c1c69f0527a35bb34875221dAlexey Samsonov} 50268902f431172d101f3c6322d96a99d705a37ad95Dmitry Vyukov 50368902f431172d101f3c6322d96a99d705a37ad95Dmitry Vyukov#endif // #if TSAN_DEBUG==0 504