# HG changeset patch # User iignatyev # Date 1492571455 25200 # Node ID d5572756efd6ce814f4eccc6122915ebb96a852d # Parent e33ea5371600bcd297d189a01c4c25e37bc34425 8178835: CTW Runner should check that all classes have been compiled Reviewed-by: kvn diff -r e33ea5371600 -r d5572756efd6 hotspot/test/applications/ctw/Modules.java --- a/hotspot/test/applications/ctw/Modules.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/applications/ctw/Modules.java Tue Apr 18 20:10:55 2017 -0700 @@ -33,6 +33,6 @@ * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run driver/timeout=0 sun.hotspot.tools.ctw.CtwRunner modules + * @run main/timeout=0 sun.hotspot.tools.ctw.CtwRunner modules */ diff -r e33ea5371600 -r d5572756efd6 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java Tue Apr 18 20:10:55 2017 -0700 @@ -66,6 +66,16 @@ } } + @Override + public long classCount() { + try { + return Files.walk(root, FileVisitOption.FOLLOW_LINKS).count(); + } catch (IOException e) { + throw new Error("can not walk dir " + root + " : " + + e.getMessage(), e); + } + } + private void processFile(Path file) { if (Utils.isClassFile(file.toString())) { processClass(pathToClassName(file)); diff -r e33ea5371600 -r d5572756efd6 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java Tue Apr 18 20:10:55 2017 -0700 @@ -69,7 +69,20 @@ } } - private void processJarEntry(JarEntry entry) { + @Override + public long classCount() { + try (JarFile jarFile = new JarFile(root.toFile())) { + return jarFile.stream() + .map(JarEntry::getName) + .filter(Utils::isClassFile) + .count(); + } catch (IOException e) { + throw new Error("can not open jar file " + root + " : " + + e.getMessage() , e); + } + } + + private void processJarEntry(JarEntry entry) { String filename = entry.getName(); if (Utils.isClassFile(filename)) { processClass(Utils.fileNameToClassName(filename)); diff -r e33ea5371600 -r d5572756efd6 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java Tue Apr 18 20:10:55 2017 -0700 @@ -56,5 +56,18 @@ ioe.printStackTrace(); } } + + @Override + public long classCount() { + try { + return Files.list(root) + .filter(p -> p.getFileName().toString().endsWith(".jar")) + .map(p -> new ClassPathJarEntry(p, executor)) + .mapToLong(ClassPathJarEntry::classCount).sum(); + } catch (IOException e) { + throw new Error("can not walk dir " + root + " : " + + e.getMessage(), e); + } + } } diff -r e33ea5371600 -r d5572756efd6 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJimageEntry.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJimageEntry.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJimageEntry.java Tue Apr 18 20:10:55 2017 -0700 @@ -64,4 +64,18 @@ ioe.printStackTrace(); } } + + @Override + public long classCount() { + try (ImageReader reader = ImageReader.open(root)) { + return Arrays.stream(reader.getEntryNames()) + .filter(name -> name.endsWith(".class")) + .filter(name -> !name.endsWith("module-info.class")) + .map(Utils::fileNameToClassName) + .count(); + } catch (IOException e) { + throw new Error("can not open jimage file " + root + " : " + + e.getMessage() , e); + } + } } diff -r e33ea5371600 -r d5572756efd6 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java Tue Apr 18 20:10:55 2017 -0700 @@ -45,8 +45,7 @@ return; } try { - try (BufferedReader reader = Files.newBufferedReader(root, - StandardCharsets.UTF_8)) { + try (BufferedReader reader = Files.newBufferedReader(root)) { String line; while (!isFinished() && ((line = reader.readLine()) != null)) { processClass(line); @@ -56,4 +55,16 @@ e.printStackTrace(); } } + + @Override + public long classCount() { + try { + try (BufferedReader reader = Files.newBufferedReader(root)) { + return reader.lines().count(); + } + } catch (IOException e) { + throw new Error("can not read list " + root + " : " + + e.getMessage(), e); + } + } } diff -r e33ea5371600 -r d5572756efd6 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java Tue Apr 18 20:10:55 2017 -0700 @@ -83,7 +83,7 @@ await(executor); } CompileTheWorld.OUT.printf("Done (%d classes, %d methods, %d ms)%n", - PathHandler.getClassCount(), + PathHandler.getProcessedClassCount(), Compiler.getMethodCount(), System.currentTimeMillis() - start); passed = true; diff -r e33ea5371600 -r d5572756efd6 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java Tue Apr 18 20:10:55 2017 -0700 @@ -23,6 +23,7 @@ package sun.hotspot.tools.ctw; +import jdk.test.lib.Asserts; import jdk.test.lib.Utils; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.Pair; @@ -34,6 +35,8 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -98,7 +101,10 @@ private void startCtwforAllClasses() { - long classStart = 0; + long classStart = 0L; + long classCount = classCount(); + Asserts.assertGreaterThan(classCount, 0L, + targetPath + " does not have any classes"); boolean done = false; while (!done) { String[] cmd = cmd(classStart); @@ -124,6 +130,16 @@ exitCode); Pair lastClass = getLastClass(out); if (exitCode == 0) { + long lastIndex = lastClass == null ? -1 : lastClass.second; + if (lastIndex != classCount) { + errors.add(new Error(phase + ": Unexpected zero exit code" + + "before finishing all compilations." + + " lastClass[" + lastIndex + + "] != classCount[" + classCount + "]")); + } else { + System.out.println("Executed CTW for all " + classCount + + " classes in " + targetPath); + } done = true; } else { if (lastClass == null) { @@ -145,6 +161,11 @@ } } + private long classCount() { + return PathHandler.create(targetPath.toString(), Runnable::run) + .classCount(); + } + private Pair getLastClass(Path errFile) { try (BufferedReader reader = Files.newBufferedReader(errFile)) { String line = reader.lines() @@ -167,7 +188,7 @@ private String[] cmd(long classStart) { String phase = phaseName(classStart); - return new String[]{ + return new String[] { "-Xbatch", "-XX:-UseCounterDecay", "-XX:-ShowMessageBoxOnError", diff -r e33ea5371600 -r d5572756efd6 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Tue Apr 18 20:10:54 2017 -0700 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Tue Apr 18 20:10:55 2017 -0700 @@ -62,7 +62,7 @@ this.loader = ClassLoader.getSystemClassLoader(); } - /** + /** * Factory method. Construct concrete handler in depends from {@code path}. * * @param path the path to process @@ -118,11 +118,16 @@ } /** - * Processes all classes in specified path. + * Processes all classes in the specified path. */ public abstract void process(); - /** + /** + * @return count of all classes in the specified path. + */ + public abstract long classCount(); + + /** * Sets class loader, that will be used to define class at * {@link #processClass(String)}. * @@ -168,7 +173,7 @@ /** * @return count of processed classes */ - public static long getClassCount() { + public static long getProcessedClassCount() { long id = CLASS_COUNT.get(); if (id < Utils.COMPILE_THE_WORLD_START_AT) { return 0;