1 kkz      1.1.2.1 // WriteBarrierPrePass.java, created Mon Aug 13 18:29:34 2001 by kkz
  2 kkz      1.1.2.1 // Copyright (C) 2000 Karen Zee <kkz@tmi.lcs.mit.edu>
  3 kkz      1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 kkz      1.1.2.1 package harpoon.Analysis.PreciseGC;
  5 kkz      1.1.2.1 
  6 kkz      1.1.2.1 import harpoon.Backend.Generic.Frame;
  7 kkz      1.1.2.1 import harpoon.ClassFile.HClass;
  8 kkz      1.1.2.1 import harpoon.ClassFile.HCode;
  9 kkz      1.1.2.1 import harpoon.ClassFile.HCodeFactory;
 10 kkz      1.1.2.1 import harpoon.ClassFile.HCodeAndMaps;
 11 kkz      1.1.2.1 import harpoon.ClassFile.HMethod;
 12 kkz      1.1.2.1 import harpoon.ClassFile.Linker;
 13 kkz      1.1.2.1 import harpoon.IR.LowQuad.DerivationMap;
 14 kkz      1.1.2.1 import harpoon.IR.LowQuad.LowQuadFactory;
 15 kkz      1.1.2.1 import harpoon.IR.LowQuad.LowQuadVisitor;
 16 kkz      1.1.2.1 import harpoon.IR.LowQuad.PCALL;
 17 kkz      1.1.2.1 import harpoon.IR.LowQuad.PMCONST;
 18 kkz      1.1.2.1 import harpoon.IR.LowQuad.PSET;
 19 kkz      1.1.2.1 import harpoon.IR.Quads.Code;
 20 kkz      1.1.2.1 import harpoon.IR.Quads.Edge;
 21 kkz      1.1.2.1 import harpoon.IR.Quads.FOOTER;
 22 kkz      1.1.2.1 import harpoon.IR.Quads.GET;
 23 kkz      1.1.2.1 import harpoon.IR.Quads.HEADER;
 24 kkz      1.1.2.1 import harpoon.IR.Quads.Quad;
 25 kkz      1.1.2.1 import harpoon.IR.Quads.QuadFactory;
 26 kkz      1.1.2.1 import harpoon.IR.Quads.THROW;
 27 kkz      1.1.2.2 import harpoon.IR.Quads.Code;
 28 kkz      1.1.2.1 import harpoon.Temp.Temp;
 29 kkz      1.1.2.1 import harpoon.Temp.TempFactory;
 30 kkz      1.1.2.1 
 31 kkz      1.1.2.1 
 32 kkz      1.1.2.1 /**
 33 kkz      1.1.2.1  * <code>WriteBarrierPrePass</code> takes code in LowQuad form and
 34 kkz      1.1.2.1  * inserts a fake call to a write barrier that is later replaced with
 35 kkz      1.1.2.1  * a real implementation in <code>WriteBarrierPostPass</code>.
 36 kkz      1.1.2.1  * 
 37 kkz      1.1.2.1  * @author  Karen Zee <kkz@tmi.lcs.mit.edu>
 38 cananian 1.2      * @version $Id: WriteBarrierPrePass.java,v 1.2 2002/02/25 20:58:54 cananian Exp $
 39 kkz      1.1.2.1  */
 40 kkz      1.1.2.1 public class WriteBarrierPrePass extends 
 41 kkz      1.1.2.1     harpoon.Analysis.Transformation.MethodMutator {
 42 kkz      1.1.2.1     
 43 kkz      1.1.2.1     final private HMethod dummyHM;
 44 kkz      1.1.2.1     final private HClass JLT;
 45 kkz      1.1.2.1     
 46 kkz      1.1.2.1     /** Creates a <code>WriteBarrierPrePass</code>. */
 47 kkz      1.1.2.1     public WriteBarrierPrePass(HCodeFactory parent, Linker linker) { 
 48 kkz      1.1.2.1         super(parent);
 49 kkz      1.1.2.1         this.JLT = linker.forName("java.lang.Throwable");
 50 kkz      1.1.2.1         HClass WB = linker.forName("harpoon.Runtime.PreciseGC.WriteBarrier");
 51 kkz      1.1.2.1         HClass JLO = linker.forName("java.lang.Object");
 52 kkz      1.1.2.1         this.dummyHM = WB.getMethod("storeCheck", new HClass[] { JLO });
 53 kkz      1.1.2.1     }
 54 kkz      1.1.2.1 
 55 kkz      1.1.2.1     protected HCode mutateHCode(HCodeAndMaps input) {
 56 kkz      1.1.2.1         Code hc = (harpoon.IR.Quads.Code)input.hcode();
 57 kkz      1.1.2.1         //hc.print(new java.io.PrintWriter(System.out), null);
 58 kkz      1.1.2.1         HEADER header = (HEADER) hc.getRootElement();
 59 kkz      1.1.2.1         FOOTER footer = (FOOTER) header.footer();
 60 kkz      1.1.2.1         LowQuadVisitor qv = new WriteBarrierVisitor
 61 kkz      1.1.2.2             ((DerivationMap)hc.getDerivation(), JLT, dummyHM, footer);
 62 kkz      1.1.2.1         // we put all elements in array to avoid screwing up the
 63 kkz      1.1.2.1         // iterator as we mutate the quad graph in-place.
 64 kkz      1.1.2.1         Quad[] allquads = (Quad[]) hc.getElements();
 65 kkz      1.1.2.1         for (int i=0; i<allquads.length; i++)
 66 kkz      1.1.2.1             allquads[i].accept(qv);
 67 kkz      1.1.2.1         // yay, done!
 68 kkz      1.1.2.1         //hc.print(new java.io.PrintWriter(System.out), null);
 69 kkz      1.1.2.1         return hc;
 70 kkz      1.1.2.1     }
 71 kkz      1.1.2.1 
 72 kkz      1.1.2.1     /** Return an <code>HCodeFactory</code> that will clean up the
 73 kkz      1.1.2.1      *  tree form of the transformed code by performing some optimizations
 74 kkz      1.1.2.1      *  which can't be represented in quad form. */
 75 kkz      1.1.2.1     public HCodeFactory treeCodeFactory(Frame f, HCodeFactory hcf) {
 76 kkz      1.1.2.1         return new WriteBarrierPostPass(f, dummyHM).codeFactory(hcf);
 77 kkz      1.1.2.1     }
 78 kkz      1.1.2.1 
 79 kkz      1.1.2.1 
 80 kkz      1.1.2.1     private static class WriteBarrierVisitor extends LowQuadVisitor {
 81 kkz      1.1.2.1         final DerivationMap dm;
 82 kkz      1.1.2.1         final HClass JLT;
 83 kkz      1.1.2.1         final HMethod dummyHM;
 84 kkz      1.1.2.1         FOOTER footer;
 85 kkz      1.1.2.2         WriteBarrierVisitor(DerivationMap dm, HClass JLT, HMethod dummyHM, 
 86 kkz      1.1.2.2                             FOOTER footer) {
 87 kkz      1.1.2.1             this.dm = dm;
 88 kkz      1.1.2.1             this.JLT = JLT;
 89 kkz      1.1.2.1             this.dummyHM = dummyHM;
 90 kkz      1.1.2.1             this.footer = footer;
 91 kkz      1.1.2.1         }
 92 kkz      1.1.2.1         public void visit(Quad q) { /* do nothing */ }
 93 kkz      1.1.2.1         public void visit(PSET q) {
 94 kkz      1.1.2.1             if (!q.type().isPrimitive()) {
 95 kkz      1.1.2.1                 LowQuadFactory qf = (LowQuadFactory)q.getFactory();
 96 kkz      1.1.2.1                 TempFactory tf = qf.tempFactory();
 97 kkz      1.1.2.1                 // create needed Temps
 98 kkz      1.1.2.1                 Temp func = new Temp(tf, "wb");
 99 kkz      1.1.2.1                 Temp retex = new Temp(tf, "wbex");
100 kkz      1.1.2.1                 // create needed LowQuads
101 kkz      1.1.2.1                 PMCONST pmconst = new PMCONST(qf, q, func, dummyHM);
102 kkz      1.1.2.1                 PCALL pcall = new PCALL(qf, q, func,
103 kkz      1.1.2.1                                         new Temp[] { q.ptr() }, null, retex, 
104 kkz      1.1.2.1                                         new Temp[0],  false, false);
105 kkz      1.1.2.1                 THROW thr = new THROW(qf, q, retex);
106 kkz      1.1.2.1                 // update derivation information
107 kkz      1.1.2.1                 dm.putType(pmconst, func, HClass.Void);
108 kkz      1.1.2.1                 dm.putType(pcall, retex, JLT);
109 kkz      1.1.2.1                 // add PMCONST and PCALL before PSET
110 kkz      1.1.2.1                 splice(pmconst, q.prevEdge(0));
111 kkz      1.1.2.1                 splice(pcall, q.prevEdge(0));
112 kkz      1.1.2.1                 // add THROW after PCALL
113 kkz      1.1.2.1                 Quad.addEdge(pcall, 1, thr, 0);
114 kkz      1.1.2.1                 footer = footer.attach(thr, 0);
115 kkz      1.1.2.1             }
116 kkz      1.1.2.1         }
117 kkz      1.1.2.1         /** inserts the given Quad on the given Edge */
118 kkz      1.1.2.1         private void splice(Quad q, Edge e) {
119 kkz      1.1.2.1             Quad.addEdge((Quad)e.from(), e.which_succ(), q, 0);
120 kkz      1.1.2.1             Quad.addEdge(q, 0, (Quad)e.to(), e.which_pred());
121 kkz      1.1.2.1         }
122 kkz      1.1.2.1     }
123 cananian 1.2     }