[cfe-commits] r149311 - 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

Ted Kremenek kremenek at apple.com
Mon Jan 30 16:57:20 PST 2012


Author: kremenek
Date: Mon Jan 30 18:57:20 2012
New Revision: 149311

URL: http://llvm.org/viewvc/llvm-project?rev=149311&view=rev
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=149311&r1=149310&r2=149311&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h Mon Jan 30 18:57:20 2012
@@ -119,14 +119,11 @@
   explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state,
                         bool IsSink)
     : Location(loc), State(state) {
-    const_cast<ProgramState*>(State)->incrementReferenceCount();
     if (IsSink)
       Succs.setFlag();
   }
   
-  ~ExplodedNode() {
-    const_cast<ProgramState*>(State)->decrementReferenceCount();
-  }
+  ~ExplodedNode() {}
 
   /// getLocation - Returns the edge associated with the given node.
   ProgramPoint getLocation() const { return Location; }
@@ -156,7 +153,7 @@
                       ProgramStateRef state,
                       bool IsSink) {
     ID.Add(Loc);
-    ID.AddPointer(state);
+    ID.AddPointer(state.getPtr());
     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=149311&r1=149310&r2=149311&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Mon Jan 30 18:57:20 2012
@@ -93,7 +93,6 @@
   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);
@@ -107,9 +106,6 @@
   /// 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; }
@@ -127,7 +123,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, ProgramStateRef V) {
+  static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
     V->Env.Profile(ID);
     ID.AddPointer(V->store);
     V->GDM.Profile(ID);
@@ -376,14 +372,8 @@
   void dumpTaint() 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;
-  }
+  friend void ProgramStateRetain(const ProgramState *state);
+  friend void ProgramStateRelease(const ProgramState *state);
   
   ProgramStateRef 
   invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
@@ -392,45 +382,13 @@
                         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. */
@@ -453,10 +411,6 @@
 
   /// 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;
@@ -563,10 +517,6 @@
     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=149311&r1=149310&r2=149311&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 18:57:20 2012
@@ -10,11 +10,31 @@
 #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;
-  typedef const ProgramState* ProgramStateRef;
+  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;
 }
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp?rev=149311&r1=149310&r2=149311&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Checker.cpp Mon Jan 30 18:57:20 2012
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#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=149311&r1=149310&r2=149311&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Jan 30 18:57:20 2012
@@ -238,13 +238,8 @@
 
 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(),
@@ -1856,7 +1851,7 @@
     }
 
     ProgramStateRef state = N->getState();
-    Out << "\\|StateID: " << (void*) state
+    Out << "\\|StateID: " << (void*) state.getPtr()
         << " 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=149311&r1=149310&r2=149311&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Mon Jan 30 18:57:20 2012
@@ -25,6 +25,26 @@
 // 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),
@@ -328,23 +348,10 @@
   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);
 }
@@ -368,12 +375,11 @@
   }
   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