1 cananian 1.1.2.1 // Runtime.java, created Wed Sep  8 14:30:28 1999 by cananian
  2 cananian 1.1.2.1 // Copyright (C) 1999 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.Backend.RuntimeTiny;
  5 cananian 1.1.2.1 
  6 cananian 1.1.2.1 import harpoon.Analysis.ClassHierarchy;
  7 cananian 1.1.2.1 import harpoon.Analysis.CallGraph;
  8 cananian 1.1.2.1 import harpoon.Backend.Generic.Frame;
  9 cananian 1.1.2.1 import harpoon.Backend.Maps.ClassDepthMap;
 10 cananian 1.1.2.1 import harpoon.Backend.Maps.NameMap;
 11 cananian 1.1.2.1 import harpoon.ClassFile.HClass;
 12 cananian 1.1.2.1 import harpoon.ClassFile.HCode;
 13 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory;
 14 cananian 1.1.2.1 import harpoon.ClassFile.HData;
 15 cananian 1.1.2.1 import harpoon.ClassFile.HMethod;
 16 cananian 1.1.2.1 import harpoon.ClassFile.Linker;
 17 cananian 1.1.2.2 import harpoon.IR.Tree.DATUM;
 18 cananian 1.1.2.2 import harpoon.IR.Tree.CONST;
 19 cananian 1.1.2.2 import harpoon.IR.Tree.Stm;
 20 cananian 1.1.2.2 import harpoon.IR.Tree.TreeFactory;
 21 cananian 1.1.2.1 
 22 cananian 1.1.2.1 import harpoon.Backend.Runtime1.AllocationStrategy;
 23 cananian 1.1.2.1 import harpoon.Backend.Runtime1.ObjectBuilder.RootOracle;
 24 cananian 1.1.2.1 
 25 cananian 1.1.2.1 import java.lang.reflect.Modifier;
 26 cananian 1.1.2.1 
 27 cananian 1.1.2.1 import java.util.ArrayList;
 28 cananian 1.1.2.1 import java.util.Arrays;
 29 cananian 1.1.2.1 import java.util.Collection;
 30 cananian 1.1.2.1 import java.util.HashSet;
 31 cananian 1.1.2.1 import java.util.Iterator;
 32 cananian 1.1.2.1 import java.util.List;
 33 cananian 1.1.2.1 import java.util.Set;
 34 cananian 1.4     
 35 cananian 1.4     import net.cscott.jutil.Util;
 36 cananian 1.1.2.1 /**
 37 cananian 1.1.2.1  * <code>RuntimeTiny.Runtime</code> is a size-optimized version of the
 38 cananian 1.1.2.1  * FLEX backend.  It inherits most of the implementation of Runtime1,
 39 cananian 1.1.2.1  * but uses indices rather than direct pointers to compress the claz
 40 cananian 1.1.2.1  * field and (will) support byte- and bit-aligned (i.e. "unaligned")
 41 cananian 1.1.2.1  * fields in object layouts.
 42 cananian 1.1.2.1  *
 43 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 44 cananian 1.4      * @version $Id: Runtime.java,v 1.4 2004/02/08 01:57:47 cananian Exp $
 45 cananian 1.1.2.1  */
 46 cananian 1.1.2.1 public class Runtime extends harpoon.Backend.Runtime1.Runtime {
 47 cananian 1.1.2.1     // options.
 48 cananian 1.1.2.1     /* turning this on reduces the size of the claz pointer (by using an
 49 cananian 1.1.2.1      * index) at the expense of an extra dereference every time the claz is
 50 cananian 1.1.2.1      * used. */
 51 cananian 1.1.2.1     protected static final boolean clazShrink =
 52 cananian 1.1.2.3         !Boolean.getBoolean("harpoon.runtime.tiny.no-claz-shrink");
 53 cananian 1.1.2.5     protected static final boolean hashlockShrink =
 54 cananian 1.1.2.5         !Boolean.getBoolean("harpoon.runtime.tiny.no-hashlock-shrink");
 55 cananian 1.1.2.3     protected static final boolean byteAlign =
 56 cananian 1.1.2.3         System.getProperty("harpoon.runtime.tiny.field-align","byte")
 57 cananian 1.1.2.3         .equalsIgnoreCase("byte");
 58 cananian 1.1.2.3     protected final static boolean fixAlign =
 59 cananian 1.1.2.3         Boolean.getBoolean("harpoon.runtime.tiny.fix-align");
 60 cananian 1.1.2.5     static {
 61 cananian 1.1.2.5         // report the runtime settings, just to double-check w/ the user.
 62 cananian 1.1.2.5         System.out.print("TINY RUNTIME: ");
 63 cananian 1.1.2.6         if (clazShrink) System.out.print("[CLAZ-SHRINK] ");
 64 cananian 1.1.2.6         if (hashlockShrink) System.out.print("[HASH-SHRINK] ");
 65 cananian 1.1.2.6         if (byteAlign) System.out.print("[BYTE-ALIGN] ");
 66 cananian 1.1.2.6         if (fixAlign) System.out.print("[FIX-ALIGN] ");
 67 cananian 1.1.2.5         System.out.println();
 68 cananian 1.1.2.5     }
 69 cananian 1.1.2.1 
 70 cananian 1.1.2.1     // local fields
 71 cananian 1.1.2.1     protected ClazNumbering cn;
 72 cananian 1.1.2.4     int clazBytes;
 73 cananian 1.1.2.1 
 74 cananian 1.1.2.1     public Runtime(Frame frame, AllocationStrategy as,
 75 cananian 1.1.2.1                    HMethod main, boolean prependUnderscore) {
 76 cananian 1.1.2.1         this(frame, as, main, prependUnderscore, null);
 77 cananian 1.1.2.1     }
 78 cananian 1.1.2.1 
 79 cananian 1.1.2.1     public Runtime(Frame frame, AllocationStrategy as,
 80 cananian 1.1.2.1                    HMethod main, 
 81 cananian 1.1.2.1                    boolean prependUnderscore, RootOracle rootOracle) {
 82 cananian 1.1.2.1         super(frame,as,main,prependUnderscore,rootOracle);
 83 cananian 1.1.2.1     }
 84 cananian 1.1.2.2     protected ObjectBuilder initObjectBuilder(RootOracle ro) {
 85 cananian 1.1.2.2         if (ro==null)
 86 cananian 1.1.2.2             return new harpoon.Backend.RuntimeTiny.ObjectBuilder(this);
 87 cananian 1.1.2.2         return new harpoon.Backend.RuntimeTiny.ObjectBuilder(this, ro);
 88 cananian 1.1.2.2     }
 89 cananian 1.1.2.1     protected harpoon.Backend.RuntimeTiny.TreeBuilder initTreeBuilder() {
 90 cananian 1.1.2.1         return new harpoon.Backend.RuntimeTiny.TreeBuilder
 91 cananian 1.1.2.1             (this, frame.getLinker(), as, frame.pointersAreLong());
 92 cananian 1.1.2.1     }
 93 cananian 1.1.2.1     public void setClassHierarchy(ClassHierarchy ch) {
 94 cananian 1.1.2.1         // do class numbering w/ this classhierarchy
 95 cananian 1.1.2.1         this.cn = new CompleteClazNumbering(ch);
 96 cananian 1.1.2.4         this.clazBytes = !clazShrink ? 4 :
 97 cananian 1.1.2.4             (Util.log2c(ch.instantiatedClasses().size())+7)/8;
 98 cananian 1.1.2.4         // reset treebuilder, etc.
 99 cananian 1.1.2.4         super.setClassHierarchy(ch);
100 cananian 1.1.2.1     }
101 cananian 1.1.2.3     // we're going to hack in our own codefactory in w/ the
102 cananian 1.1.2.3     // nativetreecodefactory.  beware: tree is not yet canonicalized!
103 cananian 1.1.2.3     public HCodeFactory nativeTreeCodeFactory(final HCodeFactory hcf) {
104 cananian 1.1.2.3         HCodeFactory parent = super.nativeTreeCodeFactory(hcf);
105 cananian 1.1.2.3         if (!byteAlign) return parent;
106 cananian 1.1.2.3         if (!fixAlign) return parent;
107 cananian 1.1.2.3         return FixUnaligned.codeFactory
108 cananian 1.1.2.3             (harpoon.IR.Tree.CanonicalTreeCode.codeFactory(parent, frame));
109 cananian 1.1.2.3     }
110 cananian 1.1.2.3 
111 cananian 1.1.2.1     public List<HData> classData(HClass hc) {
112 cananian 1.1.2.4         // assume classhierarchy is frozen by time this is called.
113 cananian 1.1.2.4         if (clazShrink)
114 cananian 1.1.2.4             configurationSet.add
115 cananian 1.1.2.4                 ("check_with_claz_shrink_should_be_"+clazBytes);
116 cananian 1.1.2.5         else
117 cananian 1.1.2.5             configurationSet.add
118 cananian 1.1.2.5                 ("check_with_claz_shrink_not_needed");
119 cananian 1.1.2.5         configurationSet.add
120 cananian 1.1.2.5             (hashlockShrink ? "check_with_hashlock_shrink_needed" :
121 cananian 1.1.2.5              "check_with_hashlock_shrink_not_needed");
122 cananian 1.1.2.4         // end configset
123 cananian 1.1.2.1         List<HData> r = new ArrayList<HData>(super.classData(hc));
124 cananian 1.1.2.1         r.add(new DataClazTable(frame,hc,ch,cn));
125 cananian 1.1.2.1         return r;
126 cananian 1.1.2.2     }
127 cananian 1.1.2.2     // add new field to DataClaz:
128 cananian 1.1.2.2     protected ExtraClazInfo getExtraClazInfo() {
129 cananian 1.1.2.2         final ExtraClazInfo eci = super.getExtraClazInfo();
130 cananian 1.1.2.2         if (!clazShrink) return eci;
131 cananian 1.1.2.2         return new ExtraClazInfo() {
132 cananian 1.1.2.2                 public int fields_size() {
133 cananian 1.1.2.2                     return
134 cananian 1.1.2.2                         // first the superclass' fields.
135 cananian 1.1.2.2                         eci.fields_size() +
136 cananian 1.1.2.2                         // now ours.
137 cananian 1.3                             (frame.pointersAreLong() ? 8 : 4);
138 cananian 1.1.2.2                 }
139 cananian 1.1.2.2                 public Stm emit(TreeFactory tf, Frame f, HClass hc,
140 cananian 1.1.2.2                                 ClassHierarchy ch) {
141 cananian 1.1.2.2                     List<Stm> stmlist = new ArrayList<Stm>();
142 cananian 1.1.2.2                     // first the superclass' fields.
143 cananian 1.1.2.2                     Stm s = eci.emit(tf,f,hc,ch);
144 cananian 1.1.2.2                     if (s!=null) stmlist.add(s);
145 cananian 1.1.2.2                     // now ours.
146 cananian 1.1.2.2                     int num = cn.clazNumber(hc);// good thing this is complete!
147 cananian 1.1.2.2                     stmlist.add(new DATUM(tf, null, new CONST(tf, null, num)));
148 cananian 1.3                         // padding for 64-bit platforms.
149 cananian 1.3                         if (f.pointersAreLong())
150 cananian 1.3                             stmlist.add(new DATUM(tf,null,new CONST(tf, null, 0)));
151 cananian 1.1.2.2                     // ta-da!
152 cananian 1.1.2.2                     return Stm.toStm(stmlist);
153 cananian 1.1.2.2                 }
154 cananian 1.1.2.2             };
155 cananian 1.1.2.1     }
156 cananian 1.2     }