1 cananian 1.1.2.1 // DataReflection1.java, created Sat Oct 16 13:43:17 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.Runtime1; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.Analysis.ClassHierarchy; 7 cananian 1.1.2.1 import harpoon.Backend.Generic.Frame; 8 cananian 1.1.2.1 import harpoon.Backend.Generic.Runtime.ObjectBuilder.ObjectInfo; 9 cananian 1.1.2.1 import harpoon.Backend.Generic.Runtime.ObjectBuilder; 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.HDataElement; 13 cananian 1.1.2.1 import harpoon.ClassFile.HField; 14 cananian 1.1.2.1 import harpoon.ClassFile.HMethod; 15 cananian 1.1.2.1 import harpoon.IR.Tree.Stm; 16 cananian 1.1.2.1 import harpoon.IR.Tree.TreeFactory; 17 cananian 1.1.2.2 import harpoon.IR.Tree.ALIGN; 18 cananian 1.1.2.1 import harpoon.IR.Tree.CONST; 19 cananian 1.1.2.1 import harpoon.IR.Tree.LABEL; 20 cananian 1.1.2.1 import harpoon.IR.Tree.SEGMENT; 21 cananian 1.1.2.1 import harpoon.Temp.Label; 22 cananian 1.1.2.1 23 cananian 1.1.2.1 import java.util.ArrayList; 24 cananian 1.1.2.1 import java.util.Collections; 25 cananian 1.1.2.1 import java.util.Comparator; 26 cananian 1.1.2.1 import java.util.Iterator; 27 cananian 1.1.2.1 import java.util.List; 28 cananian 1.1.2.1 /** 29 cananian 1.1.2.1 * <code>DataReflection1</code> creates tables which the JNI interface 30 cananian 1.1.2.1 * will use. This includes:<OL> 31 cananian 1.1.2.1 * <LI>a table to map class names to <code>java.lang.Class</code> objects, 32 cananian 1.1.2.1 * sorted in order of the UTF-8 encodings of the class names. 33 cananian 1.1.2.6 * (begins at <code>name2class_start</code>, ends at 34 cananian 1.1.2.6 * <code>name2class_end</code>) 35 cananian 1.1.2.1 * <LI>a table to map <code>java.lang.Class</code> objects to class 36 cananian 1.1.2.1 * information structures, sorted in order of the (non-relocatable) 37 cananian 1.1.2.1 * <code>Class</code> object address. 38 cananian 1.1.2.6 * (begins at <code>class2info_start</code>, ends at 39 cananian 1.1.2.6 * <code>class2info_end</code>) 40 cananian 1.1.2.1 * <LI>UTF-8 encoded class name strings, used by the first table as 41 cananian 1.1.2.1 * well as by the class information structures. 42 cananian 1.1.2.1 * <LI>Static <Code>java.lang.Class</code> objects. As the JDK dictates, 43 cananian 1.1.2.1 * these contain no actual class data; however, table #2 above can 44 cananian 1.1.2.1 * be keyed by the object address to fetch the actual class information 45 cananian 1.1.2.1 * structures. 46 cananian 1.1.2.1 * </OL> 47 cananian 1.1.2.1 * 48 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 49 cananian 1.6 * @version $Id: DataReflection1.java,v 1.6 2004/02/08 03:20:58 cananian Exp $ 50 cananian 1.1.2.1 */ 51 cananian 1.1.2.1 public class DataReflection1 extends Data { 52 cananian 1.1.2.1 final NameMap m_nm; 53 cananian 1.1.2.1 final ObjectBuilder m_ob; 54 cananian 1.1.2.1 55 cananian 1.1.2.1 /** Creates a <code>DataReflection1</code>. */ 56 cananian 1.1.2.1 public DataReflection1(Frame f, HClass hc, ClassHierarchy ch) { 57 cananian 1.1.2.1 super("reflection-data-1", hc, f); 58 cananian 1.1.2.9 this.m_nm = f.getRuntime().getNameMap(); 59 cananian 1.1.2.1 this.m_ob = ((Runtime) f.getRuntime()).ob; 60 cananian 1.1.2.1 // only build one of these (so we can make sure the 61 cananian 1.1.2.1 // table is properly sorted); wait until hc is 62 cananian 1.1.2.1 // java.lang.Object 63 cananian 1.1.2.5 this.root = (hc==linker.forName("java.lang.Object")) ? 64 cananian 1.1.2.1 build(ch) : null; 65 cananian 1.1.2.1 } 66 cananian 1.1.2.1 private HDataElement build(ClassHierarchy ch) { 67 cananian 1.1.2.1 // okay, some preliminaries first: build properly sorted list of 68 cananian 1.1.2.1 // classes. 69 cananian 1.1.2.1 List sorted = new ArrayList(ch.classes()); 70 cananian 1.1.2.1 Collections.sort(sorted, new Comparator() { 71 cananian 1.1.2.1 public int compare(Object o1, Object o2) { 72 cananian 1.1.2.1 // compare two classes by ordering the UTF-8 encodings of 73 cananian 1.1.2.1 // their names. 74 cananian 1.1.2.1 byte[] b1 = toUTF8(((HClass)o1).getName().replace('.','/')); 75 cananian 1.1.2.1 byte[] b2 = toUTF8(((HClass)o2).getName().replace('.','/')); 76 cananian 1.1.2.1 for (int i=0; i<b1.length && i<b2.length; i++) 77 cananian 1.1.2.1 if (b1[i] != b2[i]) 78 cananian 1.1.2.1 // ack. we want an unsigned comparison 79 cananian 1.1.2.1 return (((int)b1[i])&0xFF) - (((int)b2[i])&0xFF); 80 cananian 1.1.2.1 // okay, they're equal, up to minlen. 81 cananian 1.1.2.1 return b1.length - b2.length; 82 cananian 1.1.2.1 } 83 cananian 1.1.2.1 }); 84 cananian 1.1.2.1 // yay, team. we've got a properly sorted list. 85 cananian 1.1.2.1 86 cananian 1.1.2.1 List stmlist = new ArrayList(6); 87 cananian 1.1.2.1 // change to table data segment. 88 cananian 1.1.2.1 stmlist.add(new SEGMENT(tf, null, SEGMENT.REFLECTION_DATA)); 89 cananian 1.1.2.1 // build class name string -> class object table. 90 cananian 1.1.2.1 stmlist.add(buildStr2Class(sorted)); 91 cananian 1.1.2.1 // build class object -> class info table. 92 cananian 1.1.2.1 stmlist.add(buildClass2Info(sorted)); 93 cananian 1.1.2.1 // build class name strings 94 cananian 1.1.2.1 stmlist.add(buildStrings(sorted)); 95 cananian 1.1.2.1 // change to object data segment. 96 cananian 1.1.2.1 stmlist.add(new SEGMENT(tf, null, SEGMENT.REFLECTION_OBJECTS)); 97 cananian 1.1.2.1 // build actual class objects 98 cananian 1.1.2.1 stmlist.add(buildClassObjects(sorted)); 99 cananian 1.1.2.1 // yay, done. 100 cananian 1.1.2.1 return (HDataElement) Stm.toStm(stmlist); 101 cananian 1.1.2.1 } 102 cananian 1.1.2.1 private Stm buildStr2Class(List sorted) { 103 cananian 1.4 Label ls, le; 104 cananian 1.1.2.2 List stmlist = new ArrayList(3+2*sorted.size()); 105 cananian 1.1.2.1 // make a sorted table mapping name strings to class objects. 106 cananian 1.4 stmlist.add(new ALIGN(tf, null, 8)); // align table to double-word boundary 107 cananian 1.1.2.1 stmlist.add(new LABEL(tf, null, 108 cananian 1.4 ls = new Label(m_nm.c_function_name 109 cananian 1.4 ("name2class_start")), true)); 110 cananian 1.6 for (Object hcO : sorted) { 111 cananian 1.6 HClass hc = (HClass) hcO; 112 cananian 1.1.2.4 stmlist.add(_DATUM(m_nm.label(hc, "namestr"))); 113 cananian 1.1.2.4 stmlist.add(_DATUM(m_nm.label(hc, "classobj"))); 114 cananian 1.1.2.1 } 115 cananian 1.1.2.1 stmlist.add(new LABEL(tf, null, 116 cananian 1.4 le = new Label(m_nm.c_function_name 117 cananian 1.4 ("name2class_end")), true)); 118 cananian 1.4 // add two bogus words to keep gcc from putting class2info_end into 119 cananian 1.4 // the BSS segment when compiling with PreciseC and NO_SECTION_SUPPORT 120 cananian 1.4 stmlist.add(_DATUM(ls)); 121 cananian 1.4 stmlist.add(_DATUM(le)); 122 cananian 1.4 // okay, done now. 123 cananian 1.1.2.1 return Stm.toStm(stmlist); 124 cananian 1.1.2.1 } 125 cananian 1.1.2.1 private Stm buildClass2Info(List sorted) { 126 cananian 1.4 Label ls, le; 127 cananian 1.1.2.2 List stmlist = new ArrayList(3+2*sorted.size()); 128 cananian 1.1.2.1 // make a sorted table mapping class objects to class info structures. 129 cananian 1.5 stmlist.add(new ALIGN(tf, null, 8)); // align table to double-word boundary 130 cananian 1.1.2.1 stmlist.add(new LABEL(tf, null, 131 cananian 1.4 ls = new Label(m_nm.c_function_name 132 cananian 1.4 ("class2info_start")), true)); 133 cananian 1.6 for (Object hcO : sorted) { 134 cananian 1.6 HClass hc = (HClass) hcO; 135 cananian 1.1.2.4 stmlist.add(_DATUM(m_nm.label(hc, "classobj"))); 136 cananian 1.1.2.4 stmlist.add(_DATUM(m_nm.label(hc, "classinfo"))); 137 cananian 1.1.2.1 } 138 cananian 1.1.2.1 stmlist.add(new LABEL(tf, null, 139 cananian 1.4 le = new Label(m_nm.c_function_name 140 cananian 1.4 ("class2info_end")), true)); 141 cananian 1.4 // add two bogus words to keep gcc from putting class2info_end into 142 cananian 1.4 // the BSS segment when compiling with PreciseC and NO_SECTION_SUPPORT 143 cananian 1.4 stmlist.add(_DATUM(ls)); 144 cananian 1.4 stmlist.add(_DATUM(le)); 145 cananian 1.4 // okay, done now. 146 cananian 1.1.2.1 return Stm.toStm(stmlist); 147 cananian 1.1.2.1 } 148 cananian 1.1.2.1 private Stm buildStrings(List sorted) { 149 cananian 1.1.2.3 List stmlist = new ArrayList(1+2*sorted.size()); 150 cananian 1.1.2.1 // build actual c-style string data from UTF-8 encoded class name 151 cananian 1.6 for (Object hcO : sorted) { 152 cananian 1.6 HClass hc = (HClass) hcO; 153 cananian 1.1.2.1 stmlist.add(new LABEL(tf, null, m_nm.label(hc, "namestr"), true)); 154 cananian 1.1.2.3 stmlist.add(emitUtf8String(hc.getName().replace('.','/'))); 155 cananian 1.1.2.1 } 156 cananian 1.1.2.2 // pad out to a full word after the last byte. 157 cananian 1.1.2.2 stmlist.add(new ALIGN(tf, null, 4)); 158 cananian 1.1.2.1 return Stm.toStm(stmlist); 159 cananian 1.1.2.1 } 160 cananian 1.1.2.1 private Stm buildClassObjects(List sorted) { 161 cananian 1.1.2.1 List stmlist = new ArrayList(sorted.size()); 162 cananian 1.1.2.5 final HClass HCclass = linker.forName("java.lang.Class"); 163 cananian 1.1.2.1 for (Iterator it=sorted.iterator(); it.hasNext(); ) { 164 cananian 1.1.2.1 final HClass hc = (HClass) it.next(); 165 cananian 1.1.2.1 // make an ObjectInfo -- that doesn't actual provide any info. 166 cananian 1.1.2.1 ObjectInfo info = new ObjectInfo() { 167 cananian 1.1.2.1 public HClass type() { return HCclass; } 168 cananian 1.1.2.1 public Label label() { return m_nm.label(hc, "classobj"); } 169 cananian 1.1.2.1 public Object get(HField hf) { 170 cananian 1.3 if (hf.getDeclaringClass().equals(HCclass) && 171 cananian 1.3 (hf.getName().equals("signers") || 172 cananian 1.3 hf.getName().equals("pd"))) 173 cananian 1.3 return null; 174 cananian 1.3 throw new Error("Unknown field of Class object: "+hf); 175 cananian 1.1.2.1 } 176 cananian 1.1.2.1 }; 177 cananian 1.1.2.1 stmlist.add(m_ob.buildObject(tf, info, true)); 178 cananian 1.1.2.1 } 179 cananian 1.1.2.1 return Stm.toStm(stmlist); 180 cananian 1.1.2.1 } 181 cananian 1.2 }