From e8d7ab452123d22888dbc2813db3f9502d93c9cd Mon Sep 17 00:00:00 2001 From: Ruoxi Sun Date: Wed, 15 May 2024 12:03:39 +0800 Subject: [PATCH 1/8] WIP --- cpp/src/arrow/compute/util_internal.cc | 46 ++++++++++++++++---------- cpp/src/arrow/compute/util_internal.h | 4 +-- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/cpp/src/arrow/compute/util_internal.cc b/cpp/src/arrow/compute/util_internal.cc index cc26982fef1..c7e2bd20c58 100644 --- a/cpp/src/arrow/compute/util_internal.cc +++ b/cpp/src/arrow/compute/util_internal.cc @@ -20,16 +20,23 @@ #include "arrow/compute/util.h" #include "arrow/memory_pool.h" +#include + namespace arrow { namespace util { +// TempVectorStack::~TempVectorStack() { +// if (buffer_) { +// ASAN_UNPOISON_MEMORY_REGION(buffer_->mutable_data(), buffer_size_); +// } +// } + Status TempVectorStack::Init(MemoryPool* pool, int64_t size) { num_vectors_ = 0; top_ = 0; - buffer_size_ = EstimatedAllocationSize(size); + buffer_size_ = PaddedAllocationSize(size); ARROW_ASSIGN_OR_RAISE(auto buffer, AllocateResizableBuffer(size, pool)); - // Ensure later operations don't accidentally read uninitialized memory. - std::memset(buffer->mutable_data(), 0xFF, size); + ASAN_POISON_MEMORY_REGION(buffer->mutable_data(), size); buffer_ = std::move(buffer); return Status::OK(); } @@ -46,32 +53,35 @@ int64_t TempVectorStack::PaddedAllocationSize(int64_t num_bytes) { } void TempVectorStack::alloc(uint32_t num_bytes, uint8_t** data, int* id) { - int64_t estimated_alloc_size = EstimatedAllocationSize(num_bytes); - int64_t new_top = top_ + estimated_alloc_size; + // int64_t estimated_alloc_size = EstimatedAllocationSize(num_bytes); + int64_t alloc_size = PaddedAllocationSize(num_bytes); + int64_t new_top = top_ + alloc_size; // Stack overflow check (see GH-39582). // XXX cannot return a regular Status because most consumers do not either. ARROW_CHECK_LE(new_top, buffer_size_) - << "TempVectorStack::alloc overflow: allocating " << estimated_alloc_size - << " on top of " << top_ << " in stack of size " << buffer_size_; - *data = buffer_->mutable_data() + top_ + sizeof(uint64_t); - // We set 8 bytes before the beginning of the allocated range and - // 8 bytes after the end to check for stack overflow (which would - // result in those known bytes being corrupted). - reinterpret_cast(buffer_->mutable_data() + top_)[0] = kGuard1; - reinterpret_cast(buffer_->mutable_data() + new_top)[-1] = kGuard2; + << "TempVectorStack::alloc overflow: allocating " << alloc_size << " on top of " + << top_ << " in stack of size " << buffer_size_; + *data = buffer_->mutable_data() + top_; + ASAN_UNPOISON_MEMORY_REGION(*data, alloc_size); + // // We set 8 bytes before the beginning of the allocated range and + // // 8 bytes after the end to check for stack overflow (which would + // // result in those known bytes being corrupted). + // reinterpret_cast(buffer_->mutable_data() + top_)[0] = kGuard1; + // reinterpret_cast(buffer_->mutable_data() + new_top)[-1] = kGuard2; *id = num_vectors_++; top_ = new_top; } void TempVectorStack::release(int id, uint32_t num_bytes) { ARROW_DCHECK(num_vectors_ == id + 1); - int64_t size = EstimatedAllocationSize(num_bytes); - ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[-1] == - kGuard2); + int64_t size = PaddedAllocationSize(num_bytes); + // ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[-1] == + // kGuard2); ARROW_DCHECK(top_ >= size); top_ -= size; - ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[0] == - kGuard1); + ASAN_POISON_MEMORY_REGION(buffer_->mutable_data() + top_, size); + // ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[0] == + // kGuard1); --num_vectors_; } diff --git a/cpp/src/arrow/compute/util_internal.h b/cpp/src/arrow/compute/util_internal.h index 043ff118062..4646f3fac58 100644 --- a/cpp/src/arrow/compute/util_internal.h +++ b/cpp/src/arrow/compute/util_internal.h @@ -38,6 +38,8 @@ class ARROW_EXPORT TempVectorStack { friend class TempVectorHolder; public: + // ~TempVectorStack() = default; + Status Init(MemoryPool* pool, int64_t size); int64_t AllocatedSize() const { return top_; } @@ -51,8 +53,6 @@ class ARROW_EXPORT TempVectorStack { void alloc(uint32_t num_bytes, uint8_t** data, int* id); void release(int id, uint32_t num_bytes); - static constexpr uint64_t kGuard1 = 0x3141592653589793ULL; - static constexpr uint64_t kGuard2 = 0x0577215664901532ULL; static constexpr int64_t kPadding = 64; int num_vectors_; int64_t top_; From bf9abeeccf550af2b8670e9f17dc72628915ea4e Mon Sep 17 00:00:00 2001 From: Ruoxi Sun Date: Thu, 16 May 2024 13:23:02 +0800 Subject: [PATCH 2/8] WIP --- cpp/src/arrow/compute/util_internal.cc | 30 +++++++++++++++++++++----- cpp/src/arrow/compute/util_internal.h | 23 ++++++++++++++++---- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/cpp/src/arrow/compute/util_internal.cc b/cpp/src/arrow/compute/util_internal.cc index c7e2bd20c58..1cef072908e 100644 --- a/cpp/src/arrow/compute/util_internal.cc +++ b/cpp/src/arrow/compute/util_internal.cc @@ -20,24 +20,32 @@ #include "arrow/compute/util.h" #include "arrow/memory_pool.h" +#ifdef ADDRESS_SANITIZER #include +#endif namespace arrow { namespace util { -// TempVectorStack::~TempVectorStack() { -// if (buffer_) { -// ASAN_UNPOISON_MEMORY_REGION(buffer_->mutable_data(), buffer_size_); -// } -// } +TempVectorStack::~TempVectorStack() { +#ifdef ADDRESS_SANITIZER + if (buffer_) { + ASAN_UNPOISON_MEMORY_REGION(buffer_->mutable_data(), buffer_size_); + } +#endif +} Status TempVectorStack::Init(MemoryPool* pool, int64_t size) { num_vectors_ = 0; top_ = 0; buffer_size_ = PaddedAllocationSize(size); ARROW_ASSIGN_OR_RAISE(auto buffer, AllocateResizableBuffer(size, pool)); +#ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(buffer->mutable_data(), size); +#endif buffer_ = std::move(buffer); + // buffer_cure_.buffer = buffer_->mutable_data(); + // buffer_cure_.size = buffer_size_; return Status::OK(); } @@ -62,7 +70,9 @@ void TempVectorStack::alloc(uint32_t num_bytes, uint8_t** data, int* id) { << "TempVectorStack::alloc overflow: allocating " << alloc_size << " on top of " << top_ << " in stack of size " << buffer_size_; *data = buffer_->mutable_data() + top_; +#ifdef ADDRESS_SANITIZER ASAN_UNPOISON_MEMORY_REGION(*data, alloc_size); +#endif // // We set 8 bytes before the beginning of the allocated range and // // 8 bytes after the end to check for stack overflow (which would // // result in those known bytes being corrupted). @@ -79,11 +89,21 @@ void TempVectorStack::release(int id, uint32_t num_bytes) { // kGuard2); ARROW_DCHECK(top_ >= size); top_ -= size; +#ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(buffer_->mutable_data() + top_, size); +#endif // ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[0] == // kGuard1); --num_vectors_; } +// #ifdef ADDRESS_SANITIZER +// TempVectorStack::BufferCure::~BufferCure() { +// if (buffer) { +// ASAN_UNPOISON_MEMORY_REGION(buffer, size); +// } +// } +// #endif + } // namespace util } // namespace arrow diff --git a/cpp/src/arrow/compute/util_internal.h b/cpp/src/arrow/compute/util_internal.h index 4646f3fac58..14f3e7d1776 100644 --- a/cpp/src/arrow/compute/util_internal.h +++ b/cpp/src/arrow/compute/util_internal.h @@ -38,16 +38,22 @@ class ARROW_EXPORT TempVectorStack { friend class TempVectorHolder; public: - // ~TempVectorStack() = default; + TempVectorStack() = default; + ~TempVectorStack(); + + TempVectorStack(const TempVectorStack&) = delete; + TempVectorStack& operator=(const TempVectorStack&) = delete; + TempVectorStack(TempVectorStack&&) = default; + TempVectorStack& operator=(TempVectorStack&&) = default; Status Init(MemoryPool* pool, int64_t size); int64_t AllocatedSize() const { return top_; } private: - static int64_t EstimatedAllocationSize(int64_t size) { - return PaddedAllocationSize(size) + 2 * sizeof(uint64_t); - } + // static int64_t EstimatedAllocationSize(int64_t size) { + // return PaddedAllocationSize(size) + 2 * sizeof(uint64_t); + // } static int64_t PaddedAllocationSize(int64_t num_bytes); @@ -58,6 +64,15 @@ class ARROW_EXPORT TempVectorStack { int64_t top_; std::unique_ptr buffer_; int64_t buffer_size_; + + // #ifdef ADDRESS_SANITIZER + // struct BufferCure { + // uint8_t* buffer = nullptr; + // int64_t size = 0; + // ~BufferCure(); + // }; + // BufferCure buffer_cure_; + // #endif }; template From e6e5dd8af6c51f6d1fe88a4c9eaf2099d78206c6 Mon Sep 17 00:00:00 2001 From: Ruoxi Sun Date: Thu, 16 May 2024 22:42:19 +0800 Subject: [PATCH 3/8] Finalize --- cpp/src/arrow/compute/util_internal.cc | 28 -------------------------- cpp/src/arrow/compute/util_internal.h | 14 +------------ 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/cpp/src/arrow/compute/util_internal.cc b/cpp/src/arrow/compute/util_internal.cc index 1cef072908e..2a5da9a4ea5 100644 --- a/cpp/src/arrow/compute/util_internal.cc +++ b/cpp/src/arrow/compute/util_internal.cc @@ -20,19 +20,15 @@ #include "arrow/compute/util.h" #include "arrow/memory_pool.h" -#ifdef ADDRESS_SANITIZER #include -#endif namespace arrow { namespace util { TempVectorStack::~TempVectorStack() { -#ifdef ADDRESS_SANITIZER if (buffer_) { ASAN_UNPOISON_MEMORY_REGION(buffer_->mutable_data(), buffer_size_); } -#endif } Status TempVectorStack::Init(MemoryPool* pool, int64_t size) { @@ -40,9 +36,7 @@ Status TempVectorStack::Init(MemoryPool* pool, int64_t size) { top_ = 0; buffer_size_ = PaddedAllocationSize(size); ARROW_ASSIGN_OR_RAISE(auto buffer, AllocateResizableBuffer(size, pool)); -#ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(buffer->mutable_data(), size); -#endif buffer_ = std::move(buffer); // buffer_cure_.buffer = buffer_->mutable_data(); // buffer_cure_.size = buffer_size_; @@ -61,7 +55,6 @@ int64_t TempVectorStack::PaddedAllocationSize(int64_t num_bytes) { } void TempVectorStack::alloc(uint32_t num_bytes, uint8_t** data, int* id) { - // int64_t estimated_alloc_size = EstimatedAllocationSize(num_bytes); int64_t alloc_size = PaddedAllocationSize(num_bytes); int64_t new_top = top_ + alloc_size; // Stack overflow check (see GH-39582). @@ -70,14 +63,7 @@ void TempVectorStack::alloc(uint32_t num_bytes, uint8_t** data, int* id) { << "TempVectorStack::alloc overflow: allocating " << alloc_size << " on top of " << top_ << " in stack of size " << buffer_size_; *data = buffer_->mutable_data() + top_; -#ifdef ADDRESS_SANITIZER ASAN_UNPOISON_MEMORY_REGION(*data, alloc_size); -#endif - // // We set 8 bytes before the beginning of the allocated range and - // // 8 bytes after the end to check for stack overflow (which would - // // result in those known bytes being corrupted). - // reinterpret_cast(buffer_->mutable_data() + top_)[0] = kGuard1; - // reinterpret_cast(buffer_->mutable_data() + new_top)[-1] = kGuard2; *id = num_vectors_++; top_ = new_top; } @@ -85,25 +71,11 @@ void TempVectorStack::alloc(uint32_t num_bytes, uint8_t** data, int* id) { void TempVectorStack::release(int id, uint32_t num_bytes) { ARROW_DCHECK(num_vectors_ == id + 1); int64_t size = PaddedAllocationSize(num_bytes); - // ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[-1] == - // kGuard2); ARROW_DCHECK(top_ >= size); top_ -= size; -#ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(buffer_->mutable_data() + top_, size); -#endif - // ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[0] == - // kGuard1); --num_vectors_; } -// #ifdef ADDRESS_SANITIZER -// TempVectorStack::BufferCure::~BufferCure() { -// if (buffer) { -// ASAN_UNPOISON_MEMORY_REGION(buffer, size); -// } -// } -// #endif - } // namespace util } // namespace arrow diff --git a/cpp/src/arrow/compute/util_internal.h b/cpp/src/arrow/compute/util_internal.h index 14f3e7d1776..8f3df96ec14 100644 --- a/cpp/src/arrow/compute/util_internal.h +++ b/cpp/src/arrow/compute/util_internal.h @@ -43,6 +43,7 @@ class ARROW_EXPORT TempVectorStack { TempVectorStack(const TempVectorStack&) = delete; TempVectorStack& operator=(const TempVectorStack&) = delete; + TempVectorStack(TempVectorStack&&) = default; TempVectorStack& operator=(TempVectorStack&&) = default; @@ -51,10 +52,6 @@ class ARROW_EXPORT TempVectorStack { int64_t AllocatedSize() const { return top_; } private: - // static int64_t EstimatedAllocationSize(int64_t size) { - // return PaddedAllocationSize(size) + 2 * sizeof(uint64_t); - // } - static int64_t PaddedAllocationSize(int64_t num_bytes); void alloc(uint32_t num_bytes, uint8_t** data, int* id); @@ -64,15 +61,6 @@ class ARROW_EXPORT TempVectorStack { int64_t top_; std::unique_ptr buffer_; int64_t buffer_size_; - - // #ifdef ADDRESS_SANITIZER - // struct BufferCure { - // uint8_t* buffer = nullptr; - // int64_t size = 0; - // ~BufferCure(); - // }; - // BufferCure buffer_cure_; - // #endif }; template From 9da611e8e5129955f81d9d42373cacb49af2f810 Mon Sep 17 00:00:00 2001 From: Ruoxi Sun Date: Thu, 16 May 2024 22:51:46 +0800 Subject: [PATCH 4/8] Remove dead code --- cpp/src/arrow/compute/util_internal.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp/src/arrow/compute/util_internal.cc b/cpp/src/arrow/compute/util_internal.cc index 2a5da9a4ea5..8ef0af8267f 100644 --- a/cpp/src/arrow/compute/util_internal.cc +++ b/cpp/src/arrow/compute/util_internal.cc @@ -38,8 +38,6 @@ Status TempVectorStack::Init(MemoryPool* pool, int64_t size) { ARROW_ASSIGN_OR_RAISE(auto buffer, AllocateResizableBuffer(size, pool)); ASAN_POISON_MEMORY_REGION(buffer->mutable_data(), size); buffer_ = std::move(buffer); - // buffer_cure_.buffer = buffer_->mutable_data(); - // buffer_cure_.size = buffer_size_; return Status::OK(); } From b75b8042abb94dc0a97d27caa34697de37eaeccd Mon Sep 17 00:00:00 2001 From: Ruoxi Sun Date: Thu, 16 May 2024 23:05:40 +0800 Subject: [PATCH 5/8] Add macro check for asan code --- cpp/src/arrow/compute/util_internal.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cpp/src/arrow/compute/util_internal.cc b/cpp/src/arrow/compute/util_internal.cc index 8ef0af8267f..d01a9515a55 100644 --- a/cpp/src/arrow/compute/util_internal.cc +++ b/cpp/src/arrow/compute/util_internal.cc @@ -26,9 +26,11 @@ namespace arrow { namespace util { TempVectorStack::~TempVectorStack() { +#ifdef ADDRESS_SANITIZER if (buffer_) { ASAN_UNPOISON_MEMORY_REGION(buffer_->mutable_data(), buffer_size_); } +#endif } Status TempVectorStack::Init(MemoryPool* pool, int64_t size) { @@ -36,7 +38,9 @@ Status TempVectorStack::Init(MemoryPool* pool, int64_t size) { top_ = 0; buffer_size_ = PaddedAllocationSize(size); ARROW_ASSIGN_OR_RAISE(auto buffer, AllocateResizableBuffer(size, pool)); +#ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(buffer->mutable_data(), size); +#endif buffer_ = std::move(buffer); return Status::OK(); } @@ -61,7 +65,9 @@ void TempVectorStack::alloc(uint32_t num_bytes, uint8_t** data, int* id) { << "TempVectorStack::alloc overflow: allocating " << alloc_size << " on top of " << top_ << " in stack of size " << buffer_size_; *data = buffer_->mutable_data() + top_; +#ifdef ADDRESS_SANITIZER ASAN_UNPOISON_MEMORY_REGION(*data, alloc_size); +#endif *id = num_vectors_++; top_ = new_top; } @@ -71,7 +77,9 @@ void TempVectorStack::release(int id, uint32_t num_bytes) { int64_t size = PaddedAllocationSize(num_bytes); ARROW_DCHECK(top_ >= size); top_ -= size; +#ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(buffer_->mutable_data() + top_, size); +#endif --num_vectors_; } From 4100c32f06649e5950ae0218eb0fc6ac05af18a7 Mon Sep 17 00:00:00 2001 From: Ruoxi Sun Date: Thu, 16 May 2024 23:08:17 +0800 Subject: [PATCH 6/8] Fix --- cpp/src/arrow/compute/util_internal.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpp/src/arrow/compute/util_internal.cc b/cpp/src/arrow/compute/util_internal.cc index d01a9515a55..f88c89c4cda 100644 --- a/cpp/src/arrow/compute/util_internal.cc +++ b/cpp/src/arrow/compute/util_internal.cc @@ -20,7 +20,9 @@ #include "arrow/compute/util.h" #include "arrow/memory_pool.h" +#ifdef ADDRESS_SANITIZER #include +#endif namespace arrow { namespace util { From 3f5a3f08865431f6e5aa4696f66fb217a1fb27ca Mon Sep 17 00:00:00 2001 From: Ruoxi Sun Date: Sat, 18 May 2024 00:00:09 +0800 Subject: [PATCH 7/8] Use macros for copy/assign and move/assign --- cpp/src/arrow/compute/util_internal.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpp/src/arrow/compute/util_internal.h b/cpp/src/arrow/compute/util_internal.h index 8f3df96ec14..1505d1daf4b 100644 --- a/cpp/src/arrow/compute/util_internal.h +++ b/cpp/src/arrow/compute/util_internal.h @@ -20,6 +20,7 @@ #include "arrow/status.h" #include "arrow/type_fwd.h" #include "arrow/util/logging.h" +#include "arrow/util/macros.h" namespace arrow { namespace util { @@ -41,11 +42,9 @@ class ARROW_EXPORT TempVectorStack { TempVectorStack() = default; ~TempVectorStack(); - TempVectorStack(const TempVectorStack&) = delete; - TempVectorStack& operator=(const TempVectorStack&) = delete; + ARROW_DISALLOW_COPY_AND_ASSIGN(TempVectorStack); - TempVectorStack(TempVectorStack&&) = default; - TempVectorStack& operator=(TempVectorStack&&) = default; + ARROW_DEFAULT_MOVE_AND_ASSIGN(TempVectorStack); Status Init(MemoryPool* pool, int64_t size); From 142419c85b7e59887923ca5ba8a18be96a48e7aa Mon Sep 17 00:00:00 2001 From: Ruoxi Sun Date: Sat, 18 May 2024 00:24:54 +0800 Subject: [PATCH 8/8] Add guard back --- cpp/src/arrow/compute/util_internal.cc | 27 ++++++++++++++++++-------- cpp/src/arrow/compute/util_internal.h | 6 ++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/cpp/src/arrow/compute/util_internal.cc b/cpp/src/arrow/compute/util_internal.cc index f88c89c4cda..9780d1b2f3c 100644 --- a/cpp/src/arrow/compute/util_internal.cc +++ b/cpp/src/arrow/compute/util_internal.cc @@ -38,7 +38,7 @@ TempVectorStack::~TempVectorStack() { Status TempVectorStack::Init(MemoryPool* pool, int64_t size) { num_vectors_ = 0; top_ = 0; - buffer_size_ = PaddedAllocationSize(size); + buffer_size_ = EstimatedAllocationSize(size); ARROW_ASSIGN_OR_RAISE(auto buffer, AllocateResizableBuffer(size, pool)); #ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(buffer->mutable_data(), size); @@ -59,16 +59,23 @@ int64_t TempVectorStack::PaddedAllocationSize(int64_t num_bytes) { } void TempVectorStack::alloc(uint32_t num_bytes, uint8_t** data, int* id) { - int64_t alloc_size = PaddedAllocationSize(num_bytes); - int64_t new_top = top_ + alloc_size; + int64_t estimated_alloc_size = EstimatedAllocationSize(num_bytes); + int64_t new_top = top_ + estimated_alloc_size; // Stack overflow check (see GH-39582). // XXX cannot return a regular Status because most consumers do not either. ARROW_CHECK_LE(new_top, buffer_size_) - << "TempVectorStack::alloc overflow: allocating " << alloc_size << " on top of " - << top_ << " in stack of size " << buffer_size_; - *data = buffer_->mutable_data() + top_; + << "TempVectorStack::alloc overflow: allocating " << estimated_alloc_size + << " on top of " << top_ << " in stack of size " << buffer_size_; #ifdef ADDRESS_SANITIZER - ASAN_UNPOISON_MEMORY_REGION(*data, alloc_size); + ASAN_UNPOISON_MEMORY_REGION(buffer_->mutable_data() + top_, estimated_alloc_size); +#endif + *data = buffer_->mutable_data() + top_ + /*one guard*/ sizeof(uint64_t); +#ifndef NDEBUG + // We set 8 bytes before the beginning of the allocated range and + // 8 bytes after the end to check for stack overflow (which would + // result in those known bytes being corrupted). + reinterpret_cast(buffer_->mutable_data() + top_)[0] = kGuard1; + reinterpret_cast(buffer_->mutable_data() + new_top)[-1] = kGuard2; #endif *id = num_vectors_++; top_ = new_top; @@ -76,9 +83,13 @@ void TempVectorStack::alloc(uint32_t num_bytes, uint8_t** data, int* id) { void TempVectorStack::release(int id, uint32_t num_bytes) { ARROW_DCHECK(num_vectors_ == id + 1); - int64_t size = PaddedAllocationSize(num_bytes); + int64_t size = EstimatedAllocationSize(num_bytes); + ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[-1] == + kGuard2); ARROW_DCHECK(top_ >= size); top_ -= size; + ARROW_DCHECK(reinterpret_cast(buffer_->mutable_data() + top_)[0] == + kGuard1); #ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(buffer_->mutable_data() + top_, size); #endif diff --git a/cpp/src/arrow/compute/util_internal.h b/cpp/src/arrow/compute/util_internal.h index 1505d1daf4b..f6c5ac1f83a 100644 --- a/cpp/src/arrow/compute/util_internal.h +++ b/cpp/src/arrow/compute/util_internal.h @@ -51,10 +51,16 @@ class ARROW_EXPORT TempVectorStack { int64_t AllocatedSize() const { return top_; } private: + static int64_t EstimatedAllocationSize(int64_t size) { + return PaddedAllocationSize(size) + /*two guards*/ 2 * sizeof(uint64_t); + } + static int64_t PaddedAllocationSize(int64_t num_bytes); void alloc(uint32_t num_bytes, uint8_t** data, int* id); void release(int id, uint32_t num_bytes); + static constexpr uint64_t kGuard1 = 0x3141592653589793ULL; + static constexpr uint64_t kGuard2 = 0x0577215664901532ULL; static constexpr int64_t kPadding = 64; int num_vectors_; int64_t top_;