comparison agent/src/share/classes/sun/jvm/hotspot/code/Location.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children cecd8eb4e0ca
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2000-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 package sun.jvm.hotspot.code;
26
27 import java.io.*;
28 import java.util.*;
29
30 import sun.jvm.hotspot.runtime.*;
31 import sun.jvm.hotspot.types.*;
32 import 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 Where: [15]
43 Type: [14..12]
44 Offset: [11..0]
45 </PRE>
46 */
47
48 public 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_INT_IN_LONG = db.lookupIntConstant("Location::int_in_long").intValue();
73 TYPE_LNG = db.lookupIntConstant("Location::lng").intValue();
74 TYPE_FLOAT_IN_DBL = db.lookupIntConstant("Location::float_in_dbl").intValue();
75 TYPE_DBL = db.lookupIntConstant("Location::dbl").intValue();
76 TYPE_ADDR = db.lookupIntConstant("Location::addr").intValue();
77 TYPE_INVALID = db.lookupIntConstant("Location::invalid").intValue();
78
79 // Location::Where constants
80 WHERE_ON_STACK = db.lookupIntConstant("Location::on_stack").intValue();
81 WHERE_IN_REGISTER = db.lookupIntConstant("Location::in_register").intValue();
82 }
83
84 private int value;
85
86 // type safe enum for "Where"
87 public static class Where {
88 public static final Where ON_STACK = new Where("on_stack");
89 public static final Where IN_REGISTER = new Where("in_register");
90
91 private Where(String value) {
92 this.value = value;
93 }
94
95 public String toString() {
96 return value;
97 }
98
99 private String value;
100
101 public int getValue() {
102 if (this == ON_STACK) {
103 return WHERE_ON_STACK;
104 } else if (this == IN_REGISTER) {
105 return WHERE_IN_REGISTER;
106 } else {
107 throw new RuntimeException("should not reach here");
108 }
109 }
110 }
111
112 // type safe enum for "Type"
113 public static class Type {
114 /** Ints, floats, double halves */
115 public static final Type NORMAL = new Type("normal");
116 /** Oop (please GC me!) */
117 public static final Type OOP = new Type("oop");
118 /** Long held in one register */
119 public static final Type INT_IN_LONG = new Type("int_in_long");
120 /** Long held in one register */
121 public static final Type LNG = new Type("lng");
122 /** Float held in double register */
123 public static final Type FLOAT_IN_DBL = new Type("float_in_dbl");
124 /** Double held in one register */
125 public static final Type DBL = new Type("dbl");
126 /** JSR return address */
127 public static final Type ADDR = new Type("addr");
128 /** Invalid location */
129 public static final Type INVALID = new Type("invalid");
130
131 private Type(String value) {
132 this.value = value;
133 }
134 private String value;
135
136 public String toString() {
137 return value;
138 }
139
140 public int getValue() {
141 if (this == NORMAL) {
142 return TYPE_NORMAL;
143 } else if (this == OOP) {
144 return TYPE_OOP;
145 } else if (this == INT_IN_LONG) {
146 return TYPE_INT_IN_LONG;
147 } else if (this == LNG) {
148 return TYPE_LNG;
149 } else if (this == FLOAT_IN_DBL) {
150 return TYPE_FLOAT_IN_DBL;
151 } else if (this == DBL) {
152 return TYPE_DBL;
153 } else if (this == ADDR) {
154 return TYPE_ADDR;
155 } else if (this == INVALID) {
156 return TYPE_INVALID;
157 } else {
158 throw new RuntimeException("should not reach here");
159 }
160 }
161 }
162
163 private static int OFFSET_MASK;
164 private static int OFFSET_SHIFT;
165 private static int TYPE_MASK;
166 private static int TYPE_SHIFT;
167 private static int WHERE_MASK;
168 private static int WHERE_SHIFT;
169
170 // constants in Type enum
171 private static int TYPE_NORMAL;
172 private static int TYPE_OOP;
173 private static int TYPE_INT_IN_LONG;
174 private static int TYPE_LNG;
175 private static int TYPE_FLOAT_IN_DBL;
176 private static int TYPE_DBL;
177 private static int TYPE_ADDR;
178 private static int TYPE_INVALID;
179
180 // constants in Where enum
181 private static int WHERE_ON_STACK;
182 private static int WHERE_IN_REGISTER;
183
184 /** Create a bit-packed Location */
185 Location(Where where, Type type, int offset) {
186 setWhere(where);
187 setType(type);
188 setOffset(offset & 0x0000FFFF);
189 }
190
191 public Where getWhere() {
192 int where = (value & WHERE_MASK) >> WHERE_SHIFT;
193 if (where == WHERE_ON_STACK) {
194 return Where.ON_STACK;
195 } else if (where == WHERE_IN_REGISTER) {
196 return Where.IN_REGISTER;
197 } else {
198 throw new RuntimeException("should not reach here");
199 }
200 }
201
202 public Type getType() {
203 int type = (value & TYPE_MASK) >> TYPE_SHIFT;
204 if (type == TYPE_NORMAL) {
205 return Type.NORMAL;
206 } else if (type == TYPE_OOP) {
207 return Type.OOP;
208 } else if (type == TYPE_INT_IN_LONG) {
209 return Type.INT_IN_LONG;
210 } else if (type == TYPE_LNG) {
211 return Type.LNG;
212 } else if (type == TYPE_FLOAT_IN_DBL) {
213 return Type.FLOAT_IN_DBL;
214 } else if (type == TYPE_DBL) {
215 return Type.DBL;
216 } else if (type == TYPE_ADDR) {
217 return Type.ADDR;
218 } else if (type == TYPE_INVALID) {
219 return Type.INVALID;
220 } else {
221 throw new RuntimeException("should not reach here");
222 }
223 }
224
225 public short getOffset() {
226 return (short) ((value & OFFSET_MASK) >> OFFSET_SHIFT);
227 }
228
229 public boolean isRegister() {
230 return getWhere() == Where.IN_REGISTER;
231 }
232
233 public boolean isStack() {
234 return getWhere() == Where.ON_STACK;
235 }
236
237 public boolean holdsOop() {
238 return getType() == Type.OOP;
239 }
240
241 public boolean holdsInt() {
242 return getType() == Type.INT_IN_LONG;
243 }
244
245 public boolean holdsLong() {
246 return getType() == Type.LNG;
247 }
248
249 public boolean holdsFloat() {
250 return getType() == Type.FLOAT_IN_DBL;
251 }
252
253 public boolean holdsDouble() {
254 return getType() == Type.DBL;
255 }
256
257 public boolean holdsAddr() {
258 return getType() == Type.ADDR;
259 }
260
261 public boolean isIllegal() {
262 return getType() == Type.INVALID;
263 }
264
265 public int getStackOffset() {
266 if (Assert.ASSERTS_ENABLED) {
267 Assert.that(getWhere() == Where.ON_STACK, "wrong Where");
268 }
269 return getOffset() << VM.getVM().getLogAddressSize();
270 }
271
272 public int getRegisterNumber() {
273 if (Assert.ASSERTS_ENABLED) {
274 Assert.that(getWhere() == Where.IN_REGISTER, "wrong Where");
275 }
276 return getOffset();
277 }
278
279 public void print() {
280 printOn(System.out);
281 }
282
283 public void printOn(PrintStream tty) {
284 tty.print("Value " + value + ", ");
285 if (isIllegal()) {
286 tty.print("Illegal");
287 } else {
288 Where w = getWhere();
289 if (w == Where.ON_STACK) {
290 tty.print("stack[" + getStackOffset() + "]");
291 } else if (w == Where.IN_REGISTER) {
292 tty.print("reg " + getRegisterNumber());
293 }
294
295 Type type = getType();
296 if (type == Type.NORMAL) {
297 } else if (type == Type.OOP) {
298 tty.print(",oop");
299 } else if (type == Type.INT_IN_LONG) {
300 tty.print(",int");
301 } else if (type == Type.LNG) {
302 tty.print(",long");
303 } else if (type == Type.FLOAT_IN_DBL) {
304 tty.print(",float");
305 } else if (type == Type.DBL) {
306 tty.print(",double");
307 } else if (type == Type.ADDR) {
308 tty.print(",address");
309 } else if (type == Type.INVALID) {
310 tty.print(",invalid");
311 }
312 }
313 }
314
315 /** Serialization of debugging information */
316 public Location(DebugInfoReadStream stream) {
317 value = (0x0000FFFF & stream.readInt());
318 }
319
320 // FIXME: not yet implementable
321 // void write_on(DebugInfoWriteStream* stream);
322
323
324 //--------------------------------------------------------------------------------
325 // Internals only below this point
326 //
327
328 private void setWhere(Where where) {
329 value |= (where.getValue() << WHERE_SHIFT);
330 }
331
332 private void setType(Type type) {
333 value |= (type.getValue() << TYPE_SHIFT);
334 }
335
336 private void setOffset(int offset) {
337 value |= (offset << OFFSET_SHIFT);
338 }
339 }