KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > spark > solver > PropWorklist


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2002 - 2006 Ondrej Lhotak
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 package soot.jimple.spark.solver;
21 import soot.jimple.spark.*;
22 import soot.jimple.spark.pag.*;
23 import soot.jimple.spark.sets.*;
24 import soot.jimple.spark.internal.*;
25 import soot.*;
26 import soot.util.queue.*;
27 import java.util.*;
28 import soot.options.SparkOptions;
29
30 /** Propagates points-to sets along pointer assignment graph using a worklist.
31  * @author Ondrej Lhotak
32  */

33
34 public final class PropWorklist extends Propagator {
35     protected final Set varNodeWorkList = new TreeSet();
36
37     public PropWorklist( PAG pag ) { this.pag = pag; }
38     /** Actually does the propagation. */
39     public final void propagate() {
40         ofcg = pag.getOnFlyCallGraph();
41         new TopoSorter( pag, false ).sort();
42     for( Iterator it = pag.allocSources().iterator(); it.hasNext(); ) {
43         handleAllocNode( (AllocNode) it.next() );
44     }
45
46         boolean verbose = pag.getOpts().verbose();
47     do {
48             if( verbose ) {
49                 G.v().out.println( "Worklist has "+varNodeWorkList.size()+
50                         " nodes." );
51             }
52             while( !varNodeWorkList.isEmpty() ) {
53                 VarNode src = (VarNode) varNodeWorkList.iterator().next();
54                 varNodeWorkList.remove( src );
55                 handleVarNode( src );
56             }
57             if( verbose ) {
58                 G.v().out.println( "Now handling field references" );
59             }
60             for( Iterator srcIt = pag.storeSources().iterator(); srcIt.hasNext(); ) {
61                 final VarNode src = (VarNode) srcIt.next();
62                 Node[] targets = pag.storeLookup( src );
63                 for( int i = 0; i < targets.length; i++ ) {
64                     final FieldRefNode target = (FieldRefNode) targets[i];
65                     target.getBase().makeP2Set().forall( new P2SetVisitor() {
66                     public final void visit( Node n ) {
67                             AllocDotField nDotF = pag.makeAllocDotField(
68                                 (AllocNode) n, target.getField() );
69                             nDotF.makeP2Set().addAll( src.getP2Set(), null );
70                         }
71                     } );
72                 }
73             }
74             HashSet edgesToPropagate = new HashSet();
75         for( Iterator it = pag.loadSources().iterator(); it.hasNext(); ) {
76                 handleFieldRefNode( (FieldRefNode) it.next(), edgesToPropagate );
77         }
78             HashSet nodesToFlush = new HashSet();
79             for( Iterator pairIt = edgesToPropagate.iterator(); pairIt.hasNext(); ) {
80                 final Object JavaDoc[] pair = (Object JavaDoc[]) pairIt.next();
81                 PointsToSetInternal nDotF = (PointsToSetInternal) pair[0];
82         PointsToSetInternal newP2Set = nDotF.getNewSet();
83                 VarNode loadTarget = (VarNode) pair[1];
84                 if( loadTarget.makeP2Set().addAll( newP2Set, null ) ) {
85                     varNodeWorkList.add( loadTarget );
86                 }
87                 nodesToFlush.add( nDotF );
88             }
89             for( Iterator nDotFIt = nodesToFlush.iterator(); nDotFIt.hasNext(); ) {
90                 final PointsToSetInternal nDotF = (PointsToSetInternal) nDotFIt.next();
91                 nDotF.flushNew();
92             }
93     } while( !varNodeWorkList.isEmpty() );
94     }
95
96     /* End of public methods. */
97     /* End of package methods. */
98
99     /** Propagates new points-to information of node src to all its
100      * successors. */

101     protected final boolean handleAllocNode( AllocNode src ) {
102     boolean ret = false;
103     Node[] targets = pag.allocLookup( src );
104     for( int i = 0; i < targets.length; i++ ) {
105         if( targets[i].makeP2Set().add( src ) ) {
106                 varNodeWorkList.add( (VarNode) targets[i] );
107                 ret = true;
108             }
109     }
110     return ret;
111     }
112     /** Propagates new points-to information of node src to all its
113      * successors. */

114     protected final boolean handleVarNode( final VarNode src ) {
115     boolean ret = false;
116         boolean flush = true;
117
118         if( src.getReplacement() != src ) throw new RuntimeException JavaDoc(
119                 "Got bad node "+src+" with rep "+src.getReplacement() );
120
121     final PointsToSetInternal newP2Set = src.getP2Set().getNewSet();
122     if( newP2Set.isEmpty() ) return false;
123
124         if( ofcg != null ) {
125             QueueReader addedEdges = pag.edgeReader();
126             ofcg.updatedNode( src );
127             ofcg.build();
128
129             while(addedEdges.hasNext()) {
130                 Node addedSrc = (Node) addedEdges.next();
131                 Node addedTgt = (Node) addedEdges.next();
132                 ret = true;
133                 if( addedSrc instanceof VarNode ) {
134                     if( addedTgt instanceof VarNode ) {
135                         VarNode edgeSrc = (VarNode) addedSrc.getReplacement();
136                         VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
137
138                         if( edgeTgt.makeP2Set().addAll( edgeSrc.getP2Set(), null ) ) {
139                             varNodeWorkList.add( edgeTgt );
140                             if(edgeTgt == src) flush = false;
141                         }
142                     }
143                 } else if( addedSrc instanceof AllocNode ) {
144                     AllocNode edgeSrc = (AllocNode) addedSrc;
145                     VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
146                     if( edgeTgt.makeP2Set().add( edgeSrc ) ) {
147                         varNodeWorkList.add( edgeTgt );
148                         if(edgeTgt == src) flush = false;
149                     }
150                 }
151             }
152         }
153
154     Node[] simpleTargets = pag.simpleLookup( src );
155     for( int i = 0; i < simpleTargets.length; i++ ) {
156         if( simpleTargets[i].makeP2Set().addAll( newP2Set, null ) ) {
157                 varNodeWorkList.add( (VarNode) simpleTargets[i] );
158                 if(simpleTargets[i] == src) flush = false;
159                 ret = true;
160             }
161     }
162
163         Node[] storeTargets = pag.storeLookup( src );
164         for( int i = 0; i < storeTargets.length; i++ ) {
165             final FieldRefNode fr = (FieldRefNode) storeTargets[i];
166             final SparkField f = fr.getField();
167             ret = fr.getBase().getP2Set().forall( new P2SetVisitor() {
168             public final void visit( Node n ) {
169                     AllocDotField nDotF = pag.makeAllocDotField(
170                         (AllocNode) n, f );
171                     if( nDotF.makeP2Set().addAll( newP2Set, null ) ) {
172                         returnValue = true;
173                     }
174         }
175         } ) | ret;
176         }
177
178         final HashSet storesToPropagate = new HashSet();
179         final HashSet loadsToPropagate = new HashSet();
180     Collection fieldRefs = src.getAllFieldRefs();
181     for( Iterator frIt = fieldRefs.iterator(); frIt.hasNext(); ) {
182         final FieldRefNode fr = (FieldRefNode) frIt.next();
183         final SparkField field = fr.getField();
184         final Node[] storeSources = pag.storeInvLookup( fr );
185             if( storeSources.length > 0 ) {
186                 newP2Set.forall( new P2SetVisitor() {
187                 public final void visit( Node n ) {
188                         AllocDotField nDotF = pag.makeAllocDotField(
189                             (AllocNode) n, field );
190                         for( int i = 0; i < storeSources.length; i++ ) {
191                             Node[] pair = { storeSources[i],
192                                 nDotF.getReplacement() };
193                             storesToPropagate.add( pair );
194                         }
195                     }
196                 } );
197             }
198
199         final Node[] loadTargets = pag.loadLookup( fr );
200             if( loadTargets.length > 0 ) {
201                 newP2Set.forall( new P2SetVisitor() {
202                 public final void visit( Node n ) {
203                         AllocDotField nDotF = pag.findAllocDotField(
204                             (AllocNode) n, field );
205                         if( nDotF != null ) {
206                             for( int i = 0; i < loadTargets.length; i++ ) {
207                                 Node[] pair = { nDotF.getReplacement(),
208                                     loadTargets[i] };
209                                 loadsToPropagate.add( pair );
210                             }
211                         }
212                     }
213                 } );
214             }
215     }
216         if(flush) src.getP2Set().flushNew();
217         for( Iterator pIt = storesToPropagate.iterator(); pIt.hasNext(); ) {
218             final Node[] p = (Node[]) pIt.next();
219             VarNode storeSource = (VarNode) p[0];
220             AllocDotField nDotF = (AllocDotField) p[1];
221             if( nDotF.makeP2Set().addAll( storeSource.getP2Set(), null ) ) {
222                 ret = true;
223             }
224         }
225         for( Iterator pIt = loadsToPropagate.iterator(); pIt.hasNext(); ) {
226             final Node[] p = (Node[]) pIt.next();
227             AllocDotField nDotF = (AllocDotField) p[0];
228             VarNode loadTarget = (VarNode) p[1];
229             if( loadTarget.makeP2Set().
230                 addAll( nDotF.getP2Set(), null ) ) {
231                 varNodeWorkList.add( loadTarget );
232                 ret = true;
233             }
234         }
235     return ret;
236     }
237
238     /** Propagates new points-to information of node src to all its
239      * successors. */

240     protected final void handleFieldRefNode( FieldRefNode src,
241             final HashSet edgesToPropagate ) {
242     final Node[] loadTargets = pag.loadLookup( src );
243     if( loadTargets.length == 0 ) return;
244         final SparkField field = src.getField();
245
246     src.getBase().getP2Set().forall( new P2SetVisitor() {
247
248     public final void visit( Node n ) {
249                 AllocDotField nDotF = pag.findAllocDotField(
250                     (AllocNode) n, field );
251                 if( nDotF != null ) {
252                     PointsToSetInternal p2Set = nDotF.getP2Set();
253                     if( !p2Set.getNewSet().isEmpty() ) {
254                         for( int i = 0; i < loadTargets.length; i++ ) {
255                             Object JavaDoc[] pair = { p2Set, loadTargets[i] };
256                             edgesToPropagate.add( pair );
257                         }
258                     }
259                 }
260         }
261     } );
262     }
263     
264     protected PAG pag;
265     protected OnFlyCallGraph ofcg;
266 }
267
268
269
270
Popular Tags