KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2002 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.*;
25 import soot.util.queue.*;
26 import java.util.*;
27 import soot.options.SparkOptions;
28
29 /** Propagates points-to sets along pointer assignment graph using iteration.
30  * @author Ondrej Lhotak
31  */

32
33 public final class PropIter extends Propagator {
34     public PropIter( PAG pag ) { this.pag = pag; }
35     /** Actually does the propagation. */
36     public final void propagate() {
37         final OnFlyCallGraph ofcg = pag.getOnFlyCallGraph();
38         new TopoSorter( pag, false ).sort();
39         for( Iterator it = pag.allocSources().iterator(); it.hasNext(); ) {
40             handleAllocNode( (AllocNode) it.next() );
41         }
42         int iteration = 1;
43     boolean change;
44     do {
45         change = false;
46             TreeSet simpleSources = new TreeSet( pag.simpleSources() );
47             if( pag.getOpts().verbose() ) {
48                 G.v().out.println( "Iteration "+(iteration++) );
49             }
50             for( Iterator it = simpleSources.iterator(); it.hasNext(); ) {
51                 change = handleSimples( (VarNode) it.next() ) | change;
52             }
53             if( ofcg != null ) {
54                 QueueReader addedEdges = pag.edgeReader();
55                 for( Iterator srcIt = pag.getVarNodeNumberer().iterator(); srcIt.hasNext(); ) {
56                     final VarNode src = (VarNode) srcIt.next();
57                     ofcg.updatedNode( src );
58                 }
59                 ofcg.build();
60
61                 while(addedEdges.hasNext()) {
62                     Node addedSrc = (Node) addedEdges.next();
63                     Node addedTgt = (Node) addedEdges.next();
64                     change = true;
65                     if( addedSrc instanceof VarNode ) {
66                         PointsToSetInternal p2set = ((VarNode)addedSrc).getP2Set();
67                         if( p2set != null ) p2set.unFlushNew();
68                     } else if( addedSrc instanceof AllocNode ) {
69                         ((VarNode) addedTgt).makeP2Set().add( (AllocNode) addedSrc );
70                     }
71                 }
72                 if( change ) {
73                     new TopoSorter( pag, false ).sort();
74                 }
75             }
76         for( Iterator it = pag.loadSources().iterator(); it.hasNext(); ) {
77                 change = handleLoads( (FieldRefNode) it.next() ) | change;
78         }
79         for( Iterator it = pag.storeSources().iterator(); it.hasNext(); ) {
80                 change = handleStores( (VarNode) it.next() ) | change;
81         }
82     } while( change );
83     }
84
85     /* End of public methods. */
86     /* End of package methods. */
87
88     /** Propagates new points-to information of node src to all its
89      * successors. */

90     protected final boolean handleAllocNode( AllocNode src ) {
91     boolean ret = false;
92     Node[] targets = pag.allocLookup( src );
93     for( int i = 0; i < targets.length; i++ ) {
94         ret = targets[i].makeP2Set().add( src ) | ret;
95     }
96     return ret;
97     }
98
99     protected final boolean handleSimples( VarNode src ) {
100     boolean ret = false;
101     PointsToSetInternal srcSet = src.getP2Set();
102     if( srcSet.isEmpty() ) return false;
103     Node[] simpleTargets = pag.simpleLookup( src );
104     for( int i = 0; i < simpleTargets.length; i++ ) {
105         ret = simpleTargets[i].makeP2Set().addAll( srcSet, null ) | ret;
106     }
107         return ret;
108     }
109
110     protected final boolean handleStores( VarNode src ) {
111     boolean ret = false;
112     final PointsToSetInternal srcSet = src.getP2Set();
113     if( srcSet.isEmpty() ) return false;
114     Node[] storeTargets = pag.storeLookup( src );
115     for( int i = 0; i < storeTargets.length; i++ ) {
116             final FieldRefNode fr = (FieldRefNode) storeTargets[i];
117             final SparkField f = fr.getField();
118             ret = fr.getBase().getP2Set().forall( new P2SetVisitor() {
119             public final void visit( Node n ) {
120                     AllocDotField nDotF = pag.makeAllocDotField(
121                         (AllocNode) n, f );
122                     if( nDotF.makeP2Set().addAll( srcSet, null ) ) {
123                         returnValue = true;
124                     }
125                 }
126             } ) | ret;
127     }
128         return ret;
129     }
130
131     protected final boolean handleLoads( FieldRefNode src ) {
132     boolean ret = false;
133     final Node[] loadTargets = pag.loadLookup( src );
134         final SparkField f = src.getField();
135         ret = src.getBase().getP2Set().forall( new P2SetVisitor() {
136         public final void visit( Node n ) {
137                 AllocDotField nDotF = ((AllocNode)n).dot( f );
138                 if( nDotF == null ) return;
139                 PointsToSetInternal set = nDotF.getP2Set();
140                 if( set.isEmpty() ) return;
141                 for( int i = 0; i < loadTargets.length; i++ ) {
142                     VarNode target = (VarNode) loadTargets[i];
143                     if( target.makeP2Set().addAll( set, null ) ) {
144                         returnValue = true;
145                     }
146                 }
147             }
148         } ) | ret;
149         return ret;
150     }
151
152     protected PAG pag;
153 }
154
155
156
157
Popular Tags