forked from OSchip/llvm-project
[tsan] a better CHECK for OOM in the new allocator
llvm-svn: 159122
This commit is contained in:
parent
70ed924e18
commit
f299f7013a
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue