aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprEngine.cpp3
-rw-r--r--lib/StaticAnalyzer/GRState.cpp28
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 {