diff options
Diffstat (limited to 'sc/source/core')
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 45 |
2 files changed, 43 insertions, 6 deletions
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 8a240e617261..a6eaf5cd78ae 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -97,6 +97,7 @@ class SharedStringPool; } #define MAXSTACK (4096 / sizeof(formula::FormulaToken*)) +#define TOKEN_CACHE_SIZE 8 class ScTokenStack { @@ -229,6 +230,8 @@ private: bool bMatrixFormula; // formula cell is a matrix formula VolatileType meVolatileType; + size_t mnTokenCachePos; + std::vector<formula::FormulaToken*> maTokenCache; /// Merge global and document specific settings. void MergeCalcConfig(); @@ -395,6 +398,7 @@ private: sc::RangeMatrix PopRangeMatrix(); void QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr, sal_uLong& rRetIndexExpr); + formula::FormulaToken* CreateFormulaDoubleToken( double fVal, short nFmt = css::util::NumberFormat::NUMBER ); formula::FormulaToken* CreateDoubleOrTypedToken( double fVal ); void PushDouble(double nVal); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 73e91cfb6271..9ce2d00dde17 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -731,7 +731,7 @@ void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString, { TreatDoubleError( fVal); if (!IfErrorPushError()) - PushTempTokenWithoutError( new FormulaDoubleToken( fVal)); + PushTempTokenWithoutError( CreateFormulaDoubleToken( fVal)); } else { @@ -1687,7 +1687,7 @@ void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr { if ( xMat->IsEmptyPath( 0, 0)) { // result of empty FALSE jump path - FormulaTokenRef xRes = new FormulaDoubleToken( 0.0); + FormulaTokenRef xRes = CreateFormulaDoubleToken( 0.0); PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get())); rRetTypeExpr = css::util::NumberFormat::LOGICAL; } @@ -1716,7 +1716,7 @@ void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr if (nErr != FormulaError::NONE) xRes = new FormulaErrorToken( nErr); else - xRes = new FormulaDoubleToken( nMatVal.fVal); + xRes = CreateFormulaDoubleToken( nMatVal.fVal); PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get())); if ( rRetTypeExpr != css::util::NumberFormat::LOGICAL ) rRetTypeExpr = css::util::NumberFormat::NUMBER; @@ -1728,14 +1728,42 @@ void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr SetError( FormulaError::UnknownStackVariable); } +formula::FormulaToken* ScInterpreter::CreateFormulaDoubleToken( double fVal, short nFmt ) +{ + if ( maTokenCache.size() != TOKEN_CACHE_SIZE ) + maTokenCache.resize( TOKEN_CACHE_SIZE ); + + // Find a spare token + for ( auto p : maTokenCache ) + { + if (p && p->GetRef() == 1) + { + p->IncRef(); + p->GetDoubleAsReference() = fVal; + p->SetDoubleType( nFmt ); + return p; + } + } + + // Allocate a new token + auto p = new FormulaTypedDoubleToken( fVal, nFmt ); + size_t pos = (mnTokenCachePos++) % TOKEN_CACHE_SIZE; + if ( maTokenCache[pos] ) + maTokenCache[pos]->DecRef(); + maTokenCache[pos] = p; + p->IncRef(); + + return p; +} + formula::FormulaToken* ScInterpreter::CreateDoubleOrTypedToken( double fVal ) { // NumberFormat::NUMBER is the default untyped double. if (nFuncFmtType && nFuncFmtType != css::util::NumberFormat::NUMBER && nFuncFmtType != css::util::NumberFormat::UNDEFINED) - return new FormulaTypedDoubleToken( fVal, nFuncFmtType); + return CreateFormulaDoubleToken( fVal, nFuncFmtType); else - return new FormulaDoubleToken( fVal); + return CreateFormulaDoubleToken( fVal); } void ScInterpreter::PushDouble(double nVal) @@ -3843,6 +3871,11 @@ ScInterpreter::~ScInterpreter() else delete pStackObj; delete pTokenMatrixMap; + + for ( auto p : maTokenCache ) + if ( p && p->GetRef() == 1 ) + p->DecRef(); + } ScCalcConfig& ScInterpreter::GetOrCreateGlobalConfig() @@ -4584,7 +4617,7 @@ StackVar ScInterpreter::Interpret() nRetIndexExpr = 0; // carry format index only for matching type nRetTypeExpr = nFuncFmtType = nCurFmtType; } - PushTempToken( new FormulaDoubleToken( fVal)); + PushTempToken( CreateFormulaDoubleToken( fVal)); } if ( nFuncFmtType == css::util::NumberFormat::UNDEFINED ) { |