| 1 19 20 25 26 package soot.jimple.toolkits.invoke; 27 import soot.options.*; 28 29 import soot.*; 30 import soot.jimple.*; 31 import soot.jimple.toolkits.scalar.*; 32 import soot.jimple.toolkits.callgraph.*; 33 import soot.toolkits.graph.*; 34 import java.util.*; 35 import soot.util.*; 36 37 38 public class StaticInliner extends SceneTransformer 39 { 40 public StaticInliner( Singletons.Global g ) {} 41 public static StaticInliner v() { return G.v().soot_jimple_toolkits_invoke_StaticInliner(); } 42 43 protected void internalTransform(String phaseName, Map options) 44 { 45 Filter explicitInvokesFilter = new Filter( new ExplicitEdgesPred() ); 46 if(Options.v().verbose()) 47 G.v().out.println("[] Inlining methods..."); 48 49 boolean enableNullPointerCheckInsertion = PhaseOptions.getBoolean(options, "insert-null-checks"); 50 boolean enableRedundantCastInsertion = PhaseOptions.getBoolean(options, "insert-redundant-casts"); 51 String modifierOptions = PhaseOptions.getString(options, "allowed-modifier-changes"); 52 float expansionFactor = PhaseOptions.getFloat(options, "expansion-factor"); 53 int maxContainerSize = PhaseOptions.getInt(options, "max-container-size"); 54 int maxInlineeSize = PhaseOptions.getInt(options, "max-inlinee-size"); 55 boolean rerunJb = PhaseOptions.getBoolean(options, "rerun-jb"); 56 57 HashMap instanceToStaticMap = new HashMap(); 58 59 CallGraph cg = Scene.v().getCallGraph(); 60 Hierarchy hierarchy = Scene.v().getActiveHierarchy(); 61 62 ArrayList sitesToInline = new ArrayList(); 63 64 computeAverageMethodSizeAndSaveOriginalSizes(); 65 { 67 TopologicalOrderer orderer = new TopologicalOrderer(cg); 68 orderer.go(); 69 List order = orderer.order(); 70 ListIterator it = order.listIterator(order.size()); 71 72 while (it.hasPrevious()) 73 { 74 SootMethod container = (SootMethod)it.previous(); 75 if( methodToOriginalSize.get(container) == null ) continue; 76 77 if (!container.isConcrete()) 78 continue; 79 80 if (!explicitInvokesFilter.wrap( cg.edgesOutOf(container) ).hasNext()) 81 continue; 82 83 JimpleBody b = (JimpleBody)container.retrieveActiveBody(); 84 85 List unitList = new ArrayList(); unitList.addAll(b.getUnits()); 86 Iterator unitIt = unitList.iterator(); 87 88 while (unitIt.hasNext()) 89 { 90 Stmt s = (Stmt)unitIt.next(); 91 if (!s.containsInvokeExpr()) 92 continue; 93 94 Iterator targets = new Targets( 95 explicitInvokesFilter.wrap( cg.edgesOutOf(s) ) ); 96 if( !targets.hasNext() ) continue; 97 SootMethod target = (SootMethod)targets.next(); 98 if( targets.hasNext() ) continue; 99 100 if (!target.getDeclaringClass().isApplicationClass() || !target.isConcrete()) 101 continue; 102 103 if(!InlinerSafetyManager.ensureInlinability(target, s, container, modifierOptions)) 104 continue; 105 106 List l = new ArrayList(); 107 l.add(target); l.add(s); l.add(container); 108 109 sitesToInline.add(l); 110 } 111 } 112 } 113 114 { 117 118 Iterator sitesIt = sitesToInline.iterator(); 119 while (sitesIt.hasNext()) 120 { 121 List l = (List)sitesIt.next(); 122 SootMethod inlinee = (SootMethod)l.get(0); 123 int inlineeSize = ((JimpleBody)(inlinee.retrieveActiveBody())).getUnits().size(); 124 125 Stmt invokeStmt = (Stmt)l.get(1); 126 127 SootMethod container = (SootMethod)l.get(2); 128 int containerSize = ((JimpleBody)(container.retrieveActiveBody())).getUnits().size(); 129 130 if (inlineeSize + containerSize > maxContainerSize) 131 continue; 132 133 if (inlineeSize > maxInlineeSize) 134 continue; 135 136 if (inlineeSize + containerSize > 137 expansionFactor * ((Integer )methodToOriginalSize.get(container)).intValue()) 138 continue; 139 140 if(InlinerSafetyManager.ensureInlinability(inlinee, invokeStmt, container, modifierOptions)) 141 { 142 144 SiteInliner.inlineSite(inlinee, invokeStmt, container, options); 145 if( rerunJb ) { 146 PackManager.v().getPack("jb").apply(container.getActiveBody()); 147 } 148 } 149 } 150 } 151 } 152 153 private HashMap methodToOriginalSize = new HashMap(); 154 private int avgSize = 0; 155 156 private void computeAverageMethodSizeAndSaveOriginalSizes() 157 { 158 long sum = 0, count = 0; 159 Iterator classesIt = Scene.v().getApplicationClasses().iterator(); 160 161 while (classesIt.hasNext()) 162 { 163 SootClass c = (SootClass) classesIt.next(); 164 165 Iterator methodsIt = c.methodIterator(); 166 while (methodsIt.hasNext()) 167 { 168 SootMethod m = (SootMethod) methodsIt.next(); 169 if (m.isConcrete()) 170 { 171 int size = ((JimpleBody)m.retrieveActiveBody()).getUnits().size(); 172 sum += size; 173 methodToOriginalSize.put(m, new Integer (size)); 174 count++; 175 } 176 } 177 } 178 if (count == 0) 179 return; 180 avgSize = (int)(sum/count); 181 } 182 } 183 184 185 186 | Popular Tags |