1818 * @author Steven Arzt
1919 *
2020 */
21- public abstract class AbstractReferenceCountingGarbageCollector <N , D > extends AbstractGarbageCollector <N , D >
22- implements IGarbageCollectorPeer {
23-
24- private ConcurrentCountingMap <SootMethod > jumpFnCounter = new ConcurrentCountingMap <>();
25- private final Set <SootMethod > gcScheduleSet = new ConcurrentHashSet <>();
26- private final AtomicInteger gcedMethods = new AtomicInteger ();
27- private final AtomicInteger gcedEdges = new AtomicInteger ();
28- private final ExtendedAtomicInteger edgeCounterForThreshold = new ExtendedAtomicInteger ();
29- private GarbageCollectionTrigger trigger = GarbageCollectionTrigger .Immediate ;
30- private GarbageCollectorPeerGroup peerGroup = null ;
31- private boolean checkChangeCounter = false ;
21+ public abstract class AbstractReferenceCountingGarbageCollector <N , D , A > extends AbstractGarbageCollector <N , D , A >
22+ implements IGarbageCollectorPeer < A > {
23+
24+ protected ConcurrentCountingMap <A > jumpFnCounter = new ConcurrentCountingMap <>();
25+ protected final Set <A > gcScheduleSet = new ConcurrentHashSet <>();
26+ protected final AtomicInteger gcedAbstractions = new AtomicInteger ();
27+ protected final AtomicInteger gcedEdges = new AtomicInteger ();
28+ protected final ExtendedAtomicInteger edgeCounterForThreshold = new ExtendedAtomicInteger ();
29+ protected GarbageCollectionTrigger trigger = GarbageCollectionTrigger .Immediate ;
30+ protected GarbageCollectorPeerGroup < A > peerGroup = null ;
31+ protected boolean checkChangeCounter = false ;
3232
3333 protected boolean validateEdges = false ;
3434 protected Set <PathEdge <N , D >> oldEdges = new HashSet <>();
@@ -44,21 +44,23 @@ public abstract class AbstractReferenceCountingGarbageCollector<N, D> extends Ab
4444 protected int edgeThreshold = 0 ;
4545
4646 public AbstractReferenceCountingGarbageCollector (BiDiInterproceduralCFG <N , SootMethod > icfg ,
47- ConcurrentHashMultiMap <SootMethod , PathEdge <N , D >> jumpFunctions ,
48- IGCReferenceProvider <D , N > referenceProvider ) {
47+ ConcurrentHashMultiMap <A , PathEdge <N , D >> jumpFunctions ,
48+ IGCReferenceProvider <A > referenceProvider ) {
4949 super (icfg , jumpFunctions , referenceProvider );
5050 }
5151
5252 public AbstractReferenceCountingGarbageCollector (BiDiInterproceduralCFG <N , SootMethod > icfg ,
53- ConcurrentHashMultiMap <SootMethod , PathEdge <N , D >> jumpFunctions ) {
53+ ConcurrentHashMultiMap <A , PathEdge <N , D >> jumpFunctions ) {
5454 super (icfg , jumpFunctions );
5555 }
5656
57+ protected abstract A genAbstraction (PathEdge <N , D > edge );
58+
5759 @ Override
5860 public void notifyEdgeSchedule (PathEdge <N , D > edge ) {
59- SootMethod sm = icfg . getMethodOf (edge . getTarget () );
60- jumpFnCounter .increment (sm );
61- gcScheduleSet .add (sm );
61+ A abstraction = genAbstraction (edge );
62+ jumpFnCounter .increment (abstraction );
63+ gcScheduleSet .add (abstraction );
6264 if (trigger == GarbageCollectionTrigger .EdgeThreshold )
6365 edgeCounterForThreshold .incrementAndGet ();
6466
@@ -70,42 +72,8 @@ public void notifyEdgeSchedule(PathEdge<N, D> edge) {
7072
7173 @ Override
7274 public void notifyTaskProcessed (PathEdge <N , D > edge ) {
73- jumpFnCounter .decrement (icfg .getMethodOf (edge .getTarget ()));
74- }
75-
76- /**
77- * Checks whether the given method has any open dependencies that prevent its
78- * jump functions from being garbage collected
79- *
80- * @param method The method to check
81- * @param referenceCounter The counter that keeps track of active references to
82- * taint abstractions
83- * @return True it the method has active dependencies and thus cannot be
84- * garbage-collected, false otherwise
85- */
86- private boolean hasActiveDependencies (SootMethod method , ConcurrentCountingMap <SootMethod > referenceCounter ) {
87- int changeCounter = -1 ;
88- do {
89- // Update the change counter for the next round
90- changeCounter = referenceCounter .getChangeCounter ();
91-
92- // Check the method itself
93- if (referenceCounter .get (method ) > 0 )
94- return true ;
95-
96- // Check the transitive callees
97- Set <SootMethod > references = referenceProvider .getMethodReferences (method , null );
98- for (SootMethod ref : references ) {
99- if (referenceCounter .get (ref ) > 0 )
100- return true ;
101- }
102- } while (checkChangeCounter && changeCounter != referenceCounter .getChangeCounter ());
103- return false ;
104- }
105-
106- @ Override
107- public boolean hasActiveDependencies (SootMethod method ) {
108- return hasActiveDependencies (method , jumpFnCounter );
75+ A abstraction = genAbstraction (edge );
76+ jumpFnCounter .decrement (abstraction );
10977 }
11078
11179 /**
@@ -120,18 +88,17 @@ protected void gcImmediate() {
12088
12189 // Perform the garbage collection if required
12290 if (gc ) {
123- int tempMethods = 0 ;
12491 onBeforeRemoveEdges ();
125- for (SootMethod sm : gcScheduleSet ) {
92+ for (A abst : gcScheduleSet ) {
12693 // Is it safe to remove this method?
12794 if (peerGroup != null ) {
128- if (peerGroup .hasActiveDependencies (sm ))
95+ if (peerGroup .hasActiveDependencies (abst ))
12996 continue ;
130- } else if (hasActiveDependencies (sm ))
97+ } else if (hasActiveDependencies (abst ))
13198 continue ;
13299
133100 // Get stats for the stuff we are about to remove
134- Set <PathEdge <N , D >> oldFunctions = jumpFunctions .get (sm );
101+ Set <PathEdge <N , D >> oldFunctions = jumpFunctions .get (abst );
135102 if (oldFunctions != null ) {
136103 int gcedSize = oldFunctions .size ();
137104 gcedEdges .addAndGet (gcedSize );
@@ -142,15 +109,14 @@ protected void gcImmediate() {
142109 // First unregister the method, then delete the edges. In case some other thread
143110 // concurrently schedules a new edge, the method gets back into the GC work list
144111 // this way.
145- gcScheduleSet .remove (sm );
146- if (jumpFunctions .remove (sm )) {
147- gcedMethods .incrementAndGet ();
148- tempMethods ++;
112+ gcScheduleSet .remove (abst );
113+ if (jumpFunctions .remove (abst )) {
114+ gcedAbstractions .incrementAndGet ();
149115 if (validateEdges )
150116 oldEdges .addAll (oldFunctions );
151117 }
152118 }
153- onAfterRemoveEdges (tempMethods );
119+ onAfterRemoveEdges ();
154120 }
155121 }
156122 }
@@ -168,12 +134,12 @@ protected void onBeforeRemoveEdges() {
168134 *
169135 * @param gcedMethods The number of methods for which edges have been removed
170136 */
171- protected void onAfterRemoveEdges (int gcedMethods ) {
137+ protected void onAfterRemoveEdges () {
172138 }
173139
174140 @ Override
175- public int getGcedMethods () {
176- return gcedMethods .get ();
141+ public int getGcedAbstractions () {
142+ return gcedAbstractions .get ();
177143 }
178144
179145 @ Override
@@ -219,7 +185,7 @@ public void setTrigger(GarbageCollectionTrigger trigger) {
219185 *
220186 * @param peerGroup The peer group
221187 */
222- public void setPeerGroup (GarbageCollectorPeerGroup peerGroup ) {
188+ public void setPeerGroup (GarbageCollectorPeerGroup < A > peerGroup ) {
223189 this .peerGroup = peerGroup ;
224190 peerGroup .addGarbageCollector (this );
225191 }
0 commit comments