[cfe-commits] r149336 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h lib/StaticAnalyzer/Core/Checker.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Core/ProgramState.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Mon Jan 30 18:14:25 PST 2012
Author: akirtzidis
Date: Mon Jan 30 20:14:24 2012
New Revision: 149336
URL: http://llvm.org/viewvc/llvm-project?rev=149336&view=rev
Log:
Revert r149311 which failed to compile.
Original log:
Convert ProgramStateRef to a smart pointer for managing the reference counts of ProgramStates. This leads to a slight memory
improvement, and a simplification of the logic for managing ProgramState objects.
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h?rev=149336&r1=149335&r2=149336&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h Mon Jan 30 20:14:24 2012
@@ -119,11 +119,14 @@
explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state,
bool IsSink)
: Location(loc), State(state) {
+ const_cast<ProgramState*>(State)->incrementReferenceCount();
if (IsSink)
Succs.setFlag();
}
- ~ExplodedNode() {}
+ ~ExplodedNode() {
+ const_cast<ProgramState*>(State)->decrementReferenceCount();
+ }
/// getLocation - Returns the edge associated with the given node.
ProgramPoint getLocation() const { return Location; }
@@ -153,7 +156,7 @@
ProgramStateRef state,
bool IsSink) {
ID.Add(Loc);
- ID.AddPointer(state.getPtr());
+ ID.AddPointer(state);
ID.AddBoolean(IsSink);
}
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=149336&r1=149335&r2=149336&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Mon Jan 30 20:14:24 2012
@@ -93,6 +93,7 @@
void setStore(const StoreRef &storeRef);
public:
+
/// This ctor is used when creating the first ProgramState object.
ProgramState(ProgramStateManager *mgr, const Environment& env,
StoreRef st, GenericDataMap gdm);
@@ -106,6 +107,9 @@
/// Return the ProgramStateManager associated with this state.
ProgramStateManager &getStateManager() const { return *stateMgr; }
+ /// Return true if this state is referenced by a persistent ExplodedNode.
+ bool referencedByExplodedNode() const { return refCount > 0; }
+
/// getEnvironment - Return the environment associated with this state.
/// The environment is the mapping from expressions to values.
const Environment& getEnvironment() const { return Env; }
@@ -123,7 +127,7 @@
/// Profile - Profile the contents of a ProgramState object for use in a
/// FoldingSet. Two ProgramState objects are considered equal if they
/// have the same Environment, Store, and GenericDataMap.
- static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
+ static void Profile(llvm::FoldingSetNodeID& ID, ProgramStateRef V) {
V->Env.Profile(ID);
ID.AddPointer(V->store);
V->GDM.Profile(ID);
@@ -372,8 +376,14 @@
void dumpTaint() const;
private:
- friend void ProgramStateRetain(const ProgramState *state);
- friend void ProgramStateRelease(const ProgramState *state);
+ /// 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;
+ }
ProgramStateRef
invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
@@ -382,13 +392,45 @@
const CallOrObjCMessage *Call) const;
};
+class ProgramStateSet {
+ typedef llvm::SmallPtrSet<ProgramStateRef,5> ImplTy;
+ ImplTy Impl;
+public:
+ ProgramStateSet() {}
+
+ inline void Add(ProgramStateRef St) {
+ Impl.insert(St);
+ }
+
+ typedef ImplTy::const_iterator iterator;
+
+ inline unsigned size() const { return Impl.size(); }
+ inline bool empty() const { return Impl.empty(); }
+
+ inline iterator begin() const { return Impl.begin(); }
+ inline iterator end() const { return Impl.end(); }
+
+ class AutoPopulate {
+ ProgramStateSet &S;
+ unsigned StartSize;
+ ProgramStateRef St;
+ public:
+ AutoPopulate(ProgramStateSet &s, ProgramStateRef st)
+ : S(s), StartSize(S.size()), St(st) {}
+
+ ~AutoPopulate() {
+ if (StartSize == S.size())
+ S.Add(St);
+ }
+ };
+};
+
//===----------------------------------------------------------------------===//
// ProgramStateManager - Factory object for ProgramStates.
//===----------------------------------------------------------------------===//
class ProgramStateManager {
friend class ProgramState;
- friend void ProgramStateRelease(const ProgramState *state);
private:
/// Eng - The SubEngine that owns this state manager.
SubEngine *Eng; /* Can be null. */
@@ -411,6 +453,10 @@
/// A BumpPtrAllocator to allocate states.
llvm::BumpPtrAllocator &Alloc;
+
+ /// A vector of recently allocated ProgramStates that can potentially be
+ /// reused.
+ std::vector<ProgramState *> recentlyAllocatedStates;
/// A vector of ProgramStates that we can reuse.
std::vector<ProgramState *> freeStates;
@@ -517,6 +563,10 @@
return S1->store == S2->store;
}
+ /// Periodically called by ExprEngine to recycle ProgramStates that were
+ /// created but never used for creating an ExplodedNode.
+ void recycleUnusedStates();
+
//==---------------------------------------------------------------------==//
// Generic Data Map methods.
//==---------------------------------------------------------------------==//
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h?rev=149336&r1=149335&r2=149336&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h Mon Jan 30 20:14:24 2012
@@ -10,31 +10,11 @@
#ifndef LLVM_CLANG_PROGRAMSTATE_FWD_H
#define LLVM_CLANG_PROGRAMSTATE_FWD_H
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-
namespace clang {
namespace ento {
class ProgramState;
class ProgramStateManager;
- void ProgramStateRetain(const ProgramState *state);
- void ProgramStateRelease(const ProgramState *state);
-}
-}
-
-namespace llvm {
- template <> struct IntrusiveRefCntPtrInfo<const clang::ento::ProgramState> {
- static void retain(const clang::ento::ProgramState *state) {
- clang::ento::ProgramStateRetain(state);
- }
- static void release(const clang::ento::ProgramState *state) {
- clang::ento::ProgramStateRelease(state);
- }
- };
-}
-
-namespace clang {
-namespace ento {
- typedef llvm::IntrusiveRefCntPtr<const ProgramState> ProgramStateRef;
+ typedef const ProgramState* ProgramStateRef;
}
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp?rev=149336&r1=149335&r2=149336&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp Mon Jan 30 20:14:24 2012
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
using namespace clang;
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=149336&r1=149335&r2=149336&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Jan 30 20:14:24 2012
@@ -238,8 +238,13 @@
void ExprEngine::ProcessStmt(const CFGStmt S,
ExplodedNode *Pred) {
+ // TODO: Use RAII to remove the unnecessary, tagged nodes.
+ //RegisterCreatedNodes registerCreatedNodes(getGraph());
+
// Reclaim any unnecessary nodes in the ExplodedGraph.
G.reclaimRecentlyAllocatedNodes();
+ // Recycle any unused states in the ProgramStateManager.
+ StateMgr.recycleUnusedStates();
currentStmt = S.getStmt();
PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
@@ -1851,7 +1856,7 @@
}
ProgramStateRef state = N->getState();
- Out << "\\|StateID: " << (void*) state.getPtr()
+ Out << "\\|StateID: " << (void*) state
<< " NodeID: " << (void*) N << "\\|";
state->printDOT(Out);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=149336&r1=149335&r2=149336&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Mon Jan 30 20:14:24 2012
@@ -25,26 +25,6 @@
// FIXME: Move this elsewhere.
ConstraintManager::~ConstraintManager() {}
-namespace clang { namespace ento {
-/// Increments the number of times this state is referenced.
-
-void ProgramStateRetain(const ProgramState *state) {
- ++const_cast<ProgramState*>(state)->refCount;
-}
-
-/// Decrement the number of times this state is referenced.
-void ProgramStateRelease(const ProgramState *state) {
- assert(state->refCount > 0);
- ProgramState *s = const_cast<ProgramState*>(state);
- if (--s->refCount == 0) {
- ProgramStateManager &Mgr = s->getStateManager();
- Mgr.StateSet.RemoveNode(s);
- s->~ProgramState();
- Mgr.freeStates.push_back(s);
- }
-}
-}}
-
ProgramState::ProgramState(ProgramStateManager *mgr, const Environment& env,
StoreRef st, GenericDataMap gdm)
: stateMgr(mgr),
@@ -348,10 +328,23 @@
return getPersistentState(State);
}
+void ProgramStateManager::recycleUnusedStates() {
+ for (std::vector<ProgramState*>::iterator i = recentlyAllocatedStates.begin(),
+ e = recentlyAllocatedStates.end(); i != e; ++i) {
+ ProgramState *state = *i;
+ if (state->referencedByExplodedNode())
+ continue;
+ StateSet.RemoveNode(state);
+ freeStates.push_back(state);
+ state->~ProgramState();
+ }
+ recentlyAllocatedStates.clear();
+}
+
ProgramStateRef ProgramStateManager::getPersistentStateWithGDM(
ProgramStateRef FromState,
ProgramStateRef GDMState) {
- ProgramState NewState(*FromState);
+ ProgramState NewState = *FromState;
NewState.GDM = GDMState->GDM;
return getPersistentState(NewState);
}
@@ -375,11 +368,12 @@
}
new (newState) ProgramState(State);
StateSet.InsertNode(newState, InsertPos);
+ recentlyAllocatedStates.push_back(newState);
return newState;
}
ProgramStateRef ProgramState::makeWithStore(const StoreRef &store) const {
- ProgramState NewSt(*this);
+ ProgramState NewSt = *this;
NewSt.setStore(store);
return getStateManager().getPersistentState(NewSt);
}
More information about the cfe-commits
mailing list