Location.java revision 9883:903a2e023ffb
1/* 2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25package sun.jvm.hotspot.code; 26 27import java.io.*; 28import java.util.*; 29 30import sun.jvm.hotspot.runtime.*; 31import sun.jvm.hotspot.types.*; 32import sun.jvm.hotspot.utilities.*; 33 34/** <P> A Location describes a concrete machine variable location 35 (such as integer or floating point register or a stack-held 36 variable). Used when generating debug-information for 37 nmethods. </P> 38 39 <P> Encoding: </P> 40 <PRE> 41 bits: 42 Type: [3..0] 43 Where: [4] 44 Offset: [31..5] 45 </PRE> 46*/ 47 48public class Location { 49 static { 50 VM.registerVMInitializedObserver(new Observer() { 51 public void update(Observable o, Object data) { 52 initialize(VM.getVM().getTypeDataBase()); 53 } 54 }); 55 } 56 57 private static void initialize(TypeDataBase db) { 58 if (Assert.ASSERTS_ENABLED) { 59 Assert.that(!VM.getVM().isCore(), "Debug info not used in core build"); 60 } 61 62 OFFSET_MASK = db.lookupIntConstant("Location::OFFSET_MASK").intValue(); 63 OFFSET_SHIFT = db.lookupIntConstant("Location::OFFSET_SHIFT").intValue(); 64 TYPE_MASK = db.lookupIntConstant("Location::TYPE_MASK").intValue(); 65 TYPE_SHIFT = db.lookupIntConstant("Location::TYPE_SHIFT").intValue(); 66 WHERE_MASK = db.lookupIntConstant("Location::WHERE_MASK").intValue(); 67 WHERE_SHIFT = db.lookupIntConstant("Location::WHERE_SHIFT").intValue(); 68 69 // Location::Type constants 70 TYPE_NORMAL = db.lookupIntConstant("Location::normal").intValue(); 71 TYPE_OOP = db.lookupIntConstant("Location::oop").intValue(); 72 TYPE_NARROWOOP = db.lookupIntConstant("Location::narrowoop").intValue(); 73 TYPE_INT_IN_LONG = db.lookupIntConstant("Location::int_in_long").intValue(); 74 TYPE_LNG = db.lookupIntConstant("Location::lng").intValue(); 75 TYPE_FLOAT_IN_DBL = db.lookupIntConstant("Location::float_in_dbl").intValue(); 76 TYPE_DBL = db.lookupIntConstant("Location::dbl").intValue(); 77 TYPE_ADDR = db.lookupIntConstant("Location::addr").intValue(); 78 TYPE_INVALID = db.lookupIntConstant("Location::invalid").intValue(); 79 80 // Location::Where constants 81 WHERE_ON_STACK = db.lookupIntConstant("Location::on_stack").intValue(); 82 WHERE_IN_REGISTER = db.lookupIntConstant("Location::in_register").intValue(); 83 } 84 85 private int value; 86 87 // type safe enum for "Where" 88 public static class Where { 89 public static final Where ON_STACK = new Where("on_stack"); 90 public static final Where IN_REGISTER = new Where("in_register"); 91 92 private Where(String value) { 93 this.value = value; 94 } 95 96 public String toString() { 97 return value; 98 } 99 100 private String value; 101 102 public int getValue() { 103 if (this == ON_STACK) { 104 return WHERE_ON_STACK; 105 } else if (this == IN_REGISTER) { 106 return WHERE_IN_REGISTER; 107 } else { 108 throw new RuntimeException("should not reach here"); 109 } 110 } 111 } 112 113 // type safe enum for "Type" 114 public static class Type { 115 /** Ints, floats, double halves */ 116 public static final Type NORMAL = new Type("normal"); 117 /** Oop (please GC me!) */ 118 public static final Type OOP = new Type("oop"); 119 /** NarrowOop (please GC me!) */ 120 public static final Type NARROWOOP = new Type("narrowoop"); 121 /** Long held in one register */ 122 public static final Type INT_IN_LONG = new Type("int_in_long"); 123 /** Long held in one register */ 124 public static final Type LNG = new Type("lng"); 125 /** Float held in double register */ 126 public static final Type FLOAT_IN_DBL = new Type("float_in_dbl"); 127 /** Double held in one register */ 128 public static final Type DBL = new Type("dbl"); 129 /** JSR return address */ 130 public static final Type ADDR = new Type("addr"); 131 /** Invalid location */ 132 public static final Type INVALID = new Type("invalid"); 133 134 private Type(String value) { 135 this.value = value; 136 } 137 private String value; 138 139 public String toString() { 140 return value; 141 } 142 143 public int getValue() { 144 if (this == NORMAL) { 145 return TYPE_NORMAL; 146 } else if (this == OOP) { 147 return TYPE_OOP; 148 } else if (this == NARROWOOP) { 149 return TYPE_NARROWOOP; 150 } else if (this == INT_IN_LONG) { 151 return TYPE_INT_IN_LONG; 152 } else if (this == LNG) { 153 return TYPE_LNG; 154 } else if (this == FLOAT_IN_DBL) { 155 return TYPE_FLOAT_IN_DBL; 156 } else if (this == DBL) { 157 return TYPE_DBL; 158 } else if (this == ADDR) { 159 return TYPE_ADDR; 160 } else if (this == INVALID) { 161 return TYPE_INVALID; 162 } else { 163 throw new RuntimeException("should not reach here"); 164 } 165 } 166 } 167 168 private static int OFFSET_MASK; 169 private static int OFFSET_SHIFT; 170 private static int TYPE_MASK; 171 private static int TYPE_SHIFT; 172 private static int WHERE_MASK; 173 private static int WHERE_SHIFT; 174 175 // constants in Type enum 176 private static int TYPE_NORMAL; 177 private static int TYPE_OOP; 178 private static int TYPE_NARROWOOP; 179 private static int TYPE_INT_IN_LONG; 180 private static int TYPE_LNG; 181 private static int TYPE_FLOAT_IN_DBL; 182 private static int TYPE_DBL; 183 private static int TYPE_ADDR; 184 private static int TYPE_INVALID; 185 186 // constants in Where enum 187 private static int WHERE_ON_STACK; 188 private static int WHERE_IN_REGISTER; 189 190 /** Create a bit-packed Location */ 191 Location(Where where, Type type, int offset) { 192 setWhere(where); 193 setType(type); 194 setOffset(offset); 195 } 196 197 public Where getWhere() { 198 int where = (value & WHERE_MASK) >> WHERE_SHIFT; 199 if (where == WHERE_ON_STACK) { 200 return Where.ON_STACK; 201 } else if (where == WHERE_IN_REGISTER) { 202 return Where.IN_REGISTER; 203 } else { 204 throw new RuntimeException("should not reach here"); 205 } 206 } 207 208 public Type getType() { 209 int type = (value & TYPE_MASK) >> TYPE_SHIFT; 210 if (type == TYPE_NORMAL) { 211 return Type.NORMAL; 212 } else if (type == TYPE_OOP) { 213 return Type.OOP; 214 } else if (type == TYPE_NARROWOOP) { 215 return Type.NARROWOOP; 216 } else if (type == TYPE_INT_IN_LONG) { 217 return Type.INT_IN_LONG; 218 } else if (type == TYPE_LNG) { 219 return Type.LNG; 220 } else if (type == TYPE_FLOAT_IN_DBL) { 221 return Type.FLOAT_IN_DBL; 222 } else if (type == TYPE_DBL) { 223 return Type.DBL; 224 } else if (type == TYPE_ADDR) { 225 return Type.ADDR; 226 } else if (type == TYPE_INVALID) { 227 return Type.INVALID; 228 } else { 229 throw new RuntimeException("should not reach here"); 230 } 231 } 232 233 public short getOffset() { 234 return (short) ((value & OFFSET_MASK) >> OFFSET_SHIFT); 235 } 236 237 public boolean isRegister() { 238 return getWhere() == Where.IN_REGISTER; 239 } 240 241 public boolean isStack() { 242 return getWhere() == Where.ON_STACK; 243 } 244 245 public boolean holdsOop() { 246 return getType() == Type.OOP; 247 } 248 249 public boolean holdsNarrowOop() { 250 return getType() == Type.NARROWOOP; 251 } 252 253 public boolean holdsInt() { 254 return getType() == Type.INT_IN_LONG; 255 } 256 257 public boolean holdsLong() { 258 return getType() == Type.LNG; 259 } 260 261 public boolean holdsFloat() { 262 return getType() == Type.FLOAT_IN_DBL; 263 } 264 265 public boolean holdsDouble() { 266 return getType() == Type.DBL; 267 } 268 269 public boolean holdsAddr() { 270 return getType() == Type.ADDR; 271 } 272 273 public boolean isIllegal() { 274 return getType() == Type.INVALID; 275 } 276 277 public int getStackOffset() { 278 if (Assert.ASSERTS_ENABLED) { 279 Assert.that(getWhere() == Where.ON_STACK, "wrong Where"); 280 } 281 return getOffset() * (int)VM.getVM().getIntSize(); 282 } 283 284 public int getRegisterNumber() { 285 if (Assert.ASSERTS_ENABLED) { 286 Assert.that(getWhere() == Where.IN_REGISTER, "wrong Where"); 287 } 288 return getOffset(); 289 } 290 291 public void print() { 292 printOn(System.out); 293 } 294 295 public void printOn(PrintStream tty) { 296 tty.print("Value " + value + ", "); 297 if (isIllegal()) { 298 tty.print("Illegal"); 299 } else { 300 Where w = getWhere(); 301 if (w == Where.ON_STACK) { 302 tty.print("stack[" + getStackOffset() + "]"); 303 } else if (w == Where.IN_REGISTER) { 304 tty.print("reg " + getRegisterNumber()); 305 } 306 307 Type type = getType(); 308 if (type == Type.NORMAL) { 309 } else if (type == Type.OOP) { 310 tty.print(",oop"); 311 } else if (type == Type.NARROWOOP) { 312 tty.print(",narrowoop"); 313 } else if (type == Type.INT_IN_LONG) { 314 tty.print(",int"); 315 } else if (type == Type.LNG) { 316 tty.print(",long"); 317 } else if (type == Type.FLOAT_IN_DBL) { 318 tty.print(",float"); 319 } else if (type == Type.DBL) { 320 tty.print(",double"); 321 } else if (type == Type.ADDR) { 322 tty.print(",address"); 323 } else if (type == Type.INVALID) { 324 tty.print(",invalid"); 325 } 326 } 327 } 328 329 /** Serialization of debugging information */ 330 public Location(DebugInfoReadStream stream) { 331 value = stream.readInt(); 332 } 333 334 // FIXME: not yet implementable 335 // void write_on(DebugInfoWriteStream* stream); 336 337 338 //----------------------------------------------------------------------------- 339 // Internals only below this point 340 // 341 342 private void setWhere(Where where) { 343 value |= ((where.getValue() << WHERE_SHIFT) & WHERE_MASK); 344 } 345 346 private void setType(Type type) { 347 value |= ((type.getValue() << TYPE_SHIFT) & TYPE_MASK); 348 } 349 350 private void setOffset(int offset) { 351 value |= ((offset << OFFSET_SHIFT) & OFFSET_MASK); 352 } 353} 354