# HG changeset patch # User dnsimon # Date 1475700986 25200 # Node ID 6b97c4598667bb718f0d036d10448e83082d0867 # Parent 81c8b5be9b633828b37b9222be806db9670bc03e 8167194: [JVMCI] no reliable mechanism for querying JVMCI system properties Reviewed-by: kvn diff -r 81c8b5be9b63 -r 6b97c4598667 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Wed Oct 05 21:35:05 2016 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Wed Oct 05 13:56:26 2016 -0700 @@ -90,14 +90,17 @@ * A list of all supported JVMCI options. */ public enum Option { + // @formatter:off Compiler(String.class, null, "Selects the system compiler."), // Note: The following one is not used (see InitTimer.ENABLED). It is added here - // so that -Djvmci.PrintFlags=true shows the option. - InitTimer(boolean.class, false, "Specifies if initialization timing is enabled."), - PrintConfig(boolean.class, false, "Prints VM configuration available via JVMCI and exits."), - PrintFlags(boolean.class, false, "Prints all JVMCI flags and exits."), - ShowFlags(boolean.class, false, "Prints all JVMCI flags and continues."), - TraceMethodDataFilter(String.class, null, ""); + // so that -XX:+JVMCIPrintProperties shows the option. + InitTimer(Boolean.class, false, "Specifies if initialization timing is enabled."), + PrintConfig(Boolean.class, false, "Prints VM configuration available via JVMCI."), + TraceMethodDataFilter(String.class, null, + "Enables tracing of profiling info when read by JVMCI.", + "Empty value: trace all methods", + "Non-empty value: trace methods whose fully qualified name contains the value."); + // @formatter:on /** * The prefix for system properties that are JVMCI options. @@ -113,25 +116,25 @@ private Object value; private final Object defaultValue; private boolean isDefault; - private final String help; + private final String[] helpLines; - Option(Class type, Object defaultValue, String help) { + Option(Class type, Object defaultValue, String... helpLines) { assert Character.isUpperCase(name().charAt(0)) : "Option name must start with upper-case letter: " + name(); this.type = type; this.value = UNINITIALIZED; this.defaultValue = defaultValue; - this.help = help; + this.helpLines = helpLines; } @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "sentinel must be String since it's a static final in an enum") private Object getValue() { if (value == UNINITIALIZED) { - String propertyValue = VM.getSavedProperty(JVMCI_OPTION_PROPERTY_PREFIX + name()); + String propertyValue = VM.getSavedProperty(getPropertyName()); if (propertyValue == null) { this.value = defaultValue; this.isDefault = true; } else { - if (type == boolean.class) { + if (type == Boolean.class) { this.value = Boolean.parseBoolean(propertyValue); } else if (type == String.class) { this.value = propertyValue; @@ -147,6 +150,13 @@ } /** + * Gets the name of system property from which this option gets its value. + */ + public String getPropertyName() { + return JVMCI_OPTION_PROPERTY_PREFIX + name(); + } + + /** * Returns the option's value as boolean. * * @return option's value @@ -165,16 +175,31 @@ } /** - * Prints all option flags to {@code out}. + * Prints a description of the properties used to configure shared JVMCI code. * * @param out stream to print to */ - public static void printFlags(PrintStream out) { - out.println("[List of JVMCI options]"); - for (Option option : values()) { + public static void printProperties(PrintStream out) { + out.println("[JVMCI properties]"); + int typeWidth = 0; + int nameWidth = 0; + Option[] values = values(); + for (Option option : values) { + typeWidth = Math.max(typeWidth, option.type.getSimpleName().length()); + nameWidth = Math.max(nameWidth, option.getPropertyName().length()); + } + for (Option option : values) { Object value = option.getValue(); - String assign = option.isDefault ? ":=" : " ="; - out.printf("%9s %-40s %s %-14s %s%n", option.type.getSimpleName(), option, assign, value, option.help); + if (value instanceof String) { + value = '"' + String.valueOf(value) + '"'; + } + String assign = option.isDefault ? " =" : ":="; + String format = "%" + (typeWidth + 1) + "s %-" + (nameWidth + 1) + "s %s %s%n"; + out.printf(format, option.type.getSimpleName(), option.getPropertyName(), assign, value); + String helpFormat = "%" + (typeWidth + 1) + "s %s%n"; + for (String line : option.helpLines) { + out.printf(helpFormat, "", line); + } } } } @@ -239,7 +264,6 @@ @SuppressWarnings("unused") private final String[] trivialPrefixes; @SuppressWarnings("try") - @SuppressFBWarnings(value = "DM_EXIT", justification = "PrintFlags is meant to exit the VM") private HotSpotJVMCIRuntime() { compilerToVm = new CompilerToVM(); @@ -261,20 +285,6 @@ metaAccessContext = new HotSpotJVMCIMetaAccessContext(); - boolean printFlags = Option.PrintFlags.getBoolean(); - boolean showFlags = Option.ShowFlags.getBoolean(); - if (printFlags || showFlags) { - Option.printFlags(System.out); - if (printFlags) { - System.exit(0); - } - } - - if (Option.PrintConfig.getBoolean()) { - printConfig(configStore, compilerToVm); - System.exit(0); - } - compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory(); if (compilerFactory instanceof HotSpotJVMCICompilerFactory) { hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory; @@ -298,6 +308,16 @@ trivialPrefixes = null; compilationLevelAdjustment = config.compLevelAdjustmentNone; } + + if (config.getFlag("JVMCIPrintProperties", Boolean.class)) { + PrintStream out = new PrintStream(getLogStream()); + Option.printProperties(out); + compilerFactory.printProperties(out); + } + + if (Option.PrintConfig.getBoolean()) { + printConfig(configStore, compilerToVm); + } } private JVMCIBackend registerBackend(JVMCIBackend backend) { diff -r 81c8b5be9b63 -r 6b97c4598667 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java Wed Oct 05 21:35:05 2016 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java Wed Oct 05 13:56:26 2016 -0700 @@ -22,6 +22,8 @@ */ package jdk.vm.ci.runtime.services; +import java.io.PrintStream; + import jdk.vm.ci.runtime.JVMCICompiler; import jdk.vm.ci.runtime.JVMCIRuntime; import jdk.vm.ci.services.JVMCIPermission; @@ -70,4 +72,12 @@ * Create a new instance of a {@link JVMCICompiler}. */ public abstract JVMCICompiler createCompiler(JVMCIRuntime runtime); + + /** + * Prints a description of the properties used to configure this compiler. + * + * @param out where to print the message + */ + public void printProperties(PrintStream out) { + } } diff -r 81c8b5be9b63 -r 6b97c4598667 hotspot/src/share/vm/jvmci/jvmci_globals.cpp --- a/hotspot/src/share/vm/jvmci/jvmci_globals.cpp Wed Oct 05 21:35:05 2016 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmci_globals.cpp Wed Oct 05 13:56:26 2016 -0700 @@ -85,6 +85,7 @@ CHECK_NOT_SET(JVMCIUseFastLocking, EnableJVMCI) CHECK_NOT_SET(JVMCINMethodSizeLimit, EnableJVMCI) CHECK_NOT_SET(MethodProfileWidth, EnableJVMCI) + CHECK_NOT_SET(JVMCIPrintProperties, EnableJVMCI) CHECK_NOT_SET(TraceUncollectedSpeculations, EnableJVMCI) #ifndef PRODUCT diff -r 81c8b5be9b63 -r 6b97c4598667 hotspot/src/share/vm/jvmci/jvmci_globals.hpp --- a/hotspot/src/share/vm/jvmci/jvmci_globals.hpp Wed Oct 05 21:35:05 2016 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmci_globals.hpp Wed Oct 05 13:56:26 2016 -0700 @@ -49,6 +49,9 @@ experimental(bool, UseJVMCICompiler, false, \ "Use JVMCI as the default compiler") \ \ + experimental(bool, JVMCIPrintProperties, false, \ + "Prints properties used by the JVMCI compiler") \ + \ experimental(bool, BootstrapJVMCI, false, \ "Bootstrap JVMCI before running Java main method") \ \ diff -r 81c8b5be9b63 -r 6b97c4598667 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Wed Oct 05 21:35:05 2016 +0200 +++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Oct 05 13:56:26 2016 -0700 @@ -3768,10 +3768,21 @@ SystemDictionary::compute_java_system_loader(CHECK_(JNI_ERR)); #if INCLUDE_JVMCI - if (EnableJVMCI && UseJVMCICompiler && (!UseInterpreter || !BackgroundCompilation)) { - // 8145270: Force initialization of JVMCI runtime otherwise requests for blocking - // compilations via JVMCI will not actually block until JVMCI is initialized. - JVMCIRuntime::force_initialization(CHECK_JNI_ERR); + if (EnableJVMCI) { + // Initialize JVMCI eagerly if JVMCIPrintProperties is enabled. + // The JVMCI Java initialization code will read this flag and + // do the printing if it's set. + bool init = JVMCIPrintProperties; + + if (!init) { + // 8145270: Force initialization of JVMCI runtime otherwise requests for blocking + // compilations via JVMCI will not actually block until JVMCI is initialized. + init = UseJVMCICompiler && (!UseInterpreter || !BackgroundCompilation); + } + + if (init) { + JVMCIRuntime::force_initialization(CHECK_JNI_ERR); + } } #endif diff -r 81c8b5be9b63 -r 6b97c4598667 hotspot/test/compiler/jvmci/TestJVMCIPrintProperties.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/TestJVMCIPrintProperties.java Wed Oct 05 13:56:26 2016 -0700 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, 2016, 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 TestBasicLogOutput + * @summary Ensure -XX:-JVMCIPrintProperties can be enabled and successfully prints expected output to stdout. + * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") + * @library /test/lib + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestJVMCIPrintProperties { + + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockExperimentalVMOptions", + "-XX:+EnableJVMCI", + "-XX:+JVMCIPrintProperties", + "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("[JVMCI properties]"); // expected message + output.shouldContain("String jvmci.Compiler"); // expected message + output.shouldContain("Boolean jvmci.InitTimer"); // expected message + output.shouldContain("Boolean jvmci.PrintConfig"); // expected message + output.shouldContain("String jvmci.TraceMethodDataFilter"); // expected message + output.shouldHaveExitValue(0); + } +}