aboutsummaryrefslogtreecommitdiff
path: root/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-01-31 02:14:24 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-01-31 02:14:24 +0000
commitb9b0f6fb6e113b5e6be3ed9754c4bf01186a17bf (patch)
treef5a6d058526dd31830d98cfcdbd144b499e8121f /include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
parent6e1d2eaa7d7f1008a5bac12f73fbf6167802a46d (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149336 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h')
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h58
1 files changed, 54 insertions, 4 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index f19520984e..a3e1830be3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -93,6 +93,7 @@ private:
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 @@ public:
/// 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 @@ public:
/// 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 @@ public:
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 @@ private:
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 @@ private:
/// 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 @@ public:
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.
//==---------------------------------------------------------------------==//