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 }