1 cananian 1.1.2.1 // EpilogMutator.java, created Fri Feb 23 02:28:16 2001 by cananian 2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Analysis.Counters; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.ClassFile.HClass; 7 cananian 1.1.2.1 import harpoon.ClassFile.HCode; 8 cananian 1.1.2.1 import harpoon.ClassFile.HCodeAndMaps; 9 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 10 cananian 1.1.2.1 import harpoon.ClassFile.HMethod; 11 cananian 1.1.2.1 import harpoon.ClassFile.Linker; 12 cananian 1.1.2.1 import harpoon.IR.Quads.CALL; 13 cananian 1.1.2.1 import harpoon.IR.Quads.Edge; 14 cananian 1.1.2.1 import harpoon.IR.Quads.PHI; 15 cananian 1.1.2.1 import harpoon.IR.Quads.Quad; 16 cananian 1.1.2.1 import harpoon.IR.Quads.QuadFactory; 17 cananian 1.1.2.1 import harpoon.IR.Quads.QuadNoSSA; 18 cananian 1.1.2.1 import harpoon.IR.Quads.QuadRSSx; 19 cananian 1.1.2.1 import harpoon.IR.Quads.QuadSSA; 20 cananian 1.1.2.1 import harpoon.IR.Quads.QuadSSI; 21 cananian 1.1.2.1 import harpoon.IR.Quads.QuadVisitor; 22 cananian 1.1.2.1 import harpoon.IR.Quads.RETURN; 23 cananian 1.1.2.1 import harpoon.IR.Quads.THROW; 24 cananian 1.1.2.1 import harpoon.Temp.Temp; 25 cananian 1.6 import net.cscott.jutil.SnapshotIterator; 26 cananian 1.1.2.1 import harpoon.Util.Util; 27 cananian 1.1.2.1 28 cananian 1.5 import java.util.Iterator; 29 cananian 1.5 30 cananian 1.1.2.1 /** 31 cananian 1.1.2.1 * <code>EpilogMutator</code> adds the appropriate call to 32 cananian 1.1.2.1 * <code>harpoon.Runtime.Counters</code><code>.report()</code> at the 33 cananian 1.1.2.1 * end of the main method and just before any call to 34 cananian 1.1.2.1 * <code>System.exit()</code>. For package-internal use by 35 cananian 1.1.2.1 * <code>CounterFactory</code>. 36 cananian 1.1.2.1 * 37 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 38 cananian 1.6 * @version $Id: EpilogMutator.java,v 1.6 2004/02/08 01:51:01 cananian Exp $ 39 cananian 1.1.2.1 */ 40 cananian 1.5 class EpilogMutator 41 cananian 1.5 extends harpoon.Analysis.Transformation.MethodMutator<Quad> { 42 cananian 1.1.2.1 private final HMethod HMmain, HMreport, HMexit; 43 cananian 1.1.2.1 44 cananian 1.1.2.1 /** Creates a <code>EpilogMutator</code>. */ 45 cananian 1.1.2.1 public EpilogMutator(HCodeFactory parent, Linker l, HMethod main) { 46 cananian 1.1.2.1 super(parent); 47 cananian 1.1.2.1 this.HMmain = main; 48 cananian 1.1.2.1 this.HMexit = l.forName("java.lang.Runtime") 49 cananian 1.1.2.1 .getDeclaredMethod("exit","(I)V"); 50 cananian 1.1.2.1 this.HMreport = l.forName("harpoon.Runtime.Counters") 51 cananian 1.1.2.1 .getDeclaredMethod("report","()V"); 52 cananian 1.3.2.1 assert HMmain.isStatic(); 53 cananian 1.3.2.1 assert !HMexit.isStatic(); 54 cananian 1.3.2.1 assert HMreport.isStatic(); 55 cananian 1.3.2.1 assert parent.getCodeName().equals(QuadNoSSA.codename) || 56 cananian 1.1.2.1 parent.getCodeName().equals(QuadRSSx.codename) || 57 cananian 1.1.2.1 parent.getCodeName().equals(QuadSSA.codename) || 58 cananian 1.3.2.1 parent.getCodeName().equals(QuadSSI.codename); 59 cananian 1.1.2.1 } 60 cananian 1.5 public HCode<Quad> mutateHCode(HCodeAndMaps<Quad> input) { 61 cananian 1.1.2.1 final boolean isMain = input.hcode().getMethod().equals(HMmain); 62 cananian 1.1.2.1 QuadVisitor qv = new QuadVisitor() { 63 cananian 1.1.2.1 public void visit(Quad q) { /* do nothing */ } 64 cananian 1.1.2.1 public void visit(RETURN q) { 65 cananian 1.1.2.1 if (isMain) addReportBefore(q); 66 cananian 1.1.2.1 } 67 cananian 1.1.2.1 public void visit(THROW q) { 68 cananian 1.1.2.1 if (isMain) addReportBefore(q); 69 cananian 1.1.2.1 } 70 cananian 1.1.2.1 public void visit(CALL q) { 71 cananian 1.1.2.1 if (q.method().equals(HMexit)) addReportBefore(q); 72 cananian 1.1.2.1 } 73 cananian 1.1.2.1 private void addReportBefore(Quad q) { 74 cananian 1.3.2.1 assert q.prevLength()==1; 75 cananian 1.1.2.1 QuadFactory qf = q.getFactory(); 76 cananian 1.1.2.1 Temp t = new Temp(qf.tempFactory(), "ignore"); 77 cananian 1.1.2.1 Quad q0 = new CALL(qf, q, HMreport, new Temp[0], 78 cananian 1.1.2.1 null, t, false, false, new Temp[0]); 79 cananian 1.1.2.1 Quad q1 = new PHI(qf, q, new Temp[0], 2); 80 cananian 1.1.2.1 Quad.addEdge(q0, 0, q1, 0); 81 cananian 1.1.2.1 Quad.addEdge(q0, 1, q1, 1); 82 cananian 1.1.2.1 Edge e = q.prevEdge(0); 83 cananian 1.1.2.1 Quad.addEdge((Quad)e.from(), e.which_succ(), q0, 0); 84 cananian 1.1.2.1 Quad.addEdge(q1, 0, (Quad)e.to(), e.which_pred()); 85 cananian 1.1.2.1 } 86 cananian 1.1.2.1 }; 87 cananian 1.5 for (Iterator<Quad> it=new SnapshotIterator<Quad> 88 cananian 1.5 (input.hcode().getElementsI()); it.hasNext(); ) 89 cananian 1.5 it.next().accept(qv); 90 cananian 1.1.2.1 return input.hcode(); 91 cananian 1.1.2.1 } 92 cananian 1.2 }