This is an automated email from the ASF dual-hosted git repository.
zhztheplayer pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gluten.git
The following commit(s) were added to refs/heads/main by this push:
new 1b6197dec9 [GLUTEN-13359][CORE] Keep alignment when shrinking an
aligned block (#13360)
1b6197dec9 is described below
commit 1b6197dec94b2c16e101f0fa6dd4baa8efeb807b
Author: YangJie <[email protected]>
AuthorDate: Thu Oct 22 11:17:06 2026 -0400
[GLUTEN-13359][CORE] Keep alignment when shrinking an aligned block (#13360)
Closes #13359
---
cpp/core/memory/MemoryAllocator.cc | 21 +++++++++++++++++++--
cpp/core/tests/MemoryAllocatorTest.cc | 27 +++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/cpp/core/memory/MemoryAllocator.cc
b/cpp/core/memory/MemoryAllocator.cc
index 4e0c8df319..ef35847085 100644
--- a/cpp/core/memory/MemoryAllocator.cc
+++ b/cpp/core/memory/MemoryAllocator.cc
@@ -18,6 +18,7 @@
#include "MemoryAllocator.h"
#include "utils/Macros.h"
+#include <cstdint>
#include <limits>
namespace gluten {
@@ -171,8 +172,24 @@ bool StdMemoryAllocator::reallocateAligned(void* p,
uint64_t alignment, int64_t
if (newSize <= size) {
auto aligned = ROUND_TO_LINE(static_cast<uint64_t>(newSize), alignment);
if (aligned <= size) {
- // shrink-to-fit
- return reallocate(p, size, aligned, out);
+ // shrink-to-fit. realloc only guarantees fundamental alignment, so
allocate an aligned block first to copy into
+ // if realloc moves to a misaligned address. If that allocation fails, p
is left untouched.
+ void* alignedP = std::aligned_alloc(alignment, aligned);
+ if (alignedP == nullptr) {
+ return false;
+ }
+ if (!reallocate(p, size, aligned, out)) {
+ std::free(alignedP);
+ return false;
+ }
+ if (reinterpret_cast<uintptr_t>(*out) % alignment == 0) {
+ std::free(alignedP);
+ } else {
+ memcpy(alignedP, *out, aligned);
+ std::free(*out);
+ *out = alignedP;
+ }
+ return true;
}
}
void* reallocatedP = std::aligned_alloc(alignment, newSize);
diff --git a/cpp/core/tests/MemoryAllocatorTest.cc
b/cpp/core/tests/MemoryAllocatorTest.cc
index 92b337d8a6..bd023544bf 100644
--- a/cpp/core/tests/MemoryAllocatorTest.cc
+++ b/cpp/core/tests/MemoryAllocatorTest.cc
@@ -18,6 +18,8 @@
#include "memory/MemoryAllocator.h"
#include <gtest/gtest.h>
+#include <cstdint>
+
using namespace gluten;
TEST(StdMemoryAllocator, allocateZeroFilledAccounting) {
@@ -35,3 +37,28 @@ TEST(StdMemoryAllocator, allocateZeroFilledAccounting) {
ASSERT_TRUE(allocator.free(buf, expectedBytes));
ASSERT_EQ(allocator.getBytes(), 0);
}
+
+TEST(StdMemoryAllocator, shrinkKeepsAlignment) {
+ StdMemoryAllocator allocator;
+ constexpr uint64_t kAlignment = 64;
+ constexpr int64_t kSize = 1024;
+ // On macOS, realloc can move a shrunk block to an address that is only
16-byte aligned.
+ for (int64_t newSize = kAlignment; newSize < kSize; newSize += kAlignment) {
+ void* buf = nullptr;
+ ASSERT_TRUE(allocator.allocateAligned(kAlignment, kSize, &buf));
+ for (int64_t i = 0; i < kSize; ++i) {
+ static_cast<uint8_t*>(buf)[i] = static_cast<uint8_t>(i);
+ }
+
+ void* shrunk = nullptr;
+ ASSERT_TRUE(allocator.reallocateAligned(buf, kAlignment, kSize, newSize,
&shrunk));
+ ASSERT_EQ(reinterpret_cast<uintptr_t>(shrunk) % kAlignment, 0) << "newSize
" << newSize;
+ for (int64_t i = 0; i < newSize; ++i) {
+ ASSERT_EQ(static_cast<uint8_t*>(shrunk)[i], static_cast<uint8_t>(i)) <<
"newSize " << newSize;
+ }
+ ASSERT_EQ(allocator.getBytes(), newSize);
+
+ ASSERT_TRUE(allocator.free(shrunk, newSize));
+ ASSERT_EQ(allocator.getBytes(), 0);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]