Move token-cache for doubles to ScInterpreterContext...

...from ScInterpreter and in the s/w interpreter, create
a ScInterpreterContext for each thread for passing into
per thread ScInterpreter constructor.

Change-Id: I4e0abce043c7e1e70859efb2e5001fc284f416a9
This commit is contained in:
Dennis Francis 2017-11-17 15:30:35 +05:30
parent 4284cdcc3e
commit 2b12d3d11f
13 changed files with 47 additions and 35 deletions

View file

@ -583,7 +583,7 @@ public:
void SetFormulaResults( SCROW nRow, const double* pResults, size_t nLen );
void SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen );
void CalculateInThread( const ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal );
void CalculateInThread( ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal );
void HandleStuffAfterParallelCalculation( SCROW nRow, size_t nLen );
void SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat );

View file

@ -458,6 +458,8 @@ private:
// plain thread_local static member.
thread_local static ScDocumentThreadSpecific maThreadSpecific;
mutable ScInterpreterContext maInterpreterContext;
sal_uInt16 nSrcVer; // file version (load/save)
sal_uInt16 nFormulaTrackCount;
HardRecalcState eHardRecalcState; // off, temporary, eternal
@ -560,10 +562,11 @@ public:
SC_DLLPUBLIC void InitDrawLayer( SfxObjectShell* pDocShell = nullptr );
ScInterpreterContext GetNonThreadedContext() const
ScInterpreterContext& GetNonThreadedContext() const
{
// GetFormatTable() asserts that we are not in a threaded calculation
return ScInterpreterContext(*this, GetFormatTable());
maInterpreterContext.mpFormatter = GetFormatTable();
return maInterpreterContext;
}
SC_DLLPUBLIC sfx2::LinkManager* GetLinkManager();
@ -2056,7 +2059,7 @@ public:
void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen );
void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const formula::FormulaConstTokenRef* pResults, size_t nLen );
ScDocumentThreadSpecific CalculateInColumnInThread( const ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
ScDocumentThreadSpecific CalculateInColumnInThread( ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
void HandleStuffAfterParallelCalculation( const ScAddress& rTopPos, size_t nLen );
/**

View file

@ -150,7 +150,7 @@ public:
SCITP_FROM_ITERATION,
SCITP_CLOSE_ITERATION_CIRCLE
};
void InterpretTail( const ScInterpreterContext&, ScInterpretTailParameter );
void InterpretTail( ScInterpreterContext&, ScInterpretTailParameter );
void HandleStuffAfterParallelCalculation();

View file

@ -10,6 +10,11 @@
#ifndef INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
#define INCLUDED_SC_INC_INTERPRETERCONTEXT_HXX
#include <vector>
#include <formula/token.hxx>
#define TOKEN_CACHE_SIZE 8
class ScDocument;
class SvNumberFormatter;
@ -17,15 +22,22 @@ struct ScInterpreterContext
{
const ScDocument& mrDoc;
SvNumberFormatter* mpFormatter;
size_t mnTokenCachePos;
std::vector<formula::FormulaToken*> maTokens;
ScInterpreterContext(const ScDocument& rDoc, SvNumberFormatter* pFormatter) :
mrDoc(rDoc),
mpFormatter(pFormatter)
mpFormatter(pFormatter),
mnTokenCachePos(0),
maTokens(TOKEN_CACHE_SIZE, nullptr)
{
}
~ScInterpreterContext()
{
for ( auto p : maTokens )
if ( p )
p->DecRef();
}
SvNumberFormatter* GetFormatTable() const

View file

@ -998,7 +998,7 @@ public:
void SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen );
void SetFormulaResults( SCCOL nCol, SCROW nRow, const formula::FormulaConstTokenRef* pResults, size_t nLen );
void CalculateInColumnInThread( const ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
void CalculateInColumnInThread( ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal);
void HandleStuffAfterParallelCalculation( SCCOL nCol, SCROW nRow, size_t nLen);
/**

View file

@ -2877,7 +2877,7 @@ void ScColumn::SetFormulaResults( SCROW nRow, const formula::FormulaConstTokenRe
}
}
void ScColumn::CalculateInThread( const ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
void ScColumn::CalculateInThread( ScInterpreterContext& rContext, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
assert(pDocument->mbThreadedGroupCalcInProgress);

View file

@ -177,6 +177,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
nInterpretLevel(0),
nMacroInterpretLevel(0),
nInterpreterTableOpLevel(0),
maInterpreterContext( *this, nullptr ),
nSrcVer( SC_CURRENT_VERSION ),
nFormulaTrackCount(0),
eHardRecalcState(HardRecalcState::OFF),

View file

@ -427,7 +427,7 @@ void ScDocument::SetFormulaResults(
pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
}
ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( const ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
ScDocumentThreadSpecific ScDocument::CalculateInColumnInThread( ScInterpreterContext& rContext, const ScAddress& rTopPos, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
ScTable* pTab = FetchTable(rTopPos.Tab());
if (!pTab)

View file

@ -1746,7 +1746,7 @@ class StackCleaner
};
}
void ScFormulaCell::InterpretTail( const ScInterpreterContext& rContext, ScInterpretTailParameter eTailParam )
void ScFormulaCell::InterpretTail( ScInterpreterContext& rContext, ScInterpretTailParameter eTailParam )
{
RecursionCounter aRecursionCounter( pDocument->GetRecursionHelper(), this);
nSeenInIteration = pDocument->GetRecursionHelper().GetIteration();

View file

@ -2338,7 +2338,7 @@ void ScTable::SetFormulaResults(
aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
}
void ScTable::CalculateInColumnInThread( const ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
void ScTable::CalculateInColumnInThread( ScInterpreterContext& rContext, SCCOL nCol, SCROW nRow, size_t nLen, unsigned nThisThread, unsigned nThreadsTotal)
{
if (!ValidCol(nCol))
return;

View file

@ -97,7 +97,6 @@ class SharedStringPool;
}
#define MAXSTACK (4096 / sizeof(formula::FormulaToken*))
#define TOKEN_CACHE_SIZE 8
class ScTokenStack
{
@ -200,7 +199,7 @@ private:
formula::FormulaTokenIterator aCode;
ScAddress aPos;
ScTokenArray& rArr;
const ScInterpreterContext& mrContext;
ScInterpreterContext& mrContext;
ScDocument* pDok;
sfx2::LinkManager* mpLinkManager;
svl::SharedStringPool& mrStrPool;
@ -230,8 +229,6 @@ 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();
@ -994,7 +991,7 @@ private:
double GetTInv( double fAlpha, double fSize, int nType );
public:
ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, const ScInterpreterContext& rContext,
ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, ScInterpreterContext& rContext,
const ScAddress&, ScTokenArray& );
~ScInterpreter();

View file

@ -155,6 +155,7 @@ public:
ScAddress aBatchTopPos,
const ScAddress& rTopPos,
ScDocument& rDoc,
SvNumberFormatter* pFormatter,
std::vector<formula::FormulaConstTokenRef>& rRes,
SCROW nIndex,
SCROW nLastIndex) :
@ -162,6 +163,7 @@ public:
maBatchTopPos(aBatchTopPos),
mrTopPos(rTopPos),
mrDoc(rDoc),
mpFormatter(pFormatter),
mrResults(rRes),
mnIdx(nIndex),
mnLastIdx(nLastIndex)
@ -296,7 +298,8 @@ public:
ScCompiler aComp(&mrDoc, maBatchTopPos, aCode2);
aComp.CompileTokenArray();
ScInterpreter aInterpreter(pDest, &mrDoc, mrDoc.GetNonThreadedContext(), maBatchTopPos, aCode2);
ScInterpreterContext aContext(mrDoc, mpFormatter);
ScInterpreter aInterpreter(pDest, &mrDoc, aContext, maBatchTopPos, aCode2);
aInterpreter.Interpret();
mrResults[i] = aInterpreter.GetResultToken();
} // Row iteration for loop end
@ -307,6 +310,7 @@ private:
ScAddress maBatchTopPos;
const ScAddress& mrTopPos;
ScDocument& mrDoc;
SvNumberFormatter* mpFormatter;
std::vector<formula::FormulaConstTokenRef>& mrResults;
SCROW mnIdx;
SCROW mnLastIdx;
@ -333,11 +337,12 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
ScAddress aBatchTopPos,
const ScAddress& rTopPos2,
ScDocument& rDoc2,
SvNumberFormatter* pFormatter2,
std::vector<formula::FormulaConstTokenRef>& rRes,
SCROW nIndex,
SCROW nLastIndex) :
comphelper::ThreadTask(rTag),
maSWIFunc(rCode2, aBatchTopPos, rTopPos2, rDoc2, rRes, nIndex, nLastIndex)
maSWIFunc(rCode2, aBatchTopPos, rTopPos2, rDoc2, pFormatter2, rRes, nIndex, nLastIndex)
{
}
virtual void doWork() override
@ -353,6 +358,8 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
bool bUseThreading = !bThreadingProhibited && officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get();
SvNumberFormatter* pFormatter = rDoc.GetNonThreadedContext().GetFormatTable();
if (bUseThreading)
{
comphelper::ThreadPool& rThreadPool(comphelper::ThreadPool::getSharedOptimalPool());
@ -381,7 +388,7 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
if ( nRemaining )
--nRemaining;
SCROW nLast = nStart + nCount - 1;
rThreadPool.pushTask(new Executor(aTag, rCode, aTmpPos, rTopPos, rDoc, aResults, nStart, nLast));
rThreadPool.pushTask(new Executor(aTag, rCode, aTmpPos, rTopPos, rDoc, pFormatter, aResults, nStart, nLast));
aTmpPos.IncRow(nCount);
nLeft -= nCount;
nStart = nLast + 1;
@ -392,7 +399,7 @@ bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddres
}
else
{
SoftwareInterpreterFunc aSWIFunc(rCode, aTmpPos, rTopPos, rDoc, aResults, 0, xGroup->mnLength - 1);
SoftwareInterpreterFunc aSWIFunc(rCode, aTmpPos, rTopPos, rDoc, pFormatter, aResults, 0, xGroup->mnLength - 1);
aSWIFunc();
}

View file

@ -1730,15 +1730,13 @@ void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr
formula::FormulaToken* ScInterpreter::CreateFormulaDoubleToken( double fVal, short nFmt )
{
if ( maTokenCache.size() != TOKEN_CACHE_SIZE )
maTokenCache.resize( TOKEN_CACHE_SIZE );
assert( mrContext.maTokens.size() == TOKEN_CACHE_SIZE );
// Find a spare token
for ( auto p : maTokenCache )
for ( auto p : mrContext.maTokens )
{
if (p && p->GetRef() == 1)
{
p->IncRef();
p->GetDoubleAsReference() = fVal;
p->SetDoubleType( nFmt );
return p;
@ -1747,12 +1745,11 @@ formula::FormulaToken* ScInterpreter::CreateFormulaDoubleToken( double fVal, sho
// 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;
if ( mrContext.maTokens[mrContext.mnTokenCachePos] )
mrContext.maTokens[mrContext.mnTokenCachePos]->DecRef();
mrContext.maTokens[mrContext.mnTokenCachePos] = p;
p->IncRef();
mrContext.mnTokenCachePos = (mrContext.mnTokenCachePos + 1) % TOKEN_CACHE_SIZE;
return p;
}
@ -3811,7 +3808,7 @@ void ScInterpreter::ScTTT()
PushError(FormulaError::NoValue);
}
ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, const ScInterpreterContext& rContext,
ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, ScInterpreterContext& rContext,
const ScAddress& rPos, ScTokenArray& r )
: aCode(r)
, aPos(rPos)
@ -3871,11 +3868,6 @@ ScInterpreter::~ScInterpreter()
else
delete pStackObj;
delete pTokenMatrixMap;
for ( auto p : maTokenCache )
if ( p && p->GetRef() == 1 )
p->DecRef();
}
ScCalcConfig& ScInterpreter::GetOrCreateGlobalConfig()