1 bdemsky  1.1.2.1 // TreeBuilder.java, created Sat Sep 25 07:23:21 1999 by cananian
  2 bdemsky  1.1.2.1 // Copyright (C) 1999 C. Scott Ananian <cananian@alumni.princeton.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.Backend.Runtime2;
  5 bdemsky  1.1.2.1 
  6 bdemsky  1.1.2.1 import harpoon.Analysis.ClassHierarchy;
  7 bdemsky  1.1.2.1 import harpoon.Analysis.Maps.AllocationInformation.AllocationProperties;
  8 bdemsky  1.1.2.1 import harpoon.Analysis.Maps.Derivation;
  9 bdemsky  1.1.2.1 import harpoon.Backend.Maps.ClassDepthMap;
 10 bdemsky  1.1.2.1 import harpoon.Backend.Maps.FieldMap;
 11 bdemsky  1.1.2.1 import harpoon.Backend.Maps.MethodMap;
 12 bdemsky  1.1.2.1 import harpoon.ClassFile.HClass;
 13 bdemsky  1.1.2.1 import harpoon.ClassFile.HCodeElement;
 14 bdemsky  1.1.2.1 import harpoon.ClassFile.HField;
 15 bdemsky  1.1.2.1 import harpoon.ClassFile.HMethod;
 16 bdemsky  1.1.2.1 import harpoon.ClassFile.Linker;
 17 bdemsky  1.1.2.1 import harpoon.IR.Tree.TreeFactory;
 18 bdemsky  1.1.2.1 import harpoon.IR.Tree.Stm;
 19 bdemsky  1.1.2.1 import harpoon.IR.Tree.Exp;
 20 bdemsky  1.1.2.1 import harpoon.IR.Tree.ExpList;
 21 bdemsky  1.1.2.1 import harpoon.IR.Tree.Bop;
 22 bdemsky  1.1.2.1 import harpoon.IR.Tree.Uop;
 23 bdemsky  1.1.2.1 import harpoon.IR.Tree.Translation;
 24 bdemsky  1.1.2.1 import harpoon.IR.Tree.Type;
 25 bdemsky  1.1.2.1 import harpoon.IR.Tree.BINOP;
 26 bdemsky  1.1.2.1 import harpoon.IR.Tree.CALL;
 27 bdemsky  1.1.2.1 import harpoon.IR.Tree.CJUMP;
 28 bdemsky  1.1.2.1 import harpoon.IR.Tree.CONST;
 29 bdemsky  1.1.2.1 import harpoon.IR.Tree.DATUM;
 30 bdemsky  1.1.2.1 import harpoon.IR.Tree.DerivationGenerator;
 31 bdemsky  1.1.2.1 import harpoon.IR.Tree.ESEQ;
 32 bdemsky  1.1.2.1 import harpoon.IR.Tree.EXPR;
 33 bdemsky  1.1.2.1 import harpoon.IR.Tree.INVOCATION;
 34 bdemsky  1.1.2.1 import harpoon.IR.Tree.JUMP;
 35 bdemsky  1.1.2.1 import harpoon.IR.Tree.LABEL;
 36 bdemsky  1.1.2.1 import harpoon.IR.Tree.MEM;
 37 bdemsky  1.1.2.1 import harpoon.IR.Tree.METHOD;
 38 bdemsky  1.1.2.1 import harpoon.IR.Tree.MOVE;
 39 bdemsky  1.1.2.1 import harpoon.IR.Tree.NAME;
 40 bdemsky  1.1.2.1 import harpoon.IR.Tree.NATIVECALL;
 41 bdemsky  1.1.2.1 import harpoon.IR.Tree.OPER;
 42 bdemsky  1.1.2.1 import harpoon.IR.Tree.RETURN;
 43 bdemsky  1.1.2.1 import harpoon.IR.Tree.SEGMENT;
 44 bdemsky  1.1.2.1 import harpoon.IR.Tree.SEQ;
 45 bdemsky  1.1.2.1 import harpoon.IR.Tree.TEMP;
 46 bdemsky  1.1.2.1 import harpoon.IR.Tree.THROW;
 47 bdemsky  1.1.2.1 import harpoon.IR.Tree.UNOP;
 48 bdemsky  1.1.2.1 import harpoon.Temp.Label;
 49 bdemsky  1.1.2.1 import harpoon.Temp.Temp;
 50 bdemsky  1.1.2.1 import harpoon.Util.HClassUtil;
 51 bdemsky  1.1.2.1 import harpoon.Util.Util;
 52 bdemsky  1.1.2.1 
 53 bdemsky  1.1.2.1 import harpoon.Backend.Runtime1.AllocationStrategy;
 54 bdemsky  1.1.2.1 
 55 bdemsky  1.1.2.1 
 56 bdemsky  1.1.2.1 import java.util.HashSet;
 57 bdemsky  1.1.2.1 import java.util.List;
 58 bdemsky  1.1.2.1 import java.util.Set;
 59 bdemsky  1.1.2.1 /**
 60 bdemsky  1.1.2.1  * <code>Runtime2.TreeBuilder</code> is an implementation of
 61 bdemsky  1.1.2.1  * <code>Generic.Runtime.TreeBuilder</code> which creates
 62 bdemsky  1.1.2.1  * accessor expressions for the <code>Runtime1</code> runtime.
 63 bdemsky  1.1.2.1  * <p>Pretty straightforward.  No weird hacks.
 64 bdemsky  1.1.2.1  * 
 65 bdemsky  1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 66 cananian 1.6      * @version $Id: TreeBuilder.java,v 1.6 2003/07/15 03:33:52 cananian Exp $
 67 bdemsky  1.1.2.1  */
 68 bdemsky  1.1.2.1 public class TreeBuilder extends harpoon.Backend.Runtime1.TreeBuilder {
 69 cananian 1.2.2.1     protected TreeBuilder(harpoon.Backend.Runtime1.Runtime runtime,
 70 cananian 1.2.2.1                           Linker linker,
 71 wbeebee  1.1.2.4                 AllocationStrategy as, boolean pointersAreLong,
 72 wbeebee  1.1.2.4                 int pointerAlignment) {
 73 cananian 1.1.2.7         super(runtime, linker, as, pointersAreLong, pointerAlignment);
 74 bdemsky  1.1.2.1     }
 75 cananian 1.5     
 76 cananian 1.5         public Exp fetchHash(TreeFactory tf, HCodeElement source,
 77 cananian 1.5                              Exp object) {
 78 cananian 1.5             return new MEM(tf, source, Type.INT,
 79 cananian 1.5                            new BINOP(tf, source, Type.POINTER, Bop.ADD,
 80 cananian 1.5                                      object,
 81 cananian 1.5                                      new CONST(tf, source, OBJ_HASH_OFF)));
 82 cananian 1.5         }
 83 cananian 1.5     
 84 bdemsky  1.1.2.1     // allocate 'length' bytes plus object header; fill in object header.
 85 bdemsky  1.1.2.1     // shift return pointer appropriately for an object reference.
 86 bdemsky  1.1.2.1     public Exp objAlloc(TreeFactory tf, HCodeElement source,
 87 bdemsky  1.1.2.1                         DerivationGenerator dg,
 88 bdemsky  1.1.2.1                         AllocationProperties ap,
 89 bdemsky  1.1.2.1                         HClass objectType, Exp length) {
 90 bdemsky  1.1.2.1         Exp old=super.objAlloc(tf,source,dg,ap,objectType,length);
 91 bdemsky  1.1.2.1         Temp Tobj = new Temp(tf.tempFactory(), "BRIANTEMP");
 92 wbeebee  1.1.2.3         // If the noSync flag is on, then the second bit of the hashcode will
 93 wbeebee  1.1.2.3         // be set, allowing locks on this object to fall through.
 94 salcianu 1.4             if (ap.noSync()) {
 95 bdemsky  1.1.2.1             return new ESEQ(tf,source, 
 96 bdemsky  1.1.2.1                  new SEQ(tf,source,
 97 bdemsky  1.1.2.1                    new MOVE(tf,source,
 98 bdemsky  1.1.2.1                      DECLARE(dg,objectType,Tobj,
 99 bdemsky  1.1.2.1                      new TEMP(tf,source,Type.POINTER,Tobj)), old),
100 bdemsky  1.1.2.1                    new MOVE(tf,source,
101 cananian 1.5                          fetchHash(tf, source, 
102 cananian 1.5                                    DECLARE(dg,objectType,Tobj,
103 cananian 1.5                                    new TEMP(tf,source,Type.POINTER,Tobj))),
104 cananian 1.1.2.8                    new BINOP(tf, source, Type.INT, Bop.ADD,
105 cananian 1.5                          fetchHash(tf, source, 
106 cananian 1.5                                    DECLARE(dg,objectType,Tobj,
107 cananian 1.5                                    new TEMP(tf,source,Type.POINTER,Tobj))),
108 bdemsky  1.1.2.1                    new CONST(tf, source, 2)))),
109 bdemsky  1.1.2.1                  DECLARE(dg,objectType, Tobj,
110 bdemsky  1.1.2.1                  new TEMP(tf,source,Type.POINTER,Tobj)));
111 salcianu 1.4             }
112 bdemsky  1.1.2.1         else return old;
113 bdemsky  1.1.2.2     }
114 bdemsky  1.1.2.2     // XXX in single-threaded mode, this can be a NOP.
115 bdemsky  1.1.2.2     public Translation.Exp monitorEnter(TreeFactory tf, HCodeElement source,
116 bdemsky  1.1.2.2                                         DerivationGenerator dg,
117 bdemsky  1.1.2.2                                         Translation.Exp objectref) {
118 bdemsky  1.1.2.2         // call FNI_MonitorEnter()
119 bdemsky  1.1.2.2         return new Translation.Nx(_call_FNI_Monitor(tf, source, dg, objectref,
120 bdemsky  1.1.2.2                                                     true));
121 bdemsky  1.1.2.2     }
122 bdemsky  1.1.2.2     // XXX in single-threaded mode, this can be a NOP.
123 bdemsky  1.1.2.2     public Translation.Exp monitorExit(TreeFactory tf, HCodeElement source,
124 bdemsky  1.1.2.2                                        DerivationGenerator dg,
125 bdemsky  1.1.2.2                                        Translation.Exp objectref) {
126 bdemsky  1.1.2.2         // call FNI_MonitorExit()
127 bdemsky  1.1.2.2         return new Translation.Nx(_call_FNI_Monitor(tf, source, dg, objectref,
128 bdemsky  1.1.2.2                                                     false));
129 bdemsky  1.1.2.2     }
130 cananian 1.6         protected Stm _call_FNI_Monitor(TreeFactory tf, HCodeElement source,
131 bdemsky  1.1.2.2                                   DerivationGenerator dg,
132 bdemsky  1.1.2.2                                   Translation.Exp objectref,
133 bdemsky  1.1.2.2                                   boolean isEnter/*else exit*/) {
134 cananian 1.6             // if we're using the explicit DynamicSyncRemoval pass, we've already
135 cananian 1.6             // done this transformation (in quad form) and don't need to repeat
136 cananian 1.6             // it here.
137 cananian 1.6             if (Boolean.getBoolean("harpoon.runtime2.skip_monitor_test"))
138 cananian 1.6                 return super._call_FNI_Monitor(tf, source, dg, objectref, isEnter);
139 cananian 1.6             // otherwise...
140 bdemsky  1.1.2.2 
141 cananian 1.6             HClass HCobj = linker.forName("java.lang.Object");
142 cananian 1.6             Temp object = new Temp(tf.tempFactory(), "BRIANSOBJECT");
143 cananian 1.6     
144 cananian 1.6             MOVE move = new MOVE
145 bdemsky  1.1.2.2             (tf, source,
146 cananian 1.6                  DECLARE(dg, HCobj, object,
147 cananian 1.6                          new TEMP(tf, source, Type.POINTER, object)),
148 cananian 1.6                  objectref.unEx(tf));
149 cananian 1.6     
150 cananian 1.6             Stm old = super._call_FNI_Monitor
151 cananian 1.6                 (tf, source, dg,
152 cananian 1.6                  new Translation.Ex
153 cananian 1.6                  (DECLARE(dg, HCobj, object,
154 cananian 1.6                           new TEMP(tf, source, Type.POINTER, object))),
155 cananian 1.6                  isEnter);
156 bdemsky  1.1.2.2 
157 bdemsky  1.1.2.2         Label DLabel=new Label();
158 bdemsky  1.1.2.2         Label SLabel=new Label();
159 cananian 1.5             Exp lockvalue=fetchHash
160 cananian 1.5                 (tf, source, 
161 cananian 1.6                  DECLARE(dg, HCobj, object,
162 cananian 1.5                          new TEMP(tf,source,Type.POINTER,object)));
163 bdemsky  1.1.2.2         Exp testcond=new BINOP(tf, source, Type.INT, Bop.AND, lockvalue,
164 bdemsky  1.1.2.2                        new CONST(tf, source, 2));
165 bdemsky  1.1.2.2         Stm dotest=new CJUMP(tf,source,testcond,SLabel,DLabel);
166 bdemsky  1.1.2.2         
167 bdemsky  1.1.2.2         Stm monitor=new SEQ(tf,source,new LABEL(tf,source,DLabel,false),old);
168 bdemsky  1.1.2.2         Stm labels=new SEQ(tf,source,monitor,new LABEL(tf, source, SLabel,false));
169 bdemsky  1.1.2.2         
170 bdemsky  1.1.2.2         Stm testit=new SEQ(tf,source,dotest,labels);
171 bdemsky  1.1.2.2 
172 cananian 1.6             Stm myresult=new SEQ(tf,source,move,testit);
173 bdemsky  1.1.2.2 
174 bdemsky  1.1.2.2         return myresult;
175 bdemsky  1.1.2.1     }
176 cananian 1.2     }