summaryrefslogtreecommitdiff
path: root/sc/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core')
-rw-r--r--sc/source/core/inc/interpre.hxx4
-rw-r--r--sc/source/core/tool/interpr4.cxx45
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 )
{