8273092: Sort classlist in JDK image

Reviewed-by: redestad, ihse, dfuchs
This commit is contained in:
Ioi Lam 2021-08-31 16:33:02 +00:00
parent ba3587e524
commit 1996f649a3
3 changed files with 108 additions and 12 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# 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
$(CAT) $(LINK_OPT_DIR)/stderr $(JLI_TRACE_FILE) ; \
exit $$exitcode \
)
$(GREP) -v HelloClasslist $@.raw.2 > $@
$(GREP) -v HelloClasslist $@.raw.2 > $@.raw.3
$(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java \
-cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
build.tools.classlist.SortClasslist $@.raw.3 > $@
# The jli trace is created by the same recipe as classlist. By declaring these
# dependencies, make will correctly rebuild both jli trace and classlist

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* This application is meant to be run to create a classlist file representing
* common use.
*
* The classlist is produced by adding -XX:DumpLoadedClassList=classlist
*/
package build.tools.classlist;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Scanner;
/**
* The classlist generated by build.tools.classlist.HelloClasslist
* may have non-deterministic contents, affected by Java thread execution order.
* SortClasslist sorts the file to make the JDK image's contents more deterministic.
*/
public class SortClasslist {
public static void main(String args[]) throws FileNotFoundException {
ArrayList<String> classes = new ArrayList<>();
ArrayList<String> lambdas = new ArrayList<>();
FileInputStream fis = new FileInputStream(args[0]);
Scanner scanner = new Scanner(fis);
Pattern p = Pattern.compile("^(.*)[ ]+id:[ ]+([0-9]+)$");
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
Matcher m = p.matcher(line);
if (line.startsWith("#")) {
// Comments -- print them first without sorting. These appear only at the top
// of the file.
System.out.println(line);
} else if (line.startsWith("@")) {
// @lambda-form-invoker, @lambda-proxy, etc.
lambdas.add(line);
} else if (m.find()) {
// We found a pattern like this:
//
// <beginning of line>java/lang/Object id: 0<end of line>
//
// This is a class used by one of the three builtin class loaders
// (boot/platform/app). Since the default classlist does not support unregistered
// classes, the ID is unused. Let's omit the ID, as it may be non-deterministic.
String className = m.group(1); // matches the (.*) part of the pattern.
classes.add(className);
} else {
// HelloClasslist should not load classes in custom class loaders, or else
// we might end up with output like this:
//
// SomeClass id: 123 super: 0 source: foo.jar
//
// Such classes won't be usable for common applications, so they should
// not be included in the JDK's default classlist.
System.err.println("Unexpected line: " + line);
System.err.println("The default classlist should not contain unregistered classes");
System.exit(1);
}
}
Collections.sort(classes);
Collections.sort(lambdas);
for (String s : classes) {
System.out.println(s);
}
for (String s : lambdas) {
System.out.println(s);
}
}
}

View File

@ -356,20 +356,14 @@ compare_general_files() {
"
$CAT $OTHER_DIR/$f | eval "$SVG_FILTER" > $OTHER_FILE
$CAT $THIS_DIR/$f | eval "$SVG_FILTER" > $THIS_FILE
elif [[ "$f" = *"/lib/classlist" ]] || [ "$SUFFIX" = "jar_contents" ]; then
# The classlist files may have some lines in random order
elif [ "$SUFFIX" = "jar_contents" ]; then
# The jar_contents files may have some lines in random order
OTHER_FILE=$WORK_DIR/$f.other
THIS_FILE=$WORK_DIR/$f.this
$MKDIR -p $(dirname $OTHER_FILE) $(dirname $THIS_FILE)
$RM $OTHER_FILE $THIS_FILE
# Also filter out the "id: NNNN" in the classlists
if [[ "$f" = *"/lib/classlist" ]]; then
$CAT $OTHER_DIR/$f | $SORT | $SED "s| id: .*||g" > $OTHER_FILE
$CAT $THIS_DIR/$f | $SORT | $SED "s| id: .*||g" > $THIS_FILE
else
$CAT $OTHER_DIR/$f | $SORT > $OTHER_FILE
$CAT $THIS_DIR/$f | $SORT > $THIS_FILE
fi
$CAT $OTHER_DIR/$f | $SORT > $OTHER_FILE
$CAT $THIS_DIR/$f | $SORT > $THIS_FILE
else
OTHER_FILE=$OTHER_DIR/$f
THIS_FILE=$THIS_DIR/$f