Skip to content

Commit 0af1c00

Browse files
committed
src: fix pointer alignment
The NgLibMemoryManager::ReallocImpl method prefixes the allocated memory with its size, and returns a pointer to the region after it. This pointer can however no longer be suitably aligned. On Arm 32bits this resulted in unaligned accesses, since the NEON vst1.64 instruction was used with a not properly aligned addresses. A reproducer is available at [1]. Correct this by allocating the maximum of the the size of the size_t and the max alignment. [1] victronenergy/venus#1559.
1 parent a327288 commit 0af1c00

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

src/node_mem-inl.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace node {
1010
namespace mem {
11+
static constexpr size_t kReserveSizeAndAlign = std::max(sizeof(size_t),
12+
alignof(max_align_t));
1113

1214
template <typename Class, typename AllocatorStruct>
1315
AllocatorStruct NgLibMemoryManager<Class, AllocatorStruct>::MakeAllocator() {
@@ -30,19 +32,19 @@ void* NgLibMemoryManager<Class, T>::ReallocImpl(void* ptr,
3032
char* original_ptr = nullptr;
3133

3234
// We prepend each allocated buffer with a size_t containing the full
33-
// size of the allocation.
34-
if (size > 0) size += sizeof(size_t);
35+
// size of the allocation, while keeping the returned pointer aligned.
36+
if (size > 0) size += kReserveSizeAndAlign;
3537

3638
if (ptr != nullptr) {
3739
// We are free()ing or re-allocating.
38-
original_ptr = static_cast<char*>(ptr) - sizeof(size_t);
40+
original_ptr = static_cast<char*>(ptr) - kReserveSizeAndAlign;
3941
previous_size = *reinterpret_cast<size_t*>(original_ptr);
4042
// This means we called StopTracking() on this pointer before.
4143
if (previous_size == 0) {
4244
// Fall back to the standard Realloc() function.
4345
char* ret = UncheckedRealloc(original_ptr, size);
4446
if (ret != nullptr)
45-
ret += sizeof(size_t);
47+
ret += kReserveSizeAndAlign;
4648
return ret;
4749
}
4850
}
@@ -62,7 +64,7 @@ void* NgLibMemoryManager<Class, T>::ReallocImpl(void* ptr,
6264
manager->env()->external_memory_accounter()->Update(
6365
manager->env()->isolate(), new_size);
6466
*reinterpret_cast<size_t*>(mem) = size;
65-
mem += sizeof(size_t);
67+
mem += kReserveSizeAndAlign;
6668
} else if (size == 0) {
6769
manager->DecreaseAllocatedSize(previous_size);
6870
manager->env()->external_memory_accounter()->Decrease(
@@ -96,7 +98,7 @@ void* NgLibMemoryManager<Class, T>::CallocImpl(size_t nmemb,
9698
template <typename Class, typename T>
9799
void NgLibMemoryManager<Class, T>::StopTrackingMemory(void* ptr) {
98100
size_t* original_ptr = reinterpret_cast<size_t*>(
99-
static_cast<char*>(ptr) - sizeof(size_t));
101+
static_cast<char*>(ptr) - kReserveSizeAndAlign);
100102
Class* manager = static_cast<Class*>(this);
101103
manager->DecreaseAllocatedSize(*original_ptr);
102104
manager->env()->external_memory_accounter()->Decrease(

0 commit comments

Comments
 (0)