|
@@ -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.
|
|
|
//==---------------------------------------------------------------------==//
|