[sanitizer] fix LargeMmapAllocator::GetBlockBegin

llvm-svn: 170434
This commit is contained in:
Kostya Serebryany 2012-12-18 14:56:38 +00:00
parent 44e1beaee6
commit 12676268fa
2 changed files with 17 additions and 19 deletions

View File

@ -674,17 +674,11 @@ class LargeMmapAllocator {
} }
bool PointerIsMine(void *p) { bool PointerIsMine(void *p) {
// Fast check. return GetBlockBegin(p) != 0;
if ((reinterpret_cast<uptr>(p) & (page_size_ - 1))) return false;
SpinMutexLock l(&mutex_);
for (Header *l = list_; l; l = l->next) {
if (GetUser(l) == p) return true;
}
return false;
} }
uptr GetActuallyAllocatedSize(void *p) { uptr GetActuallyAllocatedSize(void *p) {
return RoundUpMapSize(GetHeader(p)->size) - page_size_; return RoundUpTo(GetHeader(p)->size, page_size_);
} }
// At least page_size_/2 metadata bytes is available. // At least page_size_/2 metadata bytes is available.
@ -692,12 +686,12 @@ class LargeMmapAllocator {
return GetHeader(p) + 1; return GetHeader(p) + 1;
} }
void *GetBlockBegin(void *p) { void *GetBlockBegin(void *ptr) {
uptr p = reinterpret_cast<uptr>(ptr);
SpinMutexLock l(&mutex_); SpinMutexLock l(&mutex_);
for (Header *l = list_; l; l = l->next) { for (Header *l = list_; l; l = l->next) {
void *b = GetUser(l); if (p >= l->map_beg && p < l->map_beg + l->map_size)
if (p >= b && p < (u8*)b + l->size) return GetUser(l);
return b;
} }
return 0; return 0;
} }

View File

@ -106,6 +106,8 @@ void TestSizeClassAllocator() {
CHECK_EQ(x, a->GetBlockBegin(x)); CHECK_EQ(x, a->GetBlockBegin(x));
CHECK_EQ(x, a->GetBlockBegin(x + size - 1)); CHECK_EQ(x, a->GetBlockBegin(x + size - 1));
CHECK(a->PointerIsMine(x)); CHECK(a->PointerIsMine(x));
CHECK(a->PointerIsMine(x + size - 1));
CHECK(a->PointerIsMine(x + size / 2));
CHECK_GE(a->GetActuallyAllocatedSize(x), size); CHECK_GE(a->GetActuallyAllocatedSize(x), size);
uptr class_id = a->GetSizeClass(x); uptr class_id = a->GetSizeClass(x);
CHECK_EQ(class_id, Allocator::SizeClassMapT::ClassID(size)); CHECK_EQ(class_id, Allocator::SizeClassMapT::ClassID(size));
@ -265,16 +267,16 @@ TEST(SanitizerCommon, LargeMmapAllocator) {
a.Init(); a.Init();
static const int kNumAllocs = 100; static const int kNumAllocs = 100;
void *allocated[kNumAllocs]; char *allocated[kNumAllocs];
static const uptr size = 1000; static const uptr size = 1000;
// Allocate some. // Allocate some.
for (int i = 0; i < kNumAllocs; i++) { for (int i = 0; i < kNumAllocs; i++) {
allocated[i] = a.Allocate(size, 1); allocated[i] = (char *)a.Allocate(size, 1);
} }
// Deallocate all. // Deallocate all.
CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs); CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs);
for (int i = 0; i < kNumAllocs; i++) { for (int i = 0; i < kNumAllocs; i++) {
void *p = allocated[i]; char *p = allocated[i];
CHECK(a.PointerIsMine(p)); CHECK(a.PointerIsMine(p));
a.Deallocate(p); a.Deallocate(p);
} }
@ -283,7 +285,7 @@ TEST(SanitizerCommon, LargeMmapAllocator) {
// Allocate some more, also add metadata. // Allocate some more, also add metadata.
for (int i = 0; i < kNumAllocs; i++) { for (int i = 0; i < kNumAllocs; i++) {
void *x = a.Allocate(size, 1); char *x = (char *)a.Allocate(size, 1);
CHECK_GE(a.GetActuallyAllocatedSize(x), size); CHECK_GE(a.GetActuallyAllocatedSize(x), size);
uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x)); uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x));
*meta = i; *meta = i;
@ -293,7 +295,7 @@ TEST(SanitizerCommon, LargeMmapAllocator) {
// Deallocate all in reverse order. // Deallocate all in reverse order.
for (int i = 0; i < kNumAllocs; i++) { for (int i = 0; i < kNumAllocs; i++) {
int idx = kNumAllocs - i - 1; int idx = kNumAllocs - i - 1;
void *p = allocated[idx]; char *p = allocated[idx];
uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(p)); uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(p));
CHECK_EQ(*meta, idx); CHECK_EQ(*meta, idx);
CHECK(a.PointerIsMine(p)); CHECK(a.PointerIsMine(p));
@ -304,9 +306,11 @@ TEST(SanitizerCommon, LargeMmapAllocator) {
for (uptr alignment = 8; alignment <= max_alignment; alignment *= 2) { for (uptr alignment = 8; alignment <= max_alignment; alignment *= 2) {
for (int i = 0; i < kNumAllocs; i++) { for (int i = 0; i < kNumAllocs; i++) {
uptr size = ((i % 10) + 1) * 4096; uptr size = ((i % 10) + 1) * 4096;
allocated[i] = a.Allocate(size, alignment); char *p = allocated[i] = (char *)a.Allocate(size, alignment);
CHECK_EQ(p, a.GetBlockBegin(p));
CHECK_EQ(p, a.GetBlockBegin(p + size - 1));
CHECK_EQ(p, a.GetBlockBegin(p + size / 2));
CHECK_EQ(0, (uptr)allocated[i] % alignment); CHECK_EQ(0, (uptr)allocated[i] % alignment);
char *p = (char*)allocated[i];
p[0] = p[size - 1] = 0; p[0] = p[size - 1] = 0;
} }
for (int i = 0; i < kNumAllocs; i++) { for (int i = 0; i < kNumAllocs; i++) {