From c134ee7de1919b17ee0803752beb2e19c8855d68 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Mon, 22 Aug 2016 14:03:10 -0700 Subject: [PATCH] ART: Test arena allocator alignment Add tests for Alloc and Realloc alignment. Change-Id: If17b1d898200752a6a1ae25f436c73e5b7eb23f7 Test: m test-art-host-gtest-arena_allocator_test --- runtime/base/arena_allocator_test.cc | 136 +++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/runtime/base/arena_allocator_test.cc b/runtime/base/arena_allocator_test.cc index 9de3cc431..9932586ed 100644 --- a/runtime/base/arena_allocator_test.cc +++ b/runtime/base/arena_allocator_test.cc @@ -124,4 +124,140 @@ TEST_F(ArenaAllocatorTest, LargeAllocations) { } } +TEST_F(ArenaAllocatorTest, AllocAlignment) { + ArenaPool pool; + ArenaAllocator arena(&pool); + for (size_t iterations = 0; iterations <= 10; ++iterations) { + for (size_t size = 1; size <= ArenaAllocator::kAlignment + 1; ++size) { + void* allocation = arena.Alloc(size); + EXPECT_TRUE(IsAligned(allocation)) + << reinterpret_cast(allocation); + } + } +} + +TEST_F(ArenaAllocatorTest, ReallocAlignment) { + { + // Case 1: small aligned allocation, aligned extend inside arena. + ArenaPool pool; + ArenaAllocator arena(&pool); + + const size_t original_size = ArenaAllocator::kAlignment * 2; + void* original_allocation = arena.Alloc(original_size); + ASSERT_TRUE(IsAligned(original_allocation)); + + const size_t new_size = ArenaAllocator::kAlignment * 3; + void* realloc_allocation = arena.Realloc(original_allocation, original_size, new_size); + EXPECT_TRUE(IsAligned(realloc_allocation)); + // Secondary: expect the same buffer. + EXPECT_EQ(original_allocation, realloc_allocation); + + void* after_alloc = arena.Alloc(1); + EXPECT_TRUE(IsAligned(after_alloc)); + } + + { + // Case 2: small aligned allocation, non-aligned extend inside arena. + ArenaPool pool; + ArenaAllocator arena(&pool); + + const size_t original_size = ArenaAllocator::kAlignment * 2; + void* original_allocation = arena.Alloc(original_size); + ASSERT_TRUE(IsAligned(original_allocation)); + + const size_t new_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2); + void* realloc_allocation = arena.Realloc(original_allocation, original_size, new_size); + EXPECT_TRUE(IsAligned(realloc_allocation)); + // Secondary: expect the same buffer. + EXPECT_EQ(original_allocation, realloc_allocation); + + void* after_alloc = arena.Alloc(1); + EXPECT_TRUE(IsAligned(after_alloc)); + } + + { + // Case 3: small non-aligned allocation, aligned extend inside arena. + ArenaPool pool; + ArenaAllocator arena(&pool); + + const size_t original_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2); + void* original_allocation = arena.Alloc(original_size); + ASSERT_TRUE(IsAligned(original_allocation)); + + const size_t new_size = ArenaAllocator::kAlignment * 4; + void* realloc_allocation = arena.Realloc(original_allocation, original_size, new_size); + EXPECT_TRUE(IsAligned(realloc_allocation)); + // Secondary: expect the same buffer. + EXPECT_EQ(original_allocation, realloc_allocation); + + void* after_alloc = arena.Alloc(1); + EXPECT_TRUE(IsAligned(after_alloc)); + } + + { + // Case 4: small non-aligned allocation, aligned non-extend inside arena. + ArenaPool pool; + ArenaAllocator arena(&pool); + + const size_t original_size = ArenaAllocator::kAlignment * 2 + (ArenaAllocator::kAlignment / 2); + void* original_allocation = arena.Alloc(original_size); + ASSERT_TRUE(IsAligned(original_allocation)); + + const size_t new_size = ArenaAllocator::kAlignment * 3; + void* realloc_allocation = arena.Realloc(original_allocation, original_size, new_size); + EXPECT_TRUE(IsAligned(realloc_allocation)); + // Secondary: expect the same buffer. + EXPECT_EQ(original_allocation, realloc_allocation); + + void* after_alloc = arena.Alloc(1); + EXPECT_TRUE(IsAligned(after_alloc)); + } + + // The next part is brittle, as the default size for an arena is variable, and we don't know about + // sanitization. + + { + // Case 5: large allocation, aligned extend into next arena. + ArenaPool pool; + ArenaAllocator arena(&pool); + + const size_t original_size = Arena::kDefaultSize - ArenaAllocator::kAlignment * 5; + void* original_allocation = arena.Alloc(original_size); + ASSERT_TRUE(IsAligned(original_allocation)); + + const size_t new_size = Arena::kDefaultSize + ArenaAllocator::kAlignment * 2; + void* realloc_allocation = arena.Realloc(original_allocation, original_size, new_size); + EXPECT_TRUE(IsAligned(realloc_allocation)); + // Secondary: expect new buffer. + EXPECT_NE(original_allocation, realloc_allocation); + + void* after_alloc = arena.Alloc(1); + EXPECT_TRUE(IsAligned(after_alloc)); + } + + { + // Case 6: large allocation, non-aligned extend into next arena. + ArenaPool pool; + ArenaAllocator arena(&pool); + + const size_t original_size = Arena::kDefaultSize - + ArenaAllocator::kAlignment * 4 - + ArenaAllocator::kAlignment / 2; + void* original_allocation = arena.Alloc(original_size); + ASSERT_TRUE(IsAligned(original_allocation)); + + const size_t new_size = Arena::kDefaultSize + + ArenaAllocator::kAlignment * 2 + + ArenaAllocator::kAlignment / 2; + void* realloc_allocation = arena.Realloc(original_allocation, original_size, new_size); + EXPECT_TRUE(IsAligned(realloc_allocation)); + // Secondary: expect new buffer. + EXPECT_NE(original_allocation, realloc_allocation); + + void* after_alloc = arena.Alloc(1); + EXPECT_TRUE(IsAligned(after_alloc)); + } +} + + } // namespace art -- 2.11.0