Skip to content

Commit 1f4cdb3

Browse files
committedSep 5, 2023
8315127: CDSMapTest fails with incorrect number of oop references
Reviewed-by: ccheung
1 parent 939d7c5 commit 1f4cdb3

File tree

2 files changed

+61
-27
lines changed

2 files changed

+61
-27
lines changed
 

‎test/hotspot/jtreg/runtime/cds/CDSMapReader.java

+60-19
Original file line numberDiff line numberDiff line change
@@ -24,33 +24,57 @@
2424
import java.io.BufferedReader;
2525
import java.io.FileReader;
2626
import java.io.IOException;
27-
import java.io.RandomAccessFile;
2827
import java.util.ArrayList;
2928
import java.util.HashMap;
3029
import java.util.regex.Matcher;
3130
import java.util.regex.Pattern;
3231

33-
// This is a simple parser for parsing the output of
34-
//
35-
// java -Xshare:dump -Xlog:cds+map=debug,cds+map+oops=trace:file=cds.map:none:filesize=0
36-
//
37-
// Currently it just check the output related to JDK-8308903.
38-
// I.e., each oop fields in the HeapObjects must point to a valid HeapObject.
39-
//
40-
// It can be extended to check for the other parts of the map file, or perform
41-
// more analysis on the HeapObjects.
32+
/*
33+
34+
This is a simple parser for parsing the output of
35+
36+
java -Xshare:dump -Xlog:cds+map=debug,cds+map+oops=trace:file=cds.map:none:filesize=0
37+
38+
The map file contains patterns like this for the heap objects:
39+
40+
======================================================================
41+
0x00000000ffe00000: @@ Object (0xffe00000) java.lang.String
42+
- klass: 'java/lang/String' 0x0000000800010220
43+
- fields (3 words):
44+
- private 'hash' 'I' @12 0 (0x00000000)
45+
- private final 'coder' 'B' @16 0 (0x00)
46+
- private 'hashIsZero' 'Z' @17 true (0x01)
47+
- injected 'flags' 'B' @18 1 (0x01)
48+
- private final 'value' '[B' @20 0x00000000ffe00018 (0xffe00018) [B length: 0
49+
0x00000000ffe00018: @@ Object (0xffe00018) [B length: 0
50+
- klass: {type array byte} 0x00000008000024d8
51+
======================================================================
52+
53+
Currently this parser just check the output related to JDK-8308903.
54+
I.e., each oop field must point to a valid HeapObject. For example, the 'value' field
55+
in the String must point to a valid byte array.
56+
57+
This parser can be extended to check for the other parts of the map file, or perform
58+
more analysis on the HeapObjects.
59+
60+
*/
61+
4262
public class CDSMapReader {
4363
public static class MapFile {
4464
ArrayList<HeapObject> heapObjects = new ArrayList<>();
4565
HashMap<Long, HeapObject> oopToObject = new HashMap<>();
4666
HashMap<Long, HeapObject> narrowOopToObject = new HashMap<>();
67+
public int stringCount = 0;
4768

4869
void add(HeapObject heapObject) {
4970
heapObjects.add(heapObject);
5071
oopToObject.put(heapObject.address.oop, heapObject);
5172
if (heapObject.address.narrowOop != 0) {
5273
narrowOopToObject.put(heapObject.address.narrowOop, heapObject);
5374
}
75+
if (heapObject.className.equals("java.lang.String")) {
76+
stringCount ++;
77+
}
5478
}
5579

5680
public int heapObjectCount() {
@@ -184,7 +208,6 @@ private static HeapObject parseHeapObjectImpl(String className, String oop, Stri
184208
if ((m = match(line, fieldsWordsPattern)) == null) {
185209
throw new RuntimeException("Expected field size info");
186210
}
187-
// TODO: read all the array elements
188211
while (true) {
189212
nextLine();
190213
if (line == null || !line.startsWith(" - ")) {
@@ -233,6 +256,7 @@ static String nextLine() throws IOException {
233256

234257
public static MapFile read(String fileName) {
235258
mapFile = new MapFile();
259+
lineCount = 0;
236260

237261
try (BufferedReader r = new BufferedReader(new FileReader(fileName))) {
238262
reader = r;
@@ -254,7 +278,8 @@ public static MapFile read(String fileName) {
254278
throw new RuntimeException(t);
255279
} finally {
256280
System.out.println("Parsed " + lineCount + " lines in " + fileName);
257-
System.out.println("Found " + mapFile.heapObjectCount() + " heap objects");
281+
System.out.println("Found " + mapFile.heapObjectCount() + " heap objects ("
282+
+ mapFile.stringCount + " strings)");
258283
mapFile = null;
259284
reader = null;
260285
line = null;
@@ -270,8 +295,9 @@ private static void mustContain(HashMap<Long, HeapObject> allObjects, Field fiel
270295
}
271296

272297
// Check that each oop fields in the HeapObjects must point to a valid HeapObject.
273-
public static int validate(MapFile mapFile) {
274-
int count = 0;
298+
public static void validate(MapFile mapFile) {
299+
int count1 = 0;
300+
int count2 = 0;
275301
for (HeapObject heapObject : mapFile.heapObjects) {
276302
if (heapObject.fields != null) {
277303
for (Field field : heapObject.fields) {
@@ -281,17 +307,32 @@ public static int validate(MapFile mapFile) {
281307
// Is this test actually doing something?
282308
// To see how an invalidate pointer may be found, change oop in the
283309
// following line to oop+1
284-
mustContain(mapFile.oopToObject, field, oop, false);
285-
count ++;
310+
if (oop != 0) {
311+
mustContain(mapFile.oopToObject, field, oop, false);
312+
count1 ++;
313+
}
286314
if (narrowOop != 0) {
287315
mustContain(mapFile.narrowOopToObject, field, narrowOop, true);
288-
count ++;
316+
count2 ++;
289317
}
290318
}
291319
}
292320
}
293-
System.out.println("Checked " + count + " oop field references");
294-
return count;
321+
System.out.println("Found " + count1 + " non-null oop field references (normal)");
322+
System.out.println("Found " + count2 + " non-null oop field references (narrow)");
323+
324+
if (mapFile.heapObjectCount() > 0) {
325+
// heapObjectCount() may be zero if the selected GC doesn't support heap object archiving.
326+
if (mapFile.stringCount <= 0) {
327+
throw new RuntimeException("CDS map file should contain at least one string");
328+
}
329+
if (count1 < mapFile.stringCount) {
330+
throw new RuntimeException("CDS map file seems incorrect: " + mapFile.heapObjectCount() +
331+
" objects (" + mapFile.stringCount + " strings). Each string should" +
332+
" have one non-null oop field but we found only " + count1 +
333+
" non-null oop field references");
334+
}
335+
}
295336
}
296337

297338
public static void main(String args[]) {

‎test/hotspot/jtreg/runtime/cds/CDSMapTest.java

+1-8
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
import jdk.test.lib.cds.CDSOptions;
3434
import jdk.test.lib.cds.CDSTestUtils;
3535
import jdk.test.lib.Platform;
36-
import java.io.FileInputStream;
37-
import java.io.IOException;
3836
import java.util.ArrayList;
3937

4038
public class CDSMapTest {
@@ -76,11 +74,6 @@ static void dump(ArrayList<String> args, String... more) throws Exception {
7674
CDSTestUtils.createArchiveAndCheck(opts);
7775

7876
CDSMapReader.MapFile mapFile = CDSMapReader.read(mapName);
79-
int oopFieldCount = CDSMapReader.validate(mapFile);
80-
if (mapFile.heapObjectCount() > 0 && oopFieldCount < 10000) {
81-
// heapObjectCount() may be zero if the selected GC doesn't support heap object archiving.
82-
throw new RuntimeException("CDS map file seems incorrect: " + mapFile.heapObjectCount() +
83-
" objects but only " + oopFieldCount + " oop field references");
84-
}
77+
CDSMapReader.validate(mapFile);
8578
}
8679
}

0 commit comments

Comments
 (0)