From 2fda62d190b78a7622fd7195a6a3574956e3b5a3 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Fri, 29 Sep 2017 14:26:29 +0300 Subject: Move nInterpretLevel back to ScDocument Move the calls to increment and decrement it out of InterpretTail(), to those call sites that aren't reached during parallelized calculations. Use unique_ptr for pInt in StackCleaner Change-Id: Ie1bd03dd62aea5f6c71c383df21afff29391dade --- sc/inc/document.hxx | 21 ++++++++++++++++----- sc/source/core/data/column2.cxx | 5 ++++- sc/source/core/data/documen2.cxx | 1 + sc/source/core/data/document.cxx | 26 -------------------------- sc/source/core/data/formulacell.cxx | 26 +++++++++++++------------- 5 files changed, 34 insertions(+), 45 deletions(-) diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index fd13f36d22ee..a497bf3f178c 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -276,7 +276,6 @@ const sal_uInt8 SC_DDE_IGNOREMODE = 255; /// For usage in FindDdeLink() // During threaded calculation fields being mutated are kept in this struct struct ScDocumentThreadSpecific { - sal_uInt16 nInterpretLevel; // >0 if in interpreter sal_uInt16 nMacroInterpretLevel; // >0 if macro in interpreter sal_uInt16 nInterpreterTableOpLevel; // >0 if in interpreter TableOp @@ -285,7 +284,6 @@ struct ScDocumentThreadSpecific ScLookupCacheMapImpl* pLookupCacheMapImpl; // cache for lookups like VLOOKUP and MATCH ScDocumentThreadSpecific() : - nInterpretLevel(0), nMacroInterpretLevel(0), nInterpreterTableOpLevel(0), pRecursionHelper(nullptr), @@ -454,6 +452,8 @@ private: sal_uLong nFormulaCodeInTree; // formula RPN in the formula tree sal_uLong nXMLImportedFormulaCount; // progress count during XML import + sal_uInt16 nInterpretLevel; // >0 if in interpreter + ScDocumentThreadSpecific maNonThreaded; // There can be only one ScDocument being calculated in a thread at a time, so we can use a @@ -2178,9 +2178,20 @@ public: void SetForcedFormulas( bool bVal ) { bHasForcedFormulas = bVal; } sal_uLong GetFormulaCodeInTree() const { return nFormulaCodeInTree; } - bool IsInInterpreter() const; - void IncInterpretLevel(); - void DecInterpretLevel(); + bool IsInInterpreter() const { return nInterpretLevel != 0; } + + void IncInterpretLevel() + { + assert(!mbThreadedGroupCalcInProgress); + if ( nInterpretLevel < USHRT_MAX ) + nInterpretLevel++; + } + void DecInterpretLevel() + { + assert(!mbThreadedGroupCalcInProgress); + if ( nInterpretLevel ) + nInterpretLevel--; + } sal_uInt16 GetMacroInterpretLevel(); void IncMacroInterpretLevel(); void DecMacroInterpretLevel(); diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 0178d7664197..aaa897889603 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * @@ -2899,6 +2899,9 @@ void ScColumn::CalculateInThread( SCROW nRow, size_t nLen, unsigned nThisThread, continue; ScFormulaCell& rCell = **itCell; + // Here we don't call IncInterpretLevel() and DecInterpretLevel() as this call site is + // always in a threaded calculation. + assert(pDocument->mbThreadedGroupCalcInProgress); rCell.InterpretTail(ScFormulaCell::SCITP_NORMAL); } } diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 43332c2ec873..c5d0c7e8cea2 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -174,6 +174,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) : mbThreadedGroupCalcInProgress( false ), nFormulaCodeInTree(0), nXMLImportedFormulaCount( 0 ), + nInterpretLevel(0), nSrcVer( SC_CURRENT_VERSION ), nFormulaTrackCount(0), eHardRecalcState(HardRecalcState::OFF), diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 2f2a0dabe995..2df3f8e10a8b 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -6771,30 +6771,6 @@ ScMutationGuard::~ScMutationGuard() thread_local ScDocumentThreadSpecific ScDocument::maThreadSpecific; -bool ScDocument::IsInInterpreter() const -{ - if (!mbThreadedGroupCalcInProgress) - return maNonThreaded.nInterpretLevel != 0; - else - return maThreadSpecific.nInterpretLevel != 0; -} - -void ScDocument::IncInterpretLevel() -{ - if (!mbThreadedGroupCalcInProgress) - maNonThreaded.nInterpretLevel++; - else - maThreadSpecific.nInterpretLevel++; -} - -void ScDocument::DecInterpretLevel() -{ - if (!mbThreadedGroupCalcInProgress) - maNonThreaded.nInterpretLevel--; - else - maThreadSpecific.nInterpretLevel--; -} - sal_uInt16 ScDocument::GetMacroInterpretLevel() { if (!mbThreadedGroupCalcInProgress) @@ -6873,7 +6849,6 @@ ScRecursionHelper& ScDocument::GetRecursionHelper() void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSpecific& rNonThreadedData) { - nInterpretLevel = rNonThreadedData.nInterpretLevel; nMacroInterpretLevel = rNonThreadedData.nMacroInterpretLevel; nInterpreterTableOpLevel = rNonThreadedData.nInterpreterTableOpLevel; @@ -6883,7 +6858,6 @@ void ScDocumentThreadSpecific::SetupFromNonThreadedData(const ScDocumentThreadSp void ScDocumentThreadSpecific::MergeBackIntoNonThreadedData(ScDocumentThreadSpecific& rNonThreadedData) { - assert(nInterpretLevel == rNonThreadedData.nInterpretLevel); assert(nMacroInterpretLevel == rNonThreadedData.nMacroInterpretLevel); assert(nInterpreterTableOpLevel == rNonThreadedData.nInterpreterTableOpLevel); diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 2d04938d2632..7e4a92b1e146 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1522,6 +1522,7 @@ void ScFormulaCell::Interpret() } else { + pDocument->IncInterpretLevel(); #if DEBUG_CALCULATION aDC.enterGroup(); bool bGroupInterpreted = InterpretFormulaGroup(); @@ -1532,6 +1533,7 @@ void ScFormulaCell::Interpret() if (!InterpretFormulaGroup()) InterpretTail( SCITP_NORMAL); #endif + pDocument->DecInterpretLevel(); } // While leaving a recursion or iteration stack, insert its cells to the @@ -1592,8 +1594,10 @@ void ScFormulaCell::Interpret() { bResumeIteration = false; // Close circle once. + pDocument->IncInterpretLevel(); rRecursionHelper.GetList().back().pCell->InterpretTail( SCITP_CLOSE_ITERATION_CIRCLE); + pDocument->DecInterpretLevel(); // Start at 1, init things. rRecursionHelper.StartIteration(); // Mark all cells being in iteration. @@ -1622,7 +1626,9 @@ void ScFormulaCell::Interpret() pIterCell->GetSeenInIteration()) { (*aIter).aPreviousResult = pIterCell->aResult; + pDocument->IncInterpretLevel(); pIterCell->InterpretTail( SCITP_FROM_ITERATION); + pDocument->DecInterpretLevel(); } rDone = rDone && !pIterCell->IsDirtyOrInTableOpDirty(); } @@ -1692,7 +1698,9 @@ void ScFormulaCell::Interpret() ScFormulaCell* pCell = (*aIter).pCell; if (pCell->IsDirtyOrInTableOpDirty()) { + pDocument->IncInterpretLevel(); pCell->InterpretTail( SCITP_NORMAL); + pDocument->DecInterpretLevel(); if (!pCell->IsDirtyOrInTableOpDirty() && !pCell->IsIterCell()) pCell->bRunning = (*aIter).bOldRunning; } @@ -1728,17 +1736,11 @@ void ScFormulaCell::Interpret() namespace { class StackCleaner { - ScDocument* pDoc; - ScInterpreter* pInt; + std::unique_ptr pInt; public: - StackCleaner( ScDocument* pD, ScInterpreter* pI ) - : pDoc(pD), pInt(pI) + StackCleaner( ScInterpreter* pI ) + : pInt(pI) {} - ~StackCleaner() - { - delete pInt; - pDoc->DecInterpretLevel(); - } }; } @@ -1769,9 +1771,8 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam ) if( pCode->GetCodeLen() && pDocument ) { - pDocument->IncInterpretLevel(); ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode ); - StackCleaner aStackCleaner( pDocument, pInterpreter); + StackCleaner aStackCleaner(pInterpreter); FormulaError nOldErrCode = aResult.GetResultError(); if ( nSeenInIteration == 0 ) { // Only the first time @@ -2163,9 +2164,8 @@ void ScFormulaCell::HandleStuffAfterParallelCalculation() if ( !pCode->IsRecalcModeAlways() ) pDocument->RemoveFromFormulaTree( this ); - pDocument->IncInterpretLevel(); ScInterpreter* pInterpreter = new ScInterpreter( this, pDocument, aPos, *pCode ); - StackCleaner aStackCleaner( pDocument, pInterpreter); + StackCleaner aStackCleaner(pInterpreter); switch (pInterpreter->GetVolatileType()) { -- cgit v1.2.3