Skip to content

Commit 1996f64

Browse files
committed
8273092: Sort classlist in JDK image
Reviewed-by: redestad, ihse, dfuchs
1 parent ba3587e commit 1996f64

File tree

3 files changed

+108
-12
lines changed

3 files changed

+108
-12
lines changed

make/GenerateLinkOptData.gmk

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2016, 2021, 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
@@ -88,7 +88,10 @@ $(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXECUTABLE_SUFFIX) $(CLASSLIST
8888
$(CAT) $(LINK_OPT_DIR)/stderr $(JLI_TRACE_FILE) ; \
8989
exit $$exitcode \
9090
)
91-
$(GREP) -v HelloClasslist $@.raw.2 > $@
91+
$(GREP) -v HelloClasslist $@.raw.2 > $@.raw.3
92+
$(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java \
93+
-cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
94+
build.tools.classlist.SortClasslist $@.raw.3 > $@
9295

9396
# The jli trace is created by the same recipe as classlist. By declaring these
9497
# dependencies, make will correctly rebuild both jli trace and classlist
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (c) 2021, 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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
/**
27+
* This application is meant to be run to create a classlist file representing
28+
* common use.
29+
*
30+
* The classlist is produced by adding -XX:DumpLoadedClassList=classlist
31+
*/
32+
package build.tools.classlist;
33+
34+
import java.io.FileInputStream;
35+
import java.io.FileNotFoundException;
36+
import java.util.ArrayList;
37+
import java.util.Collections;
38+
import java.util.regex.Pattern;
39+
import java.util.regex.Matcher;
40+
import java.util.Scanner;
41+
42+
/**
43+
* The classlist generated by build.tools.classlist.HelloClasslist
44+
* may have non-deterministic contents, affected by Java thread execution order.
45+
* SortClasslist sorts the file to make the JDK image's contents more deterministic.
46+
*/
47+
public class SortClasslist {
48+
public static void main(String args[]) throws FileNotFoundException {
49+
ArrayList<String> classes = new ArrayList<>();
50+
ArrayList<String> lambdas = new ArrayList<>();
51+
52+
FileInputStream fis = new FileInputStream(args[0]);
53+
Scanner scanner = new Scanner(fis);
54+
Pattern p = Pattern.compile("^(.*)[ ]+id:[ ]+([0-9]+)$");
55+
while (scanner.hasNextLine()) {
56+
String line = scanner.nextLine();
57+
Matcher m = p.matcher(line);
58+
if (line.startsWith("#")) {
59+
// Comments -- print them first without sorting. These appear only at the top
60+
// of the file.
61+
System.out.println(line);
62+
} else if (line.startsWith("@")) {
63+
// @lambda-form-invoker, @lambda-proxy, etc.
64+
lambdas.add(line);
65+
} else if (m.find()) {
66+
// We found a pattern like this:
67+
//
68+
// <beginning of line>java/lang/Object id: 0<end of line>
69+
//
70+
// This is a class used by one of the three builtin class loaders
71+
// (boot/platform/app). Since the default classlist does not support unregistered
72+
// classes, the ID is unused. Let's omit the ID, as it may be non-deterministic.
73+
String className = m.group(1); // matches the (.*) part of the pattern.
74+
classes.add(className);
75+
} else {
76+
// HelloClasslist should not load classes in custom class loaders, or else
77+
// we might end up with output like this:
78+
//
79+
// SomeClass id: 123 super: 0 source: foo.jar
80+
//
81+
// Such classes won't be usable for common applications, so they should
82+
// not be included in the JDK's default classlist.
83+
System.err.println("Unexpected line: " + line);
84+
System.err.println("The default classlist should not contain unregistered classes");
85+
System.exit(1);
86+
}
87+
}
88+
89+
Collections.sort(classes);
90+
Collections.sort(lambdas);
91+
92+
for (String s : classes) {
93+
System.out.println(s);
94+
}
95+
for (String s : lambdas) {
96+
System.out.println(s);
97+
}
98+
}
99+
}

make/scripts/compare.sh

+4-10
Original file line numberDiff line numberDiff line change
@@ -356,20 +356,14 @@ compare_general_files() {
356356
"
357357
$CAT $OTHER_DIR/$f | eval "$SVG_FILTER" > $OTHER_FILE
358358
$CAT $THIS_DIR/$f | eval "$SVG_FILTER" > $THIS_FILE
359-
elif [[ "$f" = *"/lib/classlist" ]] || [ "$SUFFIX" = "jar_contents" ]; then
360-
# The classlist files may have some lines in random order
359+
elif [ "$SUFFIX" = "jar_contents" ]; then
360+
# The jar_contents files may have some lines in random order
361361
OTHER_FILE=$WORK_DIR/$f.other
362362
THIS_FILE=$WORK_DIR/$f.this
363363
$MKDIR -p $(dirname $OTHER_FILE) $(dirname $THIS_FILE)
364364
$RM $OTHER_FILE $THIS_FILE
365-
# Also filter out the "id: NNNN" in the classlists
366-
if [[ "$f" = *"/lib/classlist" ]]; then
367-
$CAT $OTHER_DIR/$f | $SORT | $SED "s| id: .*||g" > $OTHER_FILE
368-
$CAT $THIS_DIR/$f | $SORT | $SED "s| id: .*||g" > $THIS_FILE
369-
else
370-
$CAT $OTHER_DIR/$f | $SORT > $OTHER_FILE
371-
$CAT $THIS_DIR/$f | $SORT > $THIS_FILE
372-
fi
365+
$CAT $OTHER_DIR/$f | $SORT > $OTHER_FILE
366+
$CAT $THIS_DIR/$f | $SORT > $THIS_FILE
373367
else
374368
OTHER_FILE=$OTHER_DIR/$f
375369
THIS_FILE=$THIS_DIR/$f

0 commit comments

Comments
 (0)