Mercurial > hg > graal-compiler
changeset 22797:9329eb8678f7
fixed CompileTheWorld functionality for jdk9
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Oct 2015 01:45:13 +0200 |
parents | ed5fd346003c |
children | 509a9eadd120 |
files | graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorldOptions.java mx.graal/mx_graal.py |
diffstat | 4 files changed, 185 insertions(+), 71 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java Sun Oct 11 14:50:24 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java Mon Oct 12 01:45:13 2015 +0200 @@ -42,10 +42,8 @@ public void testRtJar() throws Throwable { boolean originalSetting = ExitVMOnException.getValue(); // Compile a couple classes in rt.jar - String file = System.getProperty("java.home") + "/lib/rt.jar"; HotSpotJVMCIRuntimeProvider runtime = HotSpotJVMCIRuntime.runtime(); - new CompileTheWorld(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), file, new Config(null), 1, 5, null, null, false).compile(); + new CompileTheWorld(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), CompileTheWorld.SUN_BOOT_CLASS_PATH, new Config(null), 1, 5, null, null, false).compile(); assert ExitVMOnException.getValue() == originalSetting; } - }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Sun Oct 11 14:50:24 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Mon Oct 12 01:45:13 2015 +0200 @@ -34,6 +34,7 @@ import static jdk.vm.ci.compiler.Compiler.PrintStackTraceOnException; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; @@ -42,9 +43,16 @@ import java.lang.reflect.Modifier; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; @@ -87,8 +95,11 @@ */ public final class CompileTheWorld { + private static final String JAVA_VERSION = System.getProperty("java.specification.version"); + /** - * Magic token to trigger reading files from the boot class path. + * Magic token to trigger reading files from {@code rt.jar} if {@link #JAVA_VERSION} denotes a + * JDK earlier than 9 otherwise from {@code java.base} module. */ public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path"; @@ -144,20 +155,23 @@ private final HotSpotGraalCompiler compiler; /** - * List of Zip/Jar files to compile (see {@link CompileTheWorldOptions#CompileTheWorldClasspath} - * ). + * Class path denoting classes to compile. + * + * @see CompileTheWorldOptions#CompileTheWorldClasspath */ - private final String files; + private final String inputClassPath; /** - * Class index to start compilation at (see - * {@link CompileTheWorldOptions#CompileTheWorldStartAt}). + * Class index to start compilation at. + * + * @see CompileTheWorldOptions#CompileTheWorldStartAt */ private final int startAt; /** - * Class index to stop compilation at (see {@link CompileTheWorldOptions#CompileTheWorldStopAt} - * ). + * Class index to stop compilation at. + * + * @see CompileTheWorldOptions#CompileTheWorldStopAt */ private final int stopAt; @@ -196,7 +210,7 @@ String excludeMethodFilters, boolean verbose) { this.jvmciRuntime = jvmciRuntime; this.compiler = compiler; - this.files = files; + this.inputClassPath = files; this.startAt = startAt; this.stopAt = stopAt; this.methodFilters = methodFilters == null || methodFilters.isEmpty() ? null : MethodFilter.parse(methodFilters); @@ -219,36 +233,35 @@ } /** - * Compiles all methods in all classes in the Zip/Jar archive files in - * {@link CompileTheWorldOptions#CompileTheWorldClasspath}. If - * {@link CompileTheWorldOptions#CompileTheWorldClasspath} contains the magic token - * {@link #SUN_BOOT_CLASS_PATH} passed up from HotSpot we take the files from the boot class - * path. + * Compiles all methods in all classes in {@link #inputClassPath}. If {@link #inputClassPath} + * equals {@link #SUN_BOOT_CLASS_PATH} the boot class path is used. */ public void compile() throws Throwable { // By default only report statistics for the CTW threads themselves if (GraalDebugConfig.Options.DebugValueThreadFilter.hasDefaultValue()) { GraalDebugConfig.Options.DebugValueThreadFilter.setValue("^CompileTheWorld"); } - - if (SUN_BOOT_CLASS_PATH.equals(files)) { + if (SUN_BOOT_CLASS_PATH.equals(inputClassPath)) { final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator); - String bcpFiles = ""; - for (int i = 0; i < entries.length; i++) { - final String entry = entries[i]; - - // We stop at rt.jar, unless it is the first boot class path entry. - if (entry.endsWith("rt.jar") && (i > 0)) { - break; + String bcpEntry = null; + boolean useRtJar = JAVA_VERSION.compareTo("1.9") < 0; + for (int i = 0; i < entries.length && bcpEntry == null; i++) { + String entry = entries[i]; + File entryFile = new File(entry); + if (useRtJar) { + // We stop at rt.jar, unless it is the first boot class path entry. + if (entryFile.getName().endsWith("rt.jar") && entryFile.isFile()) { + bcpEntry = entry; + } + } else { + if (entryFile.getName().endsWith("java.base") && entryFile.isDirectory()) { + bcpEntry = entry; + } } - if (i > 0) { - bcpFiles += File.pathSeparator; - } - bcpFiles += entry; } - compile(bcpFiles); + compile(bcpEntry); } else { - compile(files); + compile(inputClassPath); } } @@ -270,15 +283,111 @@ private static void dummy() { } + abstract static class ClassPathEntry implements Closeable { + final String name; + + public ClassPathEntry(String name) { + this.name = name; + } + + public abstract ClassLoader createClassLoader() throws IOException; + + public abstract List<String> getClassNames() throws IOException; + + @Override + public String toString() { + return name; + } + } + + static class DirClassPathEntry extends ClassPathEntry { + + private final File dir; + + public DirClassPathEntry(String name) { + super(name); + dir = new File(name); + assert dir.isDirectory(); + } + + @Override + public ClassLoader createClassLoader() throws IOException { + URL url = dir.toURI().toURL(); + return new URLClassLoader(new URL[]{url}); + } + + @Override + public List<String> getClassNames() throws IOException { + List<String> classNames = new ArrayList<>(); + String root = dir.getPath(); + SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (attrs.isRegularFile()) { + File path = file.toFile(); + if (path.getName().endsWith(".class")) { + String pathString = path.getPath(); + assert pathString.startsWith(root); + String classFile = pathString.substring(root.length() + 1); + String className = classFile.replace(File.separatorChar, '.'); + classNames.add(className.replace('/', '.').substring(0, className.length() - ".class".length())); + } + } + return super.visitFile(file, attrs); + } + }; + Files.walkFileTree(dir.toPath(), visitor); + return classNames; + } + + public void close() throws IOException { + } + } + + static class JarClassPathEntry extends ClassPathEntry { + + private final JarFile jarFile; + + public JarClassPathEntry(String name) throws IOException { + super(name); + jarFile = new JarFile(name); + } + + @Override + public ClassLoader createClassLoader() throws IOException { + URL url = new URL("jar", "", "file:" + name + "!/"); + return new URLClassLoader(new URL[]{url}); + } + + @Override + public List<String> getClassNames() throws IOException { + Enumeration<JarEntry> e = jarFile.entries(); + List<String> classNames = new ArrayList<>(jarFile.size()); + while (e.hasMoreElements()) { + JarEntry je = e.nextElement(); + if (je.isDirectory() || !je.getName().endsWith(".class")) { + continue; + } + String className = je.getName().substring(0, je.getName().length() - ".class".length()); + classNames.add(className.replace('/', '.')); + } + return classNames; + } + + public void close() throws IOException { + jarFile.close(); + } + } + /** - * Compiles all methods in all classes in the Zip/Jar files passed. + * Compiles all methods in all classes in a given class path. * - * @param fileList {@link File#pathSeparator} separated list of Zip/Jar files to compile + * @param classPath class path denoting classes to compile * @throws IOException */ @SuppressWarnings("try") - private void compile(String fileList) throws IOException { - final String[] entries = fileList.split(File.pathSeparator); + private void compile(String classPath) throws IOException { + final String[] entries = classPath.split(File.pathSeparator); long start = System.currentTimeMillis(); CompilerThreadFactory factory = new CompilerThreadFactory("CompileTheWorld", new DebugConfigAccess() { @@ -291,7 +400,8 @@ }); try { - // compile dummy method to get compiler initilized outside of the config debug override. + // compile dummy method to get compiler initialized outside of the + // config debug override. HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod( CompileTheWorld.class.getDeclaredMethod("dummy")); int entryBCI = Compiler.INVOCATION_ENTRY_BCI; @@ -320,11 +430,16 @@ for (int i = 0; i < entries.length; i++) { final String entry = entries[i]; - // For now we only compile all methods in all classes in zip/jar files. + ClassPathEntry cpe; if (!entry.endsWith(".zip") && !entry.endsWith(".jar")) { - println("CompileTheWorld : Skipped classes in " + entry); - println(); - continue; + if (!new File(entry).isDirectory()) { + println("CompileTheWorld : Skipped classes in " + entry); + println(); + continue; + } + cpe = new DirClassPathEntry(entry); + } else { + cpe = new JarClassPathEntry(entry); } if (methodFilters == null || methodFilters.length == 0) { @@ -339,41 +454,31 @@ } println(); - URL url = new URL("jar", "", "file:" + entry + "!/"); - ClassLoader loader = new URLClassLoader(new URL[]{url}); - - JarFile jarFile = new JarFile(entry); - Enumeration<JarEntry> e = jarFile.entries(); + ClassLoader loader = cpe.createClassLoader(); - while (e.hasMoreElements()) { - JarEntry je = e.nextElement(); - if (je.isDirectory() || !je.getName().endsWith(".class")) { - continue; - } + for (String className : cpe.getClassNames()) { // Are we done? if (classFileCounter >= stopAt) { break; } - String className = je.getName().substring(0, je.getName().length() - ".class".length()); - String dottedClassName = className.replace('/', '.'); classFileCounter++; - if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, dottedClassName)) { + if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, className)) { continue; } - if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, dottedClassName)) { + if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, className)) { continue; } - if (dottedClassName.startsWith("jdk.management.") || dottedClassName.startsWith("jdk.internal.cmm.*")) { + if (className.startsWith("jdk.management.") || className.startsWith("jdk.internal.cmm.*")) { continue; } try { // Load and initialize class - Class<?> javaClass = Class.forName(dottedClassName, true, loader); + Class<?> javaClass = Class.forName(className, true, loader); // Pre-load all classes in the constant pool. try { @@ -411,7 +516,7 @@ t.printStackTrace(); } } - jarFile.close(); + cpe.close(); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorldOptions.java Sun Oct 11 14:50:24 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorldOptions.java Mon Oct 12 01:45:13 2015 +0200 @@ -35,7 +35,7 @@ */ public class CompileTheWorldOptions { // @formatter:off - @Option(help = "Compile all methods in all classes on given class path", type = OptionType.Debug) + @Option(help = "Class path denoting methods to compile", type = OptionType.Debug) public static final OptionValue<String> CompileTheWorldClasspath = new OptionValue<>(CompileTheWorld.SUN_BOOT_CLASS_PATH); @Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug) public static final OptionValue<Boolean> CompileTheWorldVerbose = new OptionValue<>(true);
--- a/mx.graal/mx_graal.py Sun Oct 11 14:50:24 2015 +0200 +++ b/mx.graal/mx_graal.py Mon Oct 12 01:45:13 2015 +0200 @@ -33,13 +33,13 @@ import re import mx -from mx_jvmci import JvmciJDKDeployedDist, add_bootclasspath_prepend, buildvms +from mx_jvmci import JvmciJDKDeployedDist, add_bootclasspath_prepend, buildvms, get_jvmci_jdk, get_vm, run_vm, VM from mx_jvmci import jdkDeployedDists #pylint: disable=unused-import from mx_gate import Task from sanitycheck import _noneAsEmptyList try: - from mx_jvmci import run_vm, VM, get_vm, isJVMCIEnabled, relativeVmLibDirInJdk, get_jvmci_jdk, get_jvmci_jdk_dir #pylint: disable=no-name-in-module + from mx_jvmci import isJVMCIEnabled, relativeVmLibDirInJdk, get_jvmci_jdk_dir #pylint: disable=no-name-in-module except ImportError: pass from mx_unittest import unittest @@ -204,7 +204,7 @@ parser = ArgumentParser(prog='mx ctw') parser.add_argument('--ctwopts', action='store', help='space separated JVMCI options used for CTW compilations (default: --ctwopts="' + defaultCtwopts + '")', default=defaultCtwopts, metavar='<options>') - parser.add_argument('--jar', action='store', help='jar of classes to compiled instead of rt.jar', metavar='<path>') + parser.add_argument('--cp', '--jar', action='store', help='jar or class path denoting classes to compile', metavar='<path>') args, vmargs = parser.parse_known_args(args) @@ -213,22 +213,33 @@ # when they are collated in the "jvmci.options" system property vmargs.append('-G:CompileTheWorldConfig=' + re.sub(r'\s+', '#', args.ctwopts)) - if args.jar: - jar = os.path.abspath(args.jar) + if args.cp: + cp = os.path.abspath(args.cp) else: - jar = join(get_jvmci_jdk_dir(deployDists=False), 'jre', 'lib', 'rt.jar') + if get_jvmci_jdk().javaCompliance < '9': + cp = join(get_jvmci_jdk().home, 'jre', 'lib', 'rt.jar') + else: + cp = join(get_jvmci_jdk().home, 'modules', 'java.base') vmargs.append('-G:CompileTheWorldExcludeMethodFilter=sun.awt.X11.*.*') # suppress menubar and dock when running on Mac; exclude x11 classes as they may cause vm crashes (on Solaris) vmargs = ['-Djava.awt.headless=true'] + vmargs - vm_ = get_vm() - if isJVMCIEnabled(vm_): - if vm_ == 'jvmci': - vmargs += ['-XX:+BootstrapJVMCI'] - vmargs += ['-G:CompileTheWorldClasspath=' + jar, '-XX:-UseJVMCIClassLoader', 'com.oracle.graal.hotspot.CompileTheWorld'] + vm = get_vm() + if isinstance(vm, VM): + if vm.jvmciMode == 'disabled': + vmargs += ['-XX:+CompileTheWorld', '-Xbootclasspath/p:' + cp] + else: + if vm.jvmciMode == 'jit': + vmargs += ['-XX:+BootstrapJVMCI'] + vmargs += ['-G:CompileTheWorldClasspath=' + cp, 'com.oracle.graal.hotspot.CompileTheWorld'] else: - vmargs += ['-XX:+CompileTheWorld', '-Xbootclasspath/p:' + jar] + if isJVMCIEnabled(vm): + if vm == 'jvmci': + vmargs += ['-XX:+BootstrapJVMCI'] + vmargs += ['-G:CompileTheWorldClasspath=' + cp, '-XX:-UseJVMCIClassLoader', 'com.oracle.graal.hotspot.CompileTheWorld'] + else: + vmargs += ['-XX:+CompileTheWorld', '-Xbootclasspath/p:' + cp] run_vm(vmargs + _noneAsEmptyList(extraVMarguments))