Mercurial > hg > truffle
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 } |