KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > invoke > StaticInliner


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1999 Patrick Lam, Raja Vallee-Rai
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 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

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 /** Uses the Scene's currently-active InvokeGraph to inline monomorphic call sites. */
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 JavaDoc 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 JavaDoc 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         // Visit each potential site in reverse pseudo topological order.
66
{
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         // Proceed to inline the sites, one at a time, keeping track of
115
// expansion rates.
116
{
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 JavaDoc)methodToOriginalSize.get(container)).intValue())
138                     continue;
139
140                 if(InlinerSafetyManager.ensureInlinability(inlinee, invokeStmt, container, modifierOptions))
141                 {
142                     // Not that it is important to check right before inlining if the site is still valid.
143

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 JavaDoc(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