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     }