#define SKIP_ON_SOLARIS_SPARCV9(x) x
#endif
+// On 64-bit systems with small virtual address spaces (e.g. 39-bit) we can't
+// use size class maps with a large number of classes, as that will make the
+// SizeClassAllocator64 region size too small (< 2^32).
+#if SANITIZER_ANDROID && defined(__aarch64__)
+#define ALLOCATOR64_SMALL_SIZE 1
+#elif SANITIZER_RISCV64
+#define ALLOCATOR64_SMALL_SIZE 1
+#else
+#define ALLOCATOR64_SMALL_SIZE 0
+#endif
+
// Too slow for debug build
#if !SANITIZER_DEBUG
static const uptr kAllocatorSize = 0x2000000000ULL;
static const u64 kAddressSpaceSize = 1ULL << 39;
typedef VeryCompactSizeClassMap SizeClassMap;
+#elif SANITIZER_RISCV64
+const uptr kAllocatorSpace = ~(uptr)0;
+const uptr kAllocatorSize = 0x2000000000ULL; // 128G.
+static const u64 kAddressSpaceSize = 1ULL << 38;
+typedef VeryDenseSizeClassMap SizeClassMap;
#else
static const uptr kAllocatorSpace = 0x700000000000ULL;
static const uptr kAllocatorSize = 0x010000000000ULL; // 1T.
TestSizeClassAllocator<Allocator64Dynamic>();
}
-#if !SANITIZER_ANDROID
+#if !ALLOCATOR64_SMALL_SIZE
// Android only has 39-bit address space, so mapping 2 * kAllocatorSize
// sometimes fails.
TEST(SanitizerCommon, SizeClassAllocator64DynamicPremapped) {
TestSizeClassAllocator<Allocator64Dynamic>(h.Addr());
}
-//FIXME(kostyak): find values so that those work on Android as well.
TEST(SanitizerCommon, SizeClassAllocator64Compact) {
TestSizeClassAllocator<Allocator64Compact>();
}
SizeClassAllocatorMetadataStress<Allocator64Dynamic>();
}
-#if !SANITIZER_ANDROID
+#if !ALLOCATOR64_SMALL_SIZE
TEST(SanitizerCommon, SizeClassAllocator64DynamicPremappedMetadataStress) {
ScopedPremappedHeap h;
SizeClassAllocatorMetadataStress<Allocator64Dynamic>(h.Addr());
SizeClassAllocatorGetBlockBeginStress<Allocator64Dynamic>(
1ULL << (SANITIZER_ANDROID ? 31 : 33));
}
-#if !SANITIZER_ANDROID
+#if !ALLOCATOR64_SMALL_SIZE
TEST(SanitizerCommon, SizeClassAllocator64DynamicPremappedGetBlockBegin) {
ScopedPremappedHeap h;
SizeClassAllocatorGetBlockBeginStress<Allocator64Dynamic>(
// Don't test OOM conditions on Win64 because it causes other tests on the same
// machine to OOM.
-#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 && !SANITIZER_ANDROID
+#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64
TEST(SanitizerCommon, SizeClassAllocator64Overflow) {
Allocator64 a;
a.Init(kReleaseToOSIntervalNever);
uint32_t chunks[kNumChunks];
bool allocation_failed = false;
for (int i = 0; i < 1000000; i++) {
- if (!a.GetFromAllocator(&stats, 52, chunks, kNumChunks)) {
+ uptr class_id = a.kNumClasses - 1;
+ if (!a.GetFromAllocator(&stats, class_id, chunks, kNumChunks)) {
allocation_failed = true;
break;
}
TestCombinedAllocator<Allocator64Dynamic>();
}
-#if !SANITIZER_ANDROID
+#if !ALLOCATOR64_SMALL_SIZE
#if !SANITIZER_WINDOWS
// Windows fails to map 1TB, so disable this test.
TEST(SanitizerCommon, CombinedAllocator64DynamicPremapped) {
TestSizeClassAllocatorLocalCache<Allocator64Dynamic>();
}
-#if !SANITIZER_ANDROID
+#if !ALLOCATOR64_SMALL_SIZE
TEST(SanitizerCommon, SizeClassAllocator64DynamicPremappedLocalCache) {
ScopedPremappedHeap h;
TestSizeClassAllocatorLocalCache<Allocator64Dynamic>(h.Addr());
TEST(SanitizerCommon, SizeClassAllocator64DynamicIteration) {
TestSizeClassAllocatorIteration<Allocator64Dynamic>();
}
-#if !SANITIZER_ANDROID
+#if !ALLOCATOR64_SMALL_SIZE
TEST(SanitizerCommon, SizeClassAllocator64DynamicPremappedIteration) {
ScopedPremappedHeap h;
TestSizeClassAllocatorIteration<Allocator64Dynamic>(h.Addr());
// Don't test OOM conditions on Win64 because it causes other tests on the same
// machine to OOM.
-#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 && !SANITIZER_ANDROID
-typedef __sanitizer::SizeClassMap<3, 4, 8, 38, 128, 16> SpecialSizeClassMap;
+#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64
+typedef __sanitizer::SizeClassMap<2, 22, 22, 34, 128, 16> SpecialSizeClassMap;
template <typename AddressSpaceViewTy = LocalAddressSpaceView>
struct AP64_SpecialSizeClassMap {
static const uptr kSpaceBeg = kAllocatorSpace;
// ...one man is on a mission to overflow a region with a series of
// successive allocations.
- const uptr kClassID = 107;
+ const uptr kClassID = ALLOCATOR64_SMALL_SIZE ? 18 : 24;
const uptr kAllocationSize = SpecialSizeClassMap::Size(kClassID);
ASSERT_LT(2 * kAllocationSize, kRegionSize);
ASSERT_GT(3 * kAllocationSize, kRegionSize);
EXPECT_NE(cache.Allocate(a, kClassID), nullptr);
EXPECT_EQ(cache.Allocate(a, kClassID), nullptr);
- const uptr Class2 = 100;
+ const uptr Class2 = ALLOCATOR64_SMALL_SIZE ? 15 : 21;
const uptr Size2 = SpecialSizeClassMap::Size(Class2);
ASSERT_EQ(Size2 * 8, kRegionSize);
char *p[7];
TestReleaseFreeMemoryToOS<Allocator64>();
}
-#if !SANITIZER_ANDROID
+#if !ALLOCATOR64_SMALL_SIZE
TEST(SanitizerCommon, SizeClassAllocator64CompactReleaseFreeMemoryToOS) {
TestReleaseFreeMemoryToOS<Allocator64Compact>();
}
TEST(SanitizerCommon, SizeClassAllocator64VeryCompactReleaseFreeMemoryToOS) {
TestReleaseFreeMemoryToOS<Allocator64VeryCompact>();
}
-#endif // !SANITIZER_ANDROID
+#endif // !ALLOCATOR64_SMALL_SIZE
#endif // SANITIZER_CAN_USE_ALLOCATOR64