1 cananian 1.1.2.1 // MethodTraceFactory.java, created Fri Nov  2 14:30:00 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.Quads;
 5 cananian 1.1.2.1 
 6 cananian 1.1.2.2 import harpoon.Analysis.Transformation.MethodMutator;
 7 cananian 1.1.2.2 import harpoon.ClassFile.HCode;
 8 cananian 1.1.2.2 import harpoon.ClassFile.HCodeAndMaps;
 9 cananian 1.1.2.2 import harpoon.ClassFile.HCodeFactory;
10 cananian 1.1.2.2 import harpoon.IR.Quads.DEBUG;
11 cananian 1.1.2.2 import harpoon.IR.Quads.Edge;
12 cananian 1.1.2.2 import harpoon.IR.Quads.METHOD;
13 cananian 1.1.2.2 import harpoon.IR.Quads.Quad;
14 cananian 1.1.2.2 import harpoon.IR.Quads.QuadVisitor;
15 cananian 1.1.2.2 import harpoon.IR.Quads.RETURN;
16 cananian 1.1.2.2 import harpoon.IR.Quads.THROW;
17 cananian 1.4     import net.cscott.jutil.SnapshotIterator;
18 cananian 1.3     
19 cananian 1.3     import java.util.Iterator;
20 cananian 1.1.2.1 
21 cananian 1.1.2.1 /**
22 cananian 1.1.2.1  * <code>MethodTraceFactory</code> adds <code>DEBUG</code> quads
23 cananian 1.1.2.1  * to the entry and exit points of every method.  Comparing
24 cananian 1.1.2.1  * the debug output of a working and 'broken' program should
25 cananian 1.1.2.1  * make it easier to isolate which part of the 'broken' binary
26 cananian 1.1.2.1  * isn't behaving as expected.
27 cananian 1.1.2.1  * 
28 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
29 cananian 1.4      * @version $Id: MethodTraceFactory.java,v 1.4 2004/02/08 01:53:14 cananian Exp $
30 cananian 1.1.2.1  */
31 cananian 1.3     public class MethodTraceFactory extends MethodMutator<Quad> {
32 cananian 1.1.2.1     
33 cananian 1.1.2.1     /** Creates a <code>MethodTraceFactory</code>. */
34 cananian 1.1.2.1     public MethodTraceFactory(HCodeFactory parent) {
35 cananian 1.1.2.1         super(parent);
36 cananian 1.1.2.1     }
37 cananian 1.3         public HCode<Quad> mutateHCode(HCodeAndMaps<Quad> input) {
38 cananian 1.3             final HCode<Quad> hc = input.hcode();
39 cananian 1.1.2.1         QuadVisitor qv = new QuadVisitor() {
40 cananian 1.1.2.1                 public void visit(Quad q) { /* do nothing */ }
41 cananian 1.1.2.1                 public void visit(METHOD q) {
42 cananian 1.1.2.1                     addAt(q.nextEdge(0),
43 cananian 1.1.2.1                           new DEBUG(q.getFactory(), q,
44 cananian 1.1.2.1                                     ("ENTERING "+hc.getMethod()).intern()));
45 cananian 1.1.2.1                 }
46 cananian 1.1.2.1                 public void visit(RETURN q) {
47 cananian 1.1.2.1                     addAt(q.prevEdge(0),
48 cananian 1.1.2.1                           new DEBUG(q.getFactory(), q,
49 cananian 1.1.2.1                                     ("RETURN from "+hc.getMethod()).intern()));
50 cananian 1.1.2.1                 }
51 cananian 1.1.2.1                 public void visit(THROW q) {
52 cananian 1.1.2.1                     addAt(q.prevEdge(0),
53 cananian 1.1.2.1                           new DEBUG(q.getFactory(), q,
54 cananian 1.1.2.1                                     ("THROW from "+hc.getMethod()).intern()));
55 cananian 1.1.2.1                 }
56 cananian 1.1.2.1             };
57 cananian 1.3             for (Iterator<Quad> it=new SnapshotIterator<Quad>(hc.getElementsI());
58 cananian 1.3                  it.hasNext(); )
59 cananian 1.3                 it.next().accept(qv);
60 cananian 1.1.2.1         return hc;
61 cananian 1.1.2.1     }
62 cananian 1.1.2.1     /** helper routine to add a quad on an edge. */
63 cananian 1.1.2.1     private static Edge addAt(Edge e, Quad q) { return addAt(e, 0, q, 0); }
64 cananian 1.1.2.1     private static Edge addAt(Edge e, int which_pred, Quad q, int which_succ) {
65 cananian 1.3             Quad frm = e.from(); int frm_succ = e.which_succ();
66 cananian 1.3             Quad to  = e.to();   int to_pred = e.which_pred();
67 cananian 1.1.2.1         Quad.addEdge(frm, frm_succ, q, which_pred);
68 cananian 1.1.2.1         Quad.addEdge(q, which_succ, to, to_pred);
69 cananian 1.1.2.1         return to.prevEdge(to_pred);
70 cananian 1.1.2.1     }
71 cananian 1.2     }