< prev index next >

src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsParser.java

Print this page

        

*** 20,44 **** * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.vm.ci.options; ! import static jdk.vm.ci.inittimer.InitTimer.*; ! import java.io.*; ! import java.util.*; ! import jdk.vm.ci.inittimer.*; /** * This class contains methods for parsing JVMCI options and matching them against a set of ! * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded from JVMCI jars, either ! * {@linkplain JVMCIJarsOptionDescriptorsProvider directly} or via a {@link ServiceLoader}. */ public class OptionsParser { private static final OptionValue<Boolean> PrintFlags = new OptionValue<>(false); /** * A service for looking up {@link OptionDescriptor}s. */ public interface OptionDescriptorsProvider { --- 20,56 ---- * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.vm.ci.options; ! import static jdk.vm.ci.inittimer.InitTimer.timer; ! import java.io.BufferedReader; ! import java.io.File; ! import java.io.FileReader; ! import java.io.IOException; ! import java.io.PrintStream; ! import java.util.ArrayList; ! import java.util.Collections; ! import java.util.Formatter; ! import java.util.HashSet; ! import java.util.List; ! import java.util.Map; ! import java.util.ServiceLoader; ! import java.util.Set; ! import java.util.SortedMap; ! import jdk.vm.ci.inittimer.InitTimer; /** * This class contains methods for parsing JVMCI options and matching them against a set of ! * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded via a {@link ServiceLoader}. */ public class OptionsParser { private static final OptionValue<Boolean> PrintFlags = new OptionValue<>(false); + private static final OptionValue<Boolean> ShowFlags = new OptionValue<>(false); /** * A service for looking up {@link OptionDescriptor}s. */ public interface OptionDescriptorsProvider {
*** 52,150 **** public interface OptionConsumer { void set(OptionDescriptor desc, Object value); } /** ! * Parses the options in {@code <jre>/lib/jvmci/options} if {@code parseOptionsFile == true} and * the file exists followed by the JVMCI options in {@code options} if {@code options != null}. * * Called from VM. This method has an object return type to allow it to be called with a VM * utility function used to call other static initialization methods. * * @param options JVMCI options as serialized (name, value) pairs * @param parseOptionsFile specifies whether to look for and parse ! * {@code <jre>/lib/jvmci/options} */ @SuppressWarnings("try") public static Boolean parseOptionsFromVM(String[] options, boolean parseOptionsFile) { try (InitTimer t = timer("ParseOptions")) { - JVMCIJarsOptionDescriptorsProvider odp = new JVMCIJarsOptionDescriptorsProvider(); if (parseOptionsFile) { File javaHome = new File(System.getProperty("java.home")); File lib = new File(javaHome, "lib"); ! File jvmci = new File(lib, "jvmci"); ! File jvmciOptions = new File(jvmci, "options"); if (jvmciOptions.exists()) { try (BufferedReader br = new BufferedReader(new FileReader(jvmciOptions))) { String optionSetting = null; int lineNo = 1; while ((optionSetting = br.readLine()) != null) { if (!optionSetting.isEmpty() && optionSetting.charAt(0) != '#') { try { ! parseOptionSetting(optionSetting, null, odp); } catch (Throwable e) { throw new InternalError("Error parsing " + jvmciOptions + ", line " + lineNo, e); } } lineNo++; } } catch (IOException e) { throw new InternalError("Error reading " + jvmciOptions, e); } } } ! if (options != null) { ! assert options.length % 2 == 0; ! for (int i = 0; i < options.length / 2; i++) { ! String name = options[i * 2]; ! String value = options[i * 2 + 1]; ! parseOption(OptionsLoader.options, name, value, null, odp); } } } ! return Boolean.TRUE; } /** ! * Parses a given option setting. * * @param optionSetting a string matching the pattern {@code <name>=<value>} - * @param setter the object to notify of the parsed option and value */ ! public static void parseOptionSetting(String optionSetting, OptionConsumer setter, OptionDescriptorsProvider odp) { int eqIndex = optionSetting.indexOf('='); if (eqIndex == -1) { throw new InternalError("Option setting has does not match the pattern <name>=<value>: " + optionSetting); } ! String name = optionSetting.substring(0, eqIndex); ! String value = optionSetting.substring(eqIndex + 1); ! parseOption(OptionsLoader.options, name, value, setter, odp); } /** * Parses a given option name and value. * - * @param options * @param name the option name * @param valueString the option value as a string * @param setter the object to notify of the parsed option and value ! * @param odp ! * * @throws IllegalArgumentException if there's a problem parsing {@code option} */ ! public static void parseOption(SortedMap<String, OptionDescriptor> options, String name, String valueString, OptionConsumer setter, OptionDescriptorsProvider odp) { ! OptionDescriptor desc = options.get(name); ! if (desc == null && odp != null) { ! desc = odp.get(name); ! } ! if (desc == null && name.equals("PrintFlags")) { desc = OptionDescriptor.create("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags); } if (desc == null) { ! List<OptionDescriptor> matches = fuzzyMatch(options, name); Formatter msg = new Formatter(); msg.format("Could not find option %s", name); if (!matches.isEmpty()) { msg.format("%nDid you mean one of the following?"); for (OptionDescriptor match : matches) { --- 64,233 ---- public interface OptionConsumer { void set(OptionDescriptor desc, Object value); } /** ! * Parses the options in {@code <jdk>/lib/jvmci.options} if {@code parseOptionsFile == true} and * the file exists followed by the JVMCI options in {@code options} if {@code options != null}. * * Called from VM. This method has an object return type to allow it to be called with a VM * utility function used to call other static initialization methods. * * @param options JVMCI options as serialized (name, value) pairs * @param parseOptionsFile specifies whether to look for and parse ! * {@code <jdk>/lib/jvmci.options} */ @SuppressWarnings("try") public static Boolean parseOptionsFromVM(String[] options, boolean parseOptionsFile) { + try (InitTimer t = timer("ParseOptions")) { if (parseOptionsFile) { File javaHome = new File(System.getProperty("java.home")); File lib = new File(javaHome, "lib"); ! File jvmciOptions = new File(lib, "jvmci.options"); if (jvmciOptions.exists()) { try (BufferedReader br = new BufferedReader(new FileReader(jvmciOptions))) { String optionSetting = null; int lineNo = 1; + List<String> optionSettings = new ArrayList<>(); while ((optionSetting = br.readLine()) != null) { if (!optionSetting.isEmpty() && optionSetting.charAt(0) != '#') { try { ! parseOptionSettingTo(optionSetting, optionSettings); } catch (Throwable e) { throw new InternalError("Error parsing " + jvmciOptions + ", line " + lineNo, e); } } lineNo++; } + try { + parseOptions(optionSettings.toArray(new String[optionSettings.size()]), null, null, null); + } catch (Throwable e) { + throw new InternalError("Error parsing an option from " + jvmciOptions, e); + } } catch (IOException e) { throw new InternalError("Error reading " + jvmciOptions, e); } } } ! parseOptions(options, null, null, null); ! } ! return Boolean.TRUE; ! } ! ! /** ! * Parses an ordered list of (name, value) pairs assigning values to JVMCI options. ! * ! * @param optionSettings JVMCI options as serialized (name, value) pairs ! * @param setter the object to notify of the parsed option and value ! * @param odp if non-null, the service to use for looking up {@link OptionDescriptor}s ! * @param options the options database to use if {@code odp == null}. If ! * {@code options == null && odp == null}, {@link OptionsLoader#options} is used. ! * @throws IllegalArgumentException if there's a problem parsing {@code option} ! */ ! public static void parseOptions(String[] optionSettings, OptionConsumer setter, OptionDescriptorsProvider odp, SortedMap<String, OptionDescriptor> options) { ! if (optionSettings != null && optionSettings.length != 0) { ! assert optionSettings.length % 2 == 0; ! ! moveHelpFlagsToTail(optionSettings); ! ! for (int i = 0; i < optionSettings.length / 2; i++) { ! String name = optionSettings[i * 2]; ! String value = optionSettings[i * 2 + 1]; ! parseOption(name, value, setter, odp, options); ! } ! if (PrintFlags.getValue() || ShowFlags.getValue()) { ! Set<String> explicitlyAssigned = new HashSet<>(optionSettings.length / 2); ! for (int i = 0; i < optionSettings.length / 2; i++) { ! String name = optionSettings[i * 2]; ! explicitlyAssigned.add(name); } + printFlags(resolveOptions(options), "JVMCI", System.out, explicitlyAssigned); + if (PrintFlags.getValue()) { + System.exit(0); } } ! } ! } ! ! /** ! * Moves all {@code PrintFlags} and {@code ShowFlags} option settings to the back of ! * {@code optionSettings}. This allows the help message to show which options had their value ! * explicitly set (even if to their default value). ! */ ! private static void moveHelpFlagsToTail(String[] optionSettings) { ! List<String> tail = null; ! int insert = 0; ! for (int i = 0; i < optionSettings.length / 2; i++) { ! String name = optionSettings[i * 2]; ! String value = optionSettings[i * 2 + 1]; ! if (name.equals("ShowFlags") || name.equals("PrintFlags")) { ! if (tail == null) { ! tail = new ArrayList<>(4); ! insert = i * 2; ! } ! tail.add(name); ! tail.add(value); ! } else if (tail != null) { ! optionSettings[insert++] = name; ! optionSettings[insert++] = value; ! } ! } ! if (tail != null) { ! assert tail.size() + insert == optionSettings.length; ! String[] tailArr = tail.toArray(new String[tail.size()]); ! System.arraycopy(tailArr, 0, optionSettings, insert, tailArr.length); ! } } /** ! * Parses a given option setting string to a list of (name, value) pairs. * * @param optionSetting a string matching the pattern {@code <name>=<value>} */ ! public static void parseOptionSettingTo(String optionSetting, List<String> dst) { int eqIndex = optionSetting.indexOf('='); if (eqIndex == -1) { throw new InternalError("Option setting has does not match the pattern <name>=<value>: " + optionSetting); } ! dst.add(optionSetting.substring(0, eqIndex)); ! dst.add(optionSetting.substring(eqIndex + 1)); ! } ! ! /** ! * Resolves {@code options} to a non-null value. This ensures {@link OptionsLoader#options} is ! * only loaded if necessary. ! */ ! private static SortedMap<String, OptionDescriptor> resolveOptions(SortedMap<String, OptionDescriptor> options) { ! return options != null ? options : OptionsLoader.options; } /** * Parses a given option name and value. * * @param name the option name * @param valueString the option value as a string * @param setter the object to notify of the parsed option and value ! * @param odp if non-null, the service to use for looking up {@link OptionDescriptor}s ! * @param options the options database to use if {@code odp == null}. If ! * {@code options == null && odp == null}, {@link OptionsLoader#options} is used. * @throws IllegalArgumentException if there's a problem parsing {@code option} */ ! private static void parseOption(String name, String valueString, OptionConsumer setter, OptionDescriptorsProvider odp, SortedMap<String, OptionDescriptor> options) { ! ! OptionDescriptor desc = odp != null ? odp.get(name) : resolveOptions(options).get(name); ! if (desc == null) { ! if (name.equals("PrintFlags")) { desc = OptionDescriptor.create("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags); + } else if (name.equals("ShowFlags")) { + desc = OptionDescriptor.create("ShowFlags", Boolean.class, "Prints all JVMCI flags and continues", OptionsParser.class, "ShowFlags", ShowFlags); + } } if (desc == null) { ! List<OptionDescriptor> matches = fuzzyMatch(resolveOptions(options), name); Formatter msg = new Formatter(); msg.format("Could not find option %s", name); if (!matches.isEmpty()) { msg.format("%nDid you mean one of the following?"); for (OptionDescriptor match : matches) {
*** 180,194 **** if (setter == null) { desc.getOptionValue().setValue(value); } else { setter.set(desc, value); } - - if (PrintFlags.getValue()) { - printFlags(options, "JVMCI", System.out); - System.exit(0); - } } private static long parseLong(String v) { String valueString = v.toLowerCase(); long scale = 1; --- 263,272 ----
*** 250,269 **** } } return lines; } ! public static void printFlags(SortedMap<String, OptionDescriptor> sortedOptions, String prefix, PrintStream out) { out.println("[List of " + prefix + " options]"); for (Map.Entry<String, OptionDescriptor> e : sortedOptions.entrySet()) { e.getKey(); OptionDescriptor desc = e.getValue(); Object value = desc.getOptionValue().getValue(); List<String> helpLines = wrap(desc.getHelp(), 70); ! out.println(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, helpLines.get(0))); for (int i = 1; i < helpLines.size(); i++) { ! out.println(String.format("%67s %s", " ", helpLines.get(i))); } } } /** --- 328,349 ---- } } return lines; } ! private static void printFlags(SortedMap<String, OptionDescriptor> sortedOptions, String prefix, PrintStream out, Set<String> explicitlyAssigned) { out.println("[List of " + prefix + " options]"); for (Map.Entry<String, OptionDescriptor> e : sortedOptions.entrySet()) { e.getKey(); OptionDescriptor desc = e.getValue(); Object value = desc.getOptionValue().getValue(); List<String> helpLines = wrap(desc.getHelp(), 70); ! String name = e.getKey(); ! String assign = explicitlyAssigned.contains(name) ? ":=" : " ="; ! out.printf("%9s %-40s %s %-14s %s%n", desc.getType().getSimpleName(), name, assign, value, helpLines.get(0)); for (int i = 1; i < helpLines.size(); i++) { ! out.printf("%67s %s%n", " ", helpLines.get(i)); } } } /**
< prev index next >