# HG changeset patch # User Christian Wimmer # Date 1440541633 25200 # Node ID a6adaf9c330d48930c3003098e363e8f50cbf311 # Parent 5e61ca976049d0eef61b191cbdabbd9f71a3fa6d Ensure only one OptionDescriptor is created per option; allow custom lists of options passed to OptionParser diff -r 5e61ca976049 -r a6adaf9c330d jvmci/jdk.internal.jvmci.options.processor/src/jdk/internal/jvmci/options/processor/OptionProcessor.java --- a/jvmci/jdk.internal.jvmci.options.processor/src/jdk/internal/jvmci/options/processor/OptionProcessor.java Tue Aug 25 15:01:40 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.options.processor/src/jdk/internal/jvmci/options/processor/OptionProcessor.java Tue Aug 25 15:27:13 2015 -0700 @@ -191,9 +191,9 @@ String declaringClass = option.declaringClass; Name fieldName = option.field.getSimpleName(); if (info.options.size() == 1) { - out.printf(" return new %s(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue); + out.printf(" return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue); } else { - out.printf(" case \"" + name + "\": return new %s(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue); + out.printf(" case \"" + name + "\": return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue); } } out.println(" }"); @@ -219,7 +219,7 @@ String declaringClass = option.declaringClass; Name fieldName = option.field.getSimpleName(); String comma = i == info.options.size() - 1 ? "" : ","; - out.printf(" new %s(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s)%s\n", desc, name, type, help, declaringClass, fieldName, optionValue, comma); + out.printf(" %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s)%s\n", desc, name, type, help, declaringClass, fieldName, optionValue, comma); i++; } out.println(" );"); diff -r 5e61ca976049 -r a6adaf9c330d jvmci/jdk.internal.jvmci.options.test/src/jdk/internal/jvmci/options/test/NestedBooleanOptionValueTest.java --- a/jvmci/jdk.internal.jvmci.options.test/src/jdk/internal/jvmci/options/test/NestedBooleanOptionValueTest.java Tue Aug 25 15:01:40 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.options.test/src/jdk/internal/jvmci/options/test/NestedBooleanOptionValueTest.java Tue Aug 25 15:27:13 2015 -0700 @@ -40,12 +40,12 @@ public static final OptionValue NestedOption2 = new NestedBooleanOptionValue(Master2, false); } - static final OptionDescriptor master0 = new OptionDescriptor("Master0", Boolean.class, "", Options.class, "Master0", Master0); - static final OptionDescriptor nestedOption0 = new OptionDescriptor("NestedOption0", Boolean.class, "", Options.class, "NestedOption0", NestedOption0); - static final OptionDescriptor master1 = new OptionDescriptor("Master1", Boolean.class, "", Options.class, "Master1", Master1); - static final OptionDescriptor nestedOption1 = new OptionDescriptor("NestedOption1", Boolean.class, "", Options.class, "NestedOption1", NestedOption1); - static final OptionDescriptor master2 = new OptionDescriptor("Master2", Boolean.class, "", Options.class, "Master2", Master2); - static final OptionDescriptor nestedOption2 = new OptionDescriptor("NestedOption2", Boolean.class, "", Options.class, "NestedOption2", NestedOption2); + static final OptionDescriptor master0 = OptionDescriptor.create("Master0", Boolean.class, "", Options.class, "Master0", Master0); + static final OptionDescriptor nestedOption0 = OptionDescriptor.create("NestedOption0", Boolean.class, "", Options.class, "NestedOption0", NestedOption0); + static final OptionDescriptor master1 = OptionDescriptor.create("Master1", Boolean.class, "", Options.class, "Master1", Master1); + static final OptionDescriptor nestedOption1 = OptionDescriptor.create("NestedOption1", Boolean.class, "", Options.class, "NestedOption1", NestedOption1); + static final OptionDescriptor master2 = OptionDescriptor.create("Master2", Boolean.class, "", Options.class, "Master2", Master2); + static final OptionDescriptor nestedOption2 = OptionDescriptor.create("NestedOption2", Boolean.class, "", Options.class, "NestedOption2", NestedOption2); @Test public void runOverrides() { diff -r 5e61ca976049 -r a6adaf9c330d jvmci/jdk.internal.jvmci.options.test/src/jdk/internal/jvmci/options/test/TestOptionValue.java --- a/jvmci/jdk.internal.jvmci.options.test/src/jdk/internal/jvmci/options/test/TestOptionValue.java Tue Aug 25 15:01:40 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.options.test/src/jdk/internal/jvmci/options/test/TestOptionValue.java Tue Aug 25 15:27:13 2015 -0700 @@ -40,9 +40,9 @@ public static final OptionValue SecondMutable = new OptionValue<>("second"); } - static final OptionDescriptor stable = new OptionDescriptor("Stable", Boolean.class, "", Options.class, "Stable", Stable); - static final OptionDescriptor mutable = new OptionDescriptor("Mutable", String.class, "", Options.class, "Mutable", Mutable); - static final OptionDescriptor secondMutable = new OptionDescriptor("SecondMutable", String.class, "", Options.class, "SecondMutable", SecondMutable); + static final OptionDescriptor stable = OptionDescriptor.create("Stable", Boolean.class, "", Options.class, "Stable", Stable); + static final OptionDescriptor mutable = OptionDescriptor.create("Mutable", String.class, "", Options.class, "Mutable", Mutable); + static final OptionDescriptor secondMutable = OptionDescriptor.create("SecondMutable", String.class, "", Options.class, "SecondMutable", SecondMutable); @Test public void testMutable() { diff -r 5e61ca976049 -r a6adaf9c330d jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionDescriptor.java --- a/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionDescriptor.java Tue Aug 25 15:01:40 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionDescriptor.java Tue Aug 25 15:27:13 2015 -0700 @@ -26,7 +26,7 @@ * Describes the attributes of a static field {@linkplain Option option} and provides access to its * {@linkplain OptionValue value}. */ -public class OptionDescriptor { +public final class OptionDescriptor { protected final String name; protected final Class type; @@ -35,7 +35,17 @@ protected final Class declaringClass; protected final String fieldName; - public OptionDescriptor(String name, Class type, String help, Class declaringClass, String fieldName, OptionValue option) { + public static OptionDescriptor create(String name, Class type, String help, Class declaringClass, String fieldName, OptionValue option) { + OptionDescriptor result = option.getDescriptor(); + if (result == null) { + result = new OptionDescriptor(name, type, help, declaringClass, fieldName, option); + option.setDescriptor(result); + } + assert result.name.equals(name) && result.type == type && result.declaringClass == declaringClass && result.fieldName.equals(fieldName) && result.option == option; + return result; + } + + private OptionDescriptor(String name, Class type, String help, Class declaringClass, String fieldName, OptionValue option) { this.name = name; this.type = type; this.help = help; @@ -43,7 +53,6 @@ this.declaringClass = declaringClass; this.fieldName = fieldName; assert !type.isPrimitive() : "must used boxed type instead of " + type; - option.setDescriptor(this); } /** diff -r 5e61ca976049 -r a6adaf9c330d jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionValue.java --- a/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionValue.java Tue Aug 25 15:01:40 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionValue.java Tue Aug 25 15:27:13 2015 -0700 @@ -193,6 +193,7 @@ * Sets the descriptor for this option. */ public void setDescriptor(OptionDescriptor descriptor) { + assert this.descriptor == null : "Overwriting existing descriptor"; this.descriptor = descriptor; } @@ -234,7 +235,9 @@ * Returns true if the option has the same value that was set in the source code. */ public boolean hasDefaultValue() { - getValue(); // ensure initialized + if (!(this instanceof StableOptionValue)) { + getValue(); // ensure initialized + } return value == DEFAULT || Objects.equals(value, getDefaultValue()); } diff -r 5e61ca976049 -r a6adaf9c330d jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionsParser.java --- a/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionsParser.java Tue Aug 25 15:01:40 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionsParser.java Tue Aug 25 15:27:13 2015 -0700 @@ -24,6 +24,7 @@ import static jdk.internal.jvmci.inittimer.InitTimer.*; +import java.io.*; import java.util.*; import jdk.internal.jvmci.inittimer.*; @@ -88,6 +89,10 @@ return Boolean.TRUE; } + public static void parseOption(String option, OptionConsumer setter, OptionDescriptorsProvider odp) { + parseOption(OptionsLoader.options, option, setter, odp); + } + /** * Parses a given option value specification. * @@ -95,7 +100,7 @@ * @param setter the object to notify of the parsed option and value * @throws IllegalArgumentException if there's a problem parsing {@code option} */ - public static void parseOption(String option, OptionConsumer setter, OptionDescriptorsProvider odp) { + public static void parseOption(SortedMap options, String option, OptionConsumer setter, OptionDescriptorsProvider odp) { if (option.length() == 0) { return; } @@ -119,19 +124,19 @@ } } - OptionDescriptor desc = odp == null ? OptionsLoader.options.get(optionName) : odp.get(optionName); + OptionDescriptor desc = odp == null ? options.get(optionName) : odp.get(optionName); if (desc == null && value != null) { int index = option.indexOf('='); if (index != -1) { optionName = option.substring(1, index); - desc = odp == null ? OptionsLoader.options.get(optionName) : odp.get(optionName); + desc = odp == null ? options.get(optionName) : odp.get(optionName); } if (desc == null && optionName.equals("PrintFlags")) { - desc = new OptionDescriptor("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags); + desc = OptionDescriptor.create("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags); } } if (desc == null) { - List matches = fuzzyMatch(optionName); + List matches = fuzzyMatch(options, optionName); Formatter msg = new Formatter(); msg.format("Could not find option %s", optionName); if (!matches.isEmpty()) { @@ -180,7 +185,8 @@ } if (PrintFlags.getValue()) { - printFlags(); + printFlags(options, "JVMCI", System.out); + System.exit(0); } } @@ -247,21 +253,18 @@ return lines; } - public static void printFlags() { - System.out.println("[List of JVMCI options]"); - SortedMap sortedOptions = OptionsLoader.options; + public static void printFlags(SortedMap sortedOptions, String prefix, PrintStream out) { + out.println("[List of " + prefix + " options]"); for (Map.Entry e : sortedOptions.entrySet()) { e.getKey(); OptionDescriptor desc = e.getValue(); Object value = desc.getOptionValue().getValue(); List helpLines = wrap(desc.getHelp(), 70); - System.out.println(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, helpLines.get(0))); + 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++) { - System.out.println(String.format("%67s %s", " ", helpLines.get(i))); + out.println(String.format("%67s %s", " ", helpLines.get(i))); } } - - System.exit(0); } /** @@ -287,9 +290,9 @@ /** * Returns the set of options that fuzzy match a given option name. */ - private static List fuzzyMatch(String optionName) { + private static List fuzzyMatch(SortedMap options, String optionName) { List matches = new ArrayList<>(); - for (Map.Entry e : OptionsLoader.options.entrySet()) { + for (Map.Entry e : options.entrySet()) { float score = stringSimiliarity(e.getKey(), optionName); if (score >= FUZZY_MATCH_THRESHOLD) { matches.add(e.getValue());