[tsan] a better CHECK for OOM in the new allocator

llvm-svn: 159122
This commit is contained in:
Kostya Serebryany 2012-06-25 04:12:49 +00:00
parent 70ed924e18
commit f299f7013a
2 changed files with 31 additions and 6 deletions

View File

@ -122,7 +122,7 @@ class SizeClassAllocator64 {
uptr TotalMemoryUsedIncludingFreeLists() { uptr TotalMemoryUsedIncludingFreeLists() {
uptr res = 0; uptr res = 0;
for (uptr i = 0; i < kNumClasses; i++) for (uptr i = 0; i < kNumClasses; i++)
res += GetRegionInfo(i)->allocated; res += GetRegionInfo(i)->allocated_user;
return res; return res;
} }
@ -130,6 +130,7 @@ class SizeClassAllocator64 {
void TestOnlyUnmap() { void TestOnlyUnmap() {
UnmapOrDie(reinterpret_cast<void*>(AllocBeg()), AllocSize()); UnmapOrDie(reinterpret_cast<void*>(AllocBeg()), AllocSize());
} }
private: private:
static const uptr kNumClasses = 256; // Power of two <= 256 static const uptr kNumClasses = 256; // Power of two <= 256
COMPILER_CHECK(kNumClasses <= SizeClassMap::kNumClasses); COMPILER_CHECK(kNumClasses <= SizeClassMap::kNumClasses);
@ -146,9 +147,11 @@ class SizeClassAllocator64 {
struct RegionInfo { struct RegionInfo {
uptr mutex; // FIXME uptr mutex; // FIXME
LifoListNode *free_list; LifoListNode *free_list;
uptr allocated; uptr allocated_user; // Bytes allocated for user memory.
uptr allocated_meta; // Bytes allocated for metadata.
char padding[kCacheLineSize - char padding[kCacheLineSize -
sizeof(mutex) - sizeof(free_list) - sizeof(allocated)]; sizeof(mutex) - sizeof(free_list) -
sizeof(allocated_user) - sizeof(allocated_meta)];
}; };
COMPILER_CHECK(sizeof(RegionInfo) == kCacheLineSize); COMPILER_CHECK(sizeof(RegionInfo) == kCacheLineSize);
@ -183,18 +186,21 @@ class SizeClassAllocator64 {
LifoListNode *PopulateFreeList(uptr class_id, RegionInfo *region) { LifoListNode *PopulateFreeList(uptr class_id, RegionInfo *region) {
uptr size = SizeClassMap::Size(class_id); uptr size = SizeClassMap::Size(class_id);
uptr beg_idx = region->allocated; uptr beg_idx = region->allocated_user;
uptr end_idx = beg_idx + kPopulateSize; uptr end_idx = beg_idx + kPopulateSize;
LifoListNode *res = 0; LifoListNode *res = 0;
uptr region_beg = kSpaceBeg + kRegionSize * class_id; uptr region_beg = kSpaceBeg + kRegionSize * class_id;
uptr idx = beg_idx; uptr idx = beg_idx;
uptr i = 0;
do { // do-while loop because we need to put at least one item. do { // do-while loop because we need to put at least one item.
uptr p = region_beg + idx; uptr p = region_beg + idx;
PushLifoList(&res, reinterpret_cast<LifoListNode*>(p)); PushLifoList(&res, reinterpret_cast<LifoListNode*>(p));
idx += size; idx += size;
i++;
} while (idx < end_idx); } while (idx < end_idx);
CHECK_LT(idx, kRegionSize); region->allocated_user += idx - beg_idx;
region->allocated += idx - beg_idx; region->allocated_meta += i * kMetadataSize;
CHECK_LT(region->allocated_user + region->allocated_meta, kRegionSize);
return res; return res;
} }

View File

@ -125,3 +125,22 @@ TEST(SanitizerCommon, SizeClassAllocator64MetadataStress) {
a.TestOnlyUnmap(); a.TestOnlyUnmap();
} }
void FailInAssertionOnOOM() {
typedef DefaultSizeClassMap SCMap;
typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize,
16, SCMap> Allocator;
Allocator a;
a.Init();
const uptr size = 1 << 20;
for (int i = 0; i < 1000000; i++) {
a.Allocate(size);
}
a.TestOnlyUnmap();
}
TEST(SanitizerCommon, SizeClassAllocator64Overflow) {
EXPECT_DEATH(FailInAssertionOnOOM(),
"allocated_user.*allocated_meta.*kRegionSize");
}