forked from OSchip/llvm-project
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:
parent
d4fcc05304
commit
75e4564140
|
@ -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.
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue