< prev index next >

test/lib/jdk/test/lib/hprof/model/JavaObject.java

Print this page

 25 /*
 26  * The Original Code is HAT. The Initial Developer of the
 27  * Original Code is Bill Foote, with contributions from others
 28  * at JavaSoft/Sun.
 29  */
 30 
 31 package jdk.test.lib.hprof.model;
 32 
 33 import java.io.IOException;
 34 import jdk.test.lib.hprof.parser.ReadBuffer;
 35 
 36 /**
 37  * Represents Java instance
 38  *
 39  * @author      Bill Foote
 40  */
 41 public class JavaObject extends JavaLazyReadObject {
 42 
 43     private Object clazz;       // Number before resolve
 44                                 // JavaClass after resolve






 45     /**
 46      * Construct a new JavaObject.
 47      *
 48      * @param classID id of the class object
 49      * @param offset The offset of field data
 50      */
 51     public JavaObject(long classID, long offset) {
 52         super(offset);
 53         this.clazz = makeId(classID);
 54     }
 55 
 56     public void resolve(Snapshot snapshot) {
 57         if (clazz instanceof JavaClass) {
 58             return;
 59         }
 60         if (clazz instanceof Number) {
 61             long classID = getIdValue((Number)clazz);
 62             clazz = snapshot.findThing(classID);
 63             if (! (clazz instanceof JavaClass)) {
 64                 warn("Class " + Long.toHexString(classID) + " not found, " +
 65                      "adding fake class!");
 66                 int length;
 67                 ReadBuffer buf = snapshot.getReadBuffer();
 68                 int idSize = snapshot.getIdentifierSize();
 69                 long lenOffset = getOffset() + 2*idSize + 4;
 70                 try {
 71                     length = buf.getInt(lenOffset);
 72                 } catch (IOException exp) {
 73                     throw new RuntimeException(exp);

194             } else {
195                 return "null";
196             }
197         } else {
198             return super.toString();
199         }
200     }
201 
202     // Internals only below this point
203 
204     /*
205      * Java instance record (HPROF_GC_INSTANCE_DUMP) looks as below:
206      *
207      *     object ID
208      *     stack trace serial number (int)
209      *     class ID
210      *     data length (int)
211      *     byte[length]
212      */
213     @Override
214     protected final long readValueLength() throws IOException {
215         long lengthOffset = getOffset() + 2 * idSize() + 4;
216         return buf().getInt(lengthOffset);
217     }
218 
219     @Override
220     protected final JavaThing[] readValue() throws IOException {
221         return parseFields(false);
222     }
223 
224     private long dataStartOffset() {
225         return getOffset() + idSize() + 4 + idSize() + 4;
226     }
227 
228     private JavaThing[] parseFields(boolean verbose) {
229         JavaClass cl = getClazz();
230         int target = cl.getNumFieldsForInstance();
231         JavaField[] fields = cl.getFields();
232         JavaThing[] fieldValues = new JavaThing[target];
233         Snapshot snapshot = cl.getSnapshot();
234         int fieldNo = 0;
235         // In the dump file, the fields are stored in this order:
236         // fields of most derived class (immediate class) are stored
237         // first and then the super class and so on. In this object,
238         // fields are stored in the reverse ("natural") order. i.e.,
239         // fields of most super class are stored first.
240 
241         // target variable is used to compensate for the fact that
242         // the dump file starts field values from the leaf working
243         // upwards in the inheritance hierarchy, whereas JavaObject
244         // starts with the top of the inheritance hierarchy and works down.
245         target -= fields.length;
246         JavaClass currClass = cl;
247         long offset = dataStartOffset();
248         for (int i = 0; i < fieldValues.length; i++, fieldNo++) {
249             while (fieldNo >= fields.length) {
250                 currClass = currClass.getSuperclass();
251                 fields = currClass.getFields();
252                 fieldNo = 0;
253                 target -= fields.length;
254             }
255             JavaField f = fields[fieldNo];
256             char sig = f.getSignature().charAt(0);
257             try {
258                 switch (sig) {
259                     case 'L':
260                     case '[': {
261                         long id = objectIdAt(offset);
262                         offset += idSize();
263                         JavaObjectRef ref = new JavaObjectRef(id);
264                         fieldValues[target+fieldNo] = ref.dereference(snapshot, f, verbose);
265                         break;
266                     }
267                     case 'Z': {
268                         byte value = byteAt(offset);
269                         offset++;
270                         fieldValues[target+fieldNo] = new JavaBoolean(value != 0);
271                         break;
272                     }
273                     case 'B': {
274                         byte value = byteAt(offset);
275                         offset++;
276                         fieldValues[target+fieldNo] = new JavaByte(value);
277                         break;
278                     }
279                     case 'S': {
280                         short value = shortAt(offset);
281                         offset += 2;
282                         fieldValues[target+fieldNo] = new JavaShort(value);
283                         break;
284                     }
285                     case 'C': {
286                         char value = charAt(offset);
287                         offset += 2;
288                         fieldValues[target+fieldNo] = new JavaChar(value);
289                         break;
290                     }
291                     case 'I': {
292                         int value = intAt(offset);
293                         offset += 4;
294                         fieldValues[target+fieldNo] = new JavaInt(value);
295                         break;
296                     }
297                     case 'J': {
298                         long value = longAt(offset);
299                         offset += 8;
300                         fieldValues[target+fieldNo] = new JavaLong(value);
301                         break;
302                     }
303                     case 'F': {
304                         float value = floatAt(offset);
305                         offset += 4;
306                         fieldValues[target+fieldNo] = new JavaFloat(value);
307                         break;
308                     }
309                     case 'D': {
310                         double value = doubleAt(offset);
311                         offset += 8;
312                         fieldValues[target+fieldNo] = new JavaDouble(value);
313                         break;
314                     }
315                     default:
316                         throw new RuntimeException("invalid signature: " + sig);









317 

318                 }
319         } catch (IOException exp) {
320             System.err.println("lazy read failed at offset " + offset);
321             exp.printStackTrace();
322             return Snapshot.EMPTY_JAVATHING_ARRAY;
323             }
324         }
325         return fieldValues;
326     }
327 
328     private void warn(String msg) {
329         System.out.println("WARNING: " + msg);
330     }
331 }

 25 /*
 26  * The Original Code is HAT. The Initial Developer of the
 27  * Original Code is Bill Foote, with contributions from others
 28  * at JavaSoft/Sun.
 29  */
 30 
 31 package jdk.test.lib.hprof.model;
 32 
 33 import java.io.IOException;
 34 import jdk.test.lib.hprof.parser.ReadBuffer;
 35 
 36 /**
 37  * Represents Java instance
 38  *
 39  * @author      Bill Foote
 40  */
 41 public class JavaObject extends JavaLazyReadObject {
 42 
 43     private Object clazz;       // Number before resolve
 44                                 // JavaClass after resolve
 45 
 46     public JavaObject(Object clazz, long offset) {
 47         super(offset);
 48         this.clazz = clazz;
 49     }
 50 
 51     /**
 52      * Construct a new JavaObject.
 53      *
 54      * @param classID id of the class object
 55      * @param offset The offset of field data
 56      */
 57     public JavaObject(long classID, long offset) {
 58         this(makeId(classID), offset);

 59     }
 60 
 61     public void resolve(Snapshot snapshot) {
 62         if (clazz instanceof JavaClass) {
 63             return;
 64         }
 65         if (clazz instanceof Number) {
 66             long classID = getIdValue((Number)clazz);
 67             clazz = snapshot.findThing(classID);
 68             if (! (clazz instanceof JavaClass)) {
 69                 warn("Class " + Long.toHexString(classID) + " not found, " +
 70                      "adding fake class!");
 71                 int length;
 72                 ReadBuffer buf = snapshot.getReadBuffer();
 73                 int idSize = snapshot.getIdentifierSize();
 74                 long lenOffset = getOffset() + 2*idSize + 4;
 75                 try {
 76                     length = buf.getInt(lenOffset);
 77                 } catch (IOException exp) {
 78                     throw new RuntimeException(exp);

199             } else {
200                 return "null";
201             }
202         } else {
203             return super.toString();
204         }
205     }
206 
207     // Internals only below this point
208 
209     /*
210      * Java instance record (HPROF_GC_INSTANCE_DUMP) looks as below:
211      *
212      *     object ID
213      *     stack trace serial number (int)
214      *     class ID
215      *     data length (int)
216      *     byte[length]
217      */
218     @Override
219     protected long readValueLength() throws IOException {
220         long lengthOffset = getOffset() + 2 * idSize() + 4;
221         return buf().getInt(lengthOffset);
222     }
223 
224     @Override
225     protected final JavaThing[] readValue() throws IOException {
226         return parseFields(false);
227     }
228 
229     protected long dataStartOffset() {
230         return getOffset() + idSize() + 4 + idSize() + 4;
231     }
232 
233     private JavaThing[] parseFields(boolean verbose) {
234         JavaClass cl = getClazz();
235         int target = cl.getNumFieldsForInstance();
236         JavaField[] fields = cl.getFields();
237         JavaThing[] fieldValues = new JavaThing[target];
238         Snapshot snapshot = cl.getSnapshot();
239         int fieldNo = 0;
240         // In the dump file, the fields are stored in this order:
241         // fields of most derived class (immediate class) are stored
242         // first and then the super class and so on. In this object,
243         // fields are stored in the reverse ("natural") order. i.e.,
244         // fields of most super class are stored first.
245 
246         // target variable is used to compensate for the fact that
247         // the dump file starts field values from the leaf working
248         // upwards in the inheritance hierarchy, whereas JavaObject
249         // starts with the top of the inheritance hierarchy and works down.
250         target -= fields.length;
251         JavaClass currClass = cl;
252         long offset = dataStartOffset();
253         for (int i = 0; i < fieldValues.length; i++, fieldNo++) {
254             while (fieldNo >= fields.length) {
255                 currClass = currClass.getSuperclass();
256                 fields = currClass.getFields();
257                 fieldNo = 0;
258                 target -= fields.length;
259             }
260             JavaField f = fields[fieldNo];
261             char sig = f.getSignature().charAt(0);
262             try {
263                 if (f instanceof InlinedJavaField inlinedField) {
264                     JavaClass fieldClass = inlinedField.getInlinedFieldClass();
265                     fieldValues[target+fieldNo] = new InlinedJavaObject(fieldClass, offset);
266                     offset += fieldClass.getInlinedInstanceSize();
267                 } else {
268                     switch (sig) {
269                         case 'Q': {
270                             warn("(parseFields) field " + getClazz().getName() + "." + f.getName()
271                                     + " is not inlined, but has Q-signature: " + f.getSignature());
272                         } // continue as 'L' object
273                         case 'L':
274                         case '[': {
275                             long id = objectIdAt(offset);
276                             offset += idSize();
277                             JavaObjectRef ref = new JavaObjectRef(id);
278                             fieldValues[target + fieldNo] = ref.dereference(snapshot, f, verbose);
279                             break;
280                         }
281                         case 'Z': {
282                             byte value = byteAt(offset);
283                             offset++;
284                             fieldValues[target + fieldNo] = new JavaBoolean(value != 0);
285                             break;
286                         }
287                         case 'B': {
288                             byte value = byteAt(offset);
289                             offset++;
290                             fieldValues[target + fieldNo] = new JavaByte(value);
291                             break;
292                         }
293                         case 'S': {
294                             short value = shortAt(offset);
295                             offset += 2;
296                             fieldValues[target + fieldNo] = new JavaShort(value);
297                             break;
298                         }
299                         case 'C': {
300                             char value = charAt(offset);
301                             offset += 2;
302                             fieldValues[target + fieldNo] = new JavaChar(value);
303                             break;
304                         }
305                         case 'I': {
306                             int value = intAt(offset);
307                             offset += 4;
308                             fieldValues[target + fieldNo] = new JavaInt(value);
309                             break;
310                         }
311                         case 'J': {
312                             long value = longAt(offset);
313                             offset += 8;
314                             fieldValues[target + fieldNo] = new JavaLong(value);
315                             break;
316                         }
317                         case 'F': {
318                             float value = floatAt(offset);
319                             offset += 4;
320                             fieldValues[target + fieldNo] = new JavaFloat(value);
321                             break;
322                         }
323                         case 'D': {
324                             double value = doubleAt(offset);
325                             offset += 8;
326                             fieldValues[target + fieldNo] = new JavaDouble(value);
327                             break;
328                         }
329                         default:
330                             throw new RuntimeException("invalid signature: " + sig);
331 
332                     }
333                 }
334             } catch (IOException exp) {
335                 System.err.println("lazy read failed at offset " + offset);
336                 exp.printStackTrace();
337                 return Snapshot.EMPTY_JAVATHING_ARRAY;
338             }
339         }
340         return fieldValues;
341     }
342 
343     private void warn(String msg) {
344         System.out.println("WARNING: " + msg);
345     }
346 }
< prev index next >