diff --git a/stan/math/memory/stack_alloc.hpp b/stan/math/memory/stack_alloc.hpp index 4706473c384..8a8ef2cc7c1 100644 --- a/stan/math/memory/stack_alloc.hpp +++ b/stan/math/memory/stack_alloc.hpp @@ -158,7 +158,9 @@ class stack_alloc { * Return a newly allocated block of memory of the appropriate * size managed by the stack allocator. * - * The allocated pointer will be 8-byte aligned. + * The allocated pointer will be 8-byte aligned. If the number + * of bytes requested is not a multiple of 8, the reserved space + * will be padded up to the next multiple of 8. * * This function may call C++'s malloc() function, * with any exceptions percolated through this function. @@ -167,9 +169,11 @@ class stack_alloc { * @return A pointer to the allocated memory. */ inline void* alloc(size_t len) { + size_t pad = len % 8 == 0 ? 0 : 8 - len % 8; + // Typically, just return and increment the next location. char* result = next_loc_; - next_loc_ += len; + next_loc_ += len + pad; // Occasionally, we have to switch blocks. if (unlikely(next_loc_ >= cur_block_end_)) { result = move_to_next_block(len); diff --git a/test/unit/math/memory/stack_alloc_test.cpp b/test/unit/math/memory/stack_alloc_test.cpp index f4e244afcae..b395df387e9 100644 --- a/test/unit/math/memory/stack_alloc_test.cpp +++ b/test/unit/math/memory/stack_alloc_test.cpp @@ -91,6 +91,15 @@ TEST(stack_alloc, alloc) { allocator.recover_all(); } +TEST(stack_alloc, alloc_aligned) { + stan::math::stack_alloc allocator; + int* x = allocator.alloc_array(3); + + double* y = allocator.alloc_array(4); + EXPECT_TRUE(stan::math::is_aligned(y, 8)); + allocator.recover_all(); +} + TEST(stack_alloc, in_stack) { stan::math::stack_alloc allocator; @@ -113,7 +122,11 @@ TEST(stack_alloc, in_stack_second_block) { char* y = allocator.alloc_array(1); EXPECT_TRUE(allocator.in_stack(x)); EXPECT_TRUE(allocator.in_stack(y)); - EXPECT_FALSE(allocator.in_stack(y + 1)); + // effect of padding + EXPECT_TRUE(allocator.in_stack(y + 1)); + EXPECT_TRUE(allocator.in_stack(y + 7)); + + EXPECT_FALSE(allocator.in_stack(y + 8)); allocator.recover_all(); EXPECT_FALSE(allocator.in_stack(x));