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) explicit ExplodedNode(const ProgramPoint& loc, const GRState* state)
: Location(loc), State(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. /// getLocation - Returns the edge associated with the given node.

View File

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

View File

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