1 cananian 1.1.4.1 // DataStaticFields.java, created Mon Oct 11 23:46:16 1999 by cananian 2 cananian 1.1.4.1 // Copyright (C) 1999 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.4.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.4.1 package harpoon.Backend.Runtime1; 5 cananian 1.1.4.1 6 cananian 1.1.4.1 import harpoon.Backend.Generic.Frame; 7 cananian 1.1.4.3 import harpoon.Backend.Maps.FieldMap; 8 cananian 1.1.4.1 import harpoon.Backend.Maps.NameMap; 9 cananian 1.1.4.1 import harpoon.ClassFile.HClass; 10 cananian 1.1.4.1 import harpoon.ClassFile.HDataElement; 11 cananian 1.1.4.1 import harpoon.ClassFile.HField; 12 cananian 1.1.4.1 import harpoon.IR.Tree.Exp; 13 cananian 1.1.4.1 import harpoon.IR.Tree.Stm; 14 cananian 1.1.4.3 import harpoon.IR.Tree.ALIGN; 15 cananian 1.1.4.1 import harpoon.IR.Tree.CONST; 16 cananian 1.1.4.4 import harpoon.IR.Tree.DATUM; 17 cananian 1.1.4.1 import harpoon.IR.Tree.LABEL; 18 cananian 1.1.4.1 import harpoon.IR.Tree.NAME; 19 cananian 1.1.4.1 import harpoon.IR.Tree.SEGMENT; 20 cananian 1.1.4.1 import harpoon.Util.Util; 21 cananian 1.1.4.1 22 cananian 1.1.4.1 import java.util.ArrayList; 23 cananian 1.1.4.1 import java.util.Arrays; 24 cananian 1.1.4.3 import java.util.Collections; 25 cananian 1.1.4.3 import java.util.Comparator; 26 cananian 1.1.4.1 import java.util.HashSet; 27 cananian 1.1.4.1 import java.util.List; 28 cananian 1.1.4.1 import java.util.Set; 29 cananian 1.1.4.1 /** 30 cananian 1.1.4.1 * <code>DataStaticFields</code> lays out the static fields of a class. 31 cananian 1.1.4.1 * 32 cananian 1.1.4.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 33 cananian 1.5 * @version $Id: DataStaticFields.java,v 1.5 2003/10/21 02:11:02 cananian Exp $ 34 cananian 1.1.4.1 */ 35 cananian 1.1.4.1 public class DataStaticFields extends Data { 36 cananian 1.1.4.1 final NameMap m_nm; 37 cananian 1.1.4.3 final FieldMap m_fm; 38 cananian 1.1.4.1 39 cananian 1.1.4.1 /** Creates a <code>DataStaticFields</code>. */ 40 cananian 1.1.4.1 public DataStaticFields(Frame f, HClass hc) { 41 cananian 1.1.4.1 super("static-fields", hc, f); 42 cananian 1.1.4.5 this.m_nm = f.getRuntime().getNameMap(); 43 cananian 1.1.4.3 // note that technically this is a *class* field map, and so 44 cananian 1.1.4.3 // we can't be sure that it will work on static fields. but 45 cananian 1.1.4.3 // in fact, we wrote the code, so we know it will. Slight 46 cananian 1.1.4.3 // violation of abstraction, but it makes everything more 47 cananian 1.1.4.3 // maintainable *not* to duplicate the code here. 48 cananian 1.1.4.5 this.m_fm = ((TreeBuilder)f.getRuntime().getTreeBuilder()).cfm; 49 cananian 1.5 this.root = build(hc, f.pointersAreLong()); 50 cananian 1.1.4.1 } 51 cananian 1.5 private HDataElement build(HClass hc, boolean pointersAreLong) { 52 cananian 1.1.4.3 HField[] fields = (HField[]) hc.getDeclaredFields().clone(); 53 cananian 1.1.4.3 // first, sort fields by size to pack 'em in as tight as we can. 54 cananian 1.1.4.3 Collections.sort(Arrays.asList(fields), new Comparator() { 55 cananian 1.1.4.3 public int compare(Object o1, Object o2) { 56 cananian 1.1.4.3 return m_fm.fieldSize((HField)o1) - m_fm.fieldSize((HField)o2); 57 cananian 1.1.4.3 } 58 cananian 1.1.4.3 }); 59 cananian 1.1.4.3 List stmlist = new ArrayList(2+3*fields.length/*at most*/); 60 cananian 1.1.4.1 // first do static fields with non-primitive type 61 cananian 1.1.4.1 stmlist.add(new SEGMENT(tf, null, SEGMENT.STATIC_OBJECTS)); 62 cananian 1.5 stmlist.add(new ALIGN(tf, null, // align pointer fields to pointer size 63 cananian 1.5 pointersAreLong ? 8 : 4)); 64 cananian 1.1.4.1 for (int i=0; i<fields.length; i++) { 65 cananian 1.1.4.1 if (!fields[i].isStatic() || fields[i].getType().isPrimitive()) 66 cananian 1.1.4.1 continue; 67 cananian 1.1.4.1 stmlist.add(new LABEL(tf, null, m_nm.label(fields[i]), true)); 68 cananian 1.1.4.4 stmlist.add(_DATUM(new CONST(tf, null))); // null pointer. 69 cananian 1.1.4.1 } 70 cananian 1.1.4.1 // next do static fields with primitive types 71 cananian 1.1.4.1 stmlist.add(new SEGMENT(tf, null, SEGMENT.STATIC_PRIMITIVES)); 72 cananian 1.1.4.1 for (int i=0; i<fields.length; i++) { 73 cananian 1.1.4.1 if (!fields[i].isStatic() || !fields[i].getType().isPrimitive()) 74 cananian 1.1.4.1 continue; 75 cananian 1.1.4.3 // align to field size. 76 cananian 1.1.4.3 stmlist.add(new ALIGN(tf, null, m_fm.fieldSize(fields[i]))); 77 cananian 1.1.4.1 stmlist.add(new LABEL(tf, null, m_nm.label(fields[i]), true)); 78 cananian 1.1.4.4 stmlist.add(_DATUM(fieldInitializer(fields[i]))); 79 cananian 1.1.4.1 } 80 cananian 1.1.4.1 return (HDataElement) Stm.toStm(stmlist); 81 cananian 1.1.4.1 } 82 cananian 1.1.4.1 Exp fieldInitializer(HField f) { 83 cananian 1.1.4.1 HClass ty = f.getType(); 84 cananian 1.3.2.1 assert ty.isPrimitive(); 85 cananian 1.1.4.1 Object cvo = f.getConstant(); 86 cananian 1.1.4.1 if (ty==HClass.Int) 87 cananian 1.1.4.1 return new CONST(tf, null, (int) 88 cananian 1.1.4.1 (cvo==null?0:((Integer)cvo).intValue())); 89 cananian 1.1.4.1 if (ty==HClass.Long) 90 cananian 1.1.4.1 return new CONST(tf, null, (long) 91 cananian 1.1.4.1 (cvo==null?0:((Long)cvo).longValue())); 92 cananian 1.1.4.1 if (ty==HClass.Float) 93 cananian 1.1.4.1 return new CONST(tf, null, (float) 94 cananian 1.1.4.1 (cvo==null?0:((Float)cvo).floatValue())); 95 cananian 1.1.4.1 if (ty==HClass.Double) 96 cananian 1.1.4.1 return new CONST(tf, null, (double) 97 cananian 1.1.4.1 (cvo==null?0:((Double)cvo).doubleValue())); 98 cananian 1.1.4.2 // sub-integer types represented by Integer wrapped values. 99 cananian 1.1.4.1 if (ty==HClass.Boolean) 100 cananian 1.1.4.1 return new CONST(tf, null, 8, false, 101 cananian 1.1.4.2 (cvo==null?0:((Number)cvo).intValue())); 102 cananian 1.1.4.1 if (ty==HClass.Byte) 103 cananian 1.1.4.1 return new CONST(tf, null, 8, true, 104 cananian 1.1.4.2 (cvo==null?0:((Number)cvo).intValue())); 105 cananian 1.1.4.1 if (ty==HClass.Char) 106 cananian 1.1.4.1 return new CONST(tf, null, 16, false, 107 cananian 1.1.4.2 (cvo==null?0:((Number)cvo).intValue())); 108 cananian 1.1.4.1 if (ty==HClass.Short) 109 cananian 1.1.4.1 return new CONST(tf, null, 16, true, 110 cananian 1.1.4.2 (cvo==null?0:((Number)cvo).intValue())); 111 cananian 1.1.4.1 throw new Error("Unknown primitive type"); 112 cananian 1.1.4.1 } 113 cananian 1.2 }