Mercurial > hg > graal-compiler
changeset 22783:da7d39c53b92
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Thu, 08 Oct 2015 16:54:27 +0200 |
parents | ef56f81f88ee (current diff) 5b5bcde5a0de (diff) |
children | 2c244f95fcbf |
files | |
diffstat | 14 files changed, 366 insertions(+), 88 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugInitializationPropertyProvider.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugInitializationPropertyProvider.java Thu Oct 08 16:54:27 2015 +0200 @@ -40,13 +40,13 @@ if (GraalDebugConfig.areDebugScopePatternsEnabled()) { System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true"); } - if ("".equals(GraalDebugConfig.Meter.getValue())) { + if ("".equals(GraalDebugConfig.Options.Meter.getValue())) { System.setProperty(Debug.ENABLE_UNSCOPED_METRICS_PROPERTY_NAME, "true"); } - if ("".equals(GraalDebugConfig.Time.getValue())) { + if ("".equals(GraalDebugConfig.Options.Time.getValue())) { System.setProperty(Debug.ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME, "true"); } - if ("".equals(GraalDebugConfig.TrackMemUse.getValue())) { + if ("".equals(GraalDebugConfig.Options.TrackMemUse.getValue())) { System.setProperty(Debug.ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME, "true"); } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Thu Oct 08 16:54:27 2015 +0200 @@ -24,7 +24,7 @@ import static com.oracle.graal.compiler.common.BackendOptions.ConstructionSSAlirDuringLirBuilding; import static com.oracle.graal.compiler.common.GraalOptions.MatchExpressions; -import static com.oracle.graal.debug.GraalDebugConfig.LogVerbose; +import static com.oracle.graal.debug.GraalDebugConfig.Options.LogVerbose; import static com.oracle.graal.lir.LIR.verifyBlock; import static jdk.internal.jvmci.code.ValueUtil.asRegister; import static jdk.internal.jvmci.code.ValueUtil.isLegal;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Thu Oct 08 16:54:27 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.match; -import static com.oracle.graal.debug.GraalDebugConfig.LogVerbose; +import static com.oracle.graal.debug.GraalDebugConfig.Options.LogVerbose; import java.util.ArrayList; import java.util.Arrays;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Thu Oct 08 16:54:27 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.match; -import static com.oracle.graal.debug.GraalDebugConfig.LogVerbose; +import static com.oracle.graal.debug.GraalDebugConfig.Options.LogVerbose; import java.util.ArrayList; import java.util.HashMap;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java Thu Oct 08 16:54:27 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.match; -import static com.oracle.graal.debug.GraalDebugConfig.LogVerbose; +import static com.oracle.graal.debug.GraalDebugConfig.Options.LogVerbose; import java.util.List;
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugEnvironment.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugEnvironment.java Thu Oct 08 16:54:27 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, 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 @@ -22,13 +22,13 @@ */ package com.oracle.graal.debug; -import static com.oracle.graal.debug.GraalDebugConfig.Dump; -import static com.oracle.graal.debug.GraalDebugConfig.Log; -import static com.oracle.graal.debug.GraalDebugConfig.Meter; -import static com.oracle.graal.debug.GraalDebugConfig.MethodFilter; -import static com.oracle.graal.debug.GraalDebugConfig.Time; -import static com.oracle.graal.debug.GraalDebugConfig.TrackMemUse; -import static com.oracle.graal.debug.GraalDebugConfig.Verify; +import static com.oracle.graal.debug.GraalDebugConfig.Options.Dump; +import static com.oracle.graal.debug.GraalDebugConfig.Options.Log; +import static com.oracle.graal.debug.GraalDebugConfig.Options.Meter; +import static com.oracle.graal.debug.GraalDebugConfig.Options.MethodFilter; +import static com.oracle.graal.debug.GraalDebugConfig.Options.Time; +import static com.oracle.graal.debug.GraalDebugConfig.Options.TrackMemUse; +import static com.oracle.graal.debug.GraalDebugConfig.Options.Verify; import java.io.PrintStream; import java.util.ArrayList;
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugFilter.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugFilter.java Thu Oct 08 16:54:27 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, 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 @@ -25,19 +25,18 @@ import java.util.Arrays; import java.util.regex.Pattern; +import com.oracle.graal.debug.GraalDebugConfig.Options; import com.oracle.graal.debug.internal.DebugScope; /** - * Implements the filter specified by the {@link GraalDebugConfig#Dump}, - * {@link GraalDebugConfig#Log}, {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} - * options. + * Implements the filter specified by the {@link Options#Dump}, {@link Options#Log}, + * {@link Options#Meter} and {@link Options#Time} options. * <p> * These options enable the associated debug facility if their filter matches the * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current - * scope}. For the {@link GraalDebugConfig#Dump} and {@link GraalDebugConfig#Log} options, the log - * or dump level is set. The {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} - * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0} - * means enabled. + * scope}. For the {@link Options#Dump} and {@link Options#Log} options, the log or dump level is + * set. The {@link Options#Meter} and {@link Options#Time} options don't have a level, for them + * {@code level = 0} means disabled and a {@code level > 0} means enabled. * <p> * A filter is a list of comma-separated terms of the form {@code <pattern>[:<level>]}. * {@code <pattern>} is interpreted as a glob pattern if it contains a "*" or "?" character.
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/GraalDebugConfig.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/GraalDebugConfig.java Thu Oct 08 16:54:27 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, 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 @@ -43,64 +43,66 @@ return assertionsEnabled; } - // @formatter:off - @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug) - public static final OptionValue<String> Dump = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " + - "An empty value enables all metrics unconditionally.", type = OptionType.Debug) - public static final OptionValue<String> Meter = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug) - public static final OptionValue<String> Verify = new OptionValue<String>() { - @Override - protected String defaultValue() { - return assertionsEnabled() ? "" : null; - } - }; - @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " + - "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug) - public static final OptionValue<String> TrackMemUse = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " + - "An empty value enables all timers unconditionally.", type = OptionType.Debug) - public static final OptionValue<String> Time = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug) - public static final OptionValue<String> Log = new OptionValue<>(null); - @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug) - public static final OptionValue<String> MethodFilter = new OptionValue<>(null); - @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug) - public static final OptionValue<Boolean> MethodFilterRootOnly = new OptionValue<>(false); + public static class Options { + // @formatter:off + @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug) + public static final OptionValue<String> Dump = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " + + "An empty value enables all metrics unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> Meter = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug) + public static final OptionValue<String> Verify = new OptionValue<String>() { + @Override + protected String defaultValue() { + return assertionsEnabled() ? "" : null; + } + }; + @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " + + "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> TrackMemUse = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " + + "An empty value enables all timers unconditionally.", type = OptionType.Debug) + public static final OptionValue<String> Time = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug) + public static final OptionValue<String> Log = new OptionValue<>(null); + @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug) + public static final OptionValue<String> MethodFilter = new OptionValue<>(null); + @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug) + public static final OptionValue<Boolean> MethodFilterRootOnly = new OptionValue<>(false); - @Option(help = "How to print metric and timing values:%n" + - "Name - aggregate by unqualified name%n" + - "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + - "Complete - aggregate by qualified name%n" + - "Thread - aggregate by qualified name and thread", type = OptionType.Debug) - public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name"); - @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) - public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true); - @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug) - public static final OptionValue<String> DebugValueThreadFilter = new OptionValue<>(null); - @Option(help = "Send JVMCI compiler IR to dump handlers on error", type = OptionType.Debug) - public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false); - @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) - public static final OptionValue<Boolean> InterceptBailout = new OptionValue<>(false); - @Option(help = "Enable more verbose log output when available", type = OptionType.Debug) - public static final OptionValue<Boolean> LogVerbose = new OptionValue<>(false); - // @formatter:on + @Option(help = "How to print metric and timing values:%n" + + "Name - aggregate by unqualified name%n" + + "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + + "Complete - aggregate by qualified name%n" + + "Thread - aggregate by qualified name and thread", type = OptionType.Debug) + public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name"); + @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) + public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true); + @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug) + public static final OptionValue<String> DebugValueThreadFilter = new OptionValue<>(null); + @Option(help = "Send JVMCI compiler IR to dump handlers on error", type = OptionType.Debug) + public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false); + @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) + public static final OptionValue<Boolean> InterceptBailout = new OptionValue<>(false); + @Option(help = "Enable more verbose log output when available", type = OptionType.Debug) + public static final OptionValue<Boolean> LogVerbose = new OptionValue<>(false); + // @formatter:on + } static boolean isNotEmpty(OptionValue<String> option) { return option.getValue() != null && !option.getValue().isEmpty(); } public static boolean areDebugScopePatternsEnabled() { - return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areScopedMetricsOrTimersEnabled(); + return Options.DumpOnError.getValue() || Options.Dump.getValue() != null || Options.Log.getValue() != null || areScopedMetricsOrTimersEnabled(); } /** - * Determines if any of {@link #Meter}, {@link #Time} or {@link #TrackMemUse} has a non-null, - * non-empty value. + * Determines if any of {@link Options#Meter}, {@link Options#Time} or + * {@link Options#TrackMemUse} has a non-null, non-empty value. */ public static boolean areScopedMetricsOrTimersEnabled() { - return isNotEmpty(Meter) || isNotEmpty(Time) || isNotEmpty(TrackMemUse); + return isNotEmpty(Options.Meter) || isNotEmpty(Options.Time) || isNotEmpty(Options.TrackMemUse); } private final DebugFilter logFilter; @@ -222,7 +224,7 @@ } else if (methodFilter != null) { JavaMethod method = asJavaMethod(o); if (method != null) { - if (!MethodFilterRootOnly.getValue()) { + if (!Options.MethodFilterRootOnly.getValue()) { if (com.oracle.graal.debug.MethodFilter.matches(methodFilter, method)) { return true; } @@ -271,13 +273,13 @@ @Override public RuntimeException interceptException(Throwable e) { - if (e instanceof BailoutException && !InterceptBailout.getValue()) { + if (e instanceof BailoutException && !Options.InterceptBailout.getValue()) { return null; } Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); for (Object o : Debug.context()) { - if (DumpOnError.getValue()) { + if (Options.DumpOnError.getValue()) { Debug.dump(o, "Exception: " + e.toString()); } else { Debug.log("Context obj %s", o);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Thu Oct 08 16:54:27 2015 +0200 @@ -227,8 +227,8 @@ */ public void compile() throws Throwable { // By default only report statistics for the CTW threads themselves - if (GraalDebugConfig.DebugValueThreadFilter.hasDefaultValue()) { - GraalDebugConfig.DebugValueThreadFilter.setValue("^CompileTheWorld"); + if (GraalDebugConfig.Options.DebugValueThreadFilter.hasDefaultValue()) { + GraalDebugConfig.Options.DebugValueThreadFilter.setValue("^CompileTheWorld"); } if (SUN_BOOT_CLASS_PATH.equals(files)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java Thu Oct 08 16:54:27 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, 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 @@ -22,9 +22,9 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.debug.GraalDebugConfig.DebugValueSummary; -import static com.oracle.graal.debug.GraalDebugConfig.DebugValueThreadFilter; -import static com.oracle.graal.debug.GraalDebugConfig.SuppressZeroDebugValues; +import static com.oracle.graal.debug.GraalDebugConfig.Options.DebugValueSummary; +import static com.oracle.graal.debug.GraalDebugConfig.Options.DebugValueThreadFilter; +import static com.oracle.graal.debug.GraalDebugConfig.Options.SuppressZeroDebugValues; import java.io.PrintStream; import java.util.ArrayList;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Oct 08 15:59:44 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Oct 08 16:54:27 2015 +0200 @@ -22,11 +22,11 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.debug.GraalDebugConfig.DebugValueSummary; -import static com.oracle.graal.debug.GraalDebugConfig.Dump; -import static com.oracle.graal.debug.GraalDebugConfig.Log; -import static com.oracle.graal.debug.GraalDebugConfig.MethodFilter; -import static com.oracle.graal.debug.GraalDebugConfig.Verify; +import static com.oracle.graal.debug.GraalDebugConfig.Options.DebugValueSummary; +import static com.oracle.graal.debug.GraalDebugConfig.Options.Dump; +import static com.oracle.graal.debug.GraalDebugConfig.Options.Log; +import static com.oracle.graal.debug.GraalDebugConfig.Options.MethodFilter; +import static com.oracle.graal.debug.GraalDebugConfig.Options.Verify; import static com.oracle.graal.debug.GraalDebugConfig.areScopedMetricsOrTimersEnabled; import static jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime.runtime; import static jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/SubprocessUtil.java Thu Oct 08 16:54:27 2015 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, 2015, 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 com.oracle.graal.test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.List; + +/** + * Utility methods for spawning a VM in a subprocess during unit tests. + */ +public final class SubprocessUtil { + + private SubprocessUtil() { + } + + /** + * Gets the command line for the current process. + * + * @return the command line arguments for the current process or {@code null} if they are not + * available + */ + public static List<String> getProcessCommandLine() { + String processArgsFile = System.getenv().get("MX_SUBPROCESS_COMMAND_FILE"); + if (processArgsFile != null) { + try { + return Files.readAllLines(new File(processArgsFile).toPath()); + } catch (IOException e) { + } + } + return null; + } + + /** + * Gets the command line used to start the current Java VM, including all VM arguments, but not + * including the main class or any Java arguments. This can be used to spawn an identical VM, + * but running different Java code. + */ + public static List<String> getVMCommandLine() { + List<String> args = getProcessCommandLine(); + if (args == null) { + return null; + } else { + int index = findMainClassIndex(args); + return args.subList(0, index); + } + } + + private static int findMainClassIndex(List<String> commandLine) { + int i = 1; // Skip the java executable + while (i < commandLine.size()) { + String s = commandLine.get(i); + if (s.charAt(0) != '-') { + return i; + } else if (s.equals("-cp") || s.equals("-classpath")) { + i += 2; + } else { + i++; + } + } + throw new InternalError(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/LazyInitializationTest.java Thu Oct 08 16:54:27 2015 +0200 @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2015, 2015, 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 com.oracle.graal.truffle.test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import jdk.internal.jvmci.compiler.CompilerFactory; +import jdk.internal.jvmci.options.OptionDescriptor; +import jdk.internal.jvmci.options.OptionDescriptors; +import jdk.internal.jvmci.options.OptionValue; + +import org.junit.Assert; +import org.junit.Test; + +import com.oracle.graal.compiler.CompilerThreadFactory; +import com.oracle.graal.test.SubprocessUtil; + +/** + * Test lazy initialization of Graal in the context of Truffle. When simply executing Truffle code, + * Graal should not be initialized unless there is an actual compilation request. + */ +public class LazyInitializationTest { + + private final Class<?> hotSpotVMEventListener; + private final Class<?> hotSpotGraalCompilerFactoryOptions; + + public LazyInitializationTest() { + hotSpotVMEventListener = forNameOrNull("jdk.internal.jvmci.hotspot.HotSpotVMEventListener"); + hotSpotGraalCompilerFactoryOptions = forNameOrNull("com.oracle.graal.hotspot.HotSpotGraalCompilerFactory$Options"); + } + + private static Class<?> forNameOrNull(String name) { + try { + return Class.forName(name); + } catch (ClassNotFoundException e) { + return null; + } + } + + @Test + public void testSLTck() throws IOException, InterruptedException { + spawnUnitTests("com.oracle.truffle.sl.test.SLTckTest"); + } + + /** + * Spawn a new VM, execute unit tests, and check which classes are loaded. + */ + private void spawnUnitTests(String... tests) throws IOException, InterruptedException { + ArrayList<String> args = new ArrayList<>(SubprocessUtil.getVMCommandLine()); + + int jvmciArg = args.indexOf("-jvmci"); + if (jvmciArg >= 0) { + args.set(jvmciArg, "-server"); + } + + args.add("-XX:+TraceClassLoading"); + args.add("com.oracle.mxtool.junit.MxJUnitWrapper"); + args.addAll(Arrays.asList(tests)); + + ArrayList<Class<?>> loadedGraalClasses = new ArrayList<>(); + + Process process = new ProcessBuilder(args).start(); + + int testCount = 0; + BufferedReader stdout = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = stdout.readLine()) != null) { + if (line.startsWith("[Loaded ")) { + int start = "[Loaded ".length(); + int end = line.indexOf(' ', start); + String loadedClass = line.substring(start, end); + if (isGraalClass(loadedClass)) { + try { + loadedGraalClasses.add(Class.forName(loadedClass)); + } catch (ClassNotFoundException e) { + Assert.fail("loaded class " + loadedClass + " not found"); + } + } + } else if (line.startsWith("OK (")) { + Assert.assertTrue(testCount == 0); + int start = "OK (".length(); + int end = line.indexOf(' ', start); + testCount = Integer.parseInt(line.substring(start, end)); + } + } + + Assert.assertNotEquals("test count", 0, testCount); + Assert.assertEquals("exit code", 0, process.waitFor()); + + checkAllowedGraalClasses(loadedGraalClasses); + } + + private static boolean isGraalClass(String className) { + if (className.startsWith("com.oracle.graal.truffle.")) { + // Ignore classes in the com.oracle.graal.truffle package, they are all allowed. + return false; + } else { + return className.startsWith("com.oracle.graal."); + } + } + + private void checkAllowedGraalClasses(List<Class<?>> loadedGraalClasses) { + HashSet<Class<?>> whitelist = new HashSet<>(); + + /* + * Look for all loaded OptionDescriptors classes, and whitelist the classes that declare the + * options. They may be loaded by the option parsing code. + */ + for (Class<?> cls : loadedGraalClasses) { + if (OptionDescriptors.class.isAssignableFrom(cls)) { + try { + OptionDescriptors optionDescriptors = cls.asSubclass(OptionDescriptors.class).newInstance(); + for (OptionDescriptor option : optionDescriptors) { + whitelist.add(option.getDeclaringClass()); + } + } catch (ReflectiveOperationException e) { + } + } + } + + for (Class<?> cls : loadedGraalClasses) { + if (whitelist.contains(cls)) { + continue; + } + + if (!isGraalClassAllowed(cls)) { + Assert.fail("loaded class: " + cls.getName()); + } + } + } + + private boolean isGraalClassAllowed(Class<?> cls) { + if (CompilerThreadFactory.class.equals(cls) || CompilerThreadFactory.DebugConfigAccess.class.equals(cls)) { + // The HotSpotTruffleRuntime creates a CompilerThreadFactory for Truffle. + return true; + } + + if (cls.equals(hotSpotGraalCompilerFactoryOptions)) { + // The JVMCI initialization code needs to accesses an option defined in this class. + return true; + } + + if (CompilerFactory.class.isAssignableFrom(cls)) { + // The compiler factories have to be loaded and instantiated by the JVMCI. + return true; + } + + if (OptionDescriptors.class.isAssignableFrom(cls)) { + // If options are specified, the corresponding *_OptionDescriptors classes are loaded. + return true; + } + + if (OptionValue.class.isAssignableFrom(cls)) { + // If options are specified, that may implicitly load a custom OptionValue subclass. + return true; + } + + if (hotSpotVMEventListener != null && hotSpotVMEventListener.isAssignableFrom(cls)) { + // HotSpotVMEventListeners need to be loaded on JVMCI startup. + return true; + } + + // No other class from the com.oracle.graal package should be loaded. + return false; + } +}
--- a/mx.graal/suite.py Thu Oct 08 15:59:44 2015 +0200 +++ b/mx.graal/suite.py Thu Oct 08 16:54:27 2015 +0200 @@ -14,7 +14,7 @@ }, { "name" : "truffle", - "version" : "cf203af4610c25642a6db00a8fd98e20e8f515b0", + "version" : "c3ea80aa57628eec5686982fbb2110a48edec36e", "urls" : [ {"url" : "http://lafo.ssw.uni-linz.ac.at/hg/truffle", "kind" : "hg"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},