diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ExprEngine.cpp | 3 | ||||
-rw-r--r-- | lib/StaticAnalyzer/GRState.cpp | 28 |
2 files changed, 27 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp index 53931dc607..f311bea877 100644 --- a/lib/StaticAnalyzer/Checkers/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Checkers/ExprEngine.cpp @@ -574,6 +574,9 @@ void ExprEngine::processCFGElement(const CFGElement E, } void ExprEngine::ProcessStmt(const CFGStmt S, StmtNodeBuilder& builder) { + // Recycle any unused states in the GRStateManager. + StateMgr.recycleUnusedStates(); + currentStmt = S.getStmt(); PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), currentStmt->getLocStart(), diff --git a/lib/StaticAnalyzer/GRState.cpp b/lib/StaticAnalyzer/GRState.cpp index 60832e8f79..18995b2ce7 100644 --- a/lib/StaticAnalyzer/GRState.cpp +++ b/lib/StaticAnalyzer/GRState.cpp @@ -285,6 +285,18 @@ const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) { return getPersistentState(State); } +void GRStateManager::recycleUnusedStates() { + for (std::vector<GRState*>::iterator i = recentlyAllocatedStates.begin(), + e = recentlyAllocatedStates.end(); i != e; ++i) { + GRState *state = *i; + if (state->referencedByExplodedNode()) + continue; + StateSet.RemoveNode(state); + freeStates.push_back(state); + } + recentlyAllocatedStates.clear(); +} + const GRState* GRStateManager::getPersistentState(GRState& State) { llvm::FoldingSetNodeID ID; @@ -294,10 +306,18 @@ const GRState* GRStateManager::getPersistentState(GRState& State) { if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos)) return I; - GRState* I = (GRState*) Alloc.Allocate<GRState>(); - new (I) GRState(State); - StateSet.InsertNode(I, InsertPos); - return I; + GRState *newState = 0; + if (!freeStates.empty()) { + newState = freeStates.back(); + freeStates.pop_back(); + } + else { + newState = (GRState*) Alloc.Allocate<GRState>(); + } + new (newState) GRState(State); + StateSet.InsertNode(newState, InsertPos); + recentlyAllocatedStates.push_back(newState); + return newState; } const GRState* GRState::makeWithStore(Store store) const { |