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 }