1 marinov 1.1.2.1 // TypeInfo.java, created Thu Sep 10 14:58:21 1998 by cananian 2 marinov 1.1.2.1 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 marinov 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 marinov 1.1.2.1 package harpoon.Analysis.TypeInference; 5 marinov 1.1.2.1 6 marinov 1.1.2.1 import harpoon.Analysis.Maps.UseDefMap; 7 marinov 1.1.2.1 import harpoon.Analysis.UseDef; 8 cananian 1.1.2.14 import harpoon.ClassFile.HClass; 9 cananian 1.1.2.14 import harpoon.ClassFile.HCodeFactory; 10 cananian 1.1.2.14 import harpoon.ClassFile.HCodeElement; 11 cananian 1.1.2.14 import harpoon.ClassFile.HMethod; 12 cananian 1.1.2.16 import harpoon.ClassFile.Linker; 13 cananian 1.1.2.14 import harpoon.IR.Quads.Quad; 14 cananian 1.1.2.14 import harpoon.IR.Quads.QuadSSI; 15 cananian 1.1.2.14 import harpoon.IR.Quads.QuadVisitor; 16 cananian 1.1.2.14 import harpoon.IR.Quads.AGET; 17 cananian 1.1.2.14 import harpoon.IR.Quads.ANEW; 18 cananian 1.1.2.14 import harpoon.IR.Quads.ALENGTH; 19 cananian 1.1.2.14 import harpoon.IR.Quads.ARRAYINIT; 20 cananian 1.1.2.14 import harpoon.IR.Quads.ASET; 21 cananian 1.1.2.14 import harpoon.IR.Quads.CALL; 22 cananian 1.1.2.14 import harpoon.IR.Quads.CJMP; 23 cananian 1.1.2.14 import harpoon.IR.Quads.COMPONENTOF; 24 cananian 1.1.2.14 import harpoon.IR.Quads.CONST; 25 cananian 1.1.2.14 import harpoon.IR.Quads.DEBUG; 26 cananian 1.1.2.14 import harpoon.IR.Quads.GET; 27 cananian 1.1.2.14 import harpoon.IR.Quads.FOOTER; 28 cananian 1.1.2.14 import harpoon.IR.Quads.HANDLER; 29 cananian 1.1.2.14 import harpoon.IR.Quads.HEADER; 30 cananian 1.1.2.14 import harpoon.IR.Quads.INSTANCEOF; 31 cananian 1.1.2.14 import harpoon.IR.Quads.LABEL; 32 cananian 1.1.2.14 import harpoon.IR.Quads.METHOD; 33 cananian 1.1.2.14 import harpoon.IR.Quads.MONITORENTER; 34 cananian 1.1.2.14 import harpoon.IR.Quads.MONITOREXIT; 35 cananian 1.1.2.14 import harpoon.IR.Quads.MOVE; 36 cananian 1.1.2.14 import harpoon.IR.Quads.NEW; 37 cananian 1.1.2.14 import harpoon.IR.Quads.NOP; 38 cananian 1.1.2.14 import harpoon.IR.Quads.OPER; 39 cananian 1.1.2.14 import harpoon.IR.Quads.PHI; 40 cananian 1.1.2.14 import harpoon.IR.Quads.RETURN; 41 cananian 1.1.2.14 import harpoon.IR.Quads.SET; 42 cananian 1.1.2.14 import harpoon.IR.Quads.SIGMA; 43 cananian 1.1.2.14 import harpoon.IR.Quads.SWITCH; 44 cananian 1.1.2.14 import harpoon.IR.Quads.THROW; 45 cananian 1.1.2.14 import harpoon.IR.Quads.TYPECAST; 46 marinov 1.1.2.1 import harpoon.Util.Util; 47 cananian 1.1.2.14 import harpoon.Temp.Temp; 48 marinov 1.1.2.1 import harpoon.Util.Worklist; 49 cananian 1.1.2.19 import harpoon.Util.Collections.WorkSet; 50 cananian 1.5 import java.util.Iterator; 51 cananian 1.1.2.17 import java.util.HashMap; 52 cananian 1.1.2.17 import java.util.HashSet; 53 cananian 1.1.2.17 import java.util.Iterator; 54 cananian 1.1.2.17 import java.util.Map; 55 cananian 1.1.2.17 import java.util.Set; 56 marinov 1.1.2.1 /** 57 cananian 1.1.2.13 * <code>TypeInfo</code> is a simple type analysis tool for quad-ssi form. 58 marinov 1.1.2.1 * 59 marinov 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 60 cananian 1.6 * @version $Id: IntraProc.java,v 1.6 2004/02/08 03:20:38 cananian Exp $ 61 marinov 1.1.2.1 */ 62 marinov 1.1.2.1 63 marinov 1.1.2.1 public class IntraProc { 64 marinov 1.1.2.1 InterProc environment; 65 marinov 1.1.2.1 HMethod method; 66 cananian 1.1.2.13 QuadSSI code; 67 marinov 1.1.2.1 UseDefMap usedef; 68 cananian 1.1.2.16 Linker linker; 69 marinov 1.1.2.1 70 marinov 1.1.2.1 SetHClass[] parameterTypes; 71 marinov 1.1.2.1 SetHClass returnType; 72 marinov 1.1.2.1 SetHClass exceptionType; 73 marinov 1.1.2.7 public static boolean exceptionAnalysis = false; // UGLY?! otherwise, running out of memory now 74 marinov 1.1.2.1 Set callees; 75 marinov 1.1.2.7 int depth = 0; 76 marinov 1.1.2.1 77 cananian 1.1.2.11 public IntraProc(InterProc e, HMethod m, HCodeFactory hcf) { 78 marinov 1.1.2.1 environment = e; 79 marinov 1.1.2.1 method = m; 80 cananian 1.1.2.16 linker = m.getDeclaringClass().getLinker(); 81 cananian 1.1.2.13 code = (QuadSSI)hcf.convert(m); 82 marinov 1.1.2.1 usedef = new UseDef(); 83 marinov 1.1.2.1 parameterTypes = new SetHClass[m.getParameterTypes().length+(m.isStatic()?0:1)]; 84 marinov 1.1.2.1 for (int i=0; i<parameterTypes.length; i++) 85 marinov 1.1.2.1 parameterTypes[i] = new SetHClass(); 86 marinov 1.1.2.1 returnType = new SetHClass(); 87 marinov 1.1.2.1 exceptionType = new SetHClass(); 88 pnkfelix 1.1.2.12 callees = new HashSet(); 89 marinov 1.1.2.1 } 90 marinov 1.1.2.1 91 marinov 1.1.2.1 SetHClass getReturnType() { return returnType.copy(); } 92 marinov 1.1.2.1 SetHClass getExceptionType() { return exceptionType.copy(); } 93 marinov 1.1.2.1 94 marinov 1.1.2.7 void addCallee(IntraProc i) { 95 cananian 1.1.2.17 callees.add(i); 96 marinov 1.1.2.7 int d = i.depth+1; 97 marinov 1.1.2.7 if (d>depth) depth = d; 98 marinov 1.1.2.7 } 99 marinov 1.1.2.1 boolean addParameters(SetHClass[] p) { 100 marinov 1.1.2.1 boolean changed = false; 101 marinov 1.1.2.1 for (int i=0; i<p.length; i++) 102 marinov 1.1.2.1 if (parameterTypes[i].union(p[i])) changed = true; 103 marinov 1.1.2.1 return changed; 104 marinov 1.1.2.1 } 105 marinov 1.1.2.1 106 marinov 1.1.2.1 HMethod[] possibleMethods(HMethod m, SetHClass[] p) { 107 marinov 1.1.2.1 if (m.isStatic()) return new HMethod[]{ m }; 108 marinov 1.1.2.8 if (p[0]==null) return new HMethod[0]; 109 pnkfelix 1.1.2.12 Set sm = new HashSet(); 110 cananian 1.6 for (Object cO : p[0]) { 111 cananian 1.6 HClass c = (HClass) cO; 112 marinov 1.1.2.1 boolean notDone = true; 113 marinov 1.1.2.1 HMethod nm = null; 114 marinov 1.1.2.1 do { 115 marinov 1.1.2.1 try { 116 marinov 1.1.2.1 nm = c.getDeclaredMethod(m.getName(), 117 marinov 1.1.2.1 m.getDescriptor()); 118 marinov 1.1.2.1 notDone = false; 119 marinov 1.1.2.1 } catch (NoSuchMethodError n) { 120 marinov 1.1.2.1 c = c.getSuperclass(); 121 marinov 1.1.2.1 } 122 marinov 1.1.2.1 } while (notDone&&(c!=null)); 123 marinov 1.1.2.8 while ((c!=m.getDeclaringClass())&&(c!=null)) c=c.getSuperclass(); 124 cananian 1.1.2.17 if (c!=null) sm.add(nm); 125 marinov 1.1.2.1 } 126 cananian 1.1.2.17 return (HMethod[]) sm.toArray(new HMethod[sm.size()]); 127 marinov 1.1.2.1 } 128 marinov 1.1.2.4 129 marinov 1.1.2.4 void nativeMethods() { 130 marinov 1.1.2.4 if (method.getDeclaringClass().getName().equals("java.lang.System")) { 131 marinov 1.1.2.4 if (method.getName().equals("setIn0")) 132 cananian 1.1.2.16 environment.mergeType(linker.forName("java.lang.System").getDeclaredField("in"), parameterTypes[0]); 133 marinov 1.1.2.4 else if (method.getName().equals("setOut0")) 134 cananian 1.1.2.16 environment.mergeType(linker.forName("java.lang.System").getDeclaredField("out"), parameterTypes[0]); 135 marinov 1.1.2.4 else if (method.getName().equals("setErr0")) 136 cananian 1.1.2.16 environment.mergeType(linker.forName("java.lang.System").getDeclaredField("err"), parameterTypes[0]); 137 marinov 1.1.2.4 } 138 marinov 1.1.2.4 returnType = environment.cone(method.getReturnType()); 139 marinov 1.1.2.7 if (exceptionAnalysis) // UGLY?! otherwise, running out of memory now 140 cananian 1.1.2.16 exceptionType = environment.cone(linker.forClass(Throwable.class)); 141 marinov 1.1.2.4 } 142 marinov 1.1.2.1 143 marinov 1.1.2.1 boolean outputChanged; 144 marinov 1.1.2.1 void analyze() { 145 marinov 1.1.2.8 /* added to try to save some memory */ 146 marinov 1.1.2.8 boolean noCache; 147 cananian 1.1.2.17 if (map==null) { map = new HashMap(); noCache = true; } 148 marinov 1.1.2.8 else noCache = false; 149 marinov 1.1.2.8 //OUTPUT 150 marinov 1.1.2.8 long TTT=System.currentTimeMillis(); 151 marinov 1.1.2.8 if (noCache) 152 marinov 1.1.2.8 System.out.print("[analyzed " + method.getDeclaringClass() + " " + method.getName() + " in "); 153 marinov 1.1.2.8 //OUTPUT 154 marinov 1.1.2.1 //DEBUG 155 marinov 1.1.2.1 //if (method.getName().equals("t")) { 156 marinov 1.1.2.1 //System.out.print(" analyzing " + method.getDeclaringClass() + " " + method.getName()); 157 marinov 1.1.2.1 //HClass[] II = method.getParameterTypes(); 158 marinov 1.1.2.1 //for (int ii=0; ii<II.length; ii++) 159 marinov 1.1.2.1 // System.out.print(" " + II[ii]); 160 marinov 1.1.2.1 //System.out.println(""); 161 marinov 1.1.2.1 // for (int ii=0; ii<parameterTypes.length; ii++) 162 marinov 1.1.2.1 // System.out.println("i" + ii + "= " + parameterTypes[ii]); 163 marinov 1.1.2.1 // System.out.println("r = " + returnType); 164 marinov 1.1.2.1 // System.out.println("e = " + exceptionType); 165 marinov 1.1.2.1 //} 166 marinov 1.1.2.1 //DEBUG 167 marinov 1.1.2.6 /* "regular" calculation */ 168 marinov 1.1.2.1 outputChanged = false; 169 marinov 1.1.2.4 if (code==null) // native or unanalyzable method 170 marinov 1.1.2.4 nativeMethods(); 171 marinov 1.1.2.4 else { 172 marinov 1.1.2.1 Quad ql[] = (Quad[]) code.getElements(); 173 cananian 1.1.2.17 WorkSet worklist = new WorkSet(); // use as FIFO 174 marinov 1.1.2.1 for (int i=0; i<ql.length; i++) 175 cananian 1.1.2.17 worklist.add(ql[i]); 176 marinov 1.1.2.1 177 marinov 1.1.2.1 // hack to handle typecasting: 178 marinov 1.1.2.1 // keep track of booleans defined by instanceof's and acmpeq's. 179 cananian 1.1.2.17 Map checkcast = new HashMap(); 180 marinov 1.1.2.1 for (int i=0; i<ql.length; i++) 181 marinov 1.1.2.1 if (ql[i] instanceof INSTANCEOF || 182 marinov 1.1.2.1 ql[i] instanceof OPER) 183 marinov 1.1.2.1 checkcast.put(ql[i].def()[0], ql[i]); 184 marinov 1.1.2.1 185 marinov 1.1.2.1 TypeInfoVisitor tiv = new TypeInfoVisitor(checkcast); 186 marinov 1.1.2.1 while(!worklist.isEmpty()) { 187 cananian 1.1.2.17 Quad q = (Quad) worklist.removeFirst(); // use as fifo 188 marinov 1.1.2.1 tiv.modified = false; 189 cananian 1.1.2.15 q.accept(tiv); 190 marinov 1.1.2.1 if (tiv.modified) { 191 marinov 1.1.2.1 Temp[] d = q.def(); 192 marinov 1.1.2.1 for (int i=0; i<d.length; i++) { 193 marinov 1.1.2.1 HCodeElement[] u = usedef.useMap(code, d[i]); 194 marinov 1.1.2.1 for (int j=0; j<u.length; j++) { 195 cananian 1.1.2.17 worklist.add((Quad)u[j]); // only pushes unique quads. 196 marinov 1.1.2.1 } 197 marinov 1.1.2.1 } 198 marinov 1.1.2.1 } 199 marinov 1.1.2.1 } 200 marinov 1.1.2.1 } 201 marinov 1.1.2.1 //DEBUG 202 marinov 1.1.2.4 //if (method.getName().equals("main")) { 203 marinov 1.1.2.1 //System.out.println(" finished " + method.getDeclaringClass() + " " + method.getName()); 204 marinov 1.1.2.1 // for (int ii=0; ii<parameterTypes.length; ii++) 205 marinov 1.1.2.4 // System.out.println("i" + ii + "=" + parameterTypes[ii]); 206 marinov 1.1.2.1 // System.out.println("r = " + returnType); 207 marinov 1.1.2.1 // System.out.println("e = " + exceptionType); 208 marinov 1.1.2.1 // System.out.println("changed = " + outputChanged); 209 marinov 1.1.2.1 /* 210 marinov 1.1.2.1 for (Enumeration ee=map.keys(); ee.hasMoreElements(); ) { 211 marinov 1.1.2.4 Temp t = (Temp)ee.nextElement(); 212 marinov 1.1.2.1 System.out.println(t + "=" + map.get(t)); 213 marinov 1.1.2.1 } 214 marinov 1.1.2.1 */ 215 marinov 1.1.2.1 //} 216 marinov 1.1.2.1 //DEBUG 217 marinov 1.1.2.1 218 marinov 1.1.2.6 /* added to try to save some memory */ 219 marinov 1.1.2.7 if (noCache) { map = null; if (method.getName().equals("igen")) System.gc(); } 220 marinov 1.1.2.6 /* "regular" calculation */ 221 marinov 1.1.2.1 if (outputChanged) 222 cananian 1.1.2.17 for (Iterator it=callees.iterator(); it.hasNext(); ) 223 cananian 1.1.2.17 environment.reanalyze((IntraProc)it.next()); 224 marinov 1.1.2.8 //OUTPUT 225 marinov 1.1.2.8 if (noCache) 226 marinov 1.1.2.8 System.out.println((System.currentTimeMillis()-TTT) + "ms]"); 227 marinov 1.1.2.8 //OUTPUT 228 marinov 1.1.2.1 } 229 marinov 1.1.2.1 230 marinov 1.1.2.1 HMethod[] calls() { 231 cananian 1.1.2.17 if (map==null) { map = new HashMap(); analyze(); } 232 pnkfelix 1.1.2.12 Set r = new HashSet(); 233 cananian 1.5 for (Iterator e = code.getElementsI(); e.hasNext(); ) { 234 cananian 1.5 Quad qq = (Quad) e.next(); 235 marinov 1.1.2.1 if (!(qq instanceof CALL)) continue; 236 marinov 1.1.2.1 CALL q = (CALL) qq; 237 cananian 1.1.2.9 SetHClass[] paramTypes = new SetHClass[q.paramsLength()]; 238 cananian 1.1.2.9 for (int i=0; i<q.paramsLength(); i++) { 239 cananian 1.1.2.9 SetHClass s = (SetHClass)map.get(q.params(i)); 240 cananian 1.3.2.1 //assert s!=null; 241 marinov 1.1.2.2 paramTypes[i] = s; 242 marinov 1.1.2.1 } 243 marinov 1.1.2.1 HMethod[] m; 244 cananian 1.1.2.9 if (!q.isVirtual()) m = new HMethod[]{ q.method() }; 245 cananian 1.1.2.9 else m = possibleMethods(q.method(), paramTypes); 246 marinov 1.1.2.1 for (int i=0; i<m.length; i++) 247 cananian 1.1.2.17 r.add(m[i]); 248 marinov 1.1.2.1 } 249 marinov 1.1.2.6 map = null; 250 cananian 1.1.2.17 return (HMethod[]) r.toArray(new HMethod[r.size()]); 251 marinov 1.1.2.5 } 252 marinov 1.1.2.5 253 marinov 1.1.2.8 HMethod[] calls(CALL cs, boolean last) { 254 cananian 1.1.2.17 if (map==null) { map = new HashMap(); analyze(); } 255 pnkfelix 1.1.2.12 Set r = new HashSet(); 256 cananian 1.1.2.9 SetHClass[] paramTypes = new SetHClass[cs.paramsLength()]; 257 cananian 1.1.2.9 for (int i=0; i<cs.paramsLength(); i++) { 258 cananian 1.1.2.9 SetHClass s = (SetHClass)map.get(cs.params(i)); 259 cananian 1.3.2.1 //assert s!=null; 260 marinov 1.1.2.5 paramTypes[i] = s; 261 marinov 1.1.2.5 } 262 marinov 1.1.2.5 HMethod[] m; 263 cananian 1.1.2.9 if (!cs.isVirtual()) m = new HMethod[]{ cs.method() }; 264 cananian 1.1.2.9 else m = possibleMethods(cs.method(), paramTypes); 265 marinov 1.1.2.5 for (int i=0; i<m.length; i++) 266 cananian 1.1.2.17 r.add(m[i]); 267 marinov 1.1.2.8 if (last) map = null; 268 cananian 1.1.2.17 return (HMethod[]) r.toArray(new HMethod[r.size()]); 269 marinov 1.1.2.1 } 270 marinov 1.1.2.1 271 marinov 1.1.2.6 SetHClass getTempType(Temp t) { 272 cananian 1.1.2.17 if (map==null) { map = new HashMap(); analyze(); } 273 marinov 1.1.2.6 SetHClass s = (SetHClass)map.get(t); 274 marinov 1.1.2.6 map = null; 275 marinov 1.1.2.6 return s; 276 marinov 1.1.2.6 } 277 marinov 1.1.2.1 278 cananian 1.1.2.17 Map map = null; 279 marinov 1.1.2.1 class TypeInfoVisitor extends QuadVisitor { 280 marinov 1.1.2.1 boolean modified = false; 281 cananian 1.1.2.17 Map checkcast; 282 cananian 1.1.2.17 TypeInfoVisitor(Map checkcast) { this.checkcast = checkcast; } 283 marinov 1.1.2.1 284 marinov 1.1.2.1 public void visit(Quad q) { modified = false; } 285 marinov 1.1.2.1 286 marinov 1.1.2.1 public void visit(AGET q) { 287 cananian 1.1.2.9 SetHClass t = (SetHClass)map.get(q.objectref()); 288 marinov 1.1.2.1 if (t==null) { modified=false; return; } 289 cananian 1.1.2.9 modified = merge(q.dst(), t.getComponentType()); 290 marinov 1.1.2.1 return; 291 marinov 1.1.2.1 } 292 marinov 1.1.2.1 public void visit(ALENGTH q) { 293 cananian 1.1.2.9 modified = merge(q.dst(), HClass.Int); 294 marinov 1.1.2.1 } 295 marinov 1.1.2.1 public void visit(ANEW q) { 296 cananian 1.1.2.9 modified = merge(q.dst(), environment.cone(q.hclass())); 297 marinov 1.1.2.1 } 298 marinov 1.1.2.1 public void visit(ASET q) { 299 marinov 1.1.2.1 /* ??? additional precision could be gained 300 marinov 1.1.2.1 */ 301 marinov 1.1.2.1 modified = false; 302 marinov 1.1.2.1 } 303 marinov 1.1.2.1 public void visit(CALL q) { 304 marinov 1.1.2.1 boolean r = false; 305 cananian 1.1.2.9 SetHClass[] paramTypes = new SetHClass[q.paramsLength()]; 306 cananian 1.1.2.9 for (int i=0; i<q.paramsLength(); i++) { 307 cananian 1.1.2.9 SetHClass s = (SetHClass)map.get(q.params(i)); 308 marinov 1.1.2.1 if (s==null) { modified = false; return; } 309 marinov 1.1.2.2 paramTypes[i] = s; 310 marinov 1.1.2.1 } 311 marinov 1.1.2.1 HMethod[] m; 312 cananian 1.1.2.9 if (!q.isVirtual()) m = new HMethod[]{ q.method() }; 313 cananian 1.1.2.9 else m = possibleMethods(q.method(), paramTypes); 314 marinov 1.1.2.1 for (int i=0; i<m.length; i++) { 315 marinov 1.1.2.1 IntraProc p = environment.getIntra(IntraProc.this, m[i], paramTypes); 316 cananian 1.1.2.9 boolean r1 = (q.retval()==null) ? false : merge(q.retval(), p.getReturnType()); 317 cananian 1.1.2.9 boolean r2 = merge(q.retex(), p.getExceptionType()); 318 marinov 1.1.2.1 r = r || r1 || r2; 319 marinov 1.1.2.1 } 320 marinov 1.1.2.1 modified = r; 321 marinov 1.1.2.1 } 322 marinov 1.1.2.1 public void visit(COMPONENTOF q) { 323 cananian 1.1.2.9 modified = merge(q.dst(), HClass.Boolean); 324 marinov 1.1.2.1 } 325 marinov 1.1.2.1 public void visit(CONST q) { 326 cananian 1.1.2.9 modified = merge(q.dst(), q.type()); 327 marinov 1.1.2.1 } 328 marinov 1.1.2.1 public void visit(GET q) { 329 cananian 1.1.2.9 modified = merge(q.dst(), environment.getType(q.field(), IntraProc.this)); 330 marinov 1.1.2.1 } 331 marinov 1.1.2.1 public void visit(SET q) { 332 cananian 1.1.2.9 SetHClass t = (SetHClass)map.get(q.src()); 333 marinov 1.1.2.1 if (t==null) { modified = false; return; } 334 cananian 1.1.2.9 environment.mergeType(q.field(), t); 335 marinov 1.1.2.1 modified = false; 336 marinov 1.1.2.1 } 337 marinov 1.1.2.1 public void visit(INSTANCEOF q) { 338 cananian 1.1.2.9 modified = merge(q.dst(), HClass.Boolean); 339 marinov 1.1.2.1 } 340 cananian 1.1.2.10 public void visit(METHOD q) { 341 marinov 1.1.2.1 boolean r = false; 342 cananian 1.1.2.9 for (int i=0; i<q.paramsLength(); i++) 343 cananian 1.1.2.9 if (merge(q.params(i), parameterTypes[i])) 344 marinov 1.1.2.1 r = true; 345 marinov 1.1.2.1 modified = r; 346 marinov 1.1.2.1 } 347 marinov 1.1.2.1 public void visit(MOVE q) { 348 cananian 1.1.2.9 SetHClass t = (SetHClass)map.get(q.src()); 349 marinov 1.1.2.1 if (t==null) { modified = false; return; } 350 cananian 1.1.2.9 modified = move(q.dst(), t); 351 marinov 1.1.2.1 } 352 marinov 1.1.2.1 public void visit(NEW q) { 353 cananian 1.1.2.9 modified = merge(q.dst(), q.hclass()); 354 marinov 1.1.2.1 } 355 marinov 1.1.2.1 public void visit(OPER q) { 356 cananian 1.1.2.9 modified = merge(q.dst(), q.evalType()); 357 marinov 1.1.2.1 } 358 marinov 1.1.2.1 public void visit(PHI q) { 359 marinov 1.1.2.1 boolean r = false; 360 cananian 1.1.2.9 for (int i=0; i<q.numPhis(); i++) 361 cananian 1.1.2.9 for (int j=0; j<q.arity(); j++) { 362 cananian 1.1.2.9 if (q.src(i,j)==null) continue; 363 cananian 1.1.2.9 SetHClass t = (SetHClass)map.get(q.src(i,j)); 364 marinov 1.1.2.1 if (t==null) continue; 365 cananian 1.1.2.9 if (merge(q.dst(i), t)) 366 marinov 1.1.2.1 r = true; 367 marinov 1.1.2.1 } 368 marinov 1.1.2.1 modified = r; 369 marinov 1.1.2.1 } 370 marinov 1.1.2.1 public void visit(SIGMA q) { 371 marinov 1.1.2.1 boolean r = false; 372 cananian 1.1.2.9 for (int i=0; i<q.numSigmas(); i++) { 373 cananian 1.1.2.9 if (q.src(i)==null) continue; 374 cananian 1.1.2.9 SetHClass t = (SetHClass)map.get(q.src(i)); 375 marinov 1.1.2.1 if (t==null) continue; 376 cananian 1.1.2.9 for (int j=0; j<q.arity(); j++) 377 cananian 1.1.2.9 if (move(q.dst(i,j), t)) 378 marinov 1.1.2.1 r = true; 379 marinov 1.1.2.1 } 380 marinov 1.1.2.1 modified = r; 381 marinov 1.1.2.1 } 382 marinov 1.1.2.1 /* ??? additional precision could be gained 383 marinov 1.1.2.1 public void visit(CJMP q) { 384 marinov 1.1.2.1 modified = false; 385 cananian 1.1.2.18 } 386 cananian 1.1.2.18 public void visit(TYPESWITCH q) { 387 cananian 1.1.2.18 modified = false; 388 marinov 1.1.2.1 } 389 marinov 1.1.2.1 */ 390 marinov 1.1.2.1 public void visit(RETURN q) { 391 cananian 1.1.2.9 if (q.retval()!=null) { 392 cananian 1.1.2.9 SetHClass s = (SetHClass)map.get(q.retval()); 393 marinov 1.1.2.1 if (s!=null) 394 marinov 1.1.2.1 outputChanged = returnType.union(s) || outputChanged; 395 marinov 1.1.2.1 } 396 marinov 1.1.2.1 modified = false; 397 marinov 1.1.2.1 } 398 marinov 1.1.2.1 public void visit(THROW q) { 399 cananian 1.1.2.9 SetHClass s = (SetHClass)map.get(q.throwable()); 400 marinov 1.1.2.1 if (s!=null) 401 marinov 1.1.2.7 if (exceptionAnalysis) // UGLY?! otherwise, running out of memory now 402 marinov 1.1.2.7 outputChanged = exceptionType.union(s) || outputChanged; 403 marinov 1.1.2.1 modified = false; 404 marinov 1.1.2.1 } 405 marinov 1.1.2.1 } 406 marinov 1.1.2.1 407 marinov 1.1.2.7 boolean move(Temp t, SetHClass newType) { 408 marinov 1.1.2.7 SetHClass oldType = (SetHClass)map.get(t); 409 marinov 1.1.2.7 if (oldType==null) { 410 marinov 1.1.2.7 map.put(t, newType); 411 marinov 1.1.2.7 return true; 412 marinov 1.1.2.7 } 413 marinov 1.1.2.7 // if the merged value is different from the old value, update... 414 marinov 1.1.2.7 if (oldType.union(newType)) { 415 marinov 1.1.2.7 map.put(t, oldType); 416 marinov 1.1.2.7 return true; 417 marinov 1.1.2.7 } else return false; 418 marinov 1.1.2.7 } 419 marinov 1.1.2.7 420 marinov 1.1.2.1 boolean merge(Temp t, SetHClass newType) { 421 marinov 1.1.2.1 SetHClass oldType = (SetHClass)map.get(t); 422 marinov 1.1.2.1 if (oldType==null) { 423 marinov 1.1.2.1 map.put(t, newType.copy()); 424 marinov 1.1.2.1 return true; 425 marinov 1.1.2.1 } 426 marinov 1.1.2.1 // if the merged value is different from the old value, update... 427 marinov 1.1.2.1 if (oldType.union(newType)) { 428 marinov 1.1.2.1 map.put(t, oldType); 429 marinov 1.1.2.1 return true; 430 marinov 1.1.2.1 } else return false; 431 marinov 1.1.2.1 } 432 marinov 1.1.2.1 433 marinov 1.1.2.1 boolean merge(Temp t, HClass c) { return merge(t, new SetHClass(c)); } 434 marinov 1.1.2.7 435 marinov 1.1.2.7 public String toString() { 436 marinov 1.1.2.7 StringBuffer s = new StringBuffer(); 437 marinov 1.1.2.7 s.append(method.getDeclaringClass() + " " + method.getName() + " "); 438 marinov 1.1.2.7 for (int i=0; i<parameterTypes.length; i++) 439 marinov 1.1.2.7 s.append(parameterTypes[i] + " "); 440 marinov 1.1.2.7 s.append(returnType); 441 marinov 1.1.2.7 return s.toString(); 442 marinov 1.1.2.7 } 443 marinov 1.1.2.1 444 cananian 1.2 }