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]

Reply via email to