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
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
3836import java .lang .reflect .Field ;
3937import java .lang .reflect .Modifier ;
4038import 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+
4244import jdk .test .lib .apps .LingeredApp ;
4345import jdk .test .lib .JDKToolLauncher ;
4446import jdk .test .lib .hprof .model .HackJavaValue ;
45- import jdk .test .lib .hprof .model .InlinedJavaObject ;
4647import jdk .test .lib .hprof .model .JavaByte ;
4748import jdk .test .lib .hprof .model .JavaClass ;
4849import jdk .test .lib .hprof .model .JavaField ;
5354import jdk .test .lib .hprof .model .JavaThing ;
5455import jdk .test .lib .hprof .model .JavaValueArray ;
5556import jdk .test .lib .hprof .model .Snapshot ;
56- import jdk .test .lib .process .ProcessTools ;
57-
58- import java .util .Enumeration ;
59-
6057import 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
148137class 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
158145public 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 }
0 commit comments