# HG changeset patch # User iignatyev # Date 1492107817 25200 # Node ID 24999171edf9acb63f8f9a6982baa5dfa249dc4a # Parent 5520c435279b2fdf83f20d00f9fc0fc5c6be6df6 8178291: Add CTW test for boot module Reviewed-by: kvn diff -r 5520c435279b -r 24999171edf9 hotspot/test/applications/ctw/Modules.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/applications/ctw/Modules.java Thu Apr 13 11:23:37 2017 -0700 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017, 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. + * + * 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. + */ + +/* + * @test + * @summary run CTW for all classes from boot "modules" jimage -- lib/modules. + * + * @library /test/lib / /testlibrary/ctw/src + * @modules java.base/jdk.internal.jimage + * java.base/jdk.internal.misc + * java.base/jdk.internal.reflect + * + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run driver/timeout=0 sun.hotspot.tools.ctw.CtwRunner modules + */ + diff -r 5520c435279b -r 24999171edf9 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java Thu Apr 13 09:42:10 2017 -0400 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java Thu Apr 13 11:23:37 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, 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 @@ -87,6 +87,8 @@ Compiler.getMethodCount(), System.currentTimeMillis() - start); passed = true; + } catch (Throwable t){ + t.printStackTrace(ERR); } finally { // might have started new threads System.exit(passed ? 0 : 1); diff -r 5520c435279b -r 24999171edf9 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java Thu Apr 13 11:23:37 2017 -0700 @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2017, 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. + * + * 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. + */ + +package sun.hotspot.tools.ctw; + +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * Runs CompileTheWorld for exact one target. If an error occurs during + * compilation of class N, this driver class saves error information and + * restarts CTW from class N + 1. All saved errors are reported at the end. + *
+ * Usage: 
+ * 
+ */ +public class CtwRunner { + private static final Predicate IS_CLASS_LINE = Pattern.compile( + "^\\[\\d+\\]\\s*\\S+\\s*$").asPredicate(); + + public static void main(String[] args) throws Exception { + if (args.length != 1) { + throw new Error("Usage: "); + } + new CtwRunner(args[0]).run(); + } + + private final List errors; + private final Path targetPath; + private final String targetName; + + private CtwRunner(String target) { + if (target.equals("modules")) { + targetPath = Paths + .get(Utils.TEST_JDK) + .resolve("lib") + .resolve(target); + } else { + targetPath = Paths.get(target).toAbsolutePath(); + } + targetName = targetPath.getFileName().toString(); + errors = new ArrayList<>(); + } + + + private void run() { + startCtwforAllClasses(); + if (!errors.isEmpty()) { + StringBuilder sb = new StringBuilder(); + sb.append("There were ") + .append(errors.size()) + .append(" errors:["); + System.err.println(sb.toString()); + for (Throwable e : errors) { + sb.append("{") + .append(e.getMessage()) + .append("}"); + e.printStackTrace(System.err); + System.err.println(); + } + sb.append("]"); + throw new AssertionError(sb.toString()); + } + } + + + private void startCtwforAllClasses() { + long classStart = 0; + boolean done = false; + while (!done) { + String[] cmd = cmd(classStart); + try { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + /* addTestVmAndJavaOptions = */ true, + cmd); + String commandLine = pb.command() + .stream() + .collect(Collectors.joining(" ")); + String phase = phaseName(classStart); + Path out = Paths.get(".", phase + ".out"); + System.out.printf("%s %dms START : [%s]%n" + + "cout/cerr are redirected to %s%n", + phase, TimeUnit.NANOSECONDS.toMillis(System.nanoTime()), + commandLine, out); + int exitCode = pb.redirectErrorStream(true) + .redirectOutput(out.toFile()) + .start() + .waitFor(); + System.out.printf("%s %dms END : exit code = %d%n", + phase, TimeUnit.NANOSECONDS.toMillis(System.nanoTime()), + exitCode); + long lastClassIndex = getLastClassIndex(out); + if (exitCode == 0) { + done = true; + } else { + if (lastClassIndex == 0) { + errors.add(new Error(phase + ": failed during preload" + + " with classStart = " + classStart)); + // skip one class + ++classStart; + } else { + errors.add(new Error(phase + ": failed during" + + " compilation of class #" + lastClassIndex)); + // continue with the next class + classStart = lastClassIndex + 1; + } + } + } catch (Exception e) { + throw new Error("failed to run from " + classStart, e); + } + } + } + + private long getLastClassIndex(Path errFile) { + long result = 0; + try { + String line = Files.newBufferedReader(errFile) + .lines() + .filter(IS_CLASS_LINE) + .reduce((a, b) -> b).orElse(null); + if (line != null) { + int open = line.indexOf('[') + 1; + int close = line.indexOf(']'); + result = Long.parseLong(line.substring(open, close)); + } + } catch (IOException ioe) { + throw new Error("can not read " + errFile + " : " + + ioe.getMessage(), ioe); + } + return result; + } + + private String[] cmd(long classStart) { + String phase = phaseName(classStart); + return new String[]{ + "-Xbatch", + "-XX:-UseCounterDecay", + "-XX:-ShowMessageBoxOnError", + "-XX:+UnlockDiagnosticVMOptions", + // define phase start + "-DCompileTheWorldStartAt=" + classStart, + // CTW library uses WhiteBox API + "-XX:+WhiteBoxAPI", "-Xbootclasspath/a:.", + // export jdk.internal packages used by CTW library + "--add-exports", "java.base/jdk.internal.jimage=ALL-UNNAMED", + "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "--add-exports", "java.base/jdk.internal.reflect=ALL-UNNAMED", + // enable diagnostic logging + "-XX:+LogCompilation", + // use phase specific log and hs_err file + String.format("-XX:LogFile=hotspot_%s_%%p.log", phase), + String.format("-XX:ErrorFile=hs_err_%s_%%p.log", phase), + // MethodHandle MUST NOT be compiled + "-XX:CompileCommand=exclude,java/lang/invoke/MethodHandle.*", + // CTW entry point + CompileTheWorld.class.getName(), + targetPath.toString(), + }; + } + + private String phaseName(long classStart) { + return String.format("%s_%d", targetName, classStart); + } + +}