Skip to content

Commit 296fe86

Browse files
author
Alex Menkov
committed
8341771: [lworld] Heap dump recognizing new flat fields formats
8328468: [lworld] Reimplement HeapDump test for JEP401 8317416: [lworld] JDK-8306441 (Two phase segmented heap dump) needs Valhalla support Reviewed-by: fparain
1 parent a0ec244 commit 296fe86

File tree

10 files changed

+477
-1123
lines changed

10 files changed

+477
-1123
lines changed

src/hotspot/share/services/heapDumper.cpp

Lines changed: 301 additions & 588 deletions
Large diffs are not rendered by default.

test/hotspot/jtreg/ProblemList.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,6 @@ serviceability/jvmti/stress/StackTrace/NotSuspended/GetStackTraceNotSuspendedStr
189189

190190

191191
# Valhalla TODO:
192-
serviceability/jvmti/valhalla/HeapDump/HeapDump.java 8317416 generic-all
193-
194192
serviceability/sa/ClhsdbCDSCore.java 8190936 generic-all
195193
serviceability/sa/ClhsdbCDSJstackPrintAll.java 8190936 generic-all
196194
serviceability/sa/ClhsdbFindPC.java 8190936 generic-all
@@ -242,7 +240,6 @@ serviceability/sa/TestInstanceKlassSize.java 8365722 generic-all
242240
serviceability/sa/TestSysProps.java 8365722 generic-all
243241
serviceability/sa/sadebugd/ClhsdbAttachToDebugServer.java 8365722 generic-all
244242
resourcehogs/serviceability/sa/TestHeapDumpForLargeArray.java 8365722 generic-all
245-
serviceability/HeapDump/DuplicateArrayClassesTest.java 8365722 generic-all
246243

247244
resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java 8190936 generic-all
248245
vmTestbase/nsk/jvmti/scenarios/events/EM04/em04t001/TestDescription.java 8367590 generic-all

test/hotspot/jtreg/serviceability/jvmti/valhalla/HeapDump/HeapDump.java

Lines changed: 70 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,13 +22,11 @@
2222
*/
2323

2424
/**
25-
* @ignore Fix JDK-8328468
2625
* @test
2726
* @modules java.base/jdk.internal.value
2827
* @library /test/lib
29-
* @requires vm.jvmti
28+
* @modules java.base/jdk.internal.vm.annotation java.base/jdk.internal.value
3029
* @enablePreview
31-
* @compile HeapDump.java
3230
* @run main/othervm HeapDump
3331
*/
3432

@@ -38,11 +36,14 @@
3836
import java.lang.reflect.Field;
3937
import java.lang.reflect.Modifier;
4038
import java.util.concurrent.TimeUnit;
41-
import jdk.internal.value.PrimitiveClass;
39+
import java.util.Enumeration;
40+
import jdk.internal.value.ValueClass;
41+
import jdk.internal.vm.annotation.NullRestricted;
42+
import jdk.internal.vm.annotation.Strict;
43+
4244
import jdk.test.lib.apps.LingeredApp;
4345
import jdk.test.lib.JDKToolLauncher;
4446
import jdk.test.lib.hprof.model.HackJavaValue;
45-
import jdk.test.lib.hprof.model.InlinedJavaObject;
4647
import jdk.test.lib.hprof.model.JavaByte;
4748
import jdk.test.lib.hprof.model.JavaClass;
4849
import jdk.test.lib.hprof.model.JavaField;
@@ -53,106 +54,92 @@
5354
import jdk.test.lib.hprof.model.JavaThing;
5455
import jdk.test.lib.hprof.model.JavaValueArray;
5556
import jdk.test.lib.hprof.model.Snapshot;
56-
import jdk.test.lib.process.ProcessTools;
57-
58-
import java.util.Enumeration;
59-
6057
import jdk.test.lib.hprof.parser.Reader;
58+
import jdk.test.lib.process.ProcessTools;
6159

6260

63-
class TestClass {
64-
65-
public static primitive class MyPrimitive0 {
66-
public byte prim0_fld1;
67-
public MyPrimitive0(int fld1) { prim0_fld1 = (byte)fld1; }
68-
}
69-
public static primitive class MyPrimitive {
70-
public MyPrimitive0 prim_prim0;
71-
public byte prim_fld1;
72-
public int prim_fld2;
61+
value class TestClass {
7362

74-
public MyPrimitive(int p0, int fld1, int fld2) {
75-
prim_fld1 = (byte)fld1; prim_fld2 = fld2; prim_prim0 = new MyPrimitive0(p0);
76-
}
63+
public static value class Value0 {
64+
public int value0_int;
65+
public Value0(int i) { value0_int = i; }
7766
}
7867

79-
public static primitive class PrimitiveHolder {
80-
// offset of the inlined hld_flatObj is the same as offset of inlined PrimitiveHolder
81-
public MyPrimitive hld_flatObj;
68+
// value class with the only value filed
69+
// offset of flattened value_value0 is the same as offset of flattened Value
70+
public static value class Value {
71+
public Value0 value_value0;
8272

83-
public PrimitiveHolder(int n) {
84-
hld_flatObj = new MyPrimitive((byte)n, n+1, n+2);
73+
public Value(int i) {
74+
value_value0 = i == 0 ? null : new Value0(i);
8575
}
8676
}
8777

88-
// primitive class with reference
89-
public static primitive class MyPrimitiveRef {
90-
public byte ref_fld1;
91-
public int ref_fld2;
92-
public String ref_strObj;
78+
public static value class ValueHolder {
79+
public Value holder_value;
9380

94-
public MyPrimitiveRef(int v1, int v2) {
95-
ref_fld1 = (byte)v1;
96-
ref_fld2 = v2;
97-
ref_strObj = "#" + String.valueOf(v2); }
81+
public ValueHolder(int i) {
82+
holder_value = new Value(i);
83+
}
9884
}
9985

100-
public static primitive class PrimitiveHolderRef {
101-
public MyPrimitiveRef[] flatArr = new MyPrimitiveRef[5];
102-
public MyPrimitiveRef flatObj;
86+
// value class with reference (String)
87+
public static value class ValueRef {
88+
public Value ref_value;
10389
public String ref_str;
104-
public PrimitiveHolderRef(int n) {
105-
ref_str = String.valueOf(n);
106-
flatObj = new MyPrimitiveRef(n, n + 10);
107-
for (int i = 0; i < flatArr.length; i++) {
108-
flatArr[i] = new MyPrimitiveRef(i + n + 1, i + n + 11);
109-
}
90+
91+
public ValueRef(int i) {
92+
ref_value = new Value(i);
93+
ref_str = "#" + String.valueOf(i);
11094
}
11195
}
11296

113-
public MyPrimitive[] main_flatArr = new MyPrimitive[3];
114-
public MyPrimitive main_flatObj = new MyPrimitive(10, 15, 9);
115-
public MyPrimitiveRef main_flatObjRef = new MyPrimitiveRef(11, 144);
116-
public MyPrimitiveRef[] flatArrRef = new MyPrimitiveRef[4];
117-
public String main_strObj = "targ.strObj";
118-
119-
public Object main_nullObj;
120-
121-
public final PrimitiveHolder main_primHolder = new PrimitiveHolder(16);
122-
// array of compound primitive objects
123-
public final PrimitiveHolderRef[] primHolderArr = new PrimitiveHolderRef[4];
97+
// nullable value
98+
public Value nullableValue = new Value(1);
99+
// null restricted value
100+
@Strict
101+
@NullRestricted
102+
public Value nullRestrictedValue = new Value(11);
103+
// null value
104+
public Value nullValue = null;
105+
// value object with reference
106+
public ValueRef refValue = new ValueRef(21);
107+
108+
// nullable array
109+
public Value[] nullableArray = createNullableArray(101);
110+
// null restricted array
111+
public Value[] nullRestrictedArray = createNullRestrictedArray(201);
112+
113+
// static value field (for sanity, cannot be flat)
114+
public static Value staticValue = new Value(31);
124115

116+
public TestClass() {
117+
}
125118

126-
// static inlined fields
127-
public static MyPrimitive main_flatObjStatic = new MyPrimitive(13, 241, 24);
128-
public static MyPrimitiveRef[] flatArrRefStatic = new MyPrimitiveRef[6];
129-
static {
130-
for (int i = 0; i < flatArrRefStatic.length; i++) {
131-
flatArrRefStatic[i] = new MyPrimitiveRef(i + 200, i + 225);
119+
static Value[] createNullableArray(int seed) {
120+
Value[] arr = (Value[])ValueClass.newNullableAtomicArray(Value.class, 5);
121+
for (int i = 0; i < arr.length; i++) {
122+
arr[i] = (i % 2 != 0) ? null : new Value(seed + i);
132123
}
124+
return arr;
133125
}
134126

135-
public TestClass() {
136-
for (int i = 0; i < main_flatArr.length; i++) {
137-
main_flatArr[i] = new MyPrimitive(i + 10, i + 110, i + 35);
138-
}
139-
for (int i = 0; i < flatArrRef.length; i++) {
140-
flatArrRef[i] = new MyPrimitiveRef(i + 100, i + 120);
141-
}
142-
for (int i = 0; i < primHolderArr.length; i++) {
143-
primHolderArr[i] = new PrimitiveHolderRef(20 + i);
127+
static Value[] createNullRestrictedArray(int seed) {
128+
Value defValue = new Value(0);
129+
Value[] arr = (Value[])ValueClass.newNullRestrictedNonAtomicArray(Value.class, 5, defValue);
130+
for (int i = 0; i < arr.length; i++) {
131+
arr[i] = new Value(seed + i);
144132
}
133+
return arr;
145134
}
146135
}
147136

148137
class HeapDumpTarg extends LingeredApp {
149-
150138
public static void main(String[] args) {
151139
TestClass testObj = new TestClass();
152140
LingeredApp.main(args);
153141
Reference.reachabilityFence(testObj);
154142
}
155-
156143
}
157144

158145
public class HeapDump {
@@ -163,7 +150,9 @@ public static void main(String[] args) throws Throwable {
163150
theApp = new HeapDumpTarg();
164151

165152
// -XX:+PrintInlineLayout is debug-only arg
166-
LingeredApp.startApp(theApp, "--enable-preview"/*, "-XX:+PrintInlineLayout"*/);
153+
LingeredApp.startApp(theApp, "--enable-preview", "-XX:+PrintInlineLayout", "-XX:+PrintFlatArrayLayout",
154+
"--add-modules=java.base",
155+
"--add-exports=java.base/jdk.internal.value=ALL-UNNAMED");
167156

168157
// jcmd <pid> GC.heap_dump
169158
JDKToolLauncher launcher = JDKToolLauncher
@@ -271,7 +260,6 @@ private static void compareObjectFields(String logPrefix, Object testObj, JavaOb
271260
boolean isStatic = Modifier.isStatic(testField.getModifiers());
272261
testField.setAccessible(true);
273262
objDescr = "- " + (isStatic ? "(static) " : "")
274-
+ (PrimitiveClass.isPrimitiveClass(testField.getType()) ? "(primitive) " : "")
275263
+ testField.getName() + " ('" + testField.getType().descriptorString() + "')";
276264
try {
277265
Object testValue = testField.get(testObj);
@@ -293,7 +281,6 @@ private static void compareObjectFields(String logPrefix, Object testObj, JavaOb
293281
} else {
294282
switch (testField.getType().descriptorString().charAt(0)) {
295283
case 'L':
296-
case 'Q':
297284
compareObjects(logPrefix, testValue, dumpValue);
298285
break;
299286
case '[':
@@ -315,12 +302,8 @@ private static void compareObjectFields(String logPrefix, Object testObj, JavaOb
315302
for (int j = 0; j < testLength; j++) {
316303
Object elementValue = Array.get(testValue, j);
317304
objDescr = "[" + j + "]";
318-
if (arr.isFlatArray()) {
319-
compareObjects(logPrefix + " ", elementValue, dumpElements[j]);
320-
} else {
321-
comparePrimitiveValues(elementValue, dumpElements[j]);
322-
log(logPrefix + " [" + j + "]: " + elementValue + " ( == " + dumpElements[j] + ")");
323-
}
305+
comparePrimitiveValues(elementValue, dumpElements[j]);
306+
log(logPrefix + " [" + j + "]: " + elementValue + " ( == " + dumpElements[j] + ")");
324307
}
325308
} else if (dumpValue instanceof JavaObjectArray arr) {
326309
int dumpLength = arr.getLength();
@@ -378,13 +361,10 @@ private static JavaField getField(JavaObject obj, String fieldName, boolean isSt
378361
private static void compareType(Field field, JavaField dumpField) throws Exception {
379362
String sig = field.getType().descriptorString();
380363
char type = sig.charAt(0);
381-
if (type == '[' || type == 'Q') {
364+
if (type == '[') {
382365
type = 'L';
383366
}
384367
char dumpType = dumpField.getSignature().charAt(0);
385-
if (dumpType == 'Q') {
386-
dumpType = 'L';
387-
}
388368
if (dumpType != type) {
389369
throw new Exception("type mismatch:"
390370
+ " expected '" + type + "' (" + sig + ")"
@@ -466,7 +446,7 @@ private static void printFieldValue(String prefix, JavaField field, boolean isSt
466446
String dumpStr = getStringValue(obj);
467447
log(logPrefix + "\"" + dumpStr + "\"");
468448
} else {
469-
log(logPrefix + (value instanceof InlinedJavaObject ? "inlined " : "") + "object " + obj);
449+
log(logPrefix + "object " + obj);
470450
print(prefix + " ", obj);
471451
}
472452
} else if (value instanceof JavaObjectArray arr) {
@@ -478,19 +458,8 @@ private static void printFieldValue(String prefix, JavaField field, boolean isSt
478458
print(prefix + " ", obj);
479459
}
480460
}
481-
} else if (value instanceof JavaValueArray arr) { // array of primitive type or flat array
482-
if (arr.isFlatArray()) {
483-
log(logPrefix + " flat array " + arr + " length: " + arr.getLength());
484-
JavaThing[] values = arr.getElements();
485-
for (int v = 0; v < values.length; v++) {
486-
log(prefix + " [" + v + "]: " + values[v]);
487-
if (values[v] instanceof JavaObject obj) {
488-
print(prefix + " ", obj);
489-
}
490-
}
491-
} else {
492-
log(logPrefix + "(array of '" + (char)arr.getElementType() + "')" + ": " + arr.valueString());
493-
}
461+
} else if (value instanceof JavaValueArray arr) {
462+
log(logPrefix + "(array of '" + (char)arr.getElementType() + "')" + ": " + arr.valueString());
494463
} else {
495464
log(logPrefix + "(" + value.getClass() + ")" + value.toString());
496465
}

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

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)