From d86cdb5fa3f75ec3af4fedf0298cd7240145909a Mon Sep 17 00:00:00 2001 From: wacfrr <284174234+wacfrr@users.noreply.github.com> Date: Tue, 2 Jun 2026 23:41:53 +0800 Subject: [PATCH 1/6] core: use ::operator delete for RVec heavy storage on Windows --- math/vecops/inc/ROOT/RVec.hxx | 33 +++++++++++++++++++++++------- math/vecops/src/RVec.cxx | 38 +++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/math/vecops/inc/ROOT/RVec.hxx b/math/vecops/inc/ROOT/RVec.hxx index fdf9d42d011f0..b0749f5d440a5 100644 --- a/math/vecops/inc/ROOT/RVec.hxx +++ b/math/vecops/inc/ROOT/RVec.hxx @@ -403,7 +403,11 @@ void R__CLING_PTRCHECK(off) SmallVectorTemplateBase::grow( // Always grow, even from zero. size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2)); NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax()); - T *NewElts = static_cast(malloc(NewCapacity * sizeof(T))); + #if _WIN32 + T *NewElts = static_cast(::operator new(NewCapacity * sizeof(T), std::nothrow)); + #else + T *NewElts = static_cast(malloc(NewCapacity * sizeof(T))); + #endif R__ASSERT(NewElts != nullptr); // Move the elements over. @@ -414,8 +418,13 @@ void R__CLING_PTRCHECK(off) SmallVectorTemplateBase::grow( destroy_range(this->begin(), this->end()); // If this wasn't grown from the inline copy, deallocate the old space. - if (!this->isSmall()) - free(this->begin()); + #if _WIN32 + if (!this->isSmall()) + ::operator delete(this->begin()); + #else + if (!this->isSmall()) + free(this->begin()); + #endif } this->fBeginX = NewElts; @@ -575,8 +584,13 @@ public: { // Subclass has already destructed this vector's elements. // If this wasn't grown from the inline copy, deallocate the old space. - if (!this->isSmall() && this->Owns()) - free(this->begin()); + #if _WIN32 + if (!this->isSmall() && this->Owns()) + ::operator delete(this->begin()); + #else + if (!this->isSmall() && this->Owns()) + free(this->begin()); + #endif } // also give up adopted memory if applicable @@ -1052,8 +1066,13 @@ RVecImpl &RVecImpl::operator=(RVecImpl &&RHS) if (!RHS.isSmall()) { if (this->Owns()) { this->destroy_range(this->begin(), this->end()); - if (!this->isSmall()) - free(this->begin()); + #if _WIN32 + if (!this->isSmall()) + ::operator delete(this->begin()); + #else + if (!this->isSmall()) + free(this->begin()); + #endif } this->fBeginX = RHS.fBeginX; this->fSize = RHS.fSize; diff --git a/math/vecops/src/RVec.cxx b/math/vecops/src/RVec.cxx index 6f54578478ecb..3739039686b91 100644 --- a/math/vecops/src/RVec.cxx +++ b/math/vecops/src/RVec.cxx @@ -68,17 +68,33 @@ void ROOT::Internal::VecOps::SmallVectorBase::grow_pod(void *FirstEl, size_t Min NewCapacity = std::min(std::max(NewCapacity, MinSize), SizeTypeMax()); void *NewElts; - if (fBeginX == FirstEl || !this->Owns()) { - NewElts = malloc(NewCapacity * TSize); - R__ASSERT(NewElts != nullptr); - - // Copy the elements over. No need to run dtors on PODs. - memcpy(NewElts, this->fBeginX, size() * TSize); - } else { - // If this wasn't grown from the inline copy, grow the allocated space. - NewElts = realloc(this->fBeginX, NewCapacity * TSize); - R__ASSERT(NewElts != nullptr); - } + #if _WIN32 + if (fBeginX == FirstEl || !this->Owns()) { + NewElts = ::operator new(NewCapacity * TSize, std::nothrow); + R__ASSERT(NewElts != nullptr); + + // Copy the elements over. No need to run dtors on PODs. + memcpy(NewElts, this->fBeginX, size() * TSize); + } else { + // If this wasn't grown from the inline copy, grow the allocated space. + NewElts = ::operator new(NewCapacity * TSize, std::nothrow); + R__ASSERT(NewElts != nullptr); + memcpy(NewElts, this->fBeginX, size() * TSize); + ::operator delete(this->fBeginX); + } + #else + if (fBeginX == FirstEl || !this->Owns()) { + NewElts = malloc(NewCapacity * TSize); + R__ASSERT(NewElts != nullptr); + + // Copy the elements over. No need to run dtors on PODs. + memcpy(NewElts, this->fBeginX, size() * TSize); + } else { + // If this wasn't grown from the inline copy, grow the allocated space. + NewElts = realloc(this->fBeginX, NewCapacity * TSize); + R__ASSERT(NewElts != nullptr); + } + #endif this->fBeginX = NewElts; this->fCapacity = NewCapacity; From 0a3a832226fc94a56f63ceec998ff993463d2593 Mon Sep 17 00:00:00 2001 From: wacfrr Date: Mon, 8 Jun 2026 21:58:13 +0800 Subject: [PATCH 2/6] Update math/vecops/inc/ROOT/RVec.hxx Co-authored-by: Bertrand Bellenot --- math/vecops/inc/ROOT/RVec.hxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/math/vecops/inc/ROOT/RVec.hxx b/math/vecops/inc/ROOT/RVec.hxx index b0749f5d440a5..1dbedec0adea1 100644 --- a/math/vecops/inc/ROOT/RVec.hxx +++ b/math/vecops/inc/ROOT/RVec.hxx @@ -403,11 +403,11 @@ void R__CLING_PTRCHECK(off) SmallVectorTemplateBase::grow( // Always grow, even from zero. size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2)); NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax()); - #if _WIN32 - T *NewElts = static_cast(::operator new(NewCapacity * sizeof(T), std::nothrow)); - #else - T *NewElts = static_cast(malloc(NewCapacity * sizeof(T))); - #endif +#ifdef _WIN32 + T *NewElts = static_cast(::operator new(NewCapacity * sizeof(T), std::nothrow)); +#else + T *NewElts = static_cast(malloc(NewCapacity * sizeof(T))); +#endif R__ASSERT(NewElts != nullptr); // Move the elements over. From 64c4664f7bc448542023b6223f531b0c5890f4d5 Mon Sep 17 00:00:00 2001 From: wacfrr Date: Mon, 8 Jun 2026 21:58:38 +0800 Subject: [PATCH 3/6] Update math/vecops/inc/ROOT/RVec.hxx Co-authored-by: Bertrand Bellenot --- math/vecops/inc/ROOT/RVec.hxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/math/vecops/inc/ROOT/RVec.hxx b/math/vecops/inc/ROOT/RVec.hxx index 1dbedec0adea1..ad58b54fc098d 100644 --- a/math/vecops/inc/ROOT/RVec.hxx +++ b/math/vecops/inc/ROOT/RVec.hxx @@ -1066,13 +1066,13 @@ RVecImpl &RVecImpl::operator=(RVecImpl &&RHS) if (!RHS.isSmall()) { if (this->Owns()) { this->destroy_range(this->begin(), this->end()); - #if _WIN32 - if (!this->isSmall()) - ::operator delete(this->begin()); - #else - if (!this->isSmall()) - free(this->begin()); - #endif +#ifdef _WIN32 + if (!this->isSmall()) + ::operator delete(this->begin()); +#else + if (!this->isSmall()) + free(this->begin()); +#endif } this->fBeginX = RHS.fBeginX; this->fSize = RHS.fSize; From 2ab9afe552cdb9cced7467ccdedf78c7c71f8073 Mon Sep 17 00:00:00 2001 From: wacfrr Date: Mon, 8 Jun 2026 21:59:04 +0800 Subject: [PATCH 4/6] Update math/vecops/src/RVec.cxx Co-authored-by: Bertrand Bellenot --- math/vecops/src/RVec.cxx | 54 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/math/vecops/src/RVec.cxx b/math/vecops/src/RVec.cxx index 3739039686b91..37de52736d8fc 100644 --- a/math/vecops/src/RVec.cxx +++ b/math/vecops/src/RVec.cxx @@ -68,33 +68,33 @@ void ROOT::Internal::VecOps::SmallVectorBase::grow_pod(void *FirstEl, size_t Min NewCapacity = std::min(std::max(NewCapacity, MinSize), SizeTypeMax()); void *NewElts; - #if _WIN32 - if (fBeginX == FirstEl || !this->Owns()) { - NewElts = ::operator new(NewCapacity * TSize, std::nothrow); - R__ASSERT(NewElts != nullptr); - - // Copy the elements over. No need to run dtors on PODs. - memcpy(NewElts, this->fBeginX, size() * TSize); - } else { - // If this wasn't grown from the inline copy, grow the allocated space. - NewElts = ::operator new(NewCapacity * TSize, std::nothrow); - R__ASSERT(NewElts != nullptr); - memcpy(NewElts, this->fBeginX, size() * TSize); - ::operator delete(this->fBeginX); - } - #else - if (fBeginX == FirstEl || !this->Owns()) { - NewElts = malloc(NewCapacity * TSize); - R__ASSERT(NewElts != nullptr); - - // Copy the elements over. No need to run dtors on PODs. - memcpy(NewElts, this->fBeginX, size() * TSize); - } else { - // If this wasn't grown from the inline copy, grow the allocated space. - NewElts = realloc(this->fBeginX, NewCapacity * TSize); - R__ASSERT(NewElts != nullptr); - } - #endif +#ifdef _WIN32 + if (fBeginX == FirstEl || !this->Owns()) { + NewElts = ::operator new(NewCapacity * TSize, std::nothrow); + R__ASSERT(NewElts != nullptr); + + // Copy the elements over. No need to run dtors on PODs. + memcpy(NewElts, this->fBeginX, size() * TSize); + } else { + // If this wasn't grown from the inline copy, grow the allocated space. + NewElts = ::operator new(NewCapacity * TSize, std::nothrow); + R__ASSERT(NewElts != nullptr); + memcpy(NewElts, this->fBeginX, size() * TSize); + ::operator delete(this->fBeginX); + } +#else + if (fBeginX == FirstEl || !this->Owns()) { + NewElts = malloc(NewCapacity * TSize); + R__ASSERT(NewElts != nullptr); + + // Copy the elements over. No need to run dtors on PODs. + memcpy(NewElts, this->fBeginX, size() * TSize); + } else { + // If this wasn't grown from the inline copy, grow the allocated space. + NewElts = realloc(this->fBeginX, NewCapacity * TSize); + R__ASSERT(NewElts != nullptr); + } +#endif this->fBeginX = NewElts; this->fCapacity = NewCapacity; From 531fb7763b9b5cbc28ae70d3f056aed2ad7ee024 Mon Sep 17 00:00:00 2001 From: wacfrr Date: Mon, 8 Jun 2026 21:59:33 +0800 Subject: [PATCH 5/6] Update math/vecops/inc/ROOT/RVec.hxx Co-authored-by: Bertrand Bellenot --- math/vecops/inc/ROOT/RVec.hxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/math/vecops/inc/ROOT/RVec.hxx b/math/vecops/inc/ROOT/RVec.hxx index ad58b54fc098d..a29c9c0719319 100644 --- a/math/vecops/inc/ROOT/RVec.hxx +++ b/math/vecops/inc/ROOT/RVec.hxx @@ -584,13 +584,13 @@ public: { // Subclass has already destructed this vector's elements. // If this wasn't grown from the inline copy, deallocate the old space. - #if _WIN32 - if (!this->isSmall() && this->Owns()) - ::operator delete(this->begin()); - #else - if (!this->isSmall() && this->Owns()) - free(this->begin()); - #endif +#ifdef _WIN32 + if (!this->isSmall() && this->Owns()) + ::operator delete(this->begin()); +#else + if (!this->isSmall() && this->Owns()) + free(this->begin()); +#endif } // also give up adopted memory if applicable From 91e7252a71769c8966806a1e9e4ea9245a0156b8 Mon Sep 17 00:00:00 2001 From: wacfrr Date: Mon, 8 Jun 2026 21:59:47 +0800 Subject: [PATCH 6/6] Update math/vecops/inc/ROOT/RVec.hxx Co-authored-by: Bertrand Bellenot --- math/vecops/inc/ROOT/RVec.hxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/math/vecops/inc/ROOT/RVec.hxx b/math/vecops/inc/ROOT/RVec.hxx index a29c9c0719319..89af62eb4ed7b 100644 --- a/math/vecops/inc/ROOT/RVec.hxx +++ b/math/vecops/inc/ROOT/RVec.hxx @@ -418,13 +418,13 @@ void R__CLING_PTRCHECK(off) SmallVectorTemplateBase::grow( destroy_range(this->begin(), this->end()); // If this wasn't grown from the inline copy, deallocate the old space. - #if _WIN32 - if (!this->isSmall()) - ::operator delete(this->begin()); - #else - if (!this->isSmall()) - free(this->begin()); - #endif +#ifdef _WIN32 + if (!this->isSmall()) + ::operator delete(this->begin()); +#else + if (!this->isSmall()) + free(this->begin()); +#endif } this->fBeginX = NewElts;