[compiler-rt] r181989 - [sanitizer] fix the GetBlockBegin overflow bug while preserving the performance optimization (use 32-bit division when possible). Improve the benchmarks that checks for performance of GetBlockBegin/GetMetaData
Kostya Serebryany
kcc at google.com
Thu May 16 00:11:16 PDT 2013
Author: kcc
Date: Thu May 16 02:11:16 2013
New Revision: 181989
URL: http://llvm.org/viewvc/llvm-project?rev=181989&view=rev
Log:
[sanitizer] fix the GetBlockBegin overflow bug while preserving the performance optimization (use 32-bit division when possible). Improve the benchmarks that checks for performance of GetBlockBegin/GetMetaData
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h?rev=181989&r1=181988&r2=181989&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h Thu May 16 02:11:16 2013
@@ -492,11 +492,12 @@ class SizeClassAllocator64 {
}
static uptr GetChunkIdx(uptr chunk, uptr size) {
- u32 offset = chunk % kRegionSize;
+ uptr 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)size;
+ // size always fits into 32-bits. If the offset fits too, use 32-bit div.
+ if (offset >> 32)
+ return offset / size;
+ return (u32)offset / (u32)size;
}
NOINLINE Batch* PopulateFreeList(AllocatorStats *stat, AllocatorCache *c,
Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator_test.cc?rev=181989&r1=181988&r2=181989&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_allocator_test.cc Thu May 16 02:11:16 2013
@@ -147,24 +147,26 @@ void SizeClassAllocatorMetadataStress()
SizeClassAllocatorLocalCache<Allocator> cache;
memset(&cache, 0, sizeof(cache));
cache.Init(0);
- static volatile void *sink;
- const uptr kNumAllocs = 10000;
+ const uptr kNumAllocs = 1 << 13;
void *allocated[kNumAllocs];
+ void *meta[kNumAllocs];
for (uptr i = 0; i < kNumAllocs; i++) {
void *x = cache.Allocate(a, 1 + i % 50);
allocated[i] = x;
+ meta[i] = a->GetMetaData(x);
}
// Get Metadata kNumAllocs^2 times.
for (uptr i = 0; i < kNumAllocs * kNumAllocs; i++) {
- sink = a->GetMetaData(allocated[i % kNumAllocs]);
+ uptr idx = i % kNumAllocs;
+ void *m = a->GetMetaData(allocated[idx]);
+ EXPECT_EQ(m, meta[idx]);
}
for (uptr i = 0; i < kNumAllocs; i++) {
cache.Deallocate(a, 1 + i % 50, allocated[i]);
}
a->TestOnlyUnmap();
- (void)sink;
delete a;
}
@@ -192,6 +194,7 @@ void SizeClassAllocatorGetBlockBeginStre
uptr max_size_class = Allocator::kNumClasses - 1;
uptr size = Allocator::SizeClassMapT::Size(max_size_class);
u64 G8 = 1ULL << 33;
+ // Make sure we correctly compute GetBlockBegin() w/o overflow.
for (size_t i = 0; i <= G8 / size; i++) {
void *x = cache.Allocate(a, max_size_class);
void *beg = a->GetBlockBegin(x);
@@ -205,9 +208,15 @@ void SizeClassAllocatorGetBlockBeginStre
}
#if SANITIZER_WORDSIZE == 64
-TEST(SanitizerCommon, DISABLED_SizeClassAllocator64GetBlockBegin) {
+TEST(SanitizerCommon, SizeClassAllocator64GetBlockBegin) {
SizeClassAllocatorGetBlockBeginStress<Allocator64>();
}
+TEST(SanitizerCommon, SizeClassAllocator64CompactGetBlockBegin) {
+ SizeClassAllocatorGetBlockBeginStress<Allocator64Compact>();
+}
+TEST(SanitizerCommon, SizeClassAllocator32CompactGetBlockBegin) {
+ SizeClassAllocatorGetBlockBeginStress<Allocator32Compact>();
+}
#endif // SANITIZER_WORDSIZE == 64
struct TestMapUnmapCallback {
More information about the llvm-commits
mailing list