Mercurial > hg > graal-compiler
comparison agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | ba764ed4b6f2 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a61af66fc99e |
---|---|
1 /* | |
2 * Copyright 2000-2004 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.types.basic; | |
26 | |
27 import java.util.*; | |
28 import sun.jvm.hotspot.debugger.*; | |
29 import sun.jvm.hotspot.types.*; | |
30 | |
31 /** <P> This is a basic implementation of the TypeDataBase interface. | |
32 It allows an external type database builder to add types to be | |
33 consumed by a client through the Type interfaces. It has no | |
34 knowledge of symbol lookup; for example, the builder is | |
35 responsible for providing the addresses of static fields. </P> | |
36 | |
37 <P> Among other things, the database builder is responsible for | |
38 providing the Types for the Java primitive types, as well as their | |
39 sizes. </P> | |
40 */ | |
41 | |
42 public class BasicTypeDataBase implements TypeDataBase { | |
43 private MachineDescription machDesc; | |
44 private VtblAccess vtblAccess; | |
45 /** Maps strings to Type objects. This does not contain the primitive types. */ | |
46 private Map nameToTypeMap = new HashMap(); | |
47 /** Maps strings to Integers, used for enums, etc. */ | |
48 private Map nameToIntConstantMap = new HashMap(); | |
49 /** Maps strings to Longs, used for 32/64-bit constants, etc. */ | |
50 private Map nameToLongConstantMap = new HashMap(); | |
51 /** Primitive types. */ | |
52 private Type jbooleanType; | |
53 private Type jbyteType; | |
54 private Type jcharType; | |
55 private Type jdoubleType; | |
56 private Type jfloatType; | |
57 private Type jintType; | |
58 private Type jlongType; | |
59 private Type jshortType; | |
60 | |
61 /** For debugging */ | |
62 private static final boolean DEBUG; | |
63 static { | |
64 DEBUG = System.getProperty("sun.jvm.hotspot.types.basic.BasicTypeDataBase.DEBUG") != null; | |
65 } | |
66 | |
67 public BasicTypeDataBase(MachineDescription machDesc, VtblAccess vtblAccess) { | |
68 this.machDesc = machDesc; | |
69 this.vtblAccess = vtblAccess; | |
70 } | |
71 | |
72 public Type lookupType(String cTypeName) { | |
73 return lookupType(cTypeName, true); | |
74 } | |
75 | |
76 public Type lookupType(String cTypeName, boolean throwException) { | |
77 Type type = (Type) nameToTypeMap.get(cTypeName); | |
78 if (type == null && throwException) { | |
79 throw new RuntimeException("No type named \"" + cTypeName + "\" in database"); | |
80 } | |
81 return type; | |
82 } | |
83 | |
84 public Integer lookupIntConstant(String constantName) { | |
85 return lookupIntConstant(constantName, true); | |
86 } | |
87 | |
88 public Integer lookupIntConstant(String constantName, boolean throwException) { | |
89 Integer i = (Integer) nameToIntConstantMap.get(constantName); | |
90 if (i == null) { | |
91 if (throwException) { | |
92 throw new RuntimeException("No integer constant named \"" + constantName + "\" present in type database"); | |
93 } | |
94 } | |
95 return i; | |
96 } | |
97 | |
98 public Long lookupLongConstant(String constantName) { | |
99 return lookupLongConstant(constantName, true); | |
100 } | |
101 | |
102 public Long lookupLongConstant(String constantName, boolean throwException) { | |
103 Long i = (Long) nameToLongConstantMap.get(constantName); | |
104 if (i == null) { | |
105 if (throwException) { | |
106 throw new RuntimeException("No long constant named \"" + constantName + "\" present in type database"); | |
107 } | |
108 } | |
109 return i; | |
110 } | |
111 | |
112 public Type getJBooleanType() { | |
113 return jbooleanType; | |
114 } | |
115 | |
116 public Type getJByteType() { | |
117 return jbyteType; | |
118 } | |
119 | |
120 public Type getJCharType() { | |
121 return jcharType; | |
122 } | |
123 | |
124 public Type getJDoubleType() { | |
125 return jdoubleType; | |
126 } | |
127 | |
128 public Type getJFloatType() { | |
129 return jfloatType; | |
130 } | |
131 | |
132 public Type getJIntType() { | |
133 return jintType; | |
134 } | |
135 | |
136 public Type getJLongType() { | |
137 return jlongType; | |
138 } | |
139 | |
140 public Type getJShortType() { | |
141 return jshortType; | |
142 } | |
143 | |
144 public long getAddressSize() { | |
145 return machDesc.getAddressSize(); | |
146 } | |
147 | |
148 public long getOopSize() { | |
149 return machDesc.getOopSize(); | |
150 } | |
151 | |
152 public boolean addressTypeIsEqualToType(Address addr, Type type) { | |
153 if (addr == null) { | |
154 return false; | |
155 } | |
156 | |
157 // This implementation should be suitably platform-independent; we | |
158 // search nearby memory for the vtbl value of the given type. | |
159 | |
160 Address vtblAddr = vtblAccess.getVtblForType(type); | |
161 | |
162 if (vtblAddr == null) { | |
163 // Type was not polymorphic, or an error occurred during lookup | |
164 if (DEBUG) { | |
165 System.err.println("BasicTypeDataBase.addressTypeIsEqualToType: vtblAddr == null"); | |
166 } | |
167 | |
168 return false; | |
169 } | |
170 | |
171 // The first implementation searched three locations for this vtbl | |
172 // value; scanning through the entire object was considered, but | |
173 // we thought we knew where we were looking, and looking only in | |
174 // these specific locations should reduce the probability of | |
175 // mistaking random bits as a pointer (although, realistically | |
176 // speaking, the likelihood of finding a match between the bit | |
177 // pattern of, for example, a double and the vtbl is vanishingly | |
178 // small.) | |
179 // 1. The first word of the object (should handle MSVC++ as | |
180 // well as the SparcWorks compilers with compatibility set to | |
181 // v5.0 or greater) | |
182 // 2. and 3. The last two Address-aligned words of the part of | |
183 // the object defined by its topmost polymorphic superclass. | |
184 // This should handle the SparcWorks compilers, v4.2 or | |
185 // earlier, as well as any other compilers which place the vptr | |
186 // at the end of the user-defined fields of the first base | |
187 // class with virtual functions. | |
188 // | |
189 // Unfortunately this algorithm did not work properly for the | |
190 // specific case of the ThreadShadow/Thread inheritance situation, | |
191 // because the Solaris compiler seems to cleverly eliminate the | |
192 // vtbl for ThreadShadow since the only virtual is empty. (We | |
193 // should get rid of the ThreadShadow and fix the include | |
194 // databases, but need to postpone this for the present.) The | |
195 // current solution performs the three-location check for this | |
196 // class and all of its known superclasses rather than just the | |
197 // topmost polymorphic one. | |
198 | |
199 Type curType = type; | |
200 | |
201 try { | |
202 while (curType != null) { | |
203 // Using the size information we have for this type, check the | |
204 // three locations described above. | |
205 | |
206 // (1) | |
207 if (vtblAddr.equals(addr.getAddressAt(0))) { | |
208 return true; | |
209 } | |
210 | |
211 // (2) | |
212 long offset = curType.getSize(); | |
213 // I don't think this should be misaligned under any | |
214 // circumstances, but I'm not sure (FIXME: also not sure which | |
215 // way to go here, up or down -- assuming down) | |
216 offset -= (offset % getAddressSize()); | |
217 if (offset <= 0) { | |
218 return false; | |
219 } | |
220 if (vtblAddr.equals(addr.getAddressAt(offset))) { | |
221 return true; | |
222 } | |
223 offset -= getAddressSize(); | |
224 if (offset <= 0) { | |
225 return false; | |
226 } | |
227 if (vtblAddr.equals(addr.getAddressAt(offset))) { | |
228 return true; | |
229 } | |
230 | |
231 curType = curType.getSuperclass(); | |
232 } | |
233 } | |
234 catch (Exception e) { | |
235 // Any UnmappedAddressExceptions, etc. are a good indication | |
236 // that the pointer is not of the specified type | |
237 if (DEBUG) { | |
238 System.err.println("BasicTypeDataBase.addressTypeIsEqualToType: exception occurred during lookup:"); | |
239 e.printStackTrace(); | |
240 } | |
241 | |
242 return false; | |
243 } | |
244 | |
245 if (DEBUG) { | |
246 System.err.println("BasicTypeDataBase.addressTypeIsEqualToType: all vptr tests failed for type " + | |
247 type.getName()); | |
248 } | |
249 | |
250 return false; | |
251 } | |
252 | |
253 public Type guessTypeForAddress(Address addr) { | |
254 for (Iterator iter = getTypes(); iter.hasNext(); ) { | |
255 Type t = (Type) iter.next(); | |
256 if (addressTypeIsEqualToType(addr, t)) { | |
257 return t; | |
258 } | |
259 } | |
260 return null; | |
261 } | |
262 | |
263 public long cIntegerTypeMaxValue(long sizeInBytes, boolean isUnsigned) { | |
264 return machDesc.cIntegerTypeMaxValue(sizeInBytes, isUnsigned); | |
265 } | |
266 | |
267 public long cIntegerTypeMinValue(long sizeInBytes, boolean isUnsigned) { | |
268 return machDesc.cIntegerTypeMinValue(sizeInBytes, isUnsigned); | |
269 } | |
270 | |
271 public Iterator getTypes() { | |
272 return nameToTypeMap.values().iterator(); | |
273 } | |
274 | |
275 public Iterator getIntConstants() { | |
276 return nameToIntConstantMap.keySet().iterator(); | |
277 } | |
278 | |
279 public Iterator getLongConstants() { | |
280 return nameToLongConstantMap.keySet().iterator(); | |
281 } | |
282 | |
283 //-------------------------------------------------------------------------------- | |
284 // Public routines only for use by the database builder | |
285 // | |
286 | |
287 /** This method should only be called by the builder of the | |
288 TypeDataBase and at most once */ | |
289 public void setJBooleanType(Type type) { | |
290 jbooleanType = type; | |
291 } | |
292 | |
293 /** This method should only be called by the builder of the | |
294 TypeDataBase and at most once */ | |
295 public void setJByteType(Type type) { | |
296 jbyteType = type; | |
297 } | |
298 | |
299 /** This method should only be called by the builder of the | |
300 TypeDataBase and at most once */ | |
301 public void setJCharType(Type type) { | |
302 jcharType = type; | |
303 } | |
304 | |
305 /** This method should only be called by the builder of the | |
306 TypeDataBase and at most once */ | |
307 public void setJDoubleType(Type type) { | |
308 jdoubleType = type; | |
309 } | |
310 | |
311 /** This method should only be called by the builder of the | |
312 TypeDataBase and at most once */ | |
313 public void setJFloatType(Type type) { | |
314 jfloatType = type; | |
315 } | |
316 | |
317 /** This method should only be called by the builder of the | |
318 TypeDataBase and at most once */ | |
319 public void setJIntType(Type type) { | |
320 jintType = type; | |
321 } | |
322 | |
323 /** This method should only be called by the builder of the | |
324 TypeDataBase and at most once */ | |
325 public void setJLongType(Type type) { | |
326 jlongType = type; | |
327 } | |
328 | |
329 /** This method should only be called by the builder of the | |
330 TypeDataBase and at most once */ | |
331 public void setJShortType(Type type) { | |
332 jshortType = type; | |
333 } | |
334 | |
335 /** This method should only be used by the builder of the | |
336 TypeDataBase. Throws a RuntimeException if a class with this | |
337 name was already present. */ | |
338 public void addType(Type type) { | |
339 if (nameToTypeMap.get(type.getName()) != null) { | |
340 throw new RuntimeException("type of name \"" + type.getName() + "\" already present"); | |
341 } | |
342 | |
343 nameToTypeMap.put(type.getName(), type); | |
344 } | |
345 | |
346 /** This method should only be used by the builder of the | |
347 TypeDataBase. Throws a RuntimeException if this class was not | |
348 present. */ | |
349 public void removeType(Type type) { | |
350 Type curType = (Type) nameToTypeMap.get(type.getName()); | |
351 if (curType == null) { | |
352 throw new RuntimeException("type of name \"" + type.getName() + "\" not present"); | |
353 } | |
354 | |
355 if (!curType.equals(type)) { | |
356 throw new RuntimeException("a different type of name \"" + type.getName() + "\" was present"); | |
357 } | |
358 | |
359 nameToTypeMap.remove(type.getName()); | |
360 } | |
361 | |
362 /** This method should only be used by the builder of the | |
363 TypeDataBase. Throws a RuntimeException if an integer constant | |
364 with this name was already present. */ | |
365 public void addIntConstant(String name, int value) { | |
366 if (nameToIntConstantMap.get(name) != null) { | |
367 throw new RuntimeException("int constant of name \"" + name + "\" already present"); | |
368 } | |
369 | |
370 nameToIntConstantMap.put(name, new Integer(value)); | |
371 } | |
372 | |
373 /** This method should only be used by the builder of the | |
374 TypeDataBase. Throws a RuntimeException if an integer constant | |
375 with this name was not present. */ | |
376 public void removeIntConstant(String name) { | |
377 Integer curConstant = (Integer) nameToIntConstantMap.get(name); | |
378 if (curConstant == null) { | |
379 throw new RuntimeException("int constant of name \"" + name + "\" not present"); | |
380 } | |
381 | |
382 nameToIntConstantMap.remove(name); | |
383 } | |
384 | |
385 /** This method should only be used by the builder of the | |
386 TypeDataBase. Throws a RuntimeException if a long constant with | |
387 this name was already present. */ | |
388 public void addLongConstant(String name, long value) { | |
389 if (nameToLongConstantMap.get(name) != null) { | |
390 throw new RuntimeException("long constant of name \"" + name + "\" already present"); | |
391 } | |
392 | |
393 nameToLongConstantMap.put(name, new Long(value)); | |
394 } | |
395 | |
396 /** This method should only be used by the builder of the | |
397 TypeDataBase. Throws a RuntimeException if a long constant with | |
398 this name was not present. */ | |
399 public void removeLongConstant(String name) { | |
400 Long curConstant = (Long) nameToLongConstantMap.get(name); | |
401 if (curConstant == null) { | |
402 throw new RuntimeException("long constant of name \"" + name + "\" not present"); | |
403 } | |
404 | |
405 nameToLongConstantMap.remove(name); | |
406 } | |
407 } |