static analyzer: Make GRStates reference counted, with reference counts managed by ExplodedNodes.

This reduces memory usage of the analyzer on sqlite by another 5%.

llvm-svn: 125260
This commit is contained in:
Ted Kremenek 2011-02-10 02:21:52 +00:00
parent d4fcc05304
commit 75e4564140
3 changed files with 28 additions and 16 deletions

View File

@ -118,7 +118,11 @@ public:
explicit ExplodedNode(const ProgramPoint& loc, const GRState* state)
: Location(loc), State(state) {
const_cast<GRState*>(State)->setReferencedByExplodedNode();
const_cast<GRState*>(State)->incrementReferenceCount();
}
~ExplodedNode() {
const_cast<GRState*>(State)->decrementReferenceCount();
}
/// getLocation - Returns the edge associated with the given node.

View File

@ -79,11 +79,13 @@ private:
friend class GRStateManager;
friend class ExplodedGraph;
friend class ExplodedNode;
llvm::PointerIntPair<GRStateManager *, 1, bool> stateMgr;
GRStateManager *stateMgr;
Environment Env; // Maps a Stmt to its current SVal.
Store St; // Maps a location to its current value.
GenericDataMap GDM; // Custom data stored by a client of this class.
unsigned refCount;
/// makeWithStore - Return a GRState with the same values as the current
/// state with the exception of using the specified Store.
@ -94,33 +96,27 @@ public:
/// This ctor is used when creating the first GRState object.
GRState(GRStateManager *mgr, const Environment& env,
Store st, GenericDataMap gdm)
: stateMgr(mgr, false),
: stateMgr(mgr),
Env(env),
St(st),
GDM(gdm) {}
GDM(gdm),
refCount(0) {}
/// Copy ctor - We must explicitly define this or else the "Next" ptr
/// in FoldingSetNode will also get copied.
GRState(const GRState& RHS)
: llvm::FoldingSetNode(),
stateMgr(RHS.stateMgr.getPointer(), false),
stateMgr(RHS.stateMgr),
Env(RHS.Env),
St(RHS.St),
GDM(RHS.GDM) {}
GDM(RHS.GDM),
refCount(0) {}
/// Return the GRStateManager associated with this state.
GRStateManager &getStateManager() const {
return *stateMgr.getPointer();
}
GRStateManager &getStateManager() const { return *stateMgr; }
/// Return true if this state is referenced by a persistent ExplodedNode.
bool referencedByExplodedNode() const {
return stateMgr.getInt();
}
void setReferencedByExplodedNode() {
stateMgr.setInt(true);
}
bool referencedByExplodedNode() const { return refCount > 0; }
/// getEnvironment - Return the environment associated with this state.
/// The environment is the mapping from expressions to values.
@ -373,6 +369,16 @@ public:
void printStdErr(CFG &C) const;
void printDOT(llvm::raw_ostream& Out, CFG &C) const;
private:
/// Increments the number of times this state is referenced by ExplodeNodes.
void incrementReferenceCount() { ++refCount; }
/// Decrement the number of times this state is referenced by ExplodeNodes.
void decrementReferenceCount() {
assert(refCount > 0);
--refCount;
}
};
class GRStateSet {

View File

@ -123,6 +123,8 @@ void ExplodedGraph::reclaimRecentlyAllocatedNodes() {
freeNodes = new NodeList();
getNodeList(freeNodes)->push_back(node);
Nodes.RemoveNode(node);
--NumNodes;
node->~ExplodedNode();
}
nl.clear();