#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_test_utils.h"
+#include "sanitizer_pthread_wrappers.h"
#include "gtest/gtest.h"
#include <stdlib.h>
-#include <pthread.h>
#include <algorithm>
#include <vector>
#include <set>
// Too slow for debug build
-#if TSAN_DEBUG == 0
+#if !SANITIZER_DEBUG
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
static const uptr kAllocatorSpace = 0x700000000000ULL;
static const uptr kAllocatorSize = 0x010000000000ULL; // 1T.
static const u64 kAddressSpaceSize = 1ULL << 47;
typedef SizeClassAllocator64<
kAllocatorSpace, kAllocatorSize, 16, CompactSizeClassMap> Allocator64Compact;
+#elif defined(__mips64)
+static const u64 kAddressSpaceSize = 1ULL << 40;
+#elif defined(__aarch64__)
+static const u64 kAddressSpaceSize = 1ULL << 39;
#else
static const u64 kAddressSpaceSize = 1ULL << 32;
#endif
uptr size = sizes[s];
if (!a->CanAllocate(size, 1)) continue;
// printf("s = %ld\n", size);
- uptr n_iter = std::max((uptr)6, 8000000 / size);
+ uptr n_iter = std::max((uptr)6, 4000000 / size);
// fprintf(stderr, "size: %ld iter: %ld\n", size, n_iter);
for (uptr i = 0; i < n_iter; i++) {
uptr class_id0 = Allocator::SizeClassMapT::ClassID(size);
delete a;
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, SizeClassAllocator64) {
TestSizeClassAllocator<Allocator64>();
}
delete a;
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, SizeClassAllocator64MetadataStress) {
SizeClassAllocatorMetadataStress<Allocator64>();
}
TEST(SanitizerCommon, SizeClassAllocator64CompactMetadataStress) {
SizeClassAllocatorMetadataStress<Allocator64Compact>();
}
-#endif // SANITIZER_WORDSIZE == 64
+#endif // SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, SizeClassAllocator32CompactMetadataStress) {
SizeClassAllocatorMetadataStress<Allocator32Compact>();
}
delete a;
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, SizeClassAllocator64GetBlockBegin) {
SizeClassAllocatorGetBlockBeginStress<Allocator64>();
}
TEST(SanitizerCommon, SizeClassAllocator32CompactGetBlockBegin) {
SizeClassAllocatorGetBlockBeginStress<Allocator32Compact>();
}
-#endif // SANITIZER_WORDSIZE == 64
+#endif // SANITIZER_CAN_USE_ALLOCATOR64
struct TestMapUnmapCallback {
static int map_count, unmap_count;
int TestMapUnmapCallback::map_count;
int TestMapUnmapCallback::unmap_count;
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) {
TestMapUnmapCallback::map_count = 0;
TestMapUnmapCallback::unmap_count = 0;
TestMapUnmapCallback::map_count = 0;
TestMapUnmapCallback::unmap_count = 0;
LargeMmapAllocator<TestMapUnmapCallback> a;
- a.Init();
+ a.Init(/* may_return_null */ false);
AllocatorStats stats;
stats.Init();
void *x = a.Allocate(&stats, 1 << 20, 1);
a.TestOnlyUnmap();
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, SizeClassAllocator64Overflow) {
EXPECT_DEATH(FailInAssertionOnOOM<Allocator64>(), "Out of memory");
}
#endif
+#if !defined(_WIN32) // FIXME: This currently fails on Windows.
TEST(SanitizerCommon, LargeMmapAllocator) {
LargeMmapAllocator<> a;
- a.Init();
+ a.Init(/* may_return_null */ false);
AllocatorStats stats;
stats.Init();
CHECK_NE(p, (char *)a.GetBlockBegin(p + page_size));
a.Deallocate(&stats, p);
}
+#endif
template
<class PrimaryAllocator, class SecondaryAllocator, class AllocatorCache>
CombinedAllocator<PrimaryAllocator, AllocatorCache, SecondaryAllocator>
Allocator;
Allocator *a = new Allocator;
- a->Init();
+ a->Init(/* may_return_null */ true);
AllocatorCache cache;
memset(&cache, 0, sizeof(cache));
a->InitCache(&cache);
- bool allocator_may_return_null = common_flags()->allocator_may_return_null;
- common_flags()->allocator_may_return_null = true;
EXPECT_EQ(a->Allocate(&cache, -1, 1), (void*)0);
EXPECT_EQ(a->Allocate(&cache, -1, 1024), (void*)0);
EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1024, 1), (void*)0);
EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1024, 1024), (void*)0);
EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1023, 1024), (void*)0);
- common_flags()->allocator_may_return_null = false;
+ // Set to false
+ a->SetMayReturnNull(false);
EXPECT_DEATH(a->Allocate(&cache, -1, 1),
"allocator is terminating the process");
- // Restore the original value.
- common_flags()->allocator_may_return_null = allocator_may_return_null;
const uptr kNumAllocs = 100000;
const uptr kNumIter = 10;
a->TestOnlyUnmap();
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, CombinedAllocator64) {
TestCombinedAllocator<Allocator64,
LargeMmapAllocator<>,
}
#endif
+#if !defined(_WIN32) // FIXME: This currently fails on Windows.
TEST(SanitizerCommon, CombinedAllocator32Compact) {
TestCombinedAllocator<Allocator32Compact,
LargeMmapAllocator<>,
SizeClassAllocatorLocalCache<Allocator32Compact> > ();
}
+#endif
template <class AllocatorCache>
void TestSizeClassAllocatorLocalCache() {
delete a;
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, SizeClassAllocator64LocalCache) {
TestSizeClassAllocatorLocalCache<
SizeClassAllocatorLocalCache<Allocator64> >();
SizeClassAllocatorLocalCache<Allocator32Compact> >();
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
typedef SizeClassAllocatorLocalCache<Allocator64> AllocatorCache;
static AllocatorCache static_allocator_cache;
uptr total_used_memory = 0;
for (int i = 0; i < 100; i++) {
pthread_t t;
- EXPECT_EQ(0, pthread_create(&t, 0, AllocatorLeakTestWorker, &a));
- EXPECT_EQ(0, pthread_join(t, 0));
+ PTHREAD_CREATE(&t, 0, AllocatorLeakTestWorker, &a);
+ PTHREAD_JOIN(t, 0);
if (i == 0)
total_used_memory = a.TotalMemoryUsed();
EXPECT_EQ(a.TotalMemoryUsed(), total_used_memory);
params->allocator = &allocator;
params->class_id = class_id;
pthread_t t;
- EXPECT_EQ(0, pthread_create(&t, 0, DeallocNewThreadWorker, params));
- EXPECT_EQ(0, pthread_join(t, 0));
+ PTHREAD_CREATE(&t, 0, DeallocNewThreadWorker, params);
+ PTHREAD_JOIN(t, 0);
}
#endif
}
}
-TEST(Allocator, InternalAllocFailure) {
- EXPECT_DEATH(Ident(InternalAlloc(10 << 20)),
- "Unexpected mmap in InternalAllocator!");
+TEST(Allocator, LargeAlloc) {
+ void *p = InternalAlloc(10 << 20);
+ InternalFree(p);
}
TEST(Allocator, ScopedBuffer) {
delete a;
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
TEST(SanitizerCommon, SizeClassAllocator64Iteration) {
TestSizeClassAllocatorIteration<Allocator64>();
}
TEST(SanitizerCommon, LargeMmapAllocatorIteration) {
LargeMmapAllocator<> a;
- a.Init();
+ a.Init(/* may_return_null */ false);
AllocatorStats stats;
stats.Init();
TEST(SanitizerCommon, LargeMmapAllocatorBlockBegin) {
LargeMmapAllocator<> a;
- a.Init();
+ a.Init(/* may_return_null */ false);
AllocatorStats stats;
stats.Init();
}
-#if SANITIZER_WORDSIZE == 64
+#if SANITIZER_CAN_USE_ALLOCATOR64
// Regression test for out-of-memory condition in PopulateFreeList().
TEST(SanitizerCommon, SizeClassAllocator64PopulateFreeListOOM) {
// In a world where regions are small and chunks are huge...
p[i].m = &m;
p[i].shard = i;
p[i].num_shards = kNumThreads;
- EXPECT_EQ(0, pthread_create(&t[i], 0, TwoLevelByteMapUserThread, &p[i]));
+ PTHREAD_CREATE(&t[i], 0, TwoLevelByteMapUserThread, &p[i]);
}
for (int i = 0; i < kNumThreads; i++) {
- EXPECT_EQ(0, pthread_join(t[i], 0));
+ PTHREAD_JOIN(t[i], 0);
}
EXPECT_EQ((uptr)TestMapUnmapCallback::map_count, m.size1());
EXPECT_EQ((uptr)TestMapUnmapCallback::unmap_count, 0UL);
EXPECT_EQ((uptr)TestMapUnmapCallback::unmap_count, m.size1());
}
-#endif // #if TSAN_DEBUG==0
+#endif // #if !SANITIZER_DEBUG