1 /*
2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
56 // non-static fields
57 private JavaField[] fields;
58 // static fields
59 private JavaStatic[] statics;
60
61 private static final JavaClass[] EMPTY_CLASS_ARRAY = new JavaClass[0];
62 // my subclasses
63 private JavaClass[] subclasses = EMPTY_CLASS_ARRAY;
64
65 // my instances
66 private Vector<JavaHeapObject> instances = new Vector<JavaHeapObject>();
67
68 // Who I belong to. Set on resolve.
69 private Snapshot mySnapshot;
70
71 // Size of an instance, including VM overhead
72 private int instanceSize;
73 // Total number of fields including inherited ones
74 private int totalNumFields;
75
76
77 public JavaClass(long id, String name, long superclassId, long loaderId,
78 long signersId, long protDomainId,
79 JavaField[] fields, JavaStatic[] statics,
80 int instanceSize) {
81 this.id = id;
82 this.name = name;
83 this.superclass = new JavaObjectRef(superclassId);
84 this.loader = new JavaObjectRef(loaderId);
85 this.signers = new JavaObjectRef(signersId);
86 this.protectionDomain = new JavaObjectRef(protDomainId);
87 this.fields = fields;
88 this.statics = statics;
89 this.instanceSize = instanceSize;
90 }
91
92 public JavaClass(String name, long superclassId, long loaderId,
93 long signersId, long protDomainId,
94 JavaField[] fields, JavaStatic[] statics,
95 int instanceSize) {
97 protDomainId, fields, statics, instanceSize);
98 }
99
100 public final JavaClass getClazz() {
101 return mySnapshot.getJavaLangClass();
102 }
103
104 public final int getIdentifierSize() {
105 return mySnapshot.getIdentifierSize();
106 }
107
108 public final int getMinimumObjectSize() {
109 return mySnapshot.getMinimumObjectSize();
110 }
111
112 public void resolve(Snapshot snapshot) {
113 if (mySnapshot != null) {
114 return;
115 }
116 mySnapshot = snapshot;
117 resolveSuperclass(snapshot);
118 if (superclass != null) {
119 ((JavaClass) superclass).addSubclass(this);
120 }
121
122 loader = loader.dereference(snapshot, null);
123 signers = signers.dereference(snapshot, null);
124 protectionDomain = protectionDomain.dereference(snapshot, null);
125
126 for (int i = 0; i < statics.length; i++) {
127 statics[i].resolve(this, snapshot);
128 }
129 snapshot.getJavaLangClass().addInstance(this);
130 super.resolve(snapshot);
131 return;
132 }
133
134 /**
135 * Resolve our superclass. This might be called well before
136 * all instances are available (like when reading deferred
137 * instances in a 1.2 dump file :-) Calling this is sufficient
138 * to be able to explore this class' fields.
139 */
140 public void resolveSuperclass(Snapshot snapshot) {
141 if (superclass == null) {
142 // We must be java.lang.Object, so we have no superclass.
143 } else {
144 totalNumFields = fields.length;
145 superclass = superclass.dereference(snapshot, null);
146 if (superclass == snapshot.getNullThing()) {
147 superclass = null;
148 } else {
149 try {
150 JavaClass sc = (JavaClass) superclass;
360 for (int i = 0; i < statics.length; i++) {
361 JavaField f = statics[i].getField();
362 if (f.hasId()) {
363 JavaThing other = statics[i].getValue();
364 if (other == target) {
365 return "static field " + f.getName();
366 }
367 }
368 }
369 return super.describeReferenceTo(target, ss);
370 }
371
372 /**
373 * @return the size of an instance of this class. Gives 0 for an array
374 * type.
375 */
376 public int getInstanceSize() {
377 return instanceSize + mySnapshot.getMinimumObjectSize();
378 }
379
380
381 /**
382 * @return The size of all instances of this class. Correctly handles
383 * arrays.
384 */
385 public long getTotalInstanceSize() {
386 int count = instances.size();
387 if (count == 0 || !isArray()) {
388 return count * instanceSize;
389 }
390
391 // array class and non-zero count, we have to
392 // get the size of each instance and sum it
393 long result = 0;
394 for (int i = 0; i < count; i++) {
395 JavaThing t = (JavaThing) instances.elementAt(i);
396 result += t.getSize();
397 }
398 return result;
399 }
|
1 /*
2 * Copyright (c) 1997, 2022, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
56 // non-static fields
57 private JavaField[] fields;
58 // static fields
59 private JavaStatic[] statics;
60
61 private static final JavaClass[] EMPTY_CLASS_ARRAY = new JavaClass[0];
62 // my subclasses
63 private JavaClass[] subclasses = EMPTY_CLASS_ARRAY;
64
65 // my instances
66 private Vector<JavaHeapObject> instances = new Vector<JavaHeapObject>();
67
68 // Who I belong to. Set on resolve.
69 private Snapshot mySnapshot;
70
71 // Size of an instance, including VM overhead
72 private int instanceSize;
73 // Total number of fields including inherited ones
74 private int totalNumFields;
75
76 // Size of the instance in the object of the class is inlined.
77 // Calculated lazily.
78 private int inlinedInstanceSize = -1;
79
80 public JavaClass(long id, String name, long superclassId, long loaderId,
81 long signersId, long protDomainId,
82 JavaField[] fields, JavaStatic[] statics,
83 int instanceSize) {
84 this.id = id;
85 this.name = name;
86 this.superclass = new JavaObjectRef(superclassId);
87 this.loader = new JavaObjectRef(loaderId);
88 this.signers = new JavaObjectRef(signersId);
89 this.protectionDomain = new JavaObjectRef(protDomainId);
90 this.fields = fields;
91 this.statics = statics;
92 this.instanceSize = instanceSize;
93 }
94
95 public JavaClass(String name, long superclassId, long loaderId,
96 long signersId, long protDomainId,
97 JavaField[] fields, JavaStatic[] statics,
98 int instanceSize) {
100 protDomainId, fields, statics, instanceSize);
101 }
102
103 public final JavaClass getClazz() {
104 return mySnapshot.getJavaLangClass();
105 }
106
107 public final int getIdentifierSize() {
108 return mySnapshot.getIdentifierSize();
109 }
110
111 public final int getMinimumObjectSize() {
112 return mySnapshot.getMinimumObjectSize();
113 }
114
115 public void resolve(Snapshot snapshot) {
116 if (mySnapshot != null) {
117 return;
118 }
119 mySnapshot = snapshot;
120
121 // Resolve inlined fields. Should be done before resolveSuperclass for correct field counting
122 Snapshot.ClassInlinedFields[] inlinedFields = snapshot.findClassInlinedFields(id);
123 if (inlinedFields != null) {
124 int newCount = fields.length;
125 for (Snapshot.ClassInlinedFields f: inlinedFields) {
126 if (f.synthFieldCount == 0) {
127 // Empty primitive class. just skip it - no data there.
128 continue;
129 }
130 JavaHeapObject clazz = snapshot.findThing(f.fieldClassID);
131 if (clazz instanceof JavaClass fieldClass) {
132 fieldClass.resolve(snapshot);
133
134 // Set new field.
135 fields[f.fieldIndex] = new InlinedJavaField(f.fieldName, 'Q' + fieldClass.getName() + ';', fieldClass);
136 newCount -= (f.synthFieldCount - 1);
137 // Reset invalid fields.
138 for (int i = 1; i < f.synthFieldCount; i++) {
139 fields[f.fieldIndex + i] = null;
140 }
141 } else {
142 // The field class not found.
143 System.out.println("WARNING: class of inlined field not found:" + getName() + "." + f.fieldName);
144 }
145 }
146
147 // Set new fields.
148 JavaField[] newFields = new JavaField[newCount];
149 int oldIndex = 0;
150 for (int i = 0; i < newFields.length; i++) {
151 while (fields[oldIndex] == null) {
152 oldIndex++;
153 }
154 newFields[i] = fields[oldIndex];
155 oldIndex++;
156 }
157 fields = newFields;
158 }
159
160 resolveSuperclass(snapshot);
161 if (superclass != null) {
162 ((JavaClass) superclass).addSubclass(this);
163 }
164
165 loader = loader.dereference(snapshot, null);
166 signers = signers.dereference(snapshot, null);
167 protectionDomain = protectionDomain.dereference(snapshot, null);
168
169 for (int i = 0; i < statics.length; i++) {
170 statics[i].resolve(this, snapshot);
171 }
172 snapshot.getJavaLangClass().addInstance(this);
173 super.resolve(snapshot);
174
175 return;
176 }
177
178 /**
179 * Resolve our superclass. This might be called well before
180 * all instances are available (like when reading deferred
181 * instances in a 1.2 dump file :-) Calling this is sufficient
182 * to be able to explore this class' fields.
183 */
184 public void resolveSuperclass(Snapshot snapshot) {
185 if (superclass == null) {
186 // We must be java.lang.Object, so we have no superclass.
187 } else {
188 totalNumFields = fields.length;
189 superclass = superclass.dereference(snapshot, null);
190 if (superclass == snapshot.getNullThing()) {
191 superclass = null;
192 } else {
193 try {
194 JavaClass sc = (JavaClass) superclass;
404 for (int i = 0; i < statics.length; i++) {
405 JavaField f = statics[i].getField();
406 if (f.hasId()) {
407 JavaThing other = statics[i].getValue();
408 if (other == target) {
409 return "static field " + f.getName();
410 }
411 }
412 }
413 return super.describeReferenceTo(target, ss);
414 }
415
416 /**
417 * @return the size of an instance of this class. Gives 0 for an array
418 * type.
419 */
420 public int getInstanceSize() {
421 return instanceSize + mySnapshot.getMinimumObjectSize();
422 }
423
424 public int getInlinedInstanceSize() {
425 if (inlinedInstanceSize < 0) {
426 int size = 0;
427 for (JavaField f: fields) {
428 if (f instanceof InlinedJavaField inlinedField) {
429 size += inlinedField.getInlinedFieldClass().getInlinedInstanceSize();
430 } else {
431 char sig = f.getSignature().charAt(0);
432 switch (sig) {
433 case 'Q': {
434 System.out.println("WARNING: (getInlinedInstanceSize) field "
435 + getClazz().getName() + "." + f.getName()
436 + " is not inlined, but has Q-signature: " + f.getSignature());
437 } // continue as 'L' object
438 case 'L':
439 case '[':
440 size += mySnapshot.getIdentifierSize();
441 break;
442 case 'B':
443 case 'Z':
444 size += 1;
445 break;
446 case 'C':
447 case 'S':
448 size += 2;
449 break;
450 case 'I':
451 case 'F':
452 size += 4;
453 break;
454 case 'J':
455 case 'D':
456 size += 8;
457 break;
458 default:
459 throw new RuntimeException("unknown field type: " + sig);
460 }
461 }
462 }
463 inlinedInstanceSize = size;
464 }
465 return inlinedInstanceSize;
466 }
467
468 /**
469 * @return The size of all instances of this class. Correctly handles
470 * arrays.
471 */
472 public long getTotalInstanceSize() {
473 int count = instances.size();
474 if (count == 0 || !isArray()) {
475 return count * instanceSize;
476 }
477
478 // array class and non-zero count, we have to
479 // get the size of each instance and sum it
480 long result = 0;
481 for (int i = 0; i < count; i++) {
482 JavaThing t = (JavaThing) instances.elementAt(i);
483 result += t.getSize();
484 }
485 return result;
486 }
|