comparison agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.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-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;
26
27 import java.io.*;
28 import java.util.*;
29 import sun.jvm.hotspot.debugger.*;
30 import sun.jvm.hotspot.types.*;
31 import sun.jvm.hotspot.types.basic.*;
32 import sun.jvm.hotspot.utilities.*;
33
34 /** <P> This is the cross-platform TypeDataBase used by the Oop
35 hierarchy. The decision was made to make this cross-platform by
36 having the VM export the necessary symbols via a built-in table;
37 see src/share/vm/runtime/vmStructs.[ch]pp for more details. </P>
38
39 <P> <B>WARNING</B>: clients should refer to this class through the
40 TypeDataBase interface and not directly to the HotSpotTypeDataBase
41 type. </P>
42
43 <P> NOTE: since we are fetching the sizes of the Java primitive types
44 */
45
46 public class HotSpotTypeDataBase extends BasicTypeDataBase {
47 private Debugger symbolLookup;
48 private String[] jvmLibNames;
49 private static final int UNINITIALIZED_SIZE = -1;
50 private static final int C_INT8_SIZE = 1;
51 private static final int C_INT32_SIZE = 4;
52 private static final int C_INT64_SIZE = 8;
53
54 private static final boolean DEBUG;
55 static {
56 DEBUG = System.getProperty("sun.jvm.hotspot.HotSpotTypeDataBase.DEBUG")
57 != null;
58 }
59
60 /** <P> This requires a SymbolLookup mechanism as well as the
61 MachineDescription. Note that we do not need a NameMangler since
62 we use the vmStructs mechanism to avoid looking up C++
63 symbols. </P>
64
65 <P> NOTE that it is guaranteed that this constructor will not
66 attempt to fetch any Java values from the remote process, only C
67 integers and addresses. This is required because we are fetching
68 the sizes of the Java primitive types from the remote process,
69 implying that attempting to fetch them before their sizes are
70 known is illegal. </P>
71
72 <P> Throws NoSuchSymbolException if a problem occurred while
73 looking up one of the bootstrapping symbols related to the
74 VMStructs table in the remote VM; this may indicate that the
75 remote process is not actually a HotSpot VM. </P>
76 */
77 public HotSpotTypeDataBase(MachineDescription machDesc,
78 VtblAccess vtblAccess,
79 Debugger symbolLookup,
80 String[] jvmLibNames) throws NoSuchSymbolException {
81 super(machDesc, vtblAccess);
82 this.symbolLookup = symbolLookup;
83 this.jvmLibNames = jvmLibNames;
84
85 readVMTypes();
86 initializePrimitiveTypes();
87 readVMStructs();
88 readVMIntConstants();
89 readVMLongConstants();
90 }
91
92 private void readVMTypes() {
93 // Get the variables we need in order to traverse the VMTypeEntry[]
94 long typeEntryTypeNameOffset;
95 long typeEntrySuperclassNameOffset;
96 long typeEntryIsOopTypeOffset;
97 long typeEntryIsIntegerTypeOffset;
98 long typeEntryIsUnsignedOffset;
99 long typeEntrySizeOffset;
100 long typeEntryArrayStride;
101
102 typeEntryTypeNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset");
103 typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset");
104 typeEntryIsOopTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
105 typeEntryIsIntegerTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
106 typeEntryIsUnsignedOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
107 typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
108 typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
109
110 // Fetch the address of the VMTypeEntry*
111 Address entryAddr = lookupInProcess("gHotSpotVMTypes");
112 // System.err.println("gHotSpotVMTypes address = " + entryAddr);
113 // Dereference this once to get the pointer to the first VMTypeEntry
114 // dumpMemory(entryAddr, 80);
115 entryAddr = entryAddr.getAddressAt(0);
116
117 if (entryAddr == null) {
118 throw new RuntimeException("gHotSpotVMTypes was not initialized properly in the remote process; can not continue");
119 }
120
121 // Start iterating down it until we find an entry with no name
122 Address typeNameAddr = null;
123 do {
124 // Fetch the type name first
125 typeNameAddr = entryAddr.getAddressAt(typeEntryTypeNameOffset);
126 if (typeNameAddr != null) {
127 String typeName = CStringUtilities.getString(typeNameAddr);
128
129 String superclassName = null;
130 Address superclassNameAddr = entryAddr.getAddressAt(typeEntrySuperclassNameOffset);
131 if (superclassNameAddr != null) {
132 superclassName = CStringUtilities.getString(superclassNameAddr);
133 }
134
135 boolean isOopType = (entryAddr.getCIntegerAt(typeEntryIsOopTypeOffset, C_INT32_SIZE, false) != 0);
136 boolean isIntegerType = (entryAddr.getCIntegerAt(typeEntryIsIntegerTypeOffset, C_INT32_SIZE, false) != 0);
137 boolean isUnsigned = (entryAddr.getCIntegerAt(typeEntryIsUnsignedOffset, C_INT32_SIZE, false) != 0);
138 long size = entryAddr.getCIntegerAt(typeEntrySizeOffset, C_INT64_SIZE, true);
139
140 createType(typeName, superclassName, isOopType, isIntegerType, isUnsigned, size);
141 }
142
143 entryAddr = entryAddr.addOffsetTo(typeEntryArrayStride);
144 } while (typeNameAddr != null);
145 }
146
147 private void initializePrimitiveTypes() {
148 // Look up the needed primitive types by name...they had better be present
149 setJBooleanType(lookupPrimitiveType("jboolean"));
150 setJByteType (lookupPrimitiveType("jbyte"));
151 setJCharType (lookupPrimitiveType("jchar"));
152 setJDoubleType (lookupPrimitiveType("jdouble"));
153 setJFloatType (lookupPrimitiveType("jfloat"));
154 setJIntType (lookupPrimitiveType("jint"));
155 setJLongType (lookupPrimitiveType("jlong"));
156 setJShortType (lookupPrimitiveType("jshort"));
157
158 // Indicate that these are the Java primitive types
159 ((BasicType) getJBooleanType()).setIsJavaPrimitiveType(true);
160 ((BasicType) getJByteType()).setIsJavaPrimitiveType(true);
161 ((BasicType) getJCharType()).setIsJavaPrimitiveType(true);
162 ((BasicType) getJDoubleType()).setIsJavaPrimitiveType(true);
163 ((BasicType) getJFloatType()).setIsJavaPrimitiveType(true);
164 ((BasicType) getJIntType()).setIsJavaPrimitiveType(true);
165 ((BasicType) getJLongType()).setIsJavaPrimitiveType(true);
166 ((BasicType) getJShortType()).setIsJavaPrimitiveType(true);
167 }
168
169 private Type lookupPrimitiveType(String typeName) {
170 Type type = lookupType(typeName, false);
171 if (type == null) {
172 throw new RuntimeException("Error initializing the HotSpotDataBase: could not find the primitive type \"" +
173 typeName + "\" in the remote VM's VMStructs table. This type is required in " +
174 "order to determine the size of Java primitive types. Can not continue.");
175 }
176 return type;
177 }
178
179 private void readVMStructs() {
180 // Get the variables we need in order to traverse the VMStructEntry[]
181 long structEntryTypeNameOffset;
182 long structEntryFieldNameOffset;
183 long structEntryTypeStringOffset;
184 long structEntryIsStaticOffset;
185 long structEntryOffsetOffset;
186 long structEntryAddressOffset;
187 long structEntryArrayStride;
188
189 structEntryTypeNameOffset = getLongValueFromProcess("gHotSpotVMStructEntryTypeNameOffset");
190 structEntryFieldNameOffset = getLongValueFromProcess("gHotSpotVMStructEntryFieldNameOffset");
191 structEntryTypeStringOffset = getLongValueFromProcess("gHotSpotVMStructEntryTypeStringOffset");
192 structEntryIsStaticOffset = getLongValueFromProcess("gHotSpotVMStructEntryIsStaticOffset");
193 structEntryOffsetOffset = getLongValueFromProcess("gHotSpotVMStructEntryOffsetOffset");
194 structEntryAddressOffset = getLongValueFromProcess("gHotSpotVMStructEntryAddressOffset");
195 structEntryArrayStride = getLongValueFromProcess("gHotSpotVMStructEntryArrayStride");
196
197 // Fetch the address of the VMStructEntry*
198 Address entryAddr = lookupInProcess("gHotSpotVMStructs");
199 // Dereference this once to get the pointer to the first VMStructEntry
200 entryAddr = entryAddr.getAddressAt(0);
201 if (entryAddr == null) {
202 throw new RuntimeException("gHotSpotVMStructs was not initialized properly in the remote process; can not continue");
203 }
204
205 // Start iterating down it until we find an entry with no name
206 Address fieldNameAddr = null;
207 String typeName = null;
208 String fieldName = null;
209 String typeString = null;
210 boolean isStatic = false;
211 long offset = 0;
212 Address staticFieldAddr = null;
213 long size = 0;
214 long index = 0;
215 String opaqueName = "<opaque>";
216 lookupOrCreateClass(opaqueName, false, false, false);
217
218 do {
219 // Fetch the field name first
220 fieldNameAddr = entryAddr.getAddressAt(structEntryFieldNameOffset);
221 if (fieldNameAddr != null) {
222 fieldName = CStringUtilities.getString(fieldNameAddr);
223
224 // Now the rest of the names. Keep in mind that the type name
225 // may be NULL, indicating that the type is opaque.
226 Address addr = entryAddr.getAddressAt(structEntryTypeNameOffset);
227 if (addr == null) {
228 throw new RuntimeException("gHotSpotVMStructs unexpectedly had a NULL type name at index " + index);
229 }
230 typeName = CStringUtilities.getString(addr);
231
232 addr = entryAddr.getAddressAt(structEntryTypeStringOffset);
233 if (addr == null) {
234 typeString = opaqueName;
235 } else {
236 typeString = CStringUtilities.getString(addr);
237 }
238
239 isStatic = !(entryAddr.getCIntegerAt(structEntryIsStaticOffset, C_INT32_SIZE, false) == 0);
240 if (isStatic) {
241 staticFieldAddr = entryAddr.getAddressAt(structEntryAddressOffset);
242 offset = 0;
243 } else {
244 offset = entryAddr.getCIntegerAt(structEntryOffsetOffset, C_INT64_SIZE, true);
245 staticFieldAddr = null;
246 }
247
248 // The containing Type must already be in the database -- no exceptions
249 BasicType containingType = lookupOrFail(typeName);
250
251 // The field's Type must already be in the database -- no exceptions
252 BasicType fieldType = lookupOrFail(typeString);
253
254 // Create field by type
255 createField(containingType, fieldName, fieldType,
256 isStatic, offset, staticFieldAddr);
257 }
258
259 ++index;
260 entryAddr = entryAddr.addOffsetTo(structEntryArrayStride);
261 } while (fieldNameAddr != null);
262 }
263
264 private void readVMIntConstants() {
265 // Get the variables we need in order to traverse the VMIntConstantEntry[]
266 long intConstantEntryNameOffset;
267 long intConstantEntryValueOffset;
268 long intConstantEntryArrayStride;
269
270 intConstantEntryNameOffset = getLongValueFromProcess("gHotSpotVMIntConstantEntryNameOffset");
271 intConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMIntConstantEntryValueOffset");
272 intConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMIntConstantEntryArrayStride");
273
274 // Fetch the address of the VMIntConstantEntry*
275 Address entryAddr = lookupInProcess("gHotSpotVMIntConstants");
276 // Dereference this once to get the pointer to the first VMIntConstantEntry
277 entryAddr = entryAddr.getAddressAt(0);
278 if (entryAddr == null) {
279 throw new RuntimeException("gHotSpotVMIntConstants was not initialized properly in the remote process; can not continue");
280 }
281
282 // Start iterating down it until we find an entry with no name
283 Address nameAddr = null;
284 do {
285 // Fetch the type name first
286 nameAddr = entryAddr.getAddressAt(intConstantEntryNameOffset);
287 if (nameAddr != null) {
288 String name = CStringUtilities.getString(nameAddr);
289 int value = (int) entryAddr.getCIntegerAt(intConstantEntryValueOffset, C_INT32_SIZE, false);
290
291 // Be a little resilient
292 Integer oldValue = lookupIntConstant(name, false);
293 if (oldValue == null) {
294 addIntConstant(name, value);
295 } else {
296 if (oldValue.intValue() != value) {
297 throw new RuntimeException("Error: the integer constant \"" + name +
298 "\" had its value redefined (old was " + oldValue +
299 ", new is " + value + ". Aborting.");
300 } else {
301 System.err.println("Warning: the int constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMIntConstants) " +
302 "had its value declared as " + value + " twice. Continuing.");
303 }
304 }
305 }
306
307 entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride);
308 } while (nameAddr != null);
309 }
310
311 private void readVMLongConstants() {
312 // Get the variables we need in order to traverse the VMLongConstantEntry[]
313 long longConstantEntryNameOffset;
314 long longConstantEntryValueOffset;
315 long longConstantEntryArrayStride;
316
317 longConstantEntryNameOffset = getLongValueFromProcess("gHotSpotVMLongConstantEntryNameOffset");
318 longConstantEntryValueOffset = getLongValueFromProcess("gHotSpotVMLongConstantEntryValueOffset");
319 longConstantEntryArrayStride = getLongValueFromProcess("gHotSpotVMLongConstantEntryArrayStride");
320
321 // Fetch the address of the VMLongConstantEntry*
322 Address entryAddr = lookupInProcess("gHotSpotVMLongConstants");
323 // Dereference this once to get the pointer to the first VMLongConstantEntry
324 entryAddr = entryAddr.getAddressAt(0);
325 if (entryAddr == null) {
326 throw new RuntimeException("gHotSpotVMLongConstants was not initialized properly in the remote process; can not continue");
327 }
328
329 // Start iterating down it until we find an entry with no name
330 Address nameAddr = null;
331 do {
332 // Fetch the type name first
333 nameAddr = entryAddr.getAddressAt(longConstantEntryNameOffset);
334 if (nameAddr != null) {
335 String name = CStringUtilities.getString(nameAddr);
336 int value = (int) entryAddr.getCIntegerAt(longConstantEntryValueOffset, C_INT64_SIZE, true);
337
338 // Be a little resilient
339 Long oldValue = lookupLongConstant(name, false);
340 if (oldValue == null) {
341 addLongConstant(name, value);
342 } else {
343 if (oldValue.longValue() != value) {
344 throw new RuntimeException("Error: the long constant \"" + name +
345 "\" had its value redefined (old was " + oldValue +
346 ", new is " + value + ". Aborting.");
347 } else {
348 System.err.println("Warning: the long constant \"" + name + "\" (declared in the remote VM in VMStructs::localHotSpotVMLongConstants) " +
349 "had its value declared as " + value + " twice. Continuing.");
350 }
351 }
352 }
353
354 entryAddr = entryAddr.addOffsetTo(longConstantEntryArrayStride);
355 } while (nameAddr != null);
356 }
357
358 private BasicType lookupOrFail(String typeName) {
359 BasicType type = (BasicType) lookupType(typeName, false);
360 if (type == null) {
361 throw new RuntimeException("Type \"" + typeName + "\", referenced in VMStructs::localHotSpotVMStructs in the remote VM, " +
362 "was not present in the remote VMStructs::localHotSpotVMTypes table (should have been caught " +
363 "in the debug build of that VM). Can not continue.");
364 }
365 return type;
366 }
367
368 private long getLongValueFromProcess(String symbol) {
369 return lookupInProcess(symbol).getCIntegerAt(0, C_INT64_SIZE, true);
370 }
371
372 private Address lookupInProcess(String symbol) throws NoSuchSymbolException {
373 // FIXME: abstract away the loadobject name
374 for (int i = 0; i < jvmLibNames.length; i++) {
375 Address addr = symbolLookup.lookup(jvmLibNames[i], symbol);
376 if (addr != null) {
377 return addr;
378 }
379 }
380 String errStr = "(";
381 for (int i = 0; i < jvmLibNames.length; i++) {
382 errStr += jvmLibNames[i];
383 if (i < jvmLibNames.length - 1) {
384 errStr += ", ";
385 }
386 }
387 errStr += ")";
388 throw new NoSuchSymbolException(symbol,
389 "Could not find symbol \"" + symbol +
390 "\" in any of the known library names " +
391 errStr);
392 }
393
394 private BasicType lookupOrCreateClass(String typeName, boolean isOopType,
395 boolean isIntegerType, boolean isUnsigned) {
396 BasicType type = (BasicType) lookupType(typeName, false);
397 if (type == null) {
398 // Create a new type
399 type = createBasicType(typeName, isOopType, isIntegerType, isUnsigned);
400 }
401 return type;
402 }
403
404 /** Creates a new BasicType, initializes its size to -1 so we can
405 test to ensure that all types' sizes are initialized by VMTypes,
406 and adds it to the database. Takes care of initializing integer
407 and oop types properly. */
408 private BasicType createBasicType(String typeName, boolean isOopType,
409 boolean isIntegerType, boolean isUnsigned) {
410
411 BasicType type = null;
412
413 if (isIntegerType) {
414 type = new BasicCIntegerType(this, typeName, isUnsigned);
415 } else {
416 if (typeNameIsPointerType(typeName)) {
417 type = recursiveCreateBasicPointerType(typeName);
418 } else {
419 type = new BasicType(this, typeName);
420 }
421
422 if (isOopType) {
423 // HACK: turn markOop into a C integer type. This allows
424 // proper handling of it in the Serviceability Agent. (FIXME
425 // -- consider doing something different here)
426 if (typeName.equals("markOop")) {
427 type = new BasicCIntegerType(this, typeName, true);
428 } else {
429 type.setIsOopType(true);
430 }
431 }
432 }
433
434 type.setSize(UNINITIALIZED_SIZE);
435 addType(type);
436 return type;
437 }
438
439 /** Recursively creates a PointerType from the string representation
440 of the type's name. Note that this currently needs some
441 workarounds due to incomplete information in the VMStructs
442 database. */
443 private BasicPointerType recursiveCreateBasicPointerType(String typeName) {
444 String targetTypeName = typeName.substring(0, typeName.lastIndexOf('*')).trim();
445 Type targetType = null;
446 if (typeNameIsPointerType(targetTypeName)) {
447 targetType = recursiveCreateBasicPointerType(targetTypeName);
448 } else {
449 targetType = lookupType(targetTypeName, false);
450 if (targetType == null) {
451 // Workaround for missing C integer types in database.
452 // Also looks like we can't throw an exception for other
453 // missing target types because there are some in old
454 // VMStructs tables that didn't have the target type declared.
455 // For this case, we create basic types that never get filled
456 // in.
457
458 if (targetTypeName.equals("char") ||
459 targetTypeName.equals("const char")) {
460 // We don't have a representation of const-ness of C types in the SA
461 BasicType basicTargetType = createBasicType(targetTypeName, false, true, false);
462 basicTargetType.setSize(1);
463 targetType = basicTargetType;
464 } else if (targetTypeName.equals("u_char")) {
465 BasicType basicTargetType = createBasicType(targetTypeName, false, true, true);
466 basicTargetType.setSize(1);
467 targetType = basicTargetType;
468 } else {
469 if (DEBUG) {
470 System.err.println("WARNING: missing target type \"" + targetTypeName + "\" for pointer type \"" + typeName + "\"");
471 }
472 targetType = createBasicType(targetTypeName, false, false, false);
473 }
474 }
475 }
476 return new BasicPointerType(this, typeName, targetType);
477 }
478
479 private boolean typeNameIsPointerType(String typeName) {
480 int i = typeName.length() - 1;
481 while (i >= 0 && Character.isWhitespace(typeName.charAt(i))) {
482 --i;
483 }
484 if (i >= 0 && typeName.charAt(i) == '*') {
485 return true;
486 }
487 return false;
488 }
489
490 public void createType(String typeName, String superclassName,
491 boolean isOopType, boolean isIntegerType,
492 boolean isUnsigned, long size) {
493 // See whether we have a superclass
494 BasicType superclass = null;
495 if (superclassName != null) {
496 // Fetch or create it (FIXME: would get oop types wrong if
497 // they had a hierarchy; consider using lookupOrFail)
498 superclass = lookupOrCreateClass(superclassName, false, false, false);
499 }
500
501 // Lookup or create the current type
502 BasicType curType = lookupOrCreateClass(typeName, isOopType, isIntegerType, isUnsigned);
503 // Set superclass and/or ensure it's correct
504 if (superclass != null) {
505 if (curType.getSuperclass() == null) {
506 // Set the superclass in the current type
507 curType.setSuperclass(superclass);
508 }
509
510 if (curType.getSuperclass() != superclass) {
511 throw new RuntimeException("Error: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " +
512 "had its superclass redefined (old was " + curType.getSuperclass().getName() + ", new is " +
513 superclass.getName() + ").");
514 }
515 }
516
517 // Classes are created with a size of UNINITIALIZED_SIZE.
518 // Set size if necessary.
519 if (curType.getSize() == UNINITIALIZED_SIZE) {
520 curType.setSize(size);
521 } else {
522 if (curType.getSize() != size) {
523 throw new RuntimeException("Error: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " +
524 "had its size redefined (old was " + curType.getSize() + ", new is " + size + ").");
525 }
526
527 System.err.println("Warning: the type \"" + typeName + "\" (declared in the remote VM in VMStructs::localHotSpotVMTypes) " +
528 "had its size declared as " + size + " twice. Continuing.");
529 }
530
531 }
532
533 /** "Virtual constructor" for fields based on type */
534 public void createField(BasicType containingType,
535 String name, Type type, boolean isStatic,
536 long offset, Address staticFieldAddress) {
537 // Add field to containing type
538 containingType.addField(internalCreateField(containingType, name, type, isStatic, offset, staticFieldAddress));
539 }
540
541 Field internalCreateField(BasicType containingType,
542 String name, Type type, boolean isStatic,
543 long offset, Address staticFieldAddress) {
544 // "Virtual constructor" based on type
545 if (type.isOopType()) {
546 return new BasicOopField(this, containingType, name, type,
547 isStatic, offset, staticFieldAddress);
548 }
549
550 if (type instanceof CIntegerType) {
551 return new BasicCIntegerField(this, containingType, name, type,
552 isStatic, offset, staticFieldAddress);
553 }
554
555 if (type.equals(getJBooleanType())) {
556 return new BasicJBooleanField(this, containingType, name, type,
557 isStatic, offset, staticFieldAddress);
558 }
559
560 if (type.equals(getJByteType())) {
561 return new BasicJByteField(this, containingType, name, type,
562 isStatic, offset, staticFieldAddress);
563 }
564
565 if (type.equals(getJCharType())) {
566 return new BasicJCharField(this, containingType, name, type,
567 isStatic, offset, staticFieldAddress);
568 }
569
570 if (type.equals(getJDoubleType())) {
571 return new BasicJDoubleField(this, containingType, name, type,
572 isStatic, offset, staticFieldAddress);
573 }
574
575 if (type.equals(getJFloatType())) {
576 return new BasicJFloatField(this, containingType, name, type,
577 isStatic, offset, staticFieldAddress);
578 }
579
580 if (type.equals(getJIntType())) {
581 return new BasicJIntField(this, containingType, name, type,
582 isStatic, offset, staticFieldAddress);
583 }
584
585 if (type.equals(getJLongType())) {
586 return new BasicJLongField(this, containingType, name, type,
587 isStatic, offset, staticFieldAddress);
588 }
589
590 if (type.equals(getJShortType())) {
591 return new BasicJShortField(this, containingType, name, type,
592 isStatic, offset, staticFieldAddress);
593 }
594
595 // Unknown ("opaque") type. Instantiate ordinary Field.
596 return new BasicField(this, containingType, name, type,
597 isStatic, offset, staticFieldAddress);
598 }
599
600 // For debugging
601 private void dumpMemory(Address addr, int len) {
602 int i = 0;
603 while (i < len) {
604 System.err.print(addr.addOffsetTo(i) + ":");
605 for (int j = 0; j < 8 && i < len; i++, j++) {
606 String s = Long.toHexString(addr.getCIntegerAt(i, 1, true));
607 System.err.print(" 0x");
608 for (int k = 0; k < 2 - s.length(); k++) {
609 System.err.print("0");
610 }
611 System.err.print(s);
612 }
613 System.err.println();
614 }
615 }
616 }