[llvm-commits] [compiler-rt] r159002 - in /compiler-rt/trunk/lib/sanitizer_common: sanitizer_allocator64.h tests/sanitizer_allocator64_test.cc
Kostya Serebryany
kcc at google.com
Fri Jun 22 09:13:29 PDT 2012
Author: kcc
Date: Fri Jun 22 11:13:28 2012
New Revision: 159002
URL: http://llvm.org/viewvc/llvm-project?rev=159002&view=rev
Log:
[tsan] add metadata to the new tsan allocator
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator64.h
compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator64.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator64.h?rev=159002&r1=159001&r2=159002&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator64.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator64.h Fri Jun 22 11:13:28 2012
@@ -96,10 +96,12 @@
CHECK_EQ(AllocBeg(), reinterpret_cast<uptr>(MmapFixedNoReserve(
AllocBeg(), AllocSize())));
}
+ NOINLINE
void *Allocate(uptr size) {
CHECK_LE(size, SizeClassMap::kMaxSize);
return AllocateBySizeClass(SizeClassMap::ClassID(size));
}
+ NOINLINE
void Deallocate(void *p) {
DeallocateBySizeClass(p, GetSizeClass(p));
}
@@ -110,6 +112,13 @@
return (reinterpret_cast<uptr>(p) / kRegionSize) % kNumClasses;
}
+ uptr GetMetaData(void *p) {
+ uptr class_id = GetSizeClass(p);
+ uptr chunk_idx = GetChunkIdx(reinterpret_cast<uptr>(p), class_id);
+ return kSpaceBeg + (kRegionSize * (class_id + 1)) -
+ (1 + chunk_idx) * kMetadataSize;
+ }
+
uptr TotalMemoryUsedIncludingFreeLists() {
uptr res = 0;
for (uptr i = 0; i < kNumClasses; i++)
@@ -125,6 +134,7 @@
static const uptr kNumClasses = 256; // Power of two <= 256
COMPILER_CHECK(kNumClasses <= SizeClassMap::kNumClasses);
static const uptr kRegionSize = kSpaceSize / kNumClasses;
+ COMPILER_CHECK((kRegionSize >> 32) > 0); // kRegionSize must be >= 2^32.
// Populate the free list with at most this number of bytes at once
// or with one element if its size is greater.
static const uptr kPopulateSize = 1 << 18;
@@ -163,6 +173,14 @@
return res;
}
+ uptr GetChunkIdx(uptr chunk, uptr class_id) {
+ u32 offset = chunk % kRegionSize;
+ // Here we divide by a non-constant. This is costly.
+ // We require that kRegionSize is at least 2^32 so that offset is 32-bit.
+ // We save 2x by using 32-bit div, but may need to use a 256-way switch.
+ return offset / (u32)SizeClassMap::Size(class_id);
+ }
+
LifoListNode *PopulateFreeList(uptr class_id, RegionInfo *region) {
uptr size = SizeClassMap::Size(class_id);
uptr beg_idx = region->allocated;
Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc?rev=159002&r1=159001&r2=159002&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator64_test.cc Fri Jun 22 11:13:28 2012
@@ -47,13 +47,13 @@
}
}
+static const uptr kAllocatorSpace = 0x600000000000ULL;
+static const uptr kAllocatorSize = 0x10000000000; // 1T.
+
TEST(SanitizerCommon, SizeClassAllocator64) {
- const uptr space_beg = 0x600000000000ULL;
- const uptr space_size = 0x10000000000; // 1T
- const uptr metadata_size = 16;
typedef DefaultSizeClassMap SCMap;
- typedef SizeClassAllocator64<space_beg, space_size,
- metadata_size, SCMap> Allocator;
+ typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize,
+ 16, SCMap> Allocator;
Allocator a;
a.Init();
@@ -76,11 +76,18 @@
CHECK(a.PointerIsMine(x));
uptr class_id = a.GetSizeClass(x);
CHECK_EQ(class_id, SCMap::ClassID(size));
+ uptr *metadata = reinterpret_cast<uptr*>(a.GetMetaData(x));
+ metadata[0] = reinterpret_cast<uptr>(x) + 1;
+ metadata[1] = 0xABCD;
}
}
// Deallocate all.
for (uptr i = 0; i < allocated.size(); i++) {
- a.Deallocate(allocated[i]);
+ void *x = allocated[i];
+ uptr *metadata = reinterpret_cast<uptr*>(a.GetMetaData(x));
+ CHECK_EQ(metadata[0], reinterpret_cast<uptr>(x) + 1);
+ CHECK_EQ(metadata[1], 0xABCD);
+ a.Deallocate(x);
}
allocated.clear();
uptr total_allocated = a.TotalMemoryUsedIncludingFreeLists();
@@ -91,3 +98,30 @@
a.TestOnlyUnmap();
}
+
+
+TEST(SanitizerCommon, SizeClassAllocator64MetadataStress) {
+ typedef DefaultSizeClassMap SCMap;
+ typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize,
+ 16, SCMap> Allocator;
+ Allocator a;
+ a.Init();
+ static volatile uptr sink;
+
+ const uptr kNumAllocs = 10000;
+ void *allocated[kNumAllocs];
+ for (uptr i = 0; i < kNumAllocs; i++) {
+ uptr size = (i % 4096) + 1;
+ void *x = a.Allocate(size);
+ allocated[i] = x;
+ }
+ // Get Metadata kNumAllocs^2 times.
+ for (uptr i = 0; i < kNumAllocs * kNumAllocs; i++) {
+ sink = a.GetMetaData(allocated[i % kNumAllocs]);
+ }
+ for (uptr i = 0; i < kNumAllocs; i++) {
+ a.Deallocate(allocated[i]);
+ }
+
+ a.TestOnlyUnmap();
+}
More information about the llvm-commits
mailing list