1 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 32 33 public final class PropIter extends Propagator { 34 public PropIter( PAG pag ) { this.pag = pag; } 35 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 86 87 88 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 |