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 }