aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2011-03-19 01:06:50 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2011-03-19 01:06:50 +0100
commit290205dfc049abc5a92c1191740b30fa91130ade (patch)
tree0d07fea8597fb5d7f023a23cce7cb0b240be84c2
parent5991d247f9b167ed738ef95ead0b5ee9a0248edd (diff)
fix memory leak when a custom scalar throw an exception
-rw-r--r--Eigen/src/Core/Product.h35
-rw-r--r--Eigen/src/Core/SolveTriangular.h17
-rw-r--r--Eigen/src/Core/products/GeneralMatrixMatrix.h16
-rw-r--r--Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h6
-rw-r--r--Eigen/src/Core/products/SelfadjointMatrixMatrix.h15
-rw-r--r--Eigen/src/Core/products/SelfadjointMatrixVector.h41
-rw-r--r--Eigen/src/Core/products/SelfadjointProduct.h20
-rw-r--r--Eigen/src/Core/products/TriangularMatrixMatrix.h16
-rw-r--r--Eigen/src/Core/products/TriangularMatrixVector.h43
-rw-r--r--Eigen/src/Core/products/TriangularSolverMatrix.h14
-rw-r--r--Eigen/src/Core/util/Memory.h82
11 files changed, 116 insertions, 189 deletions
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index 1363e83b6..bde25375d 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -416,23 +416,15 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
- ResScalar* actualDestPtr;
- bool freeDestPtr = false;
- if (evalToDest)
- {
- actualDestPtr = &dest.coeffRef(0);
- }
- else
+ ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
+ evalToDest ? dest.data() : static_dest.data());
+
+ if(!evalToDest)
{
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
int size = dest.size();
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
#endif
- if((actualDestPtr = static_dest.data())==0)
- {
- freeDestPtr = true;
- actualDestPtr = ei_aligned_stack_new(ResScalar,dest.size());
- }
if(!alphaIsCompatible)
{
MappedDest(actualDestPtr, dest.size()).setZero();
@@ -456,7 +448,6 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
else
dest = MappedDest(actualDestPtr, dest.size());
- if(freeDestPtr) ei_aligned_stack_delete(ResScalar, actualDestPtr, dest.size());
}
}
};
@@ -490,23 +481,15 @@ template<> struct gemv_selector<OnTheRight,RowMajor,true>
gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
- RhsScalar* actualRhsPtr;
- bool freeRhsPtr = false;
- if (DirectlyUseRhs)
- {
- actualRhsPtr = const_cast<RhsScalar*>(&actualRhs.coeffRef(0));
- }
- else
+ ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
+ DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
+
+ if(!DirectlyUseRhs)
{
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
int size = actualRhs.size();
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
#endif
- if((actualRhsPtr = static_rhs.data())==0)
- {
- freeRhsPtr = true;
- actualRhsPtr = ei_aligned_stack_new(RhsScalar, actualRhs.size());
- }
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
}
@@ -517,8 +500,6 @@ template<> struct gemv_selector<OnTheRight,RowMajor,true>
actualRhsPtr, 1,
&dest.coeffRef(0,0), dest.innerStride(),
actualAlpha);
-
- if((!DirectlyUseRhs) && freeRhsPtr) ei_aligned_stack_delete(RhsScalar, actualRhsPtr, prod.rhs().size());
}
};
diff --git a/Eigen/src/Core/SolveTriangular.h b/Eigen/src/Core/SolveTriangular.h
index 7cbcf3d80..71e129c7f 100644
--- a/Eigen/src/Core/SolveTriangular.h
+++ b/Eigen/src/Core/SolveTriangular.h
@@ -74,26 +74,19 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,1>
// FIXME find a way to allow an inner stride if packet_traits<Scalar>::size==1
bool useRhsDirectly = Rhs::InnerStrideAtCompileTime==1 || rhs.innerStride()==1;
- RhsScalar* actualRhs;
- if(useRhsDirectly)
- {
- actualRhs = &rhs.coeffRef(0);
- }
- else
- {
- actualRhs = ei_aligned_stack_new(RhsScalar,rhs.size());
+
+ ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhs,rhs.size(),
+ (useRhsDirectly ? rhs.data() : 0));
+
+ if(!useRhsDirectly)
MappedRhs(actualRhs,rhs.size()) = rhs;
- }
triangular_solve_vector<LhsScalar, RhsScalar, typename Lhs::Index, Side, Mode, LhsProductTraits::NeedToConjugate,
(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor>
::run(actualLhs.cols(), actualLhs.data(), actualLhs.outerStride(), actualRhs);
if(!useRhsDirectly)
- {
rhs = MappedRhs(actualRhs, rhs.size());
- ei_aligned_stack_delete(RhsScalar, actualRhs, rhs.size());
- }
}
};
diff --git a/Eigen/src/Core/products/GeneralMatrixMatrix.h b/Eigen/src/Core/products/GeneralMatrixMatrix.h
index 7736a4b29..d558b4759 100644
--- a/Eigen/src/Core/products/GeneralMatrixMatrix.h
+++ b/Eigen/src/Core/products/GeneralMatrixMatrix.h
@@ -94,8 +94,9 @@ static void run(Index rows, Index cols, Index depth,
std::size_t sizeA = kc*mc;
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
- LhsScalar* blockA = ei_aligned_stack_new(LhsScalar, sizeA);
- RhsScalar* w = ei_aligned_stack_new(RhsScalar, sizeW);
+ ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, sizeA, 0);
+ ei_declare_aligned_stack_constructed_variable(RhsScalar, w, sizeW, 0);
+
RhsScalar* blockB = blocking.blockB();
eigen_internal_assert(blockB!=0);
@@ -167,9 +168,10 @@ static void run(Index rows, Index cols, Index depth,
std::size_t sizeA = kc*mc;
std::size_t sizeB = kc*cols;
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
- LhsScalar *blockA = blocking.blockA()==0 ? ei_aligned_stack_new(LhsScalar, sizeA) : blocking.blockA();
- RhsScalar *blockB = blocking.blockB()==0 ? ei_aligned_stack_new(RhsScalar, sizeB) : blocking.blockB();
- RhsScalar *blockW = blocking.blockW()==0 ? ei_aligned_stack_new(RhsScalar, sizeW) : blocking.blockW();
+
+ ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, sizeA, blocking.blockA());
+ ei_declare_aligned_stack_constructed_variable(RhsScalar, blockB, sizeB, blocking.blockB());
+ ei_declare_aligned_stack_constructed_variable(RhsScalar, blockW, sizeW, blocking.blockW());
// For each horizontal panel of the rhs, and corresponding panel of the lhs...
// (==GEMM_VAR1)
@@ -200,10 +202,6 @@ static void run(Index rows, Index cols, Index depth,
}
}
-
- if(blocking.blockA()==0) ei_aligned_stack_delete(LhsScalar, blockA, sizeA);
- if(blocking.blockB()==0) ei_aligned_stack_delete(RhsScalar, blockB, sizeB);
- if(blocking.blockW()==0) ei_aligned_stack_delete(RhsScalar, blockW, sizeW);
}
}
diff --git a/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
index 39495c1a2..562c9c5ad 100644
--- a/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+++ b/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
@@ -83,10 +83,10 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,
if(mc > Traits::nr)
mc = (mc/Traits::nr)*Traits::nr;
- LhsScalar* blockA = ei_aligned_stack_new(LhsScalar, kc*mc);
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
std::size_t sizeB = sizeW + kc*size;
- RhsScalar* allocatedBlockB = ei_aligned_stack_new(RhsScalar, sizeB);
+ ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, kc*mc, 0);
+ ei_declare_aligned_stack_constructed_variable(RhsScalar, allocatedBlockB, sizeB, 0);
RhsScalar* blockB = allocatedBlockB + sizeW;
gemm_pack_lhs<LhsScalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
@@ -125,8 +125,6 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,
}
}
}
- ei_aligned_stack_delete(LhsScalar, blockA, kc*mc);
- ei_aligned_stack_delete(RhsScalar, allocatedBlockB, sizeB);
}
};
diff --git a/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
index cfebcf426..6eb54d6ef 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
@@ -263,10 +263,10 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
// kc must smaller than mc
kc = std::min(kc,mc);
- Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
std::size_t sizeB = sizeW + kc*cols;
- Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
+ ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
+ ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
Scalar* blockB = allocatedBlockB + sizeW;
gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
@@ -313,9 +313,6 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha);
}
}
-
- ei_aligned_stack_delete(Scalar, blockA, kc*mc);
- ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
}
};
@@ -343,11 +340,10 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLh
Index mc = rows; // cache block size along the M direction
Index nc = cols; // cache block size along the N direction
computeProductBlockingSizes<Scalar,Scalar>(kc, mc, nc);
-
- Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
std::size_t sizeB = sizeW + kc*cols;
- Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
+ ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
+ ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
Scalar* blockB = allocatedBlockB + sizeW;
gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
@@ -369,9 +365,6 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLh
gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha);
}
}
-
- ei_aligned_stack_delete(Scalar, blockA, kc*mc);
- ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
}
};
diff --git a/Eigen/src/Core/products/SelfadjointMatrixVector.h b/Eigen/src/Core/products/SelfadjointMatrixVector.h
index 1d433e16d..62744f98d 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixVector.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixVector.h
@@ -62,14 +62,12 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector(
// FIXME this copy is now handled outside product_selfadjoint_vector, so it could probably be removed.
// if the rhs is not sequentially stored in memory we copy it to a temporary buffer,
// this is because we need to extract packets
- const Scalar* EIGEN_RESTRICT rhs = _rhs;
+ ei_declare_aligned_stack_constructed_variable(Scalar,rhs,size,rhsIncr==1 ? const_cast<Scalar*>(_rhs) : 0);
if (rhsIncr!=1)
{
- Scalar* r = ei_aligned_stack_new(Scalar, size);
const Scalar* it = _rhs;
for (Index i=0; i<size; ++i, it+=rhsIncr)
- r[i] = *it;
- rhs = r;
+ rhs[i] = *it;
}
Index bound = std::max(Index(0),size-8) & 0xfffffffe;
@@ -160,9 +158,6 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector(
}
res[j] += alpha * t2;
}
-
- if(rhsIncr!=1)
- ei_aligned_stack_delete(Scalar, const_cast<Scalar*>(rhs), size);
}
} // end namespace internal
@@ -211,40 +206,28 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>
internal::gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,!EvalToDest> static_dest;
internal::gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!UseRhs> static_rhs;
+
+ ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
+ EvalToDest ? dest.data() : static_dest.data());
+
+ ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,rhs.size(),
+ UseRhs ? const_cast<RhsScalar*>(rhs.data()) : static_rhs.data());
- bool freeDestPtr = false;
- ResScalar* actualDestPtr;
- if(EvalToDest)
- actualDestPtr = dest.data();
- else
+ if(!EvalToDest)
{
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
int size = dest.size();
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
#endif
- if((actualDestPtr=static_dest.data())==0)
- {
- freeDestPtr = true;
- actualDestPtr = ei_aligned_stack_new(ResScalar,dest.size());
- }
MappedDest(actualDestPtr, dest.size()) = dest;
}
- bool freeRhsPtr = false;
- RhsScalar* actualRhsPtr;
- if(UseRhs)
- actualRhsPtr = const_cast<RhsScalar*>(rhs.data());
- else
+ if(!UseRhs)
{
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
int size = rhs.size();
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
#endif
- if((actualRhsPtr=static_rhs.data())==0)
- {
- freeRhsPtr = true;
- actualRhsPtr = ei_aligned_stack_new(RhsScalar,rhs.size());
- }
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, rhs.size()) = rhs;
}
@@ -259,11 +242,7 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>
);
if(!EvalToDest)
- {
dest = MappedDest(actualDestPtr, dest.size());
- if(freeDestPtr) ei_aligned_stack_delete(ResScalar, actualDestPtr, dest.size());
- }
- if(freeRhsPtr) ei_aligned_stack_delete(RhsScalar, actualRhsPtr, rhs.size());
}
};
diff --git a/Eigen/src/Core/products/SelfadjointProduct.h b/Eigen/src/Core/products/SelfadjointProduct.h
index da2e6ee20..3a4523fa4 100644
--- a/Eigen/src/Core/products/SelfadjointProduct.h
+++ b/Eigen/src/Core/products/SelfadjointProduct.h
@@ -81,27 +81,17 @@ struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,true>
UseOtherDirectly = _ActualOtherType::InnerStrideAtCompileTime==1
};
internal::gemv_static_vector_if<Scalar,OtherType::SizeAtCompileTime,OtherType::MaxSizeAtCompileTime,!UseOtherDirectly> static_other;
-
- bool freeOtherPtr = false;
- Scalar* actualOtherPtr;
- if(UseOtherDirectly)
- actualOtherPtr = const_cast<Scalar*>(actualOther.data());
- else
- {
- if((actualOtherPtr=static_other.data())==0)
- {
- freeOtherPtr = true;
- actualOtherPtr = ei_aligned_stack_new(Scalar,other.size());
- }
+
+ ei_declare_aligned_stack_constructed_variable(Scalar, actualOtherPtr, other.size(),
+ (UseOtherDirectly ? const_cast<Scalar*>(actualOther.data()) : static_other.data()));
+
+ if(!UseOtherDirectly)
Map<typename _ActualOtherType::PlainObject>(actualOtherPtr, actualOther.size()) = actualOther;
- }
selfadjoint_rank1_update<Scalar,Index,StorageOrder,UpLo,
OtherBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex,
(!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex>
::run(other.size(), mat.data(), mat.outerStride(), actualOtherPtr, actualAlpha);
-
- if((!UseOtherDirectly) && freeOtherPtr) ei_aligned_stack_delete(Scalar, actualOtherPtr, other.size());
}
};
diff --git a/Eigen/src/Core/products/TriangularMatrixMatrix.h b/Eigen/src/Core/products/TriangularMatrixMatrix.h
index 66a2515d0..8f7e58f62 100644
--- a/Eigen/src/Core/products/TriangularMatrixMatrix.h
+++ b/Eigen/src/Core/products/TriangularMatrixMatrix.h
@@ -118,11 +118,10 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
Index mc = rows; // cache block size along the M direction
Index nc = cols; // cache block size along the N direction
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
-
- Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
std::size_t sizeB = sizeW + kc*cols;
- Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
+ ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
+ ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
Scalar* blockB = allocatedBlockB + sizeW;
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer;
@@ -208,10 +207,6 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
}
}
}
-
- ei_aligned_stack_delete(Scalar, blockA, kc*mc);
- ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
-// delete[] allocatedBlockB;
}
};
@@ -246,10 +241,10 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
Index nc = cols; // cache block size along the N direction
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
- Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
std::size_t sizeB = sizeW + kc*cols;
- Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar,sizeB);
+ ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
+ ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
Scalar* blockB = allocatedBlockB + sizeW;
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer;
@@ -347,9 +342,6 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
-1, -1, 0, 0, allocatedBlockB);
}
}
-
- ei_aligned_stack_delete(Scalar, blockA, kc*mc);
- ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
}
};
diff --git a/Eigen/src/Core/products/TriangularMatrixVector.h b/Eigen/src/Core/products/TriangularMatrixVector.h
index 23aa52ade..1dd2fafa4 100644
--- a/Eigen/src/Core/products/TriangularMatrixVector.h
+++ b/Eigen/src/Core/products/TriangularMatrixVector.h
@@ -41,9 +41,6 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
static EIGEN_DONT_INLINE void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride,
const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha)
{
- EIGEN_UNUSED_VARIABLE(resIncr);
- eigen_assert(resIncr==1);
-
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
@@ -95,9 +92,6 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
static void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride,
const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha)
{
- eigen_assert(rhsIncr==1);
- EIGEN_UNUSED_VARIABLE(rhsIncr);
-
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
@@ -185,7 +179,7 @@ struct TriangularProduct<Mode,false,Lhs,true,Rhs,false>
template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
{
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
-
+
typedef TriangularProduct<(Mode & UnitDiag) | ((Mode & Lower) ? Upper : Lower),true,Transpose<const Rhs>,false,Transpose<const Lhs>,true> TriangularProductTranspose;
Transpose<Dest> dstT(dst);
internal::trmv_selector<(int(internal::traits<Rhs>::Flags)&RowMajorBit) ? ColMajor : RowMajor>::run(
@@ -235,23 +229,15 @@ template<> struct trmv_selector<ColMajor>
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
- ResScalar* actualDestPtr;
- bool freeDestPtr = false;
- if (evalToDest)
- {
- actualDestPtr = dest.data();
- }
- else
+ ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
+ evalToDest ? dest.data() : static_dest.data());
+
+ if(!evalToDest)
{
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
int size = dest.size();
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
#endif
- if((actualDestPtr = static_dest.data())==0)
- {
- freeDestPtr = true;
- actualDestPtr = ei_aligned_stack_new(ResScalar,dest.size());
- }
if(!alphaIsCompatible)
{
MappedDest(actualDestPtr, dest.size()).setZero();
@@ -277,7 +263,6 @@ template<> struct trmv_selector<ColMajor>
dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
else
dest = MappedDest(actualDestPtr, dest.size());
- if(freeDestPtr) ei_aligned_stack_delete(ResScalar, actualDestPtr, dest.size());
}
}
};
@@ -310,23 +295,15 @@ template<> struct trmv_selector<RowMajor>
gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
- RhsScalar* actualRhsPtr;
- bool freeRhsPtr = false;
- if (DirectlyUseRhs)
- {
- actualRhsPtr = const_cast<RhsScalar*>(actualRhs.data());
- }
- else
+ ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
+ DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
+
+ if(!DirectlyUseRhs)
{
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
int size = actualRhs.size();
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
#endif
- if((actualRhsPtr = static_rhs.data())==0)
- {
- freeRhsPtr = true;
- actualRhsPtr = ei_aligned_stack_new(RhsScalar, actualRhs.size());
- }
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
}
@@ -340,8 +317,6 @@ template<> struct trmv_selector<RowMajor>
actualRhsPtr,1,
dest.data(),dest.innerStride(),
actualAlpha);
-
- if((!DirectlyUseRhs) && freeRhsPtr) ei_aligned_stack_delete(RhsScalar, actualRhsPtr, prod.rhs().size());
}
};
diff --git a/Eigen/src/Core/products/TriangularSolverMatrix.h b/Eigen/src/Core/products/TriangularSolverMatrix.h
index 8b9143c2b..a6ad9c322 100644
--- a/Eigen/src/Core/products/TriangularSolverMatrix.h
+++ b/Eigen/src/Core/products/TriangularSolverMatrix.h
@@ -70,10 +70,10 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO
Index nc = cols; // cache block size along the N direction
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
- Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
std::size_t sizeB = sizeW + kc*cols;
- Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
+ ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
+ ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
Scalar* blockB = allocatedBlockB + sizeW;
conj_if<Conjugate> conj;
@@ -174,9 +174,6 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO
}
}
}
-
- ei_aligned_stack_delete(Scalar, blockA, kc*mc);
- ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
}
};
@@ -209,10 +206,10 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage
Index nc = rows; // cache block size along the N direction
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
- Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
std::size_t sizeB = sizeW + kc*size;
- Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
+ ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
+ ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
Scalar* blockB = allocatedBlockB + sizeW;
conj_if<Conjugate> conj;
@@ -314,9 +311,6 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage
-1, -1, 0, 0, allocatedBlockB);
}
}
-
- ei_aligned_stack_delete(Scalar, blockA, kc*mc);
- ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
}
};
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 8ccf0e603..fe61555ff 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -468,36 +468,70 @@ inline static Index first_aligned(const Scalar* array, Index size)
*** Implementation of runtime stack allocation (falling back to malloc) ***
*****************************************************************************/
+// you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA
+// to the appropriate stack allocation function
+#ifndef EIGEN_ALLOCA
+ #if (defined __linux__)
+ #define EIGEN_ALLOCA alloca
+ #elif defined(_MSC_VER)
+ #define EIGEN_ALLOCA _alloca
+ #endif
+#endif
+
+namespace internal {
+
+template<typename T> class stack_memory_destructor
+{
+ public:
+ stack_memory_destructor(T* ptr,size_t size) : m_ptr(ptr), m_size(size) {}
+ ~stack_memory_destructor()
+ {
+ Eigen::internal::destruct_elements_of_array<T>(m_ptr, m_size);
+ #ifdef EIGEN_ALLOCA
+ if(sizeof(T)*m_size>EIGEN_STACK_ALLOCATION_LIMIT)
+ #endif
+ Eigen::internal::aligned_free(m_ptr);
+ }
+ protected:
+ T* m_ptr;
+ size_t m_size;
+};
+
+}
+
/** \internal
- * Allocates an aligned buffer of SIZE bytes on the stack if SIZE is smaller than
- * EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform
- * (currently, this is Linux only). Otherwise the memory is allocated on the heap.
- * Data allocated with ei_aligned_stack_alloc \b must be freed by calling
- * ei_aligned_stack_free(PTR,SIZE).
+ * Declares, allocates and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack
+ * if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform
+ * (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap.
+ * The allocated buffer is automatically deleted when exiting the scope of this declaration.
+ * If BUFFER is non nul, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs.
+ * Here is an example:
* \code
- * float * data = ei_aligned_stack_alloc(float,array.size());
- * // ...
- * ei_aligned_stack_free(data,float,array.size());
+ * {
+ * ei_declare_aligned_stack_constructed_variable(float,data,size,0);
+ * // use data[0] to data[size-1]
+ * }
* \endcode
+ * The underlying stack allocation function can controlled with the EIGEN_ALLOCA preprocessor token.
*/
-#if (defined __linux__)
- #define ei_aligned_stack_alloc(SIZE) (SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) \
- ? alloca(SIZE) \
- : Eigen::internal::aligned_malloc(SIZE)
- #define ei_aligned_stack_free(PTR,SIZE) if(SIZE>EIGEN_STACK_ALLOCATION_LIMIT) Eigen::internal::aligned_free(PTR)
-#elif defined(_MSC_VER)
- #define ei_aligned_stack_alloc(SIZE) (SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) \
- ? _alloca(SIZE) \
- : Eigen::internal::aligned_malloc(SIZE)
- #define ei_aligned_stack_free(PTR,SIZE) if(SIZE>EIGEN_STACK_ALLOCATION_LIMIT) Eigen::internal::aligned_free(PTR)
+#ifdef EIGEN_ALLOCA
+
+ #define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
+ TYPE* NAME = (BUFFER)!=0 ? (BUFFER) \
+ : reinterpret_cast<TYPE*>( \
+ (sizeof(TYPE)*SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) ? alloca(sizeof(TYPE)*SIZE) \
+ : Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE) ); \
+ if((BUFFER)==0) Eigen::internal::construct_elements_of_array(NAME, SIZE); \
+ Eigen::internal::stack_memory_destructor<TYPE> EIGEN_CAT(stack_memory_destructor,__LINE__)((BUFFER)==0 ? NAME : 0,SIZE)
+
#else
- #define ei_aligned_stack_alloc(SIZE) Eigen::internal::aligned_malloc(SIZE)
- #define ei_aligned_stack_free(PTR,SIZE) Eigen::internal::aligned_free(PTR)
-#endif
-#define ei_aligned_stack_new(TYPE,SIZE) Eigen::internal::construct_elements_of_array(reinterpret_cast<TYPE*>(ei_aligned_stack_alloc(sizeof(TYPE)*SIZE)), SIZE)
-#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {Eigen::internal::destruct_elements_of_array<TYPE>(PTR, SIZE); \
- ei_aligned_stack_free(PTR,sizeof(TYPE)*SIZE);} while(0)
+ #define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
+ TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast<TYPE*>(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE)); \
+ if((BUFFER)==0) Eigen::internal::construct_elements_of_array(NAME, SIZE); \
+ Eigen::internal::stack_memory_destructor<TYPE> EIGEN_CAT(stack_memory_destructor,__LINE__)((BUFFER)==0 ? NAME : 0,SIZE)
+
+#endif
/*****************************************************************************