< prev index next >

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

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.
--- 1,7 ---
  /*
!  * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.

*** 71,10 ***
--- 71,13 ---
      // Size of an instance, including VM overhead
      private int instanceSize;
      // Total number of fields including inherited ones
      private int totalNumFields;
  
+     // Size of the instance in the object of the class is inlined.
+     // Calculated lazily.
+     private int inlinedInstanceSize = -1;
  
      public JavaClass(long id, String name, long superclassId, long loaderId,
                       long signersId, long protDomainId,
                       JavaField[] fields, JavaStatic[] statics,
                       int instanceSize) {

*** 112,10 ***
--- 115,50 ---
      public void resolve(Snapshot snapshot) {
          if (mySnapshot != null) {
              return;
          }
          mySnapshot = snapshot;
+ 
+         // Resolve inlined fields. Should be done before resolveSuperclass for correct field counting
+         Snapshot.ClassInlinedFields[] inlinedFields = snapshot.findClassInlinedFields(id);
+         if (inlinedFields != null) {
+             int newCount = fields.length;
+             for (Snapshot.ClassInlinedFields f: inlinedFields) {
+                 if (f.synthFieldCount == 0) {
+                     // Empty primitive class. just skip it - no data there.
+                     continue;
+                 }
+                 JavaHeapObject clazz = snapshot.findThing(f.fieldClassID);
+                 if (clazz instanceof JavaClass fieldClass) {
+                     fieldClass.resolve(snapshot);
+ 
+                     // Set new field.
+                     fields[f.fieldIndex] = new InlinedJavaField(f.fieldName, 'Q' + fieldClass.getName() + ';', fieldClass);
+                     newCount -= (f.synthFieldCount - 1);
+                     // Reset invalid fields.
+                     for (int i = 1; i < f.synthFieldCount; i++) {
+                         fields[f.fieldIndex + i] = null;
+                     }
+                 } else {
+                     // The field class not found.
+                     System.out.println("WARNING: class of inlined field not found:" + getName() + "." + f.fieldName);
+                 }
+             }
+ 
+             // Set new fields.
+             JavaField[] newFields = new JavaField[newCount];
+             int oldIndex = 0;
+             for (int i = 0; i < newFields.length; i++) {
+                 while (fields[oldIndex] == null) {
+                     oldIndex++;
+                 }
+                 newFields[i] = fields[oldIndex];
+                 oldIndex++;
+             }
+             fields = newFields;
+         }
+ 
          resolveSuperclass(snapshot);
          if (superclass != null) {
              ((JavaClass) superclass).addSubclass(this);
          }
  

*** 126,10 ***
--- 169,11 ---
          for (int i = 0; i < statics.length; i++) {
              statics[i].resolve(this, snapshot);
          }
          snapshot.getJavaLangClass().addInstance(this);
          super.resolve(snapshot);
+ 
          return;
      }
  
      /**
       * Resolve our superclass.  This might be called well before

*** 375,10 ***
--- 419,53 ---
       */
      public int getInstanceSize() {
          return instanceSize + mySnapshot.getMinimumObjectSize();
      }
  
+     public int getInlinedInstanceSize() {
+         if (inlinedInstanceSize < 0) {
+             int size = 0;
+             for (JavaField f: fields) {
+                 if (f instanceof InlinedJavaField inlinedField) {
+                     size += inlinedField.getInlinedFieldClass().getInlinedInstanceSize();
+                 } else {
+                     char sig = f.getSignature().charAt(0);
+                     switch (sig) {
+                         case 'Q': {
+                             System.out.println("WARNING: (getInlinedInstanceSize) field "
+                                     + getClazz().getName() + "." + f.getName()
+                                     + " is not inlined, but has Q-signature: " + f.getSignature());
+                         } // continue as 'L' object
+                         case 'L':
+                         case '[':
+                             size += mySnapshot.getIdentifierSize();
+                             break;
+                         case 'B':
+                         case 'Z':
+                             size += 1;
+                             break;
+                         case 'C':
+                         case 'S':
+                             size += 2;
+                             break;
+                         case 'I':
+                         case 'F':
+                             size += 4;
+                             break;
+                         case 'J':
+                         case 'D':
+                             size += 8;
+                             break;
+                         default:
+                             throw new RuntimeException("unknown field type: " + sig);
+                     }
+                 }
+             }
+             inlinedInstanceSize = size;
+         }
+         return inlinedInstanceSize;
+     }
  
      /**
       * @return The size of all instances of this class.  Correctly handles
       *          arrays.
       */
< prev index next >