1 salcianu 1.1.2.1 // CheesyPACheckRemoval.java, created Tue Jan 23 16:14:25 2001 by salcianu
  2 cananian 1.1.2.7 // Copyright (C) 2000 Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu>
  3 salcianu 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 salcianu 1.1.2.1 package harpoon.Analysis.Realtime;
  5 salcianu 1.1.2.1 
  6 salcianu 1.1.2.1 import java.util.Map;
  7 salcianu 1.1.2.1 import java.util.Hashtable;
  8 salcianu 1.1.2.1 import java.util.Set;
  9 salcianu 1.1.2.1 import java.util.HashSet;
 10 salcianu 1.1.2.1 import java.util.Iterator;
 11 salcianu 1.1.2.1 
 12 salcianu 1.1.2.1 import harpoon.ClassFile.Linker;
 13 salcianu 1.1.2.1 import harpoon.ClassFile.HCodeFactory;
 14 salcianu 1.1.2.1 import harpoon.ClassFile.HMethod;
 15 salcianu 1.1.2.1 import harpoon.IR.Quads.QuadNoSSA;
 16 salcianu 1.1.2.1 import harpoon.Analysis.ClassHierarchy;
 17 salcianu 1.1.2.1 
 18 salcianu 1.1.2.1 import harpoon.IR.Quads.Quad;
 19 salcianu 1.1.2.1 import harpoon.IR.Quads.SET;
 20 salcianu 1.1.2.1 import harpoon.IR.Quads.ASET;
 21 salcianu 1.1.2.1 import harpoon.IR.Quads.QuadVisitor;
 22 salcianu 1.1.2.1 
 23 salcianu 1.1.2.1 import harpoon.Temp.Temp;
 24 salcianu 1.1.2.1 
 25 salcianu 1.1.2.1 import harpoon.Analysis.PointerAnalysis.PointerAnalysis;
 26 salcianu 1.1.2.1 import harpoon.Analysis.PointerAnalysis.PANode;
 27 salcianu 1.1.2.1 import harpoon.Analysis.PointerAnalysis.ParIntGraph;
 28 salcianu 1.1.2.1 
 29 salcianu 1.1.2.1 import harpoon.Analysis.MetaMethods.MetaCallGraph;
 30 salcianu 1.1.2.1 import harpoon.Analysis.MetaMethods.MetaMethod;
 31 salcianu 1.1.2.1 import harpoon.Analysis.MetaMethods.FakeMetaCallGraph;
 32 salcianu 1.1.2.1 import harpoon.Analysis.MetaMethods.MetaCallGraphImpl;
 33 salcianu 1.1.2.1 import harpoon.Analysis.MetaMethods.MetaAllCallers;
 34 salcianu 1.1.2.1 import harpoon.Util.LightBasicBlocks.LBBConverter;
 35 salcianu 1.1.2.1 
 36 salcianu 1.1.2.1 import harpoon.ClassFile.CachingCodeFactory;
 37 salcianu 1.1.2.1 import harpoon.Util.BasicBlocks.CachingBBConverter;
 38 salcianu 1.1.2.1 import harpoon.Util.LightBasicBlocks.LightBasicBlock;
 39 salcianu 1.1.2.1 import harpoon.Util.LightBasicBlocks.LBBConverter;
 40 salcianu 1.1.2.1 import harpoon.Util.LightBasicBlocks.CachingLBBConverter;
 41 salcianu 1.1.2.6 import harpoon.Util.LightBasicBlocks.CachingSCCLBBFactory;
 42 salcianu 1.1.2.1 
 43 salcianu 1.1.2.1 import harpoon.Analysis.Quads.CallGraph;
 44 salcianu 1.1.2.1 import harpoon.Analysis.Quads.CallGraphImpl;
 45 salcianu 1.1.2.1 import harpoon.Analysis.MetaMethods.SmartCallGraph;
 46 salcianu 1.1.2.1 
 47 salcianu 1.1.2.1 import harpoon.Util.Util;
 48 salcianu 1.1.2.1 
 49 salcianu 1.1.2.1 
 50 salcianu 1.1.2.1 /**
 51 salcianu 1.1.2.1  * <code>CheesyPACheckRemoval</code>
 52 salcianu 1.1.2.1  * 
 53 cananian 1.1.2.7  * @author  Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu>
 54 cananian 1.8      * @version $Id: CheesyPACheckRemoval.java,v 1.8 2004/02/08 03:20:13 cananian Exp $
 55 salcianu 1.1.2.1  */
 56 salcianu 1.1.2.1 public class CheesyPACheckRemoval implements CheckRemoval {
 57 salcianu 1.1.2.1 
 58 salcianu 1.1.2.1     private static final boolean SMART_CALL_GRAPH = true;
 59 salcianu 1.1.2.1     private static final boolean DEBUG = true;
 60 salcianu 1.1.2.1 
 61 salcianu 1.1.2.1     PointerAnalysis pa = null;
 62 salcianu 1.1.2.1 
 63 salcianu 1.1.2.1     MetaCallGraph mcg = null;
 64 salcianu 1.1.2.1 
 65 salcianu 1.1.2.1     private boolean shouldRemoveAllChecks = false;
 66 salcianu 1.1.2.1 
 67 salcianu 1.1.2.1     
 68 salcianu 1.1.2.1     /** Creates a <code>CheesyPACheckRemoval</code>. */
 69 salcianu 1.1.2.1     public CheesyPACheckRemoval(Linker linker, ClassHierarchy ch,
 70 salcianu 1.1.2.1                                 HCodeFactory hcf, Set mroots) {
 71 salcianu 1.1.2.1         // 1. create the pointer analysis object
 72 salcianu 1.1.2.1         create_pa(linker, ch, hcf, mroots);
 73 salcianu 1.1.2.1         // 2. use the pointer analysis to see if ALL the checks
 74 salcianu 1.1.2.1         // can be removed or not
 75 salcianu 1.1.2.1         shouldRemoveAllChecks = uselessChecks();
 76 salcianu 1.1.2.3 
 77 salcianu 1.1.2.3         if(DEBUG)
 78 salcianu 1.1.2.3             System.out.println("shouldRemoveAllChecks = " + 
 79 salcianu 1.1.2.3                               shouldRemoveAllChecks);
 80 salcianu 1.1.2.1     }
 81 salcianu 1.1.2.1 
 82 salcianu 1.1.2.1 
 83 salcianu 1.1.2.1     /** Create the Pointer Analysis object. */
 84 salcianu 1.1.2.1     private void create_pa(Linker linker, ClassHierarchy ch,
 85 salcianu 1.1.2.1                            HCodeFactory hcf, Set mroots) {
 86 cananian 1.3.2.1         assert hcf.getCodeName().equals(QuadNoSSA.codename) : "Not a QuadNoSSA code factory";
 87 salcianu 1.1.2.1         // we really need a caching code factory; raise an error otherwise
 88 salcianu 1.1.2.1         CachingCodeFactory ccf = (CachingCodeFactory) hcf;
 89 salcianu 1.1.2.1         CachingBBConverter bbconv = new CachingBBConverter(ccf);
 90 salcianu 1.1.2.1         LBBConverter lbbconv = new CachingLBBConverter(bbconv);
 91 salcianu 1.1.2.1 
 92 salcianu 1.1.2.2         mroots = filter(mroots);
 93 salcianu 1.1.2.2 
 94 salcianu 1.1.2.1         Set run_mms = null;
 95 salcianu 1.1.2.1         CallGraph cg = null;
 96 salcianu 1.1.2.1         
 97 salcianu 1.1.2.1         System.out.print("CallGraph ... ");
 98 salcianu 1.1.2.1         long tstart = time();
 99 salcianu 1.1.2.1         if(SMART_CALL_GRAPH){ // smart call graph!
100 salcianu 1.5                 MetaCallGraph fmcg = 
101 salcianu 1.5                     new MetaCallGraphImpl(ccf, linker, ch, mroots);
102 salcianu 1.1.2.1             run_mms = fmcg.getRunMetaMethods();
103 salcianu 1.1.2.1             cg = new SmartCallGraph(fmcg);
104 salcianu 1.1.2.1         }
105 salcianu 1.1.2.1         else
106 salcianu 1.1.2.1             cg = new CallGraphImpl(ch, ccf);
107 salcianu 1.1.2.1 
108 salcianu 1.6             mcg = new FakeMetaCallGraph(cg, run_mms);
109 salcianu 1.1.2.1 
110 salcianu 1.1.2.1         MetaAllCallers mac = new MetaAllCallers(mcg);
111 salcianu 1.1.2.1         System.out.println((time() - tstart) + "ms");
112 salcianu 1.1.2.1 
113 salcianu 1.1.2.2         PointerAnalysis.CALL_CONTEXT_SENSITIVE = true;
114 salcianu 1.1.2.2         PointerAnalysis.MAX_SPEC_DEPTH = 2;
115 salcianu 1.1.2.2 
116 salcianu 1.1.2.1         System.out.println("PointerAnalysis ... ");
117 salcianu 1.1.2.1         tstart = time();
118 salcianu 1.6             pa = new PointerAnalysis(mcg, 
119 salcianu 1.1.2.6                                  new CachingSCCLBBFactory(lbbconv),
120 salcianu 1.7                                      linker, ch);
121 salcianu 1.1.2.2         /*
122 salcianu 1.1.2.1         // intrathread analysis of all the callable methods
123 cananian 1.8             for(Object mmO : mcg.getAllMetaMethods()) {
124 cananian 1.8                 MetaMethod mm = (MetaMethod) mmO;
125 salcianu 1.1.2.1             if(!analyzable(mm)) continue;
126 salcianu 1.1.2.1             pa.getIntParIntGraph(mm);
127 salcianu 1.1.2.1         }
128 salcianu 1.1.2.2         */
129 salcianu 1.1.2.1         System.out.println((time() - tstart) + "ms");
130 salcianu 1.1.2.1     }
131 salcianu 1.1.2.1 
132 salcianu 1.1.2.2 
133 salcianu 1.1.2.2     private Set filter(Set mroots) {
134 salcianu 1.1.2.2         Set result = new HashSet();
135 salcianu 1.1.2.2         if(DEBUG) System.out.println("Root methods:");
136 salcianu 1.1.2.2         for(Iterator it = mroots.iterator(); it.hasNext(); ) {
137 salcianu 1.1.2.2             Object obj = it.next();
138 salcianu 1.1.2.2             if(obj instanceof HMethod) {
139 salcianu 1.1.2.2                 if(DEBUG) System.out.println(" " + obj);
140 salcianu 1.1.2.2                 result.add(obj);
141 salcianu 1.1.2.2             }
142 salcianu 1.1.2.2         }
143 salcianu 1.1.2.2         return result;
144 salcianu 1.1.2.2     }
145 salcianu 1.1.2.1     
146 salcianu 1.1.2.1     /** Checks whether all the checks done in the program are useless or not:
147 salcianu 1.1.2.1         for any method m having the name "run", no inside object escapes
148 salcianu 1.1.2.1         from it. */
149 salcianu 1.1.2.1     private boolean uselessChecks() {
150 salcianu 1.1.2.1         Set runs = new HashSet();
151 cananian 1.8             for(Object mmO : mcg.getAllMetaMethods()) {
152 cananian 1.8                 MetaMethod mm = (MetaMethod) mmO;
153 salcianu 1.1.2.1             if(mm.getHMethod().getName().equals("run"))
154 salcianu 1.1.2.1                 runs.add(mm);
155 salcianu 1.1.2.1         }
156 salcianu 1.1.2.1 
157 salcianu 1.1.2.1         if(DEBUG) {
158 salcianu 1.1.2.1             System.out.println("Run methods: ");
159 salcianu 1.1.2.1             for(Iterator it = runs.iterator(); it.hasNext(); )
160 salcianu 1.1.2.1                 System.out.println(((MetaMethod) it.next()).getHMethod());
161 salcianu 1.1.2.1         }
162 salcianu 1.1.2.1         
163 cananian 1.8             for(Object mmO : runs) {
164 cananian 1.8                 MetaMethod mm = (MetaMethod) mmO;
165 salcianu 1.1.2.3 
166 salcianu 1.1.2.3             HMethod hm  = mm.getHMethod();
167 salcianu 1.1.2.3             String cls_name = hm.getDeclaringClass().getName();
168 salcianu 1.1.2.3             if(cls_name.equals("javax.realtime.RealtimeThread") ||
169 salcianu 1.1.2.3                cls_name.equals("java.lang.Thread")) {
170 salcianu 1.1.2.3                 System.out.println(mm + " was skipped!");
171 salcianu 1.1.2.3                 continue;
172 salcianu 1.1.2.3             }
173 salcianu 1.1.2.1             if(containsEscapingStuff(mm)) return false;
174 salcianu 1.1.2.1         }
175 salcianu 1.1.2.1         return true;
176 salcianu 1.1.2.1     }
177 salcianu 1.1.2.1 
178 salcianu 1.1.2.1     
179 salcianu 1.1.2.1     /** Checks whether any inside node escapes from <code>mm</code>. */
180 salcianu 1.1.2.1     private boolean containsEscapingStuff(MetaMethod mm) {
181 salcianu 1.1.2.5         if(!PointerAnalysis.analyzable(mm.getHMethod())) return true;
182 salcianu 1.1.2.1 
183 salcianu 1.1.2.1         // the set of nodes appearing in the external pig is the
184 salcianu 1.1.2.1         // set of the escaping objects
185 salcianu 1.1.2.2         ParIntGraph pig = pa.getExtParIntGraph(mm);
186 salcianu 1.1.2.3         System.out.println("ExtPIG(" + mm + ")\n" + pig);
187 salcianu 1.1.2.1         Set nodes = pig.allNodes();
188 salcianu 1.1.2.1 
189 salcianu 1.1.2.1         // if one of the elements of the set nodes is an INSIDE node,
190 salcianu 1.1.2.1         // some objects are leaking out of the memory scope ...
191 cananian 1.8             for(Object nodeO : nodes) {
192 cananian 1.8                 PANode node = (PANode) nodeO;
193 salcianu 1.1.2.3             if(node.type == PANode.INSIDE) return true;
194 salcianu 1.1.2.1         }
195 salcianu 1.1.2.1         // nothing escapes!
196 salcianu 1.1.2.3         return false;
197 salcianu 1.1.2.1     }
198 salcianu 1.1.2.1     
199 salcianu 1.1.2.1     private long time() {
200 salcianu 1.1.2.1         return System.currentTimeMillis();
201 salcianu 1.1.2.1     }
202 salcianu 1.1.2.1 
203 salcianu 1.1.2.1 
204 salcianu 1.1.2.1     public boolean shouldRemoveCheck(Quad instr) {
205 salcianu 1.1.2.1         return shouldRemoveAllChecks;
206 salcianu 1.1.2.1     }
207 salcianu 1.1.2.1 
208 cananian 1.2     }