1 cananian 1.1.2.6 // InterpreterOffsetMap.java, created Sat Mar 27 17:05:09 1999 by duncan 2 cananian 1.1.2.5 // Copyright (C) 1998 Duncan Bryce <duncan@lcs.mit.edu> 3 cananian 1.1.2.5 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 duncan 1.1.2.1 package harpoon.Interpret.Tree; 5 duncan 1.1.2.1 6 cananian 1.1.2.12 import harpoon.Analysis.ClassHierarchy; 7 cananian 1.1.2.13 import harpoon.Backend.Analysis.InterfaceMethodMap; 8 duncan 1.1.2.1 import harpoon.Backend.Maps.ClassDepthMap; 9 duncan 1.1.2.1 import harpoon.Backend.Maps.MethodMap; 10 duncan 1.1.2.8 import harpoon.Backend.Maps.DefaultNameMap; 11 duncan 1.1.2.8 import harpoon.Backend.Maps.NameMap; 12 duncan 1.1.2.1 import harpoon.ClassFile.HClass; 13 duncan 1.1.2.1 import harpoon.ClassFile.HField; 14 duncan 1.1.2.1 import harpoon.ClassFile.HMethod; 15 duncan 1.1.2.1 import harpoon.Temp.Label; 16 duncan 1.1.2.1 import harpoon.Util.Util; 17 duncan 1.1.2.1 18 duncan 1.1.2.8 import java.util.Iterator; 19 duncan 1.1.2.8 import java.util.HashMap; 20 duncan 1.1.2.8 import java.util.Map; 21 pnkfelix 1.1.2.9 import java.util.Set; 22 duncan 1.1.2.1 import java.util.StringTokenizer; 23 duncan 1.1.2.1 24 duncan 1.1.2.1 /** 25 duncan 1.1.2.1 * A simple OffsetMap, used by the Tree Interpreter 26 duncan 1.1.2.1 * 27 duncan 1.1.2.1 * @author Duncan Bryce <duncan@lcs.mit.edu> 28 cananian 1.5 * @version $Id: InterpreterOffsetMap.java,v 1.5 2004/02/08 01:58:09 cananian Exp $ 29 duncan 1.1.2.1 */ 30 duncan 1.1.2.1 public class InterpreterOffsetMap extends OffsetMap { 31 duncan 1.1.2.1 32 duncan 1.1.2.1 private ClassDepthMap m_cdm; 33 duncan 1.1.2.1 private FieldMap m_fm; 34 duncan 1.1.2.8 private Map m_field = new HashMap(); 35 duncan 1.1.2.8 private Map m_labels = new HashMap(); 36 duncan 1.1.2.8 private Map m_strings = new HashMap(); 37 duncan 1.1.2.1 private HClassInfo m_hci; 38 duncan 1.1.2.1 private InterfaceMethodMap m_imm; 39 duncan 1.1.2.1 private MethodMap m_cmm; 40 duncan 1.1.2.8 private NameMap m_nm; 41 duncan 1.1.2.1 42 duncan 1.1.2.1 public InterpreterOffsetMap(ClassHierarchy ch) { 43 cananian 1.1.2.16 this(ch, new DefaultNameMap(false)); 44 duncan 1.1.2.8 } 45 duncan 1.1.2.8 46 duncan 1.1.2.8 /** Class constructor */ 47 duncan 1.1.2.8 public InterpreterOffsetMap(ClassHierarchy ch, NameMap nm) { 48 duncan 1.1.2.1 m_hci = new HClassInfo(); 49 duncan 1.1.2.8 m_hci = new HClassInfo(); 50 duncan 1.1.2.8 int max = 0, depth; 51 duncan 1.1.2.8 for (Iterator it=ch.classes().iterator();it.hasNext();){ 52 duncan 1.1.2.8 depth = m_hci.depth((HClass) it.next()); 53 duncan 1.1.2.8 max = (depth>max) ? depth : max; 54 duncan 1.1.2.8 } 55 duncan 1.1.2.8 final int maxDepth = max; 56 duncan 1.1.2.8 57 duncan 1.1.2.1 m_cmm = new MethodMap() { 58 duncan 1.1.2.1 public int methodOrder(HMethod hm) { 59 duncan 1.1.2.1 return m_hci.getMethodOffset(hm); } 60 duncan 1.1.2.1 }; 61 duncan 1.1.2.1 m_cdm = new ClassDepthMap() { 62 duncan 1.1.2.1 public int classDepth(HClass hc) { return m_hci.depth(hc); } 63 duncan 1.1.2.8 public int maxDepth() { return maxDepth; } 64 duncan 1.1.2.1 }; 65 duncan 1.1.2.1 m_fm = new FieldMap() { 66 duncan 1.1.2.1 public int fieldOrder(HField hf) { 67 duncan 1.1.2.1 return m_hci.getFieldOffset(hf); } 68 duncan 1.1.2.1 }; 69 duncan 1.1.2.8 m_imm = new InterfaceMethodMap 70 cananian 1.5 (new net.cscott.jutil.IteratorEnumerator(ch.classes().iterator())); 71 duncan 1.1.2.8 m_nm = nm; 72 duncan 1.1.2.1 } 73 duncan 1.1.2.1 74 duncan 1.1.2.1 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 75 duncan 1.1.2.1 * * 76 duncan 1.1.2.1 * Implementation of label mappings * 77 duncan 1.1.2.1 * * 78 duncan 1.1.2.1 *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 79 duncan 1.1.2.1 80 duncan 1.1.2.1 public Object decodeLabel(Label label) { 81 cananian 1.1.2.14 if (Debug.DEBUG) Debug.db("DECODING: " + label); 82 duncan 1.1.2.8 for (Iterator i = m_labels.keySet().iterator(); i.hasNext();) { 83 duncan 1.1.2.8 Object next = i.next(); 84 duncan 1.1.2.1 Label lNext = (Label)m_labels.get(next); 85 duncan 1.1.2.8 if (lNext.toString().equals(label.toString())) { 86 cananian 1.1.2.14 if (Debug.DEBUG) Debug.db("Returning: " + next); 87 duncan 1.1.2.1 return next; 88 duncan 1.1.2.8 } 89 duncan 1.1.2.8 } 90 duncan 1.1.2.8 for (Iterator i = m_strings.keySet().iterator(); i.hasNext();) { 91 duncan 1.1.2.8 Object next = i.next(); 92 duncan 1.1.2.8 Label lNext = (Label)m_strings.get(next); 93 duncan 1.1.2.8 if (lNext.toString().equals(label.toString())) { 94 cananian 1.1.2.14 if (Debug.DEBUG) Debug.db("Returning: " + next); 95 duncan 1.1.2.8 return next; 96 duncan 1.1.2.8 } 97 duncan 1.1.2.1 } 98 duncan 1.1.2.8 99 duncan 1.1.2.1 throw new Error("Label not found in map: " + label); 100 duncan 1.1.2.1 } 101 duncan 1.1.2.11 102 duncan 1.1.2.11 public Label jlClass(HClass hc) { return null; } 103 duncan 1.1.2.1 104 duncan 1.1.2.1 /** Returns the label corresponding to the specified HClass */ 105 duncan 1.1.2.1 public Label label(HClass hc) { 106 duncan 1.1.2.8 if (!m_labels.containsKey(hc)) { 107 duncan 1.1.2.8 m_labels.put(hc, new Label(m_nm.mangle(hc))); 108 duncan 1.1.2.8 } 109 duncan 1.1.2.8 return (Label)m_labels.get(hc); 110 duncan 1.1.2.1 } 111 duncan 1.1.2.1 112 duncan 1.1.2.1 /** Returns the label corresponding to the specified static field */ 113 duncan 1.1.2.1 public Label label(HField hf) { 114 cananian 1.3.2.1 assert hf.isStatic(); 115 duncan 1.1.2.8 if (!m_labels.containsKey(hf)) { 116 duncan 1.1.2.8 m_labels.put(hf, new Label(m_nm.mangle(hf))); 117 duncan 1.1.2.1 } 118 duncan 1.1.2.8 return (Label)m_labels.get(hf); 119 duncan 1.1.2.1 } 120 duncan 1.1.2.1 121 duncan 1.1.2.1 /** Returns the label corrensponding to the specified method. This 122 duncan 1.1.2.1 * method is not necessarily static */ 123 duncan 1.1.2.1 public Label label(HMethod hm) { 124 duncan 1.1.2.8 if (!m_labels.containsKey(hm)) { 125 duncan 1.1.2.8 m_labels.put(hm, new Label(m_nm.mangle(hm))); 126 duncan 1.1.2.1 } 127 duncan 1.1.2.8 return (Label)m_labels.get(hm); 128 duncan 1.1.2.1 } 129 duncan 1.1.2.1 130 duncan 1.1.2.1 /** Returns the label corresponding to the specified String constant */ 131 duncan 1.1.2.1 public Label label(String stringConstant) { 132 duncan 1.1.2.8 if (!m_strings.containsKey(stringConstant)) { 133 duncan 1.1.2.8 m_strings.put(stringConstant, 134 duncan 1.1.2.8 new Label(m_nm.mangle(stringConstant))); 135 duncan 1.1.2.1 } 136 duncan 1.1.2.8 return (Label)m_strings.get(stringConstant); 137 duncan 1.1.2.8 } 138 duncan 1.1.2.8 139 pnkfelix 1.1.2.9 public Set stringConstants() { 140 pnkfelix 1.1.2.9 return m_strings.keySet(); 141 duncan 1.1.2.8 } 142 duncan 1.1.2.8 143 duncan 1.1.2.8 public Map stringConstantMap() { 144 duncan 1.1.2.8 return m_strings; 145 duncan 1.1.2.1 } 146 duncan 1.1.2.1 147 duncan 1.1.2.1 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 148 duncan 1.1.2.1 * * 149 duncan 1.1.2.1 * Implementation of offset methods * 150 duncan 1.1.2.1 * * 151 duncan 1.1.2.1 *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 152 duncan 1.1.2.1 153 duncan 1.1.2.1 154 duncan 1.1.2.1 /** Returns the offset of the class pointer */ 155 duncan 1.1.2.8 public int clazzPtrOffset(HClass hc) { 156 cananian 1.3.2.1 assert !hc.isPrimitive() : "" + hc; 157 duncan 1.1.2.1 return -1; 158 duncan 1.1.2.1 } 159 duncan 1.1.2.1 160 duncan 1.1.2.1 /** If hc is an array type, returns the offset of its component 161 duncan 1.1.2.1 * type's class pointer */ 162 duncan 1.1.2.1 public int componentTypeOffset(HClass hc) { 163 cananian 1.3.2.1 assert hc.isArray(); 164 duncan 1.1.2.1 return -1; 165 duncan 1.1.2.1 } 166 duncan 1.1.2.1 167 duncan 1.1.2.1 /** Returns the size of the display information of the specified class */ 168 duncan 1.1.2.8 public int displaySize() { 169 duncan 1.1.2.8 return m_cdm.maxDepth(); 170 duncan 1.1.2.1 } 171 duncan 1.1.2.1 172 duncan 1.1.2.1 /** Returns the offset of the first array element if hc is an array 173 duncan 1.1.2.1 * type, otherwise generates an assertion failure */ 174 duncan 1.1.2.1 public int elementsOffset(HClass hc) { 175 cananian 1.3.2.1 assert hc.isArray(); 176 duncan 1.1.2.1 return 0; 177 duncan 1.1.2.1 } 178 duncan 1.1.2.1 179 duncan 1.1.2.1 /** Returns the offset of the first field in an object of the 180 duncan 1.1.2.1 * specified type */ 181 duncan 1.1.2.1 public int fieldsOffset(HClass hc) { 182 cananian 1.3.2.1 assert (!hc.isPrimitive()) && (!hc.isArray()); 183 duncan 1.1.2.1 return 0; 184 duncan 1.1.2.1 } 185 duncan 1.1.2.1 186 duncan 1.1.2.1 /** Returns the offset of the hashcode of the specified object */ 187 duncan 1.1.2.1 public int hashCodeOffset(HClass hc) { 188 cananian 1.3.2.1 assert !hc.isPrimitive(); 189 duncan 1.1.2.1 return -2; 190 duncan 1.1.2.1 } 191 duncan 1.1.2.1 192 duncan 1.1.2.1 /** If hc is a class type, or an interface, returns the offset from 193 duncan 1.1.2.1 * the class pointer of the pointer to implemented interfaces */ 194 duncan 1.1.2.1 public int interfaceListOffset(HClass hc) { 195 cananian 1.3.2.1 assert !hc.isPrimitive() && !hc.isArray(); 196 duncan 1.1.2.8 return -4; 197 duncan 1.1.2.1 } 198 duncan 1.1.2.1 199 duncan 1.1.2.1 /** If hc is an array type, returns the offset of its length field */ 200 duncan 1.1.2.1 public int lengthOffset(HClass hc) { 201 cananian 1.3.2.1 assert hc.isArray(); 202 duncan 1.1.2.1 return -3; 203 duncan 1.1.2.1 } 204 duncan 1.1.2.1 205 duncan 1.1.2.8 /** Returns the offset from the class pointer of this class's pointer 206 duncan 1.1.2.8 * in the display */ 207 duncan 1.1.2.8 public int offset(HClass hc) { 208 cananian 1.3.2.1 assert !hc.isPrimitive() && !hc.isInterface(); 209 duncan 1.1.2.8 return m_cdm.classDepth(hc); 210 duncan 1.1.2.8 } 211 duncan 1.1.2.8 212 duncan 1.1.2.1 /** Returns the offset from the object reference of the specified 213 duncan 1.1.2.1 * non-static field */ 214 duncan 1.1.2.1 public int offset(HField hf) { 215 cananian 1.3.2.1 assert !hf.isStatic(); 216 duncan 1.1.2.1 return m_fm.fieldOrder(hf); 217 duncan 1.1.2.1 } 218 duncan 1.1.2.1 219 duncan 1.1.2.1 /** Returns the offset from the class pointer of the specified 220 duncan 1.1.2.1 * non-static method */ 221 duncan 1.1.2.1 public int offset(HMethod hm) { 222 cananian 1.3.2.1 assert !hm.isStatic(); 223 duncan 1.1.2.1 HClass hc = hm.getDeclaringClass(); 224 duncan 1.1.2.1 225 duncan 1.1.2.4 if (hc.isInterface()) return -m_imm.methodOrder(hm) + 226 duncan 1.1.2.4 interfaceListOffset(hc) - 1; 227 duncan 1.1.2.8 else return m_cmm.methodOrder(hm) + displaySize(); 228 duncan 1.1.2.1 } 229 duncan 1.1.2.1 230 duncan 1.1.2.1 /** Returns the size of the specified class */ 231 duncan 1.1.2.1 public int size(HClass hc) { 232 duncan 1.1.2.1 int size; 233 duncan 1.1.2.1 return 1; 234 duncan 1.1.2.1 } 235 duncan 1.1.2.1 236 duncan 1.1.2.1 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 237 duncan 1.1.2.1 * * 238 duncan 1.1.2.1 * Utility methods * 239 duncan 1.1.2.1 * * 240 duncan 1.1.2.1 *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ 241 duncan 1.1.2.1 242 duncan 1.1.2.1 243 duncan 1.1.2.1 private String getFieldSignature(HField hf) 244 duncan 1.1.2.1 { 245 duncan 1.1.2.1 String token = null; 246 duncan 1.1.2.1 for (StringTokenizer st = new StringTokenizer(hf.toString()); 247 duncan 1.1.2.1 st.hasMoreTokens();) 248 duncan 1.1.2.1 { 249 duncan 1.1.2.1 token = st.nextToken(); 250 duncan 1.1.2.1 } 251 duncan 1.1.2.1 return hf.getDeclaringClass() + "_" + token; 252 duncan 1.1.2.1 } 253 duncan 1.1.2.10 254 duncan 1.1.2.10 public int wordsize() { return 1; } 255 cananian 1.1.2.13 256 cananian 1.1.2.13 // stub for old FieldMap interface 257 cananian 1.1.2.13 abstract class FieldMap { 258 cananian 1.1.2.13 public abstract int fieldOrder(HField hf); 259 cananian 1.1.2.13 } 260 duncan 1.1.2.1 } 261 duncan 1.1.2.1 262 duncan 1.1.2.1 263 cananian 1.2