1 bdemsky 1.1.2.3 // Pattern.java, created Mon Aug 30 11:17:15 1999 by bdemsky 2 bdemsky 1.1.2.3 // Copyright (C) 1999 Brian Demsky <bdemsky@mit.edu> 3 bdemsky 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 bdemsky 1.1.2.1 package harpoon.IR.Quads; 5 bdemsky 1.1.2.1 import harpoon.ClassFile.HClass; 6 cananian 1.1.2.15 import harpoon.ClassFile.Linker; 7 bdemsky 1.1.2.1 import harpoon.Temp.Temp; 8 bdemsky 1.1.2.1 import harpoon.Util.Util; 9 bdemsky 1.1.2.10 import harpoon.Util.Tuple; 10 cananian 1.6 import net.cscott.jutil.WorkSet; 11 bdemsky 1.1.2.8 import harpoon.Analysis.UseDef; 12 bdemsky 1.1.2.1 13 bdemsky 1.1.2.3 import java.util.ArrayList; 14 cananian 1.1.2.19 import java.util.Collections; 15 bdemsky 1.1.2.1 import java.util.HashMap; 16 bdemsky 1.1.2.1 import java.util.Map; 17 bdemsky 1.1.2.1 import java.util.Iterator; 18 bdemsky 1.1.2.2 import java.util.Stack; 19 bdemsky 1.1.2.12 import java.util.Enumeration; 20 bdemsky 1.1.2.11 import java.util.Set; 21 bdemsky 1.1.2.1 /** 22 cananian 1.1.2.9 * <code>Pattern</code> <blink>please document me if I'm public!</blink> 23 bdemsky 1.1.2.1 * 24 bdemsky 1.1.2.1 * @author Brian Demsky <bdemsky@mit.edu> 25 cananian 1.7 * @version $Id: Pattern.java,v 1.7 2004/02/08 03:21:24 cananian Exp $ 26 bdemsky 1.1.2.1 */ 27 bdemsky 1.1.2.1 public class Pattern { 28 bdemsky 1.1.2.1 public static HClass exceptionCheck(Quad q) { 29 bdemsky 1.1.2.14 //System.out.println("==="+q); 30 bdemsky 1.1.2.1 ExcVisitor ev=new ExcVisitor(); 31 bdemsky 1.1.2.1 while (ev.status()) { 32 cananian 1.1.2.7 q.accept(ev); 33 bdemsky 1.1.2.1 if (ev.success()) 34 bdemsky 1.1.2.1 return ev.hclass(); 35 bdemsky 1.1.2.3 q=q.next(0); 36 bdemsky 1.1.2.1 } 37 bdemsky 1.1.2.14 //System.out.println("Failed on "+q); 38 bdemsky 1.1.2.1 return null; 39 bdemsky 1.1.2.1 } 40 bdemsky 1.1.2.1 41 bdemsky 1.1.2.8 public static Object[] boundCheck(Quad q, Temp array, Temp index, QuadWithTry code, UseDef ud) { 42 bdemsky 1.1.2.8 LowBoundVisitor lbv=new LowBoundVisitor(index,code, ud); 43 bdemsky 1.1.2.1 Quad lq=q; 44 bdemsky 1.1.2.1 while (lbv.status()) { 45 cananian 1.1.2.7 lq.accept(lbv); 46 bdemsky 1.1.2.1 if (lbv.success()) 47 bdemsky 1.1.2.1 break; 48 bdemsky 1.1.2.1 lq=lq.prev(0); 49 bdemsky 1.1.2.1 } 50 bdemsky 1.1.2.1 51 bdemsky 1.1.2.1 Quad hq=q; 52 bdemsky 1.1.2.1 if (lbv.success()) 53 bdemsky 1.1.2.1 hq=lq.prev(0); 54 bdemsky 1.1.2.1 55 bdemsky 1.1.2.8 HighBoundVisitor hbv=new HighBoundVisitor(index, array,code,ud); 56 bdemsky 1.1.2.1 while (hbv.status()) { 57 cananian 1.1.2.7 hq.accept(hbv); 58 bdemsky 1.1.2.1 if (hbv.success()) 59 bdemsky 1.1.2.1 break; 60 bdemsky 1.1.2.1 hq=hq.prev(0); 61 bdemsky 1.1.2.1 } 62 bdemsky 1.1.2.2 63 bdemsky 1.1.2.2 if (lbv.success()&&hbv.success()&&(lbv.exchandler()[0]==hbv.exchandler()[0])) 64 bdemsky 1.1.2.2 return new Object[] { hq, hbv.exchandler()}; 65 bdemsky 1.1.2.2 else if (lbv.success()) 66 bdemsky 1.1.2.2 return new Object[] { lq, lbv.exchandler()}; 67 bdemsky 1.1.2.2 else if (hbv.success()) 68 bdemsky 1.1.2.2 return new Object[] { hq, hbv.exchandler()}; 69 bdemsky 1.1.2.1 else 70 bdemsky 1.1.2.1 return null; 71 bdemsky 1.1.2.1 } 72 bdemsky 1.1.2.1 73 bdemsky 1.1.2.8 public static Object[] minusCheck(Quad q, Temp checked,QuadWithTry code, UseDef ud) { 74 bdemsky 1.1.2.8 MinusVisitor mv=new MinusVisitor(checked,code,ud); 75 bdemsky 1.1.2.1 while (mv.status()) { 76 cananian 1.1.2.7 q.accept(mv); 77 bdemsky 1.1.2.1 if (mv.success()) 78 bdemsky 1.1.2.1 return new Object[] {q, mv.exchandler()}; 79 bdemsky 1.1.2.1 q=q.prev(0); 80 bdemsky 1.1.2.1 } 81 bdemsky 1.1.2.1 return null; 82 bdemsky 1.1.2.1 } 83 bdemsky 1.1.2.1 84 bdemsky 1.1.2.8 public static Object[] nullCheck(Quad q, Temp checked,QuadWithTry code, UseDef ud) { 85 bdemsky 1.1.2.8 NullVisitor nv=new NullVisitor(checked,code,ud); 86 bdemsky 1.1.2.1 while (nv.status()) { 87 cananian 1.1.2.7 q.accept(nv); 88 bdemsky 1.1.2.1 if (nv.success()) 89 bdemsky 1.1.2.1 return new Object[] {q, nv.exchandler()}; 90 bdemsky 1.1.2.1 q=q.prev(0); 91 bdemsky 1.1.2.1 } 92 bdemsky 1.1.2.1 return null; 93 bdemsky 1.1.2.1 } 94 bdemsky 1.1.2.1 95 bdemsky 1.1.2.8 public static Object[] componentCheck(Quad q, Temp oref, Temp aref,QuadWithTry code, UseDef ud) { 96 bdemsky 1.1.2.8 CompVisitor cv=new CompVisitor(oref, aref,code,ud); 97 bdemsky 1.1.2.1 while (cv.status()) { 98 cananian 1.1.2.7 q.accept(cv); 99 bdemsky 1.1.2.1 if (cv.success()) 100 bdemsky 1.1.2.1 return new Object[] {q, cv.exchandler()}; 101 bdemsky 1.1.2.11 q=q.prev(cv.hint); 102 bdemsky 1.1.2.1 } 103 bdemsky 1.1.2.1 return null; 104 bdemsky 1.1.2.1 } 105 bdemsky 1.1.2.1 106 bdemsky 1.1.2.8 public static Object[] zeroCheck(Quad q, Temp checked, boolean isint,QuadWithTry code, UseDef ud) { 107 bdemsky 1.1.2.8 ZeroVisitor zv=new ZeroVisitor(checked, isint,code,ud); 108 bdemsky 1.1.2.1 while (zv.status()) { 109 cananian 1.1.2.7 q.accept(zv); 110 bdemsky 1.1.2.1 if (zv.success()) 111 bdemsky 1.1.2.1 return new Object[] {q, zv.exchandler()}; 112 bdemsky 1.1.2.1 q=q.prev(0); 113 bdemsky 1.1.2.1 } 114 bdemsky 1.1.2.1 return null; 115 bdemsky 1.1.2.1 } 116 bdemsky 1.1.2.1 117 bdemsky 1.1.2.10 public static void patternMatch(QuadWithTry code, Map typemap) { 118 bdemsky 1.1.2.1 Iterator iterate=code.getElementsI(); 119 bdemsky 1.1.2.8 PatternVisitor pv=new PatternVisitor(code); 120 bdemsky 1.1.2.3 while(iterate.hasNext()) { 121 cananian 1.1.2.7 ((Quad)iterate.next()).accept(pv); 122 bdemsky 1.1.2.3 } 123 bdemsky 1.1.2.1 Map map=pv.map(); 124 bdemsky 1.1.2.1 iterate=map.keySet().iterator(); 125 bdemsky 1.1.2.3 ArrayList handlers=new ArrayList(); 126 bdemsky 1.1.2.5 WorkSet done=new WorkSet(); 127 bdemsky 1.1.2.1 while(iterate.hasNext()) { 128 bdemsky 1.1.2.1 Quad q=(Quad)iterate.next(); 129 bdemsky 1.1.2.5 if (!done.contains(q)) { 130 bdemsky 1.1.2.5 HInfo hi=(HInfo)map.get(q); 131 bdemsky 1.1.2.5 //no pattern matching allowed on cutout regions 132 bdemsky 1.1.2.5 for (Quad ptr=q; ptr!=hi.to().prev(0); ptr=ptr.prev(0)) 133 bdemsky 1.1.2.5 done.add(ptr); 134 bdemsky 1.1.2.17 Quad ql=q; 135 bdemsky 1.1.2.17 //Don't cutout any TYPECAST quads 136 bdemsky 1.1.2.17 while (ql.prev(0).kind()==QuadKind.TYPECAST) 137 bdemsky 1.1.2.17 ql=ql.prev(0); 138 bdemsky 1.1.2.17 Quad.addEdge(hi.to().prev(0), hi.to().prevEdge(0).which_succ(), ql, 0); 139 bdemsky 1.1.2.18 if (pv.fixupCast().containsKey(q)) { 140 bdemsky 1.1.2.18 Quad tcast=(Quad)pv.fixupCast().get(q); 141 bdemsky 1.1.2.18 //gotta handle case where tcast wasn't cut out... 142 bdemsky 1.1.2.18 if (tcast!=ql.prev(0)) { 143 bdemsky 1.1.2.18 Quad.addEdge(ql.prev(0),ql.prevEdge(0).which_succ(),tcast,0); 144 bdemsky 1.1.2.18 Quad.addEdge(tcast,0,ql,0); 145 bdemsky 1.1.2.18 } 146 bdemsky 1.1.2.18 } 147 bdemsky 1.1.2.17 148 bdemsky 1.1.2.17 149 bdemsky 1.1.2.5 while (hi.needHandler()) { 150 bdemsky 1.1.2.5 Object[] handler=hi.pophandler(); 151 bdemsky 1.1.2.10 Temp Tex=new Temp(q.getFactory().tempFactory()); 152 cananian 1.1.2.19 HANDLER h=new HANDLER(q.getFactory(), q, Tex, (HClass) handler[2] , new HANDLER.HashProtectSet(Collections.singleton(q))); 153 bdemsky 1.1.2.10 typemap.put(new Tuple(new Object[]{h, Tex}), handler[2]); 154 bdemsky 1.1.2.5 handlers.add(h); 155 bdemsky 1.1.2.5 Quad.addEdge(h,0,(Quad)handler[0],((Integer)handler[1]).intValue()); 156 bdemsky 1.1.2.5 } 157 bdemsky 1.1.2.1 } 158 bdemsky 1.1.2.1 } 159 bdemsky 1.1.2.2 //need to add handlers in now 160 bdemsky 1.1.2.3 METHOD m=(METHOD)((Quad)code.getRootElement()).next(1); 161 bdemsky 1.1.2.12 for(int mc=1;mc<m.arity();mc++) 162 bdemsky 1.1.2.12 handlers.add(m.next(mc)); 163 bdemsky 1.1.2.12 164 bdemsky 1.1.2.13 Set reachable=handlerRemover(handlers,m); 165 bdemsky 1.1.2.13 166 bdemsky 1.1.2.13 //build new METHOD quad 167 bdemsky 1.1.2.13 METHOD newm=new METHOD(m.getFactory(), m, m.params(),1+handlers.size()); 168 bdemsky 1.1.2.13 //add in this node to reachable set 169 bdemsky 1.1.2.13 reachable.add(newm); 170 bdemsky 1.1.2.13 171 bdemsky 1.1.2.13 for (int i=0;i<m.paramsLength();i++) { 172 bdemsky 1.1.2.13 typemap.put(new Tuple(new Object[]{newm,m.params(i)}), 173 bdemsky 1.1.2.13 typemap.get(new Tuple(new Object[]{m,m.params(i)}))); 174 bdemsky 1.1.2.13 } 175 bdemsky 1.1.2.13 176 bdemsky 1.1.2.13 Quad.addEdge((Quad)code.getRootElement(),1,newm, 0); 177 bdemsky 1.1.2.13 for (int i=0;i<handlers.size();i++) { 178 bdemsky 1.1.2.13 Quad.addEdge(newm, i+1, (Quad)handlers.get(i), 0); 179 bdemsky 1.1.2.13 } 180 bdemsky 1.1.2.13 181 bdemsky 1.1.2.13 Quad.addEdge(newm, 0, m.next(0),m.nextEdge(0).which_pred()); 182 bdemsky 1.1.2.13 Set rset=pv.removalSet(); 183 bdemsky 1.1.2.13 iterate=rset.iterator(); 184 bdemsky 1.1.2.13 185 bdemsky 1.1.2.13 //Get rid of phi's from ASET's... 186 bdemsky 1.1.2.13 while (iterate.hasNext()) { 187 bdemsky 1.1.2.13 Object[] obj=(Object[])iterate.next(); 188 bdemsky 1.1.2.13 PHI phi=(PHI) obj[0]; 189 bdemsky 1.1.2.13 int edge=((Integer) obj[1]).intValue(); 190 bdemsky 1.1.2.13 Quad.addEdge(phi.prev(edge), phi.prevEdge(edge).which_succ(), 191 bdemsky 1.1.2.13 phi.next(0), phi.nextEdge(0).which_pred()); 192 bdemsky 1.1.2.13 //update reachable set 193 bdemsky 1.1.2.13 reachable.remove(phi); 194 bdemsky 1.1.2.13 } 195 bdemsky 1.1.2.13 196 bdemsky 1.1.2.13 // Modify this new CFG by emptying PHI nodes 197 bdemsky 1.1.2.13 // Cleaning up from removal of handlers... 198 bdemsky 1.1.2.13 // Need to make NoSSA for QuadWithTry 199 bdemsky 1.1.2.13 // Also empties out phi edges that can't be reached. 200 bdemsky 1.1.2.13 ReHandler.PHVisitor v = new ReHandler.PHVisitor(code.qf, reachable, typemap); 201 bdemsky 1.1.2.16 WorkSet oldset=new WorkSet(reachable); 202 cananian 1.7 for (Object qO : oldset) { 203 cananian 1.7 Quad q = (Quad) qO; 204 bdemsky 1.1.2.13 q.accept(v); 205 bdemsky 1.1.2.13 } 206 bdemsky 1.1.2.13 } 207 bdemsky 1.1.2.13 208 bdemsky 1.1.2.13 209 bdemsky 1.1.2.13 private static Set handlerRemover(ArrayList handlers, METHOD m) { 210 bdemsky 1.1.2.12 //remove useless HANDLERS 211 bdemsky 1.1.2.12 212 bdemsky 1.1.2.12 WorkSet reachable=new WorkSet(); 213 bdemsky 1.1.2.12 WorkSet todo=new WorkSet(); 214 bdemsky 1.1.2.12 todo.push(m.next(0)); 215 bdemsky 1.1.2.12 boolean change=true; 216 bdemsky 1.1.2.12 WorkSet handlerset=new WorkSet(); 217 bdemsky 1.1.2.12 while (change) { 218 bdemsky 1.1.2.12 while(!todo.isEmpty()) { 219 bdemsky 1.1.2.12 Quad quad=(Quad)todo.pop(); 220 bdemsky 1.1.2.12 if (!reachable.contains(quad)) { 221 bdemsky 1.1.2.12 reachable.push(quad); 222 bdemsky 1.1.2.12 for (int i=0;i<quad.next().length;i++) { 223 bdemsky 1.1.2.12 todo.push(quad.next(i)); 224 bdemsky 1.1.2.12 } 225 bdemsky 1.1.2.12 } 226 bdemsky 1.1.2.12 } 227 bdemsky 1.1.2.12 change=false; 228 cananian 1.7 for (Object hO : handlers) { 229 cananian 1.7 HANDLER h = (HANDLER) hO; 230 bdemsky 1.1.2.12 if (!reachable.contains(h)) { 231 cananian 1.5 Enumeration _enum_=h.protectedQuads(); 232 cananian 1.5 while (_enum_.hasMoreElements()) { 233 cananian 1.5 Object ne=_enum_.nextElement(); 234 bdemsky 1.1.2.12 if (reachable.contains(ne)) { 235 bdemsky 1.1.2.12 todo.push(h); 236 bdemsky 1.1.2.12 handlerset.push(h); 237 bdemsky 1.1.2.12 change=true; 238 bdemsky 1.1.2.12 break; 239 bdemsky 1.1.2.12 } 240 bdemsky 1.1.2.12 } 241 bdemsky 1.1.2.12 } 242 bdemsky 1.1.2.12 } 243 bdemsky 1.1.2.12 } 244 bdemsky 1.1.2.12 245 bdemsky 1.1.2.13 Iterator iterate=handlers.iterator(); 246 bdemsky 1.1.2.12 while(iterate.hasNext()) { 247 bdemsky 1.1.2.12 if(!reachable.contains(iterate.next())) 248 bdemsky 1.1.2.12 iterate.remove(); 249 bdemsky 1.1.2.12 } 250 bdemsky 1.1.2.13 return reachable; 251 bdemsky 1.1.2.1 } 252 bdemsky 1.1.2.1 253 cananian 1.1.2.9 static class PatternVisitor extends QuadVisitor { // this is an inner class 254 bdemsky 1.1.2.1 private Map map; 255 bdemsky 1.1.2.8 QuadWithTry code; 256 bdemsky 1.1.2.8 UseDef ud; 257 bdemsky 1.1.2.11 WorkSet phiremovalset; 258 cananian 1.1.2.15 Linker linker; 259 bdemsky 1.1.2.18 private Map typecastmap; 260 bdemsky 1.1.2.11 261 bdemsky 1.1.2.8 public PatternVisitor(QuadWithTry code) { 262 bdemsky 1.1.2.1 map=new HashMap(); 263 bdemsky 1.1.2.8 this.code=code; 264 bdemsky 1.1.2.8 this.ud=new UseDef(); 265 bdemsky 1.1.2.11 this.phiremovalset=new WorkSet(); 266 cananian 1.1.2.15 this.linker=code.qf.getLinker(); 267 bdemsky 1.1.2.18 typecastmap=new HashMap(); 268 bdemsky 1.1.2.1 } 269 bdemsky 1.1.2.1 270 bdemsky 1.1.2.18 public Map fixupCast() { 271 bdemsky 1.1.2.18 return typecastmap; 272 bdemsky 1.1.2.18 } 273 bdemsky 1.1.2.18 274 bdemsky 1.1.2.11 public Set removalSet() { 275 bdemsky 1.1.2.11 return phiremovalset; 276 bdemsky 1.1.2.11 } 277 bdemsky 1.1.2.11 278 bdemsky 1.1.2.1 public Map map() { 279 bdemsky 1.1.2.1 return map; 280 bdemsky 1.1.2.1 } 281 bdemsky 1.1.2.1 282 bdemsky 1.1.2.2 private void addmap(Quad q, Quad qd) { 283 bdemsky 1.1.2.2 if (!map.containsKey(q)) 284 bdemsky 1.1.2.2 map.put(q, new HInfo(qd)); 285 bdemsky 1.1.2.2 else { 286 bdemsky 1.1.2.2 HInfo hi=(HInfo)map.get(q); 287 bdemsky 1.1.2.2 hi.to(qd); 288 bdemsky 1.1.2.2 } 289 bdemsky 1.1.2.2 } 290 bdemsky 1.1.2.2 291 bdemsky 1.1.2.2 private void addmap(Quad q, Quad qd, Quad handler, Integer handleredge, HClass hclass) { 292 bdemsky 1.1.2.2 if (!map.containsKey(q)) 293 bdemsky 1.1.2.2 map.put(q, new HInfo(qd, handler, handleredge, hclass)); 294 bdemsky 1.1.2.2 else { 295 bdemsky 1.1.2.2 HInfo hi=(HInfo)map.get(q); 296 bdemsky 1.1.2.2 hi.to(qd); 297 bdemsky 1.1.2.2 hi.pushhandler(handler, handleredge.intValue(), hclass); 298 bdemsky 1.1.2.2 } 299 bdemsky 1.1.2.2 } 300 bdemsky 1.1.2.2 301 bdemsky 1.1.2.1 public void visit(Quad q) { 302 bdemsky 1.1.2.1 } 303 bdemsky 1.1.2.1 304 bdemsky 1.1.2.2 public void visit(AGET q) { 305 bdemsky 1.1.2.2 Quad qd=q; 306 bdemsky 1.1.2.8 Object[] n2=Pattern.boundCheck(qd.prev(0), q.objectref(), q.index(),code , ud); 307 bdemsky 1.1.2.2 if (n2!=null) { 308 bdemsky 1.1.2.2 qd=(Quad)n2[0]; 309 bdemsky 1.1.2.2 HClass hclass2=Pattern.exceptionCheck((Quad)((Object[])n2[1])[0]); 310 cananian 1.1.2.15 if (hclass2==linker.forName("java.lang.ArrayIndexOutOfBoundsException")) { 311 bdemsky 1.1.2.2 addmap(q,qd); 312 bdemsky 1.1.2.2 } else { 313 bdemsky 1.1.2.2 addmap(q, qd,(Quad)((Object[])n2[1])[0], 314 bdemsky 1.1.2.2 (Integer)((Object[])n2[1])[1], 315 cananian 1.1.2.15 linker.forName("java.lang.ArrayIndexOutOfBoundsException")); 316 bdemsky 1.1.2.2 } 317 bdemsky 1.1.2.18 if (qd.prev(0).kind()==QuadKind.TYPECAST) 318 bdemsky 1.1.2.18 typecastmap.put(q, qd.prev(0)); 319 bdemsky 1.1.2.2 } 320 bdemsky 1.1.2.2 321 bdemsky 1.1.2.18 322 bdemsky 1.1.2.18 323 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(qd.prev(0),q.objectref(), code, ud); 324 bdemsky 1.1.2.2 if (nq!=null) { 325 bdemsky 1.1.2.2 qd=(Quad)nq[0]; 326 bdemsky 1.1.2.2 HClass hclass=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 327 cananian 1.1.2.15 if (hclass==linker.forName("java.lang.NullPointerException")) { 328 bdemsky 1.1.2.2 addmap(q,qd); 329 bdemsky 1.1.2.2 } else { 330 bdemsky 1.1.2.2 addmap(q,qd, (Quad)((Object[])nq[1])[0], 331 bdemsky 1.1.2.2 (Integer)((Object[])nq[1])[1], 332 cananian 1.1.2.15 linker.forName("java.lang.NullPointerException")); 333 bdemsky 1.1.2.2 } 334 bdemsky 1.1.2.2 } 335 bdemsky 1.1.2.2 } 336 bdemsky 1.1.2.2 337 bdemsky 1.1.2.2 public void visit(ALENGTH q) { 338 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(q.prev(0), q.objectref(), code, ud); 339 bdemsky 1.1.2.2 if (nq!=null) { 340 bdemsky 1.1.2.2 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 341 cananian 1.1.2.15 if (hc==linker.forName("java.lang.NullPointerException")) 342 bdemsky 1.1.2.2 addmap(q, (Quad)nq[0]); 343 bdemsky 1.1.2.2 else 344 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.NullPointerException")); 345 bdemsky 1.1.2.2 } 346 bdemsky 1.1.2.2 } 347 bdemsky 1.1.2.2 348 bdemsky 1.1.2.11 public void visit(INSTANCEOF q) { 349 bdemsky 1.1.2.11 Object[] nq=Pattern.nullCheck(q.prev(0), q.src(), code, ud); 350 bdemsky 1.1.2.11 if (nq!=null) { 351 bdemsky 1.1.2.11 if (((Quad)((Object[]) nq[1])[0]).next(0)==q.next(0)) { 352 bdemsky 1.1.2.11 //got 353 bdemsky 1.1.2.11 if (((Quad)((Object[]) nq[1])[0]).kind()==QuadKind.CONST) 354 bdemsky 1.1.2.11 { 355 bdemsky 1.1.2.11 CONST cons=(CONST)((Object[]) nq[1])[0]; 356 bdemsky 1.1.2.11 if ((cons.dst()==q.dst())&& 357 bdemsky 1.1.2.11 (cons.type()==HClass.Int)&& 358 bdemsky 1.1.2.11 (((Integer)cons.value()).intValue()==0)&& 359 bdemsky 1.1.2.11 (((PHI)q.next(0)).arity()==2)) { 360 bdemsky 1.1.2.11 addmap(q, (Quad)nq[0]); 361 bdemsky 1.1.2.11 phiremovalset.add(new Object[] {q.next(0),new Integer(q.nextEdge(0).which_pred())}); 362 bdemsky 1.1.2.11 } 363 bdemsky 1.1.2.11 } 364 bdemsky 1.1.2.11 } 365 bdemsky 1.1.2.11 } 366 bdemsky 1.1.2.11 } 367 bdemsky 1.1.2.11 368 bdemsky 1.1.2.1 public void visit(ANEW q) { 369 bdemsky 1.1.2.2 Quad qd=q; 370 bdemsky 1.1.2.2 boolean flag=true; 371 bdemsky 1.1.2.2 HClass hclass=null; 372 bdemsky 1.1.2.2 Quad handler=null; 373 bdemsky 1.1.2.2 Integer handleredge=null; 374 bdemsky 1.1.2.2 for (int i=q.dimsLength()-1; i>=0; i--) { 375 bdemsky 1.1.2.8 Object[] nq=Pattern.minusCheck(qd.prev(0), q.dims(i),code, ud); 376 bdemsky 1.1.2.2 if (nq!=null) { 377 bdemsky 1.1.2.2 //nq[1] is the exception thrown quad... 378 bdemsky 1.1.2.6 if (i==(q.dimsLength()-1)) { 379 bdemsky 1.1.2.2 hclass=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 380 cananian 1.1.2.15 if (hclass!=linker.forName("java.lang.NegativeArraySizeException")) { 381 bdemsky 1.1.2.2 handler=(Quad)((Object[])nq[1])[0]; 382 bdemsky 1.1.2.2 handleredge=(Integer)((Object[])nq[1])[1]; 383 bdemsky 1.1.2.2 hclass=null; 384 bdemsky 1.1.2.2 } 385 bdemsky 1.1.2.2 } 386 bdemsky 1.1.2.2 else 387 bdemsky 1.1.2.2 if (hclass!=null) 388 bdemsky 1.1.2.2 flag=flag&&(hclass==Pattern.exceptionCheck((Quad)((Object[])nq[1])[0])); 389 bdemsky 1.1.2.2 else 390 bdemsky 1.1.2.2 flag=flag&&(handler==(Quad)((Object[])nq[1])[0]); 391 bdemsky 1.1.2.2 if (!flag) 392 bdemsky 1.1.2.2 //bail 393 bdemsky 1.1.2.2 break; 394 bdemsky 1.1.2.2 qd=(Quad)nq[0]; 395 bdemsky 1.1.2.2 } 396 bdemsky 1.1.2.2 } 397 cananian 1.1.2.15 if (hclass==linker.forName("java.lang.NegativeArraySizeException")) { 398 bdemsky 1.1.2.2 addmap(q, qd); 399 bdemsky 1.1.2.2 } else { 400 bdemsky 1.1.2.3 if (handler!=null) 401 cananian 1.1.2.15 addmap(q, qd, handler, handleredge, linker.forName("java.lang.NegativeArraySizeException")); 402 bdemsky 1.1.2.2 } 403 bdemsky 1.1.2.2 } 404 bdemsky 1.1.2.2 405 bdemsky 1.1.2.2 public void visit(ASET q) { 406 bdemsky 1.1.2.2 Quad qd=q; 407 bdemsky 1.1.2.8 Object[] n1=Pattern.componentCheck(qd.prev(0), q.src(), q.objectref(),code, ud); 408 bdemsky 1.1.2.5 if (n1!=null) { 409 bdemsky 1.1.2.5 qd=(Quad)n1[0]; 410 bdemsky 1.1.2.5 HClass hclass=Pattern.exceptionCheck((Quad)((Object[])n1[1])[0]); 411 cananian 1.1.2.15 if (hclass==linker.forName("java.lang.ArrayStoreException")) { 412 bdemsky 1.1.2.5 addmap(q,qd); 413 bdemsky 1.1.2.5 } else { 414 bdemsky 1.1.2.5 addmap(q,qd, (Quad)((Object[])n1[1])[0], 415 bdemsky 1.1.2.5 (Integer)((Object[])n1[1])[1], 416 cananian 1.1.2.15 linker.forName("java.lang.ArrayStoreException")); 417 bdemsky 1.1.2.5 } 418 bdemsky 1.1.2.5 } 419 bdemsky 1.1.2.11 //componentof null check... 420 bdemsky 1.1.2.11 Object[] n11=Pattern.nullCheck(qd.prev(0),q.src(),code,ud); 421 bdemsky 1.1.2.11 if (n11!=null) { 422 bdemsky 1.1.2.11 if (((Quad)((Object[])n11[1])[0])==q.prev(0)) 423 bdemsky 1.1.2.11 qd=(Quad)n11[0]; 424 bdemsky 1.1.2.11 } 425 bdemsky 1.1.2.11 426 bdemsky 1.1.2.8 Object[] n2=Pattern.boundCheck(qd.prev(0), q.objectref(), q.index(),code,ud); 427 bdemsky 1.1.2.2 if (n2!=null) { 428 bdemsky 1.1.2.2 qd=(Quad)n2[0]; 429 bdemsky 1.1.2.2 HClass hclass2=Pattern.exceptionCheck((Quad)((Object[])n2[1])[0]); 430 cananian 1.1.2.15 if (hclass2==linker.forName("java.lang.ArrayIndexOutOfBoundsException")) { 431 bdemsky 1.1.2.2 addmap(q,qd); 432 bdemsky 1.1.2.2 } else { 433 bdemsky 1.1.2.2 addmap(q, qd,(Quad)((Object[])n2[1])[0], 434 bdemsky 1.1.2.2 (Integer)((Object[])n2[1])[1], 435 cananian 1.1.2.15 linker.forName("java.lang.ArrayIndexOutOfBoundsException")); 436 bdemsky 1.1.2.2 } 437 bdemsky 1.1.2.18 if (qd.prev(0).kind()==QuadKind.TYPECAST) 438 bdemsky 1.1.2.18 typecastmap.put(q, qd.prev(0)); 439 bdemsky 1.1.2.2 } 440 bdemsky 1.1.2.2 441 bdemsky 1.1.2.18 442 bdemsky 1.1.2.18 443 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(qd.prev(0),q.objectref(),code,ud); 444 bdemsky 1.1.2.2 if (nq!=null) { 445 bdemsky 1.1.2.2 qd=(Quad)nq[0]; 446 bdemsky 1.1.2.2 HClass hclass=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 447 cananian 1.1.2.15 if (hclass==linker.forName("java.lang.NullPointerException")) { 448 bdemsky 1.1.2.2 addmap(q,qd); 449 bdemsky 1.1.2.2 } else { 450 bdemsky 1.1.2.2 addmap(q,qd, (Quad)((Object[])nq[1])[0], 451 bdemsky 1.1.2.2 (Integer)((Object[])nq[1])[1], 452 cananian 1.1.2.15 linker.forName("java.lang.NullPointerException")); 453 bdemsky 1.1.2.2 } 454 bdemsky 1.1.2.2 } 455 bdemsky 1.1.2.2 } 456 bdemsky 1.1.2.2 457 bdemsky 1.1.2.2 public void visit(CALL q) { 458 bdemsky 1.1.2.2 if (!q.isStatic()) { 459 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(q.prev(0), q.params(0),code,ud); 460 bdemsky 1.1.2.2 if (nq!=null) { 461 bdemsky 1.1.2.2 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 462 cananian 1.1.2.15 if (hc==linker.forName("java.lang.NullPointerException")) 463 bdemsky 1.1.2.2 addmap(q, (Quad)nq[0]); 464 bdemsky 1.1.2.2 else 465 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.NullPointerException")); 466 bdemsky 1.1.2.2 } 467 bdemsky 1.1.2.2 } 468 bdemsky 1.1.2.2 } 469 bdemsky 1.1.2.2 470 bdemsky 1.1.2.2 public void visit(GET q) { 471 bdemsky 1.1.2.3 if (!q.isStatic()) { 472 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(q.prev(0), q.objectref(),code,ud); 473 bdemsky 1.1.2.3 if (nq!=null) { 474 bdemsky 1.1.2.3 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 475 cananian 1.1.2.15 if (hc==linker.forName("java.lang.NullPointerException")) 476 bdemsky 1.1.2.3 addmap(q, (Quad)nq[0]); 477 bdemsky 1.1.2.3 else 478 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.NullPointerException")); 479 bdemsky 1.1.2.3 } 480 bdemsky 1.1.2.3 } 481 bdemsky 1.1.2.2 } 482 bdemsky 1.1.2.2 483 bdemsky 1.1.2.2 public void visit(MONITORENTER q) { 484 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(q.prev(0), q.lock(),code,ud); 485 bdemsky 1.1.2.2 if (nq!=null) { 486 bdemsky 1.1.2.2 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 487 cananian 1.1.2.15 if (hc==linker.forName("java.lang.NullPointerException")) 488 bdemsky 1.1.2.2 addmap(q, (Quad)nq[0]); 489 bdemsky 1.1.2.2 else 490 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.NullPointerException")); 491 bdemsky 1.1.2.2 } 492 bdemsky 1.1.2.2 } 493 bdemsky 1.1.2.2 494 bdemsky 1.1.2.2 public void visit(MONITOREXIT q) { 495 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(q.prev(0), q.lock(),code,ud); 496 bdemsky 1.1.2.2 if (nq!=null) { 497 bdemsky 1.1.2.2 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 498 cananian 1.1.2.15 if (hc==linker.forName("java.lang.NullPointerException")) 499 bdemsky 1.1.2.2 addmap(q, (Quad)nq[0]); 500 bdemsky 1.1.2.2 else 501 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.NullPointerException")); 502 bdemsky 1.1.2.2 } 503 bdemsky 1.1.2.1 } 504 bdemsky 1.1.2.1 505 bdemsky 1.1.2.1 public void visit(OPER q) { 506 bdemsky 1.1.2.1 switch (q.opcode()) { 507 bdemsky 1.1.2.1 case Qop.IDIV: 508 bdemsky 1.1.2.1 case Qop.IREM: 509 bdemsky 1.1.2.8 Object[] nq=Pattern.zeroCheck(q.prev(0), q.operands(1),true,code,ud); 510 bdemsky 1.1.2.2 if (nq!=null) { 511 bdemsky 1.1.2.2 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 512 cananian 1.1.2.15 if (hc==linker.forName("java.lang.ArithmeticException")) 513 bdemsky 1.1.2.2 addmap(q, (Quad)nq[0]); 514 bdemsky 1.1.2.2 else 515 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.ArithmeticException")); 516 bdemsky 1.1.2.2 } 517 bdemsky 1.1.2.2 break; 518 bdemsky 1.1.2.2 case Qop.LDIV: 519 bdemsky 1.1.2.2 case Qop.LREM: 520 bdemsky 1.1.2.8 nq=Pattern.zeroCheck(q.prev(0), q.operands(1),false,code,ud); 521 bdemsky 1.1.2.2 if (nq!=null) { 522 bdemsky 1.1.2.2 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 523 cananian 1.1.2.15 if (hc==linker.forName("java.lang.ArithmeticException")) 524 bdemsky 1.1.2.2 addmap(q, (Quad)nq[0]); 525 bdemsky 1.1.2.2 else 526 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.ArithmeticException")); 527 bdemsky 1.1.2.2 } 528 bdemsky 1.1.2.2 break; 529 bdemsky 1.1.2.1 default: 530 bdemsky 1.1.2.1 } 531 bdemsky 1.1.2.1 } 532 bdemsky 1.1.2.2 533 bdemsky 1.1.2.2 public void visit(SET q) { 534 bdemsky 1.1.2.3 if (!q.isStatic()) { 535 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(q.prev(0), q.objectref(),code,ud); 536 bdemsky 1.1.2.3 if (nq!=null) { 537 bdemsky 1.1.2.3 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 538 cananian 1.1.2.15 if (hc==linker.forName("java.lang.NullPointerException")) 539 bdemsky 1.1.2.3 addmap(q, (Quad)nq[0]); 540 bdemsky 1.1.2.3 else 541 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.NullPointerException")); 542 bdemsky 1.1.2.3 } 543 bdemsky 1.1.2.3 } 544 bdemsky 1.1.2.2 } 545 bdemsky 1.1.2.2 546 bdemsky 1.1.2.2 public void visit(THROW q) { 547 bdemsky 1.1.2.8 Object[] nq=Pattern.nullCheck(q.prev(0), q.throwable(),code,ud); 548 bdemsky 1.1.2.3 if (nq!=null) { 549 bdemsky 1.1.2.3 HClass hc=Pattern.exceptionCheck((Quad)((Object[])nq[1])[0]); 550 cananian 1.1.2.15 if (hc==linker.forName("java.lang.NullPointerException")) 551 bdemsky 1.1.2.3 addmap(q, (Quad)nq[0]); 552 bdemsky 1.1.2.3 else 553 cananian 1.1.2.15 addmap(q, (Quad) nq[0], (Quad)((Object[])nq[1])[0], (Integer)((Object[])nq[1])[1], linker.forName("java.lang.NullPointerException")); 554 bdemsky 1.1.2.3 } 555 bdemsky 1.1.2.2 } 556 bdemsky 1.1.2.1 } 557 bdemsky 1.1.2.1 558 cananian 1.1.2.9 static class HInfo { // this is an inner class 559 bdemsky 1.1.2.1 Quad to; 560 bdemsky 1.1.2.2 Stack handlers; 561 bdemsky 1.1.2.2 //entries look like 562 bdemsky 1.1.2.2 //new Object[] {handler, edge, hclass} 563 bdemsky 1.1.2.2 564 bdemsky 1.1.2.1 HInfo(Quad to) { 565 bdemsky 1.1.2.1 this.to=to; 566 bdemsky 1.1.2.2 this.handlers=new Stack(); 567 bdemsky 1.1.2.1 } 568 bdemsky 1.1.2.1 HInfo(Quad to, Quad handler, Integer edge, HClass hclass) { 569 bdemsky 1.1.2.1 this.to=to; 570 bdemsky 1.1.2.2 this.handlers=new Stack(); 571 bdemsky 1.1.2.2 handlers.push(new Object[] {handler, edge, hclass}); 572 bdemsky 1.1.2.1 } 573 bdemsky 1.1.2.1 HInfo(Quad to, Quad handler, int edge, HClass hclass) { 574 bdemsky 1.1.2.1 this.to=to; 575 bdemsky 1.1.2.2 this.handlers=new Stack(); 576 bdemsky 1.1.2.2 handlers.push(new Object[] {handler, new Integer(edge), hclass}); 577 bdemsky 1.1.2.1 } 578 bdemsky 1.1.2.2 579 bdemsky 1.1.2.1 boolean needHandler() { 580 bdemsky 1.1.2.2 return (!handlers.empty()); 581 bdemsky 1.1.2.2 } 582 bdemsky 1.1.2.2 583 bdemsky 1.1.2.2 void to(Quad to) { 584 bdemsky 1.1.2.2 this.to=to; 585 bdemsky 1.1.2.1 } 586 bdemsky 1.1.2.2 587 bdemsky 1.1.2.1 Quad to() { 588 bdemsky 1.1.2.1 return to; 589 bdemsky 1.1.2.1 } 590 bdemsky 1.1.2.1 591 bdemsky 1.1.2.2 Object[] pophandler() { 592 bdemsky 1.1.2.2 return ((Object [])handlers.pop()); 593 bdemsky 1.1.2.1 } 594 bdemsky 1.1.2.2 595 bdemsky 1.1.2.2 void pushhandler(Quad handler, int edge, HClass hclass) { 596 bdemsky 1.1.2.2 handlers.push(new Object[] {handler, new Integer(edge), hclass}); 597 bdemsky 1.1.2.1 } 598 bdemsky 1.1.2.1 } 599 bdemsky 1.1.2.1 600 cananian 1.1.2.9 static class ExcVisitor extends QuadVisitor { // this is an inner class 601 bdemsky 1.1.2.1 int status; 602 bdemsky 1.1.2.1 HClass hclass; 603 bdemsky 1.1.2.1 Temp exctemp; 604 bdemsky 1.1.2.1 605 bdemsky 1.1.2.1 public ExcVisitor() { 606 bdemsky 1.1.2.1 status=0; 607 bdemsky 1.1.2.1 } 608 bdemsky 1.1.2.1 609 bdemsky 1.1.2.1 public HClass hclass() { 610 bdemsky 1.1.2.1 if (this.success()) 611 bdemsky 1.1.2.1 return hclass; 612 bdemsky 1.1.2.1 else 613 bdemsky 1.1.2.1 return null; 614 bdemsky 1.1.2.1 } 615 bdemsky 1.1.2.1 616 bdemsky 1.1.2.1 public boolean status() { 617 bdemsky 1.1.2.1 return (status!=-1); 618 bdemsky 1.1.2.1 } 619 bdemsky 1.1.2.1 620 bdemsky 1.1.2.1 public boolean success() { 621 bdemsky 1.1.2.1 return (status==3); 622 bdemsky 1.1.2.1 } 623 bdemsky 1.1.2.1 624 bdemsky 1.1.2.1 public void visit(Quad q) { 625 bdemsky 1.1.2.1 status=-1; 626 bdemsky 1.1.2.1 } 627 bdemsky 1.1.2.1 628 bdemsky 1.1.2.1 public void visit(NEW q) { 629 bdemsky 1.1.2.1 if (status==0) { 630 bdemsky 1.1.2.1 hclass=q.hclass(); 631 bdemsky 1.1.2.1 exctemp=q.dst(); 632 bdemsky 1.1.2.1 status=1; 633 bdemsky 1.1.2.1 } 634 bdemsky 1.1.2.1 else 635 bdemsky 1.1.2.1 status=-1; 636 bdemsky 1.1.2.1 } 637 bdemsky 1.1.2.1 638 bdemsky 1.1.2.1 public void visit(CALL q) { 639 bdemsky 1.1.2.1 if (status==1) { 640 bdemsky 1.1.2.1 if ((q.method()==hclass.getConstructor(new HClass[0]))&& 641 bdemsky 1.1.2.1 (q.params(0)==exctemp)&& 642 bdemsky 1.1.2.1 (q.paramsLength()==1)) { 643 bdemsky 1.1.2.1 status=2; 644 bdemsky 1.1.2.1 } else 645 bdemsky 1.1.2.1 status=-1; 646 bdemsky 1.1.2.1 } 647 bdemsky 1.1.2.1 else 648 bdemsky 1.1.2.1 status=-1; 649 bdemsky 1.1.2.1 } 650 bdemsky 1.1.2.1 651 bdemsky 1.1.2.1 public void visit(THROW q) { 652 bdemsky 1.1.2.1 if (status==2) { 653 bdemsky 1.1.2.1 if (q.throwable()==exctemp) 654 bdemsky 1.1.2.1 status=3; 655 bdemsky 1.1.2.1 else 656 bdemsky 1.1.2.1 status=-1; 657 bdemsky 1.1.2.1 } else 658 bdemsky 1.1.2.1 status=-1; 659 bdemsky 1.1.2.1 } 660 bdemsky 1.1.2.1 661 bdemsky 1.1.2.17 public void visit(TYPECAST q) { 662 bdemsky 1.1.2.18 //safe to ignore. 663 bdemsky 1.1.2.17 } 664 bdemsky 1.1.2.17 665 bdemsky 1.1.2.1 public void visit(PHI q) { 666 bdemsky 1.1.2.1 //safe to ignore 667 bdemsky 1.1.2.1 } 668 bdemsky 1.1.2.1 669 bdemsky 1.1.2.1 public void visit(MOVE q) { 670 bdemsky 1.1.2.14 //System.out.println("Match failed because of: "+q.toString()); 671 bdemsky 1.1.2.1 status=-1; 672 bdemsky 1.1.2.1 } 673 bdemsky 1.1.2.1 } 674 bdemsky 1.1.2.1 675 cananian 1.1.2.9 static class HighBoundVisitor extends QuadVisitor { // this is an inner class 676 bdemsky 1.1.2.1 int status; 677 bdemsky 1.1.2.1 Temp []compares; 678 bdemsky 1.1.2.1 Temp test; 679 bdemsky 1.1.2.1 Quad exchandler; 680 bdemsky 1.1.2.1 int excedge; 681 bdemsky 1.1.2.1 Temp tested; 682 bdemsky 1.1.2.1 Temp array; 683 bdemsky 1.1.2.8 QuadWithTry code; 684 bdemsky 1.1.2.8 UseDef ud; 685 bdemsky 1.1.2.1 686 bdemsky 1.1.2.8 HighBoundVisitor(Temp tested, Temp array,QuadWithTry code, UseDef ud) { 687 bdemsky 1.1.2.1 this.status=0; 688 bdemsky 1.1.2.1 this.tested=tested; 689 bdemsky 1.1.2.1 this.array=array; 690 bdemsky 1.1.2.8 this.code=code; 691 bdemsky 1.1.2.8 this.ud=ud; 692 bdemsky 1.1.2.1 } 693 bdemsky 1.1.2.1 694 bdemsky 1.1.2.1 Object[] exchandler() { 695 bdemsky 1.1.2.1 if (this.success()) 696 bdemsky 1.1.2.1 return new Object[] {exchandler, new Integer(excedge) }; 697 bdemsky 1.1.2.1 else 698 bdemsky 1.1.2.1 return null; 699 bdemsky 1.1.2.1 } 700 bdemsky 1.1.2.1 701 bdemsky 1.1.2.1 public boolean status() { 702 bdemsky 1.1.2.1 return (status!=-1); 703 bdemsky 1.1.2.1 } 704 bdemsky 1.1.2.1 705 bdemsky 1.1.2.1 public boolean success() { 706 bdemsky 1.1.2.1 return (status==3); 707 bdemsky 1.1.2.1 } 708 bdemsky 1.1.2.1 709 bdemsky 1.1.2.1 public void visit(Quad q) { 710 bdemsky 1.1.2.1 status=-1; 711 bdemsky 1.1.2.1 } 712 bdemsky 1.1.2.1 713 bdemsky 1.1.2.1 public void visit(CONST q) { 714 bdemsky 1.1.2.1 //have to make sure that 715 bdemsky 1.1.2.1 //value of constant==alength(array) 716 bdemsky 1.1.2.1 //Punt this! 717 bdemsky 1.1.2.1 status=-1; 718 bdemsky 1.1.2.1 // if ((status==2)&&(q.type()==HClass.Int)) { 719 cananian 1.3.2.1 // assert compares.length==2; 720 bdemsky 1.1.2.1 // if ((q.value()==null)&& 721 bdemsky 1.1.2.1 // (compares[0]==q.dst())&&(compares[1]==tested)) 722 bdemsky 1.1.2.1 // status=3; 723 bdemsky 1.1.2.1 // else 724 bdemsky 1.1.2.1 // status=-1; 725 bdemsky 1.1.2.1 //} else 726 bdemsky 1.1.2.1 // status=-1; 727 bdemsky 1.1.2.1 } 728 bdemsky 1.1.2.1 729 bdemsky 1.1.2.1 public void visit(ALENGTH q) { 730 bdemsky 1.1.2.1 if ((status==2)&& 731 bdemsky 1.1.2.1 (array==q.objectref())) { 732 cananian 1.3.2.1 assert compares.length==2; 733 bdemsky 1.1.2.1 if ((compares[0]==q.dst())&&(compares[1]==tested)) 734 bdemsky 1.1.2.1 status=3; 735 bdemsky 1.1.2.1 else 736 bdemsky 1.1.2.1 status=-1; 737 bdemsky 1.1.2.1 } else 738 bdemsky 1.1.2.1 status=-1; 739 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 740 bdemsky 1.1.2.8 status=-1; 741 bdemsky 1.1.2.1 } 742 bdemsky 1.1.2.1 743 bdemsky 1.1.2.1 public void visit(OPER q) { 744 bdemsky 1.1.2.1 if ((status==1)&& 745 bdemsky 1.1.2.1 (q.opcode()==Qop.ICMPGT) 746 bdemsky 1.1.2.1 &&(test==q.dst())) { 747 bdemsky 1.1.2.1 compares=q.use(); 748 bdemsky 1.1.2.1 status=2; 749 bdemsky 1.1.2.1 } 750 bdemsky 1.1.2.1 else 751 bdemsky 1.1.2.1 status=-1; 752 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 753 bdemsky 1.1.2.8 status=-1; 754 bdemsky 1.1.2.1 } 755 bdemsky 1.1.2.1 756 bdemsky 1.1.2.17 public void visit(TYPECAST q) { 757 bdemsky 1.1.2.17 //safe to ignore 758 bdemsky 1.1.2.17 } 759 bdemsky 1.1.2.17 760 bdemsky 1.1.2.1 public void visit(CJMP q) { 761 bdemsky 1.1.2.1 if (status==0) { 762 bdemsky 1.1.2.1 test=q.test(); 763 bdemsky 1.1.2.5 //on this pattern 764 bdemsky 1.1.2.5 //the exception actually occurs on the 0 edge 765 bdemsky 1.1.2.5 exchandler=q.next(0); 766 bdemsky 1.1.2.5 excedge=q.nextEdge(0).which_pred(); 767 bdemsky 1.1.2.1 status=1; 768 bdemsky 1.1.2.1 } 769 bdemsky 1.1.2.1 else 770 bdemsky 1.1.2.1 status=-1; 771 bdemsky 1.1.2.1 } 772 bdemsky 1.1.2.1 } 773 bdemsky 1.1.2.1 774 cananian 1.1.2.9 static class LowBoundVisitor extends MinusVisitor { // this is an inner class 775 bdemsky 1.1.2.8 LowBoundVisitor(Temp tested,QuadWithTry code, UseDef ud) { 776 bdemsky 1.1.2.8 super(tested,code,ud); 777 bdemsky 1.1.2.1 } 778 bdemsky 1.1.2.1 } 779 bdemsky 1.1.2.1 780 cananian 1.1.2.9 static class MinusVisitor extends QuadVisitor { // this is an inner class 781 bdemsky 1.1.2.1 int status; 782 bdemsky 1.1.2.1 Temp []compares; 783 bdemsky 1.1.2.1 Temp test; 784 bdemsky 1.1.2.1 Quad exchandler; 785 bdemsky 1.1.2.1 int excedge; 786 bdemsky 1.1.2.1 Temp tested; 787 bdemsky 1.1.2.8 QuadWithTry code; 788 bdemsky 1.1.2.8 UseDef ud; 789 bdemsky 1.1.2.1 790 bdemsky 1.1.2.8 MinusVisitor(Temp tested,QuadWithTry code, UseDef ud) { 791 bdemsky 1.1.2.1 this.status=0; 792 bdemsky 1.1.2.1 this.tested=tested; 793 bdemsky 1.1.2.8 this.code=code; 794 bdemsky 1.1.2.8 this.ud=ud; 795 bdemsky 1.1.2.1 } 796 bdemsky 1.1.2.1 797 bdemsky 1.1.2.1 public boolean status() { 798 bdemsky 1.1.2.1 return (status!=-1); 799 bdemsky 1.1.2.1 } 800 bdemsky 1.1.2.1 801 bdemsky 1.1.2.1 public boolean success() { 802 bdemsky 1.1.2.1 return (status==3); 803 bdemsky 1.1.2.1 } 804 bdemsky 1.1.2.1 805 bdemsky 1.1.2.1 public void visit(Quad q) { 806 bdemsky 1.1.2.1 status=-1; 807 bdemsky 1.1.2.1 } 808 bdemsky 1.1.2.1 809 bdemsky 1.1.2.1 Object[] exchandler() { 810 bdemsky 1.1.2.1 if (this.success()) 811 bdemsky 1.1.2.1 return new Object[] {exchandler, new Integer(excedge)}; 812 bdemsky 1.1.2.1 else 813 bdemsky 1.1.2.1 return null; 814 bdemsky 1.1.2.1 } 815 bdemsky 1.1.2.1 816 bdemsky 1.1.2.1 public void visit(CONST q) { 817 bdemsky 1.1.2.1 if ((status==2)&& 818 bdemsky 1.1.2.4 (q.type()==HClass.Int)) { 819 cananian 1.3.2.1 assert compares.length==2; 820 bdemsky 1.1.2.4 if ((((Integer)q.value()).intValue()==0)&& 821 bdemsky 1.1.2.1 (compares[0]==q.dst())&&(compares[1]==tested)) 822 bdemsky 1.1.2.1 status=3; 823 bdemsky 1.1.2.1 else 824 bdemsky 1.1.2.1 status=-1; 825 bdemsky 1.1.2.1 } else 826 bdemsky 1.1.2.1 status=-1; 827 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 828 bdemsky 1.1.2.8 status=-1; 829 bdemsky 1.1.2.1 } 830 bdemsky 1.1.2.1 831 bdemsky 1.1.2.17 public void visit(TYPECAST q) { 832 bdemsky 1.1.2.17 //safe to ignore 833 bdemsky 1.1.2.17 } 834 bdemsky 1.1.2.17 835 bdemsky 1.1.2.1 public void visit(OPER q) { 836 bdemsky 1.1.2.1 if ((status==1)&& 837 bdemsky 1.1.2.1 (q.opcode()==Qop.ICMPGT) 838 bdemsky 1.1.2.1 &&(test==q.dst())) { 839 bdemsky 1.1.2.1 compares=q.use(); 840 bdemsky 1.1.2.1 status=2; 841 bdemsky 1.1.2.1 } 842 bdemsky 1.1.2.1 else 843 bdemsky 1.1.2.1 status=-1; 844 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 845 bdemsky 1.1.2.8 status=-1; 846 bdemsky 1.1.2.1 } 847 bdemsky 1.1.2.1 848 bdemsky 1.1.2.1 public void visit(CJMP q) { 849 bdemsky 1.1.2.1 if (status==0) { 850 bdemsky 1.1.2.1 test=q.test(); 851 bdemsky 1.1.2.1 exchandler=q.next(1); 852 bdemsky 1.1.2.1 excedge=q.nextEdge(1).which_pred(); 853 bdemsky 1.1.2.1 status=1; 854 bdemsky 1.1.2.1 } 855 bdemsky 1.1.2.1 else 856 bdemsky 1.1.2.1 status=-1; 857 bdemsky 1.1.2.1 } 858 bdemsky 1.1.2.1 } 859 bdemsky 1.1.2.1 860 cananian 1.1.2.9 static class NullVisitor extends QuadVisitor { // this is an inner class 861 bdemsky 1.1.2.1 int status; 862 bdemsky 1.1.2.1 Temp []compares; 863 bdemsky 1.1.2.1 Temp test; 864 bdemsky 1.1.2.1 Quad exchandler; 865 bdemsky 1.1.2.1 int excedge; 866 bdemsky 1.1.2.1 Temp tested; 867 bdemsky 1.1.2.8 QuadWithTry code; 868 bdemsky 1.1.2.8 UseDef ud; 869 bdemsky 1.1.2.1 870 bdemsky 1.1.2.8 NullVisitor(Temp tested,QuadWithTry code, UseDef ud) { 871 bdemsky 1.1.2.1 this.status=0; 872 bdemsky 1.1.2.1 this.tested=tested; 873 bdemsky 1.1.2.8 this.code=code; 874 bdemsky 1.1.2.8 this.ud=ud; 875 bdemsky 1.1.2.1 } 876 bdemsky 1.1.2.1 877 bdemsky 1.1.2.1 public boolean status() { 878 bdemsky 1.1.2.1 return (status!=-1); 879 bdemsky 1.1.2.1 } 880 bdemsky 1.1.2.1 881 bdemsky 1.1.2.1 public boolean success() { 882 bdemsky 1.1.2.1 return (status==3); 883 bdemsky 1.1.2.1 } 884 bdemsky 1.1.2.1 885 bdemsky 1.1.2.1 public void visit(Quad q) { 886 bdemsky 1.1.2.1 status=-1; 887 bdemsky 1.1.2.1 } 888 bdemsky 1.1.2.1 889 bdemsky 1.1.2.1 Object[] exchandler() { 890 bdemsky 1.1.2.1 if (this.success()) 891 bdemsky 1.1.2.1 return new Object[] {exchandler, new Integer(excedge)}; 892 bdemsky 1.1.2.1 else 893 bdemsky 1.1.2.1 return null; 894 bdemsky 1.1.2.1 } 895 bdemsky 1.1.2.1 896 bdemsky 1.1.2.1 public void visit(CONST q) { 897 bdemsky 1.1.2.1 if ((status==2)&& 898 bdemsky 1.1.2.1 (q.type()==HClass.Void)) { 899 cananian 1.3.2.1 assert compares.length==2; 900 bdemsky 1.1.2.1 if ((q.value()==null)&& 901 bdemsky 1.1.2.1 (((compares[0]==q.dst())&&(compares[1]==tested))|| 902 bdemsky 1.1.2.1 ((compares[1]==q.dst())&&(compares[0]==tested)))) 903 bdemsky 1.1.2.1 status=3; 904 bdemsky 1.1.2.1 else 905 bdemsky 1.1.2.1 status=-1; 906 bdemsky 1.1.2.1 } else 907 bdemsky 1.1.2.1 status=-1; 908 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 909 bdemsky 1.1.2.8 status=-1; 910 bdemsky 1.1.2.1 } 911 bdemsky 1.1.2.1 912 bdemsky 1.1.2.1 public void visit(OPER q) { 913 bdemsky 1.1.2.1 if ((status==1)&& 914 bdemsky 1.1.2.1 (q.opcode()==Qop.ACMPEQ) 915 bdemsky 1.1.2.1 &&(test==q.dst())) { 916 bdemsky 1.1.2.1 compares=q.use(); 917 bdemsky 1.1.2.1 status=2; 918 bdemsky 1.1.2.1 } 919 bdemsky 1.1.2.1 else 920 bdemsky 1.1.2.1 status=-1; 921 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 922 bdemsky 1.1.2.8 status=-1; 923 bdemsky 1.1.2.1 } 924 bdemsky 1.1.2.1 925 bdemsky 1.1.2.17 public void visit(TYPECAST q) { 926 bdemsky 1.1.2.17 //safe to ignore 927 bdemsky 1.1.2.17 } 928 bdemsky 1.1.2.17 929 bdemsky 1.1.2.1 public void visit(CJMP q) { 930 bdemsky 1.1.2.1 if (status==0) { 931 bdemsky 1.1.2.1 test=q.test(); 932 bdemsky 1.1.2.1 exchandler=q.next(1); 933 bdemsky 1.1.2.1 excedge=q.nextEdge(1).which_pred(); 934 bdemsky 1.1.2.1 status=1; 935 bdemsky 1.1.2.1 } 936 bdemsky 1.1.2.1 else 937 bdemsky 1.1.2.1 status=-1; 938 bdemsky 1.1.2.1 } 939 bdemsky 1.1.2.1 } 940 bdemsky 1.1.2.1 941 cananian 1.1.2.9 static class CompVisitor extends QuadVisitor { // this is an inner class 942 bdemsky 1.1.2.1 int status; 943 bdemsky 1.1.2.1 Temp test; 944 bdemsky 1.1.2.1 Quad exchandler; 945 bdemsky 1.1.2.1 int excedge; 946 bdemsky 1.1.2.1 Temp oref; 947 bdemsky 1.1.2.1 Temp aref; 948 bdemsky 1.1.2.8 QuadWithTry code; 949 bdemsky 1.1.2.8 UseDef ud; 950 bdemsky 1.1.2.11 int hint; 951 bdemsky 1.1.2.1 952 bdemsky 1.1.2.8 CompVisitor(Temp objectref, Temp arrayref,QuadWithTry code, UseDef ud) { 953 bdemsky 1.1.2.1 this.oref=objectref; 954 bdemsky 1.1.2.1 this.aref=arrayref; 955 bdemsky 1.1.2.1 this.status=0; 956 bdemsky 1.1.2.8 this.code=code; 957 bdemsky 1.1.2.8 this.ud=ud; 958 bdemsky 1.1.2.11 this.hint=0; 959 bdemsky 1.1.2.1 } 960 bdemsky 1.1.2.1 public boolean status() { 961 bdemsky 1.1.2.1 return (status!=-1); 962 bdemsky 1.1.2.1 } 963 bdemsky 1.1.2.1 964 bdemsky 1.1.2.1 public boolean success() { 965 bdemsky 1.1.2.11 return (status==3); 966 bdemsky 1.1.2.1 } 967 bdemsky 1.1.2.1 968 bdemsky 1.1.2.1 Object[] exchandler() { 969 bdemsky 1.1.2.1 if (this.success()) 970 bdemsky 1.1.2.1 return new Object[] { exchandler, new Integer(excedge)}; 971 bdemsky 1.1.2.1 else 972 bdemsky 1.1.2.1 return null; 973 bdemsky 1.1.2.1 } 974 bdemsky 1.1.2.1 public void visit(Quad q) { 975 bdemsky 1.1.2.1 status=-1; 976 bdemsky 1.1.2.1 } 977 bdemsky 1.1.2.1 978 bdemsky 1.1.2.1 public void visit(COMPONENTOF q) { 979 bdemsky 1.1.2.11 if ((status==2)&& 980 bdemsky 1.1.2.1 (q.dst()==test)&& 981 bdemsky 1.1.2.1 (q.arrayref()==aref)&& 982 bdemsky 1.1.2.1 (q.objectref()==oref)) 983 bdemsky 1.1.2.11 status=3; 984 bdemsky 1.1.2.1 else 985 bdemsky 1.1.2.1 status=-1; 986 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 987 bdemsky 1.1.2.8 status=-1; 988 bdemsky 1.1.2.1 } 989 bdemsky 1.1.2.1 990 bdemsky 1.1.2.11 public void visit(PHI q) { 991 bdemsky 1.1.2.1 if (status==0) { 992 bdemsky 1.1.2.11 status=1; 993 bdemsky 1.1.2.11 hint=1; 994 bdemsky 1.1.2.11 } 995 bdemsky 1.1.2.11 else 996 bdemsky 1.1.2.11 status=-1; 997 bdemsky 1.1.2.11 } 998 bdemsky 1.1.2.11 999 bdemsky 1.1.2.17 public void visit(TYPECAST q) { 1000 bdemsky 1.1.2.17 //safe to ignore 1001 bdemsky 1.1.2.17 } 1002 bdemsky 1.1.2.17 1003 bdemsky 1.1.2.11 public void visit(CJMP q) { 1004 bdemsky 1.1.2.11 if ((status==1)||(status==0)) { 1005 bdemsky 1.1.2.1 test=q.test(); 1006 bdemsky 1.1.2.5 exchandler=q.next(0); 1007 bdemsky 1.1.2.5 excedge=q.nextEdge(0).which_pred(); 1008 bdemsky 1.1.2.11 status=2; 1009 bdemsky 1.1.2.11 hint=0; 1010 bdemsky 1.1.2.1 } 1011 bdemsky 1.1.2.1 else 1012 bdemsky 1.1.2.1 status=-1; 1013 bdemsky 1.1.2.1 } 1014 bdemsky 1.1.2.1 } 1015 bdemsky 1.1.2.1 1016 cananian 1.1.2.9 static class ZeroVisitor extends QuadVisitor { // this is an inner class 1017 bdemsky 1.1.2.1 int status; 1018 bdemsky 1.1.2.1 Temp []compares; 1019 bdemsky 1.1.2.1 Temp test; 1020 bdemsky 1.1.2.1 Quad exchandler; 1021 bdemsky 1.1.2.1 int excedge; 1022 bdemsky 1.1.2.1 Temp tested; 1023 bdemsky 1.1.2.1 boolean isint; 1024 bdemsky 1.1.2.8 QuadWithTry code; 1025 bdemsky 1.1.2.8 UseDef ud; 1026 bdemsky 1.1.2.1 1027 bdemsky 1.1.2.8 ZeroVisitor(Temp tested, boolean isint,QuadWithTry code, UseDef ud) { 1028 bdemsky 1.1.2.1 this.status=0; 1029 bdemsky 1.1.2.1 this.tested=tested; 1030 bdemsky 1.1.2.1 this.isint=isint; 1031 bdemsky 1.1.2.8 this.code=code; 1032 bdemsky 1.1.2.8 this.ud=ud; 1033 bdemsky 1.1.2.1 } 1034 bdemsky 1.1.2.1 1035 bdemsky 1.1.2.1 public boolean status() { 1036 bdemsky 1.1.2.1 return (status!=-1); 1037 bdemsky 1.1.2.1 } 1038 bdemsky 1.1.2.1 1039 bdemsky 1.1.2.1 public boolean success() { 1040 bdemsky 1.1.2.1 return (status==3); 1041 bdemsky 1.1.2.1 } 1042 bdemsky 1.1.2.1 1043 bdemsky 1.1.2.1 Object[] exchandler() { 1044 bdemsky 1.1.2.1 if (this.success()) 1045 bdemsky 1.1.2.1 return new Object[] {exchandler, new Integer(excedge)}; 1046 bdemsky 1.1.2.1 else 1047 bdemsky 1.1.2.1 return null; 1048 bdemsky 1.1.2.1 } 1049 bdemsky 1.1.2.1 public void visit(Quad q) { 1050 bdemsky 1.1.2.1 status=-1; 1051 bdemsky 1.1.2.1 } 1052 bdemsky 1.1.2.1 1053 bdemsky 1.1.2.1 public void visit(CONST q) { 1054 bdemsky 1.1.2.1 if ((status==2)&& 1055 bdemsky 1.1.2.1 (((q.type()==HClass.Int)&&(isint)) 1056 bdemsky 1.1.2.1 ||((!isint)&&(q.type()==HClass.Long)))) { 1057 cananian 1.3.2.1 assert compares.length==2; 1058 bdemsky 1.1.2.1 if (isint) 1059 bdemsky 1.1.2.1 if ((((Integer)q.value()).intValue()==0)&& 1060 bdemsky 1.1.2.1 (((compares[0]==q.dst())&&(compares[1]==tested))|| 1061 bdemsky 1.1.2.1 ((compares[1]==q.dst())&&(compares[0]==tested)))) 1062 bdemsky 1.1.2.1 status=3; 1063 bdemsky 1.1.2.1 else 1064 bdemsky 1.1.2.1 status=-1; 1065 bdemsky 1.1.2.1 else 1066 bdemsky 1.1.2.1 if ((((Long)q.value()).longValue()==0)&& 1067 bdemsky 1.1.2.1 (((compares[0]==q.dst())&&(compares[1]==tested))|| 1068 bdemsky 1.1.2.1 ((compares[1]==q.dst())&&(compares[0]==tested)))) 1069 bdemsky 1.1.2.1 status=3; 1070 bdemsky 1.1.2.1 else 1071 bdemsky 1.1.2.1 status=-1; 1072 bdemsky 1.1.2.1 } else 1073 bdemsky 1.1.2.1 status=-1; 1074 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 1075 bdemsky 1.1.2.8 status=-1; 1076 bdemsky 1.1.2.1 } 1077 bdemsky 1.1.2.1 1078 bdemsky 1.1.2.1 public void visit(OPER q) { 1079 bdemsky 1.1.2.1 if ((status==1)&& 1080 bdemsky 1.1.2.1 (((q.opcode()==Qop.ICMPEQ)&&isint)||((!isint)&&(q.opcode()==Qop.LCMPEQ))) 1081 bdemsky 1.1.2.1 &&(test==q.dst())) { 1082 bdemsky 1.1.2.1 compares=q.use(); 1083 bdemsky 1.1.2.1 status=2; 1084 bdemsky 1.1.2.1 } 1085 bdemsky 1.1.2.1 else 1086 bdemsky 1.1.2.1 status=-1; 1087 bdemsky 1.1.2.8 if (ud.useMap(code,q.dst()).length!=1) 1088 bdemsky 1.1.2.8 status=-1; 1089 bdemsky 1.1.2.1 } 1090 bdemsky 1.1.2.1 1091 bdemsky 1.1.2.17 public void visit(TYPECAST q) { 1092 bdemsky 1.1.2.17 //safe to ignore 1093 bdemsky 1.1.2.17 } 1094 bdemsky 1.1.2.17 1095 bdemsky 1.1.2.1 public void visit(CJMP q) { 1096 bdemsky 1.1.2.1 if (status==0) { 1097 bdemsky 1.1.2.1 test=q.test(); 1098 bdemsky 1.1.2.1 exchandler=q.next(1); 1099 bdemsky 1.1.2.1 excedge=q.nextEdge(1).which_pred(); 1100 bdemsky 1.1.2.1 status=1; 1101 bdemsky 1.1.2.1 } 1102 bdemsky 1.1.2.1 else 1103 bdemsky 1.1.2.1 status=-1; 1104 bdemsky 1.1.2.1 } 1105 bdemsky 1.1.2.1 } 1106 bdemsky 1.1.2.8 1107 cananian 1.1.2.9 } // close the Pattern class (yes, the indentation's screwed up, 1108 cananian 1.1.2.9 // but I don't feel like re-indenting all this code) [CSA] 1109 cananian 1.2