Mercurial > hg > graal-jvmci-8
changeset 22398:4f6caa445b92
moved JVMCI option parsing back into Java
line wrap: on
line diff
--- a/jvmci/jdk.internal.jvmci.hotspot.amd64/src/jdk/internal/jvmci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot.amd64/src/jdk/internal/jvmci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java Tue Aug 04 00:47:34 2015 +0200 @@ -22,13 +22,14 @@ */ package jdk.internal.jvmci.hotspot.amd64; -import static jdk.internal.jvmci.hotspot.InitTimer.*; +import static jdk.internal.jvmci.inittimer.InitTimer.*; import java.util.*; import jdk.internal.jvmci.amd64.*; import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.hotspot.*; +import jdk.internal.jvmci.inittimer.*; import jdk.internal.jvmci.meta.*; import jdk.internal.jvmci.runtime.*; import jdk.internal.jvmci.service.*;
--- a/jvmci/jdk.internal.jvmci.hotspot.sparc/src/jdk/internal/jvmci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot.sparc/src/jdk/internal/jvmci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java Tue Aug 04 00:47:34 2015 +0200 @@ -22,16 +22,17 @@ */ package jdk.internal.jvmci.hotspot.sparc; -import static jdk.internal.jvmci.hotspot.InitTimer.*; +import static jdk.internal.jvmci.inittimer.InitTimer.*; import java.util.*; import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.hotspot.*; +import jdk.internal.jvmci.inittimer.*; import jdk.internal.jvmci.runtime.*; import jdk.internal.jvmci.service.*; import jdk.internal.jvmci.sparc.*; -import jdk.internal.jvmci.sparc.SPARC.*; +import jdk.internal.jvmci.sparc.SPARC.CPUFeature; @ServiceProvider(HotSpotJVMCIBackendFactory.class) public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVMImpl.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVMImpl.java Tue Aug 04 00:47:34 2015 +0200 @@ -23,9 +23,10 @@ package jdk.internal.jvmci.hotspot; -import static jdk.internal.jvmci.hotspot.InitTimer.*; +import static jdk.internal.jvmci.inittimer.InitTimer.*; import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.common.*; +import jdk.internal.jvmci.inittimer.*; import jdk.internal.jvmci.meta.*; /**
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompiledNmethod.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompiledNmethod.java Tue Aug 04 00:47:34 2015 +0200 @@ -23,6 +23,7 @@ package jdk.internal.jvmci.hotspot; import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.inittimer.*; /** * {@link HotSpotCompiledCode} destined for installation as an nmethod.
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotInstalledCode.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotInstalledCode.java Tue Aug 04 00:47:34 2015 +0200 @@ -24,6 +24,7 @@ import static jdk.internal.jvmci.common.UnsafeAccess.*; import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.inittimer.*; import sun.misc.*; /**
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java Tue Aug 04 00:47:34 2015 +0200 @@ -23,12 +23,13 @@ package jdk.internal.jvmci.hotspot; import static jdk.internal.jvmci.common.UnsafeAccess.*; -import static jdk.internal.jvmci.hotspot.InitTimer.*; +import static jdk.internal.jvmci.inittimer.InitTimer.*; import java.util.*; import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.common.*; +import jdk.internal.jvmci.inittimer.*; import jdk.internal.jvmci.meta.*; import jdk.internal.jvmci.options.*; import jdk.internal.jvmci.runtime.*;
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotObjectConstantImpl.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotObjectConstantImpl.java Tue Aug 04 00:47:34 2015 +0200 @@ -26,6 +26,7 @@ import java.lang.invoke.*; +import jdk.internal.jvmci.inittimer.*; import jdk.internal.jvmci.meta.*; /**
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotOptions.java Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, 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 jdk.internal.jvmci.hotspot; - -import java.util.*; - -import jdk.internal.jvmci.options.*; - -//JaCoCo Exclude - -/** - * Sets JVMCI options from the HotSpot command line. Such options are distinguished by the - * {@link #JVMCI_OPTION_PREFIX} prefix. - */ -public class HotSpotOptions { - - private static final String JVMCI_OPTION_PREFIX = "-G:"; - - /** - * Called from VM. - */ - static void printFlags() { - SortedMap<String, OptionDescriptor> options = new TreeMap<>(); - - for (Options opts : ServiceLoader.load(Options.class, HotSpotOptions.class.getClassLoader())) { - for (OptionDescriptor desc : opts) { - String name = desc.getName(); - OptionDescriptor existing = options.put(name, desc); - assert existing == null : "Option named \"" + name + "\" has multiple definitions: " + existing.getLocation() + " and " + desc.getLocation(); - } - } - - OptionUtils.printFlags(options, JVMCI_OPTION_PREFIX); - } -}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/InitTimer.java Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * 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 - * 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 jdk.internal.jvmci.hotspot; - -/** - * A facility for timing a step in the runtime initialization sequence. This must be independent - * from all other JVMCI code so as to not perturb the initialization sequence. - */ -public final class InitTimer implements AutoCloseable { - final String name; - final long start; - - private InitTimer(String name) { - this.name = name; - this.start = System.currentTimeMillis(); - System.out.println("START: " + SPACES.substring(0, timerDepth * 2) + name); - assert Thread.currentThread() == initializingThread : Thread.currentThread() + " != " + initializingThread; - timerDepth++; - } - - @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "only the initializing thread accesses this field") - public void close() { - final long end = System.currentTimeMillis(); - timerDepth--; - System.out.println(" DONE: " + SPACES.substring(0, timerDepth * 2) + name + " [" + (end - start) + " ms]"); - } - - public static InitTimer timer(String name) { - return ENABLED ? new InitTimer(name) : null; - } - - public static InitTimer timer(String name, Object suffix) { - return ENABLED ? new InitTimer(name + suffix) : null; - } - - /** - * Specifies if initialization timing is enabled. This can only be set via a system property as - * the timing facility is used to time initialization of {@link HotSpotOptions}. - */ - private static final boolean ENABLED = Boolean.getBoolean("jvmci.runtime.TimeInit"); - - public static int timerDepth = 0; - public static final String SPACES = " "; - - /** - * Used to assert the invariant that all initialization happens on the same thread. - */ - public static final Thread initializingThread; - static { - if (ENABLED) { - initializingThread = Thread.currentThread(); - System.out.println("INITIALIZING THREAD: " + initializingThread); - } else { - initializingThread = null; - } - } -}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/SuppressFBWarnings.java Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014, 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 jdk.internal.jvmci.hotspot; - -/** - * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings. - */ -public @interface SuppressFBWarnings { - /** - * The set of FindBugs <a - * href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be - * suppressed in annotated element. The value can be a bug category, kind or pattern. - */ - String[] value(); - - /** - * Reason why the warning is suppressed. - */ - String justification(); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jvmci/jdk.internal.jvmci.inittimer/src/jdk/internal/jvmci/inittimer/InitTimer.java Tue Aug 04 00:47:34 2015 +0200 @@ -0,0 +1,77 @@ +/* + * 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 + * 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 jdk.internal.jvmci.inittimer; + +/** + * A facility for timing a step in the runtime initialization sequence. This is independent from all + * other JVMCI code so as to not perturb the initialization sequence. It is enabled by setting the + * {@code "jvmci.inittimer"} system property to {@code "true"}. + */ +public final class InitTimer implements AutoCloseable { + final String name; + final long start; + + private InitTimer(String name) { + this.name = name; + this.start = System.currentTimeMillis(); + System.out.println("START: " + SPACES.substring(0, timerDepth * 2) + name); + assert Thread.currentThread() == initializingThread : Thread.currentThread() + " != " + initializingThread; + timerDepth++; + } + + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "only the initializing thread accesses this field") + public void close() { + final long end = System.currentTimeMillis(); + timerDepth--; + System.out.println(" DONE: " + SPACES.substring(0, timerDepth * 2) + name + " [" + (end - start) + " ms]"); + } + + public static InitTimer timer(String name) { + return ENABLED ? new InitTimer(name) : null; + } + + public static InitTimer timer(String name, Object suffix) { + return ENABLED ? new InitTimer(name + suffix) : null; + } + + /** + * Specifies if initialization timing is enabled. + */ + private static final boolean ENABLED = Boolean.getBoolean("jvmci.inittimer") || Boolean.getBoolean("jvmci.runtime.TimeInit"); + + public static int timerDepth = 0; + public static final String SPACES = " "; + + /** + * Used to assert the invariant that all initialization happens on the same thread. + */ + public static final Thread initializingThread; + static { + if (ENABLED) { + initializingThread = Thread.currentThread(); + System.out.println("INITIALIZING THREAD: " + initializingThread); + } else { + initializingThread = null; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jvmci/jdk.internal.jvmci.inittimer/src/jdk/internal/jvmci/inittimer/SuppressFBWarnings.java Tue Aug 04 00:47:34 2015 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, 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 jdk.internal.jvmci.inittimer; + +/** + * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings. + */ +public @interface SuppressFBWarnings { + /** + * The set of FindBugs <a + * href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be + * suppressed in annotated element. The value can be a bug category, kind or pattern. + */ + String[] value(); + + /** + * Reason why the warning is suppressed. + */ + String justification(); +}
--- a/jvmci/jdk.internal.jvmci.options.processor/src/jdk/internal/jvmci/options/processor/OptionProcessor.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.options.processor/src/jdk/internal/jvmci/options/processor/OptionProcessor.java Tue Aug 04 00:47:34 2015 +0200 @@ -36,21 +36,10 @@ import jdk.internal.jvmci.options.*; /** - * Processes static fields annotated with {@link Option}. An {@link Options} service is generated - * for each top level class containing at least one such field. The name of the generated class for - * top level class {@code com.foo.Bar} is {@code com.foo.Bar_Options}. - * - * The build system is expected to create the appropriate entries in {@code META-INF/services/} such - * that these service objects can be retrieved as follows: - * - * <pre> - * ServiceLoader<Options> sl = ServiceLoader.load(Options.class); - * for (Options opts : sl) { - * for (OptionDescriptor desc : sl) { - * // use desc - * } - * } - * </pre> + * Processes static fields annotated with {@link Option}. An {@link OptionDescriptors} + * implementation is generated for each top level class containing at least one such field. The name + * of the generated class for top level class {@code com.foo.Bar} is + * {@code com.foo.Bar_OptionDescriptors}. */ @SupportedAnnotationTypes({"jdk.internal.jvmci.options.Option"}) public class OptionProcessor extends AbstractProcessor { @@ -152,9 +141,13 @@ private void createFiles(OptionsInfo info) { String pkg = ((PackageElement) info.topDeclaringType.getEnclosingElement()).getQualifiedName().toString(); Name topDeclaringClass = info.topDeclaringType.getSimpleName(); + Element[] originatingElements = info.originatingElements.toArray(new Element[info.originatingElements.size()]); - String optionsClassName = topDeclaringClass + "_" + Options.class.getSimpleName(); - Element[] originatingElements = info.originatingElements.toArray(new Element[info.originatingElements.size()]); + createOptionsDescriptorsFile(info, pkg, topDeclaringClass, originatingElements); + } + + private void createOptionsDescriptorsFile(OptionsInfo info, String pkg, Name topDeclaringClass, Element[] originatingElements) { + String optionsClassName = topDeclaringClass + "_" + OptionDescriptors.class.getSimpleName(); Filer filer = processingEnv.getFiler(); try (PrintWriter out = createSourceFile(pkg, optionsClassName, filer, originatingElements)) { @@ -165,18 +158,52 @@ out.println("package " + pkg + ";"); out.println(""); out.println("import java.util.*;"); - out.println("import " + Options.class.getPackage().getName() + ".*;"); + out.println("import " + OptionDescriptors.class.getPackage().getName() + ".*;"); out.println(""); - out.println("public class " + optionsClassName + " implements " + Options.class.getSimpleName() + " {"); - out.println(" @Override"); + out.println("public class " + optionsClassName + " implements " + OptionDescriptors.class.getSimpleName() + " {"); + String desc = OptionDescriptor.class.getSimpleName(); - out.println(" public Iterator<" + desc + "> iterator() {"); - out.println(" // CheckStyle: stop line length check"); - out.println(" List<" + desc + "> options = Arrays.asList("); boolean needPrivateFieldAccessor = false; int i = 0; Collections.sort(info.options); + + out.println(" @Override"); + out.println(" public OptionDescriptor get(String value) {"); + out.println(" // CheckStyle: stop line length check"); + if (info.options.size() == 1) { + out.println(" if (value.equals(\"" + info.options.get(0).name + "\")) {"); + } else { + out.println(" switch (value) {"); + } + for (OptionInfo option : info.options) { + String name = option.name; + String optionValue; + if (option.field.getModifiers().contains(Modifier.PRIVATE)) { + needPrivateFieldAccessor = true; + optionValue = "field(" + option.declaringClass + ".class, \"" + option.field.getSimpleName() + "\")"; + } else { + optionValue = option.declaringClass + "." + option.field.getSimpleName(); + } + String type = option.type; + String help = option.help; + 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); + } 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.println(" }"); + out.println(" // CheckStyle: resume line length check"); + out.println(" return null;"); + out.println(" }"); + out.println(); + out.println(" @Override"); + out.println(" public Iterator<" + desc + "> iterator() {"); + out.println(" // CheckStyle: stop line length check"); + out.println(" List<" + desc + "> options = Arrays.asList("); for (OptionInfo option : info.options) { String optionValue; if (option.field.getModifiers().contains(Modifier.PRIVATE)) { @@ -213,59 +240,19 @@ } try { - createOptionsFile(info, pkg, topDeclaringClass.toString(), originatingElements); + createOptionsFile(pkg, topDeclaringClass.toString(), originatingElements); } catch (IOException e) { processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), info.topDeclaringType); } } - private void createOptionsFile(OptionsInfo info, String pkg, String relativeName, Element... originatingElements) throws IOException { + private void createOptionsFile(String pkg, String relativeName, Element... originatingElements) throws IOException { String filename = "META-INF/jvmci.options/" + pkg + "." + relativeName; FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements); PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8")); - Types types = processingEnv.getTypeUtils(); - for (OptionInfo option : info.options) { - String help = option.help; - if (help.indexOf('\t') >= 0 || help.indexOf('\r') >= 0 || help.indexOf('\n') >= 0) { - processingEnv.getMessager().printMessage(Kind.WARNING, "Option help should not contain '\\t', '\\r' or '\\n'", option.field); - help = help.replace('\t', ' ').replace('\n', ' ').replace('\r', ' '); - } - try { - char optionTypeToChar = optionTypeToChar(option); - String fqDeclaringClass = className(types.erasure(option.field.getEnclosingElement().asType())); - String fqFieldType = className(types.erasure(option.field.asType())); - writer.printf("%s\t%s\t%s\t%s\t%s%n", option.name, optionTypeToChar, help, fqDeclaringClass, fqFieldType); - } catch (IllegalArgumentException iae) { - } - } writer.close(); } - private String className(TypeMirror t) { - DeclaredType dt = (DeclaredType) t; - return processingEnv.getElementUtils().getBinaryName((TypeElement) dt.asElement()).toString(); - } - - private char optionTypeToChar(OptionInfo option) { - switch (option.type) { - case "Boolean": - return 'z'; - case "Integer": - return 'i'; - case "Long": - return 'j'; - case "Float": - return 'f'; - case "Double": - return 'd'; - case "String": - return 's'; - default: - processingEnv.getMessager().printMessage(Kind.ERROR, "Unsupported option type: " + option.type, option.field); - throw new IllegalArgumentException(); - } - } - protected PrintWriter createSourceFile(String pkg, String relativeName, Filer filer, Element... originatingElements) { try { // Ensure Unix line endings to comply with code style guide checked by Checkstyle
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/JVMCIJarsOptionDescriptorsProvider.java Tue Aug 04 00:47:34 2015 +0200 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2014, 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 jdk.internal.jvmci.options; + +import java.io.*; +import java.util.*; +import java.util.jar.*; +import java.util.zip.*; + +import jdk.internal.jvmci.options.OptionsParser.*; + +/** + * Access to the {@link OptionDescriptors} declared by + * {@code META-INF/services/jdk.internal.jvmci.options.OptionDescriptors} files in + * {@code <jre>/lib/jvmci/*.jar}. + */ +class JVMCIJarsOptionDescriptorsProvider implements OptionDescriptorsProvider { + + static final String OptionDescriptorsServiceFile = "META-INF/services/" + OptionDescriptors.class.getName(); + + private final Iterator<File> jars; + private final List<OptionDescriptors> optionsDescriptorsList; + + JVMCIJarsOptionDescriptorsProvider() { + List<File> jarsList = findJVMCIJars(); + this.jars = jarsList.iterator(); + this.optionsDescriptorsList = new ArrayList<>(jarsList.size() * 3); + } + + /** + * Finds the list of JVMCI jars. + */ + private static List<File> findJVMCIJars() { + File javaHome = new File(System.getProperty("java.home")); + File lib = new File(javaHome, "lib"); + File jvmci = new File(lib, "jvmci"); + if (!jvmci.exists()) { + throw new InternalError(jvmci + " does not exist"); + } + + List<File> jarFiles = new ArrayList<>(); + for (String fileName : jvmci.list()) { + if (fileName.endsWith(".jar")) { + File file = new File(jvmci, fileName); + if (file.isDirectory()) { + continue; + } + jarFiles.add(file); + } + } + return jarFiles; + } + + public OptionDescriptor get(String name) { + // Look up loaded option descriptors first + for (OptionDescriptors optionDescriptors : optionsDescriptorsList) { + OptionDescriptor desc = optionDescriptors.get(name); + if (desc != null) { + return desc; + } + } + while (jars.hasNext()) { + File path = jars.next(); + try (JarFile jar = new JarFile(path)) { + ZipEntry entry = jar.getEntry(OptionDescriptorsServiceFile); + if (entry != null) { + BufferedReader br = new BufferedReader(new InputStreamReader(jar.getInputStream(entry))); + String line = null; + OptionDescriptor desc = null; + while ((line = br.readLine()) != null) { + OptionDescriptors options; + try { + options = (OptionDescriptors) Class.forName(line).newInstance(); + optionsDescriptorsList.add(options); + if (desc == null) { + desc = options.get(name); + } + } catch (Exception e) { + throw new InternalError("Error instantiating class " + line + " read from " + path, e); + } + } + if (desc != null) { + return desc; + } + } + } catch (IOException e) { + throw new InternalError("Error reading " + path, e); + } + } + return null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionDescriptors.java Tue Aug 04 00:47:34 2015 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013, 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 jdk.internal.jvmci.options; + +/** + * An interface to a set of {@link OptionDescriptor}s. + */ +public interface OptionDescriptors extends Iterable<OptionDescriptor> { + /** + * Gets the {@link OptionDescriptor} matching a given option name or {@code null} if this option + * descriptor set doesn't contain a matching option. + */ + OptionDescriptor get(String value); +}
--- a/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionUtils.java Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2014, 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 jdk.internal.jvmci.options; - -import java.util.*; - -public class OptionUtils { - - public interface OptionConsumer { - void set(OptionDescriptor desc, Object value); - } - - /** - * Parses a given option value specification. - * - * @param option the specification of an option and its value - * @param setter the object to notify of the parsed option and value. - */ - public static void parseOption(String option, OptionConsumer setter) { - SortedMap<String, OptionDescriptor> options = OptionsLoader.options; - Objects.requireNonNull(setter); - if (option.length() == 0) { - return; - } - - Object value = null; - String optionName = null; - String valueString = null; - - char first = option.charAt(0); - if (first == '+' || first == '-') { - optionName = option.substring(1); - value = (first == '+'); - } else { - int index = option.indexOf('='); - if (index == -1) { - optionName = option; - valueString = null; - } else { - optionName = option.substring(0, index); - valueString = option.substring(index + 1); - } - } - - OptionDescriptor desc = options.get(optionName); - if (desc == null) { - throw new IllegalArgumentException("Option '" + optionName + "' not found"); - } - - Class<?> optionType = desc.getType(); - - if (value == null) { - if (optionType == Boolean.TYPE || optionType == Boolean.class) { - throw new IllegalArgumentException("Boolean option '" + optionName + "' must use +/- prefix"); - } - - if (valueString == null) { - throw new IllegalArgumentException("Missing value for non-boolean option '" + optionName + "' must use " + optionName + "=<value> format"); - } - - if (optionType == Float.class) { - value = Float.parseFloat(valueString); - } else if (optionType == Double.class) { - value = Double.parseDouble(valueString); - } else if (optionType == Integer.class) { - value = Integer.valueOf((int) parseLong(valueString)); - } else if (optionType == Long.class) { - value = Long.valueOf(parseLong(valueString)); - } else if (optionType == String.class) { - value = valueString; - } else { - throw new IllegalArgumentException("Wrong value for option '" + optionName + "'"); - } - } else { - if (optionType != Boolean.class) { - throw new IllegalArgumentException("Non-boolean option '" + optionName + "' can not use +/- prefix. Use " + optionName + "=<value> format"); - } - } - - setter.set(desc, value); - } - - private static long parseLong(String v) { - String valueString = v.toLowerCase(); - long scale = 1; - if (valueString.endsWith("k")) { - scale = 1024L; - } else if (valueString.endsWith("m")) { - scale = 1024L * 1024L; - } else if (valueString.endsWith("g")) { - scale = 1024L * 1024L * 1024L; - } else if (valueString.endsWith("t")) { - scale = 1024L * 1024L * 1024L * 1024L; - } - - if (scale != 1) { - /* Remove trailing scale character. */ - valueString = valueString.substring(0, valueString.length() - 1); - } - - return Long.parseLong(valueString) * scale; - } - - /** - * Wraps some given text to one or more lines of a given maximum width. - * - * @param text text to wrap - * @param width maximum width of an output line, exception for words in {@code text} longer than - * this value - * @return {@code text} broken into lines - */ - private static List<String> wrap(String text, int width) { - List<String> lines = Collections.singletonList(text); - if (text.length() > width) { - String[] chunks = text.split("\\s+"); - lines = new ArrayList<>(); - StringBuilder line = new StringBuilder(); - for (String chunk : chunks) { - if (line.length() + chunk.length() > width) { - lines.add(line.toString()); - line.setLength(0); - } - if (line.length() != 0) { - line.append(' '); - } - String[] embeddedLines = chunk.split("%n", -2); - if (embeddedLines.length == 1) { - line.append(chunk); - } else { - for (int i = 0; i < embeddedLines.length; i++) { - line.append(embeddedLines[i]); - if (i < embeddedLines.length - 1) { - lines.add(line.toString()); - line.setLength(0); - } - } - } - } - if (line.length() != 0) { - lines.add(line.toString()); - } - } - return lines; - } - - public static void printFlags(SortedMap<String, OptionDescriptor> options, String prefix) { - System.out.println("[List of " + prefix + " options]"); - SortedMap<String, OptionDescriptor> sortedOptions = 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); - System.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))); - } - } - - System.exit(0); - } -}
--- a/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/Options.java Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013, 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 jdk.internal.jvmci.options; - -import java.util.*; - -/** - * A {@linkplain ServiceLoader service} for accessing a set of {@link OptionDescriptor}s. - */ -public interface Options extends Iterable<OptionDescriptor> { -}
--- a/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionsLoader.java Mon Aug 03 15:19:14 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionsLoader.java Tue Aug 04 00:47:34 2015 +0200 @@ -34,7 +34,7 @@ * Initializes {@link #options} from {@link Options} services. */ static { - for (Options opts : ServiceLoader.load(Options.class, OptionsLoader.class.getClassLoader())) { + for (OptionDescriptors opts : ServiceLoader.load(OptionDescriptors.class, OptionsLoader.class.getClassLoader())) { for (OptionDescriptor desc : opts) { String name = desc.getName(); OptionDescriptor existing = options.put(name, desc);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jvmci/jdk.internal.jvmci.options/src/jdk/internal/jvmci/options/OptionsParser.java Tue Aug 04 00:47:34 2015 +0200 @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2014, 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 jdk.internal.jvmci.options; + +import static jdk.internal.jvmci.inittimer.InitTimer.*; + +import java.util.*; + +import jdk.internal.jvmci.inittimer.*; + +/** + * + * @author dsimon + * + */ +public class OptionsParser { + + /** + * A service for looking up {@link OptionDescriptor}s. + */ + public interface OptionDescriptorsProvider { + /** + * Gets the {@link OptionDescriptor} matching a given option {@linkplain Option#name() name} + * or null if no option of that name is provided by this object. + */ + OptionDescriptor get(String name); + } + + public interface OptionConsumer { + void set(OptionDescriptor desc, Object value); + } + + /** + * Finds the index of the next character in {@code s} starting at {@code from} that is a space + * iff {@code spaces == true}. + */ + private static int skip(String s, int from, boolean spaces) { + for (int i = from; i < s.length(); i++) { + if ((s.charAt(i) != ' ') == spaces) { + return i; + } + } + return s.length(); + } + + /** + * Parses the set of space separated JVMCI options in {@code options}. + * + * 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 space separated set of JVMCI options to parse + */ + public static Boolean parseOptionsFromVM(String options) { + try (InitTimer t = timer("ParseOptions")) { + JVMCIJarsOptionDescriptorsProvider odp = new JVMCIJarsOptionDescriptorsProvider(); + assert options != null; + int index = skip(options, 0, true); + while (index < options.length()) { + int end = skip(options, index, false); + String option = options.substring(index, end); + parseOption(option, null, odp); + index = skip(options, end, true); + } + } + return Boolean.TRUE; + } + + /** + * Parses a given option value specification. + * + * @param option the specification of an option and its value + * @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) { + if (option.length() == 0) { + return; + } + + Object value = null; + String optionName = null; + String valueString = null; + + char first = option.charAt(0); + if (first == '+' || first == '-') { + optionName = option.substring(1); + value = (first == '+'); + } else { + int index = option.indexOf('='); + if (index == -1) { + optionName = option; + valueString = null; + } else { + optionName = option.substring(0, index); + valueString = option.substring(index + 1); + } + } + + OptionDescriptor desc = odp == null ? OptionsLoader.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); + } + } + if (desc == null) { + List<OptionDescriptor> matches = fuzzyMatch(optionName); + Formatter msg = new Formatter(); + msg.format("Could not find option %s", optionName); + if (!matches.isEmpty()) { + msg.format("%nDid you mean one of the following?"); + for (OptionDescriptor match : matches) { + boolean isBoolean = match.getType() == Boolean.class; + msg.format("%n %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=<value>"); + } + } + throw new IllegalArgumentException(msg.toString()); + } + + Class<?> optionType = desc.getType(); + + if (value == null) { + if (optionType == Boolean.TYPE || optionType == Boolean.class) { + throw new IllegalArgumentException("Boolean option '" + optionName + "' must use +/- prefix"); + } + + if (valueString == null) { + throw new IllegalArgumentException("Missing value for non-boolean option '" + optionName + "' must use " + optionName + "=<value> format"); + } + + if (optionType == Float.class) { + value = Float.parseFloat(valueString); + } else if (optionType == Double.class) { + value = Double.parseDouble(valueString); + } else if (optionType == Integer.class) { + value = Integer.valueOf((int) parseLong(valueString)); + } else if (optionType == Long.class) { + value = Long.valueOf(parseLong(valueString)); + } else if (optionType == String.class) { + value = valueString; + } else { + throw new IllegalArgumentException("Wrong value for option '" + optionName + "'"); + } + } else { + if (optionType != Boolean.class) { + throw new IllegalArgumentException("Non-boolean option '" + optionName + "' can not use +/- prefix. Use " + optionName + "=<value> format"); + } + } + if (setter == null) { + desc.getOptionValue().setValue(value); + } else { + setter.set(desc, value); + } + } + + private static long parseLong(String v) { + String valueString = v.toLowerCase(); + long scale = 1; + if (valueString.endsWith("k")) { + scale = 1024L; + } else if (valueString.endsWith("m")) { + scale = 1024L * 1024L; + } else if (valueString.endsWith("g")) { + scale = 1024L * 1024L * 1024L; + } else if (valueString.endsWith("t")) { + scale = 1024L * 1024L * 1024L * 1024L; + } + + if (scale != 1) { + /* Remove trailing scale character. */ + valueString = valueString.substring(0, valueString.length() - 1); + } + + return Long.parseLong(valueString) * scale; + } + + /** + * Wraps some given text to one or more lines of a given maximum width. + * + * @param text text to wrap + * @param width maximum width of an output line, exception for words in {@code text} longer than + * this value + * @return {@code text} broken into lines + */ + private static List<String> wrap(String text, int width) { + List<String> lines = Collections.singletonList(text); + if (text.length() > width) { + String[] chunks = text.split("\\s+"); + lines = new ArrayList<>(); + StringBuilder line = new StringBuilder(); + for (String chunk : chunks) { + if (line.length() + chunk.length() > width) { + lines.add(line.toString()); + line.setLength(0); + } + if (line.length() != 0) { + line.append(' '); + } + String[] embeddedLines = chunk.split("%n", -2); + if (embeddedLines.length == 1) { + line.append(chunk); + } else { + for (int i = 0; i < embeddedLines.length; i++) { + line.append(embeddedLines[i]); + if (i < embeddedLines.length - 1) { + lines.add(line.toString()); + line.setLength(0); + } + } + } + } + if (line.length() != 0) { + lines.add(line.toString()); + } + } + return lines; + } + + public static void printFlags(SortedMap<String, OptionDescriptor> options, String prefix) { + System.out.println("[List of " + prefix + " options]"); + SortedMap<String, OptionDescriptor> sortedOptions = 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); + System.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))); + } + } + + System.exit(0); + } + + /** + * Compute string similarity based on Dice's coefficient. + * + * Ported from str_similar() in globals.cpp. + */ + static float stringSimiliarity(String str1, String str2) { + int hit = 0; + for (int i = 0; i < str1.length() - 1; ++i) { + for (int j = 0; j < str2.length() - 1; ++j) { + if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) { + ++hit; + break; + } + } + } + return 2.0f * hit / (str1.length() + str2.length()); + } + + private static final float FUZZY_MATCH_THRESHOLD = 0.7F; + + /** + * Returns the set of options that fuzzy match a given option name. + */ + private static List<OptionDescriptor> fuzzyMatch(String optionName) { + List<OptionDescriptor> matches = new ArrayList<>(); + for (Map.Entry<String, OptionDescriptor> e : OptionsLoader.options.entrySet()) { + float score = stringSimiliarity(e.getKey(), optionName); + if (score >= FUZZY_MATCH_THRESHOLD) { + matches.add(e.getValue()); + } + } + return matches; + } +}
--- a/make/defs.make Mon Aug 03 15:19:14 2015 +0200 +++ b/make/defs.make Tue Aug 04 00:47:34 2015 +0200 @@ -348,7 +348,6 @@ EXPORT_JRE_LIB_EXT_DIR = $(EXPORT_JRE_LIB_DIR)/ext EXPORT_JRE_LIB_JVMCI_DIR = $(EXPORT_JRE_LIB_DIR)/jvmci EXPORT_JRE_LIB_JVMCI_SERVICES_DIR = $(EXPORT_JRE_LIB_JVMCI_DIR)/services -EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR = $(EXPORT_JRE_LIB_JVMCI_DIR)/options EXPORT_JRE_LIB_ARCH_DIR = $(EXPORT_JRE_LIB_DIR)/$(LIBARCH) # non-universal macosx builds need to appear universal @@ -374,13 +373,6 @@ CONDITIONAL_EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/jdk.internal.jvmci.hotspot.events.EventProvider endif -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.compiler.Compiler -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotConstantPool -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotConstantReflectionProvider -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotResolvedJavaFieldImpl -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotResolvedJavaMethodImpl - # The use of CONDITIONAL_EXPORT_LIST is for the checking # done by verify_defs_make in jvmci.make EXPORT_LIST += $(CONDITIONAL_EXPORT_LIST)
--- a/make/jvmci.make Mon Aug 03 15:19:14 2015 +0200 +++ b/make/jvmci.make Tue Aug 04 00:47:34 2015 +0200 @@ -53,18 +53,17 @@ $(eval options := $(1)/$(OPTIONS_INF)) $(eval services := $(1)/META-INF/services) $(QUIETLY) test -d $(services) || mkdir -p $(services) - $(QUIETLY) test ! -d $(options) || (cd $(options) && for i in $$(ls); do echo $${i}_Options >> $(abspath $(services))/jdk.internal.jvmci.options.Options; done) + $(QUIETLY) test ! -d $(options) || (cd $(options) && for i in $$(ls); do echo $${i}_OptionDescriptors >> $(abspath $(services))/jdk.internal.jvmci.options.Options; done) endef -# Extracts META-INF/jvmci.services and META-INF/jvmci.options of a JAR file into a given directory +# Extracts META-INF/jvmci.services from a JAR file into a given directory # Arguments: # 1: JAR file to extract # 2: target directory (which already exists) define extract $(eval TMP := $(shell mktemp -d $(TARGET)/tmp_XXXXX)) $(QUIETLY) cd $(TMP) && $(JAR) xf $(abspath $(1)) && \ - ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) && \ - (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2)))); + (test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))); $(QUIETLY) rm -r $(TMP); $(QUIETLY) cp $(1) $(2) endef @@ -87,11 +86,11 @@ $(QUIETLY) rm -r $(TMP) endef -# Verifies that make/defs.make contains an appropriate line for each JVMCI service or option -# and that only existing JVMCI services and options are exported. +# Verifies that make/defs.make contains an appropriate line for each JVMCI service +# and that only existing JVMCI services are exported. # Arguments: -# 1: list of service or option files -# 2: variable name for directory of service or option files +# 1: list of service files +# 2: variable name for directory of service files define verify_defs_make $(eval defs := make/defs.make) $(eval uncondPattern := EXPORT_LIST += $$$$($(2))/) @@ -110,7 +109,6 @@ export: all $(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.services/*)),EXPORT_JRE_LIB_JVMCI_SERVICES_DIR) - $(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.options/*)),EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR) .PHONY: export clean: @@ -128,7 +126,8 @@ EXPORTED_FILES += $(JVMCI_SERVICE_JAR) -JVMCI_OPTIONS_SRC = $(shell find jvmci/jdk.internal.jvmci.options/src -type f 2> /dev/null) +JVMCI_OPTIONS_SRC = $(shell find jvmci/jdk.internal.jvmci.inittimer/src -type f 2> /dev/null) +JVMCI_OPTIONS_SRC += $(shell find jvmci/jdk.internal.jvmci.options/src -type f 2> /dev/null) JVMCI_OPTIONS_JAR = $(TARGET)/jvmci-options.jar
--- a/mx.jvmci/mx_jvmci.py Mon Aug 03 15:19:14 2015 +0200 +++ b/mx.jvmci/mx_jvmci.py Tue Aug 04 00:47:34 2015 +0200 @@ -1058,6 +1058,24 @@ exe = join(jdk, 'bin', mx.exe_suffix('java')) pfx = _vm_prefix.split() if _vm_prefix is not None else [] + # Support for legacy -G: options + jvmciArgs = [] + nonJvmciArgs = [] + existingJvmciOptionsProperty = None + for a in args: + if a.startswith('-G:'): + jvmciArg = a[len('-G:'):] + assert ' ' not in jvmciArg, 'space not supported in JVMCI arg: ' + a + jvmciArgs.append(a[len('-G:'):]) + else: + if a.startswith('-Djvmci.options=') or a == '-Djvmci.options': + existingJvmciOptionsProperty = a + nonJvmciArgs.append(a) + if jvmciArgs: + if existingJvmciOptionsProperty: + mx.abort('defining jvmci.option property is incompatible with defining one or more -G: options: ' + existingJvmciOptionsProperty) + args = ['-Djvmci.options=' + ' '.join(jvmciArgs)] + nonJvmciArgs + if '-version' in args: ignoredArgs = args[args.index('-version') + 1:] if len(ignoredArgs) > 0: @@ -1696,9 +1714,9 @@ # jdk.internal.jvmci.options.Options service created by # jdk.internal.jvmci.options.processor.OptionProcessor. optionsOwner = arcname[len('META-INF/jvmci.options/'):] - provider = optionsOwner + '_Options' + provider = optionsOwner + '_OptionDescriptors' self.expectedOptionsProviders.add(provider.replace('.', '/') + '.class') - self.services.setdefault('jdk.internal.jvmci.options.Options', []).append(provider) + self.services.setdefault('jdk.internal.jvmci.options.OptionDescriptors', []).append(provider) return False def __addsrc__(self, arcname, contents):
--- a/mx.jvmci/mx_jvmci_makefile.py Mon Aug 03 15:19:14 2015 +0200 +++ b/mx.jvmci/mx_jvmci_makefile.py Tue Aug 04 00:47:34 2015 +0200 @@ -186,18 +186,17 @@ $(eval options := $(1)/$(OPTIONS_INF)) $(eval services := $(1)/META-INF/services) $(QUIETLY) test -d $(services) || mkdir -p $(services) - $(QUIETLY) test ! -d $(options) || (cd $(options) && for i in $$(ls); do echo $${i}_Options >> $(abspath $(services))/jdk.internal.jvmci.options.Options; done) + $(QUIETLY) test ! -d $(options) || (cd $(options) && for i in $$(ls); do echo $${i}_OptionDescriptors >> $(abspath $(services))/jdk.internal.jvmci.options.Options; done) endef -# Extracts META-INF/jvmci.services and META-INF/jvmci.options of a JAR file into a given directory +# Extracts META-INF/jvmci.services from a JAR file into a given directory # Arguments: # 1: JAR file to extract # 2: target directory (which already exists) define extract $(eval TMP := $(shell mktemp -d $(TARGET)/tmp_XXXXX)) $(QUIETLY) cd $(TMP) && $(JAR) xf $(abspath $(1)) && \\ - ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) && \\ - (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2)))); + (test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))); $(QUIETLY) rm -r $(TMP); $(QUIETLY) cp $(1) $(2) endef @@ -220,11 +219,11 @@ $(QUIETLY) rm -r $(TMP) endef -# Verifies that make/defs.make contains an appropriate line for each JVMCI service or option -# and that only existing JVMCI services and options are exported. +# Verifies that make/defs.make contains an appropriate line for each JVMCI service +# and that only existing JVMCI services are exported. # Arguments: -# 1: list of service or option files -# 2: variable name for directory of service or option files +# 1: list of service files +# 2: variable name for directory of service files define verify_defs_make $(eval defs := make/defs.make) $(eval uncondPattern := EXPORT_LIST += $$$$($(2))/) @@ -243,7 +242,6 @@ export: all \t$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.services/*)),EXPORT_JRE_LIB_JVMCI_SERVICES_DIR) -\t$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.options/*)),EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR) .PHONY: export clean:
--- a/mx.jvmci/suite.py Mon Aug 03 15:19:14 2015 +0200 +++ b/mx.jvmci/suite.py Tue Aug 04 00:47:34 2015 +0200 @@ -110,10 +110,19 @@ "workingSets" : "API,JVMCI", }, + "jdk.internal.jvmci.inittimer" : { + "subDir" : "jvmci", + "sourceDirs" : ["src"], + "checkstyle" : "jdk.internal.jvmci.service", + "javaCompliance" : "1.8", + "workingSets" : "JVMCI", + }, + "jdk.internal.jvmci.options" : { "subDir" : "jvmci", "sourceDirs" : ["src"], "checkstyle" : "jdk.internal.jvmci.service", + "dependencies" : ["jdk.internal.jvmci.inittimer"], "javaCompliance" : "1.8", "workingSets" : "JVMCI", }, @@ -341,6 +350,7 @@ "subDir" : "jvmci", "sourcesPath" : "build/jvmci-api.src.zip", "dependencies" : [ + "jdk.internal.jvmci.inittimer", "jdk.internal.jvmci.runtime", "jdk.internal.jvmci.common", "jdk.internal.jvmci.compiler",
--- a/src/share/vm/jvmci/jvmciHashtable.cpp Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 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. - */ - -#include "precompiled.hpp" -#include "jvmci/jvmciHashtable.hpp" - -template<class K, class V> bool JVMCIHashtable<K,V>::add(V value, bool replace) { - K key = get_key(value); - unsigned int hash = compute_hash(key); - unsigned int index = hash_to_index(hash); - for (JVMCIHashtableEntry<V>* e = bucket(index); e != NULL; e = e->next()) { - if (key_equals(get_key(e->literal_addr()), key)) { - if (replace) { - e->set_literal(value); - } - return false; - } - } - JVMCIHashtableEntry<V>* e = new JVMCIHashtableEntry<V>(value); - e->set_next(_buckets[index]); - _buckets[index] = e; - ++_number_of_entries; - return true; -} - -template<class K, class V> V* JVMCIHashtable<K,V>::get(K key) { - unsigned int index = index_for(key); - for (JVMCIHashtableEntry<V>* e = bucket(index); e != NULL; e = e->next()) { - if (key_equals(get_key(e->literal_addr()), key)) { - return e->literal_addr(); - } - } - return NULL; -} - -template<class K, class V> void JVMCIHashtable<K, V>::for_each(ValueClosure<V>* closure) { - for (size_t i = 0; i < table_size(); ++i) { - for (JVMCIHashtableEntry<V>* e = bucket((int)i); e != NULL && !closure->is_aborted(); e = e->next()) { - closure->do_value(e->literal_addr()); - } - } -} - -template<class K, class V> JVMCIHashtable<K,V>::~JVMCIHashtable() { - for (size_t i = 0; i < table_size(); ++i) { - JVMCIHashtableEntry<V>* e = bucket((int)i); - while (e != NULL) { - JVMCIHashtableEntry<V>* current = e; - e = e->next(); - delete current; - } - } - FREE_C_HEAP_ARRAY(JVMCIHashtableEntry*, _buckets, mtCompiler); -} - -// Instantiation -#include "jvmci/jvmciOptions.hpp" -template class JVMCIHashtable<const char*, OptionDesc>; -template class JVMCIHashtable<const char*, OptionValue>;
--- a/src/share/vm/jvmci/jvmciHashtable.hpp Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -/* - * Copyright (c) 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. - */ - -#ifndef SHARE_VM_JVMCI_JVMCI_HASHTABLE_HPP -#define SHARE_VM_JVMCI_JVMCI_HASHTABLE_HPP - -#include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" - -// based on hashtable.hpp - -template <class T> class JVMCIHashtableEntry : public CHeapObj<mtCompiler> { - friend class VMStructs; -private: - T _literal; // ref to item in table. - JVMCIHashtableEntry* _next; // Link to next element in the linked list for this bucket - -public: - JVMCIHashtableEntry(T literal) : _literal(literal), _next(NULL) {} - - T literal() { - return _literal; - } - - void set_literal(T value) { - _literal = value; - } - - T* literal_addr() { - return &_literal; - } - - JVMCIHashtableEntry* next() const { - return _next; - } - - void set_next(JVMCIHashtableEntry* next) { - _next = next; - } -}; - -template <class V> -class ValueClosure : public StackObj { - bool _abort; -protected: - void abort() { _abort = true; } -public: - ValueClosure() : _abort(false) {} - virtual void do_value(V* value) = 0; - bool is_aborted() { return _abort; } -}; - -template <class K, class V> class JVMCIHashtable : public CHeapObj<mtCompiler> { - friend class VMStructs; -private: - // Instance variables - unsigned int _table_size; - JVMCIHashtableEntry<V>** _buckets; - unsigned int _number_of_entries; - -public: - JVMCIHashtable(size_t size) : _table_size((int)size), _number_of_entries(0) { - _buckets = NEW_C_HEAP_ARRAY(JVMCIHashtableEntry<V>*, table_size(), mtCompiler); - for (size_t i = 0; i < table_size(); ++i) { - _buckets[i] = NULL; - } - } - virtual ~JVMCIHashtable(); - -private: - // Bucket handling - unsigned int hash_to_index(unsigned int full_hash) { - unsigned int h = full_hash % _table_size; - assert(h >= 0 && h < _table_size, "Illegal hash value"); - return h; - } - - unsigned int index_for(K key) { - return hash_to_index(compute_hash(key)); - } - - size_t entry_size() { - return sizeof(V); - } - - size_t table_size() { return _table_size; } - - JVMCIHashtableEntry<V>* bucket(unsigned int index) { - return _buckets[index]; - } - - bool add(V v, bool replace); - -protected: - virtual unsigned int compute_hash(K key) = 0; - virtual bool key_equals(K k1, K k2) = 0; - virtual K get_key(V value) = 0; - virtual K get_key(V* value) = 0; - -public: - /** - * Tries to insert the value in the hash table. Returns false if an entry with the same key already exists. - * In this case it does *not* replace the existing entry. - */ - bool add(V v) { return add(v, false); } - /** - * Inserts the value in the hash table. Returns false if an entry with the same key already exists. - * In this case it replaces the existing entry. - */ - bool put(V v) { return add(v, true); } - V* get(K k); - void for_each(ValueClosure<V>* closure); - int number_of_entries() { return _number_of_entries; } - -}; - -#endif // SHARE_VM_JVMCI_JVMCI_HASHTABLE_HPP
--- a/src/share/vm/jvmci/jvmciOptions.cpp Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,244 +0,0 @@ -/* - * Copyright (c) 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. - */ - -#include "precompiled.hpp" -#include "jvmci/jvmciOptions.hpp" -#include "jvmci/jvmciRuntime.hpp" -#include "runtime/arguments.hpp" -#include "utilities/hashtable.inline.hpp" - -class OptionDescParseClosure : public ParseClosure { - OptionDescsTable* _table; -public: - OptionDescParseClosure(OptionDescsTable* table) : _table(table) {} - void do_line(char* line) { - char* idx = strchr(line, '\t'); - if (idx == NULL) { - warn_and_abort("invalid format: could not find first tab"); - return; - } - *idx = '\0'; - char* name = line; - line = idx + 1; - idx = strchr(line, '\t'); - if (idx == NULL) { - warn_and_abort("invalid format: could not find second tab"); - return; - } - *idx = '\0'; - if (strlen(line) != 1) { - warn_and_abort("invalid format: type should be 1 char long"); - return; - } - char typeChar = *line; - line = idx + 1; - idx = strchr(line, '\t'); - if (idx == NULL) { - warn_and_abort("invalid format: could not find third tab"); - return; - } - *idx = '\0'; - char* help = line; - line = idx + 1; - idx = strchr(line, '\t'); - if (idx == NULL) { - warn_and_abort("invalid format: could not find fourth tab"); - return; - } - *idx = '\0'; - char* declaringClass = line; - line = idx + 1; - char* fieldClass = line; - OptionType type; - switch(typeChar) { - case 's': - type = _string; - break; - case 'i': - type = _int; - break; - case 'j': - type = _long; - break; - case 'f': - type = _float; - break; - case 'd': - type = _double; - break; - case 'z': - type = _boolean; - break; - default: - warn_and_abort("unknown type"); - return; - } - char* name2 = NEW_C_HEAP_ARRAY(char, (strlen(name) + 1 + strlen(help) + 1 + strlen(declaringClass) + 1 + strlen(fieldClass) + 1), mtCompiler); - char* help2 = name2 + strlen(name) + 1; - char* declaringClass2 = help2 + strlen(help) + 1; - char* fieldClass2 = declaringClass2 + strlen(declaringClass) + 1; - strcpy(name2, name); - strcpy(help2, help); - strcpy(declaringClass2, declaringClass); - strcpy(fieldClass2, fieldClass); - OptionDesc desc = {name2, help2, type, declaringClass2, fieldClass2}; - if (!_table->add(desc)) { - warn_and_abort("duplicate option"); - return; - } - } -}; - -class FreeNamesClosure : public ValueClosure<OptionDesc> { - void do_value(OptionDesc* desc) { - if (desc->declaringClass == NULL) { - return; //skip pseudo-options whose name is not allocated with malloc - } - FREE_C_HEAP_ARRAY(char, desc->name, mtCompiler); - } -}; - -OptionDescsTable::~OptionDescsTable() { - FreeNamesClosure closure; - for_each(&closure); -} - -OptionDescsTable* OptionDescsTable::load_options() { - OptionDescsTable* table = new OptionDescsTable(); - // Add PrintFlags option manually - OptionDesc printFlagsDesc; - printFlagsDesc.name = PRINT_FLAGS_ARG; - printFlagsDesc.type = _boolean; - printFlagsDesc.help = PRINT_FLAGS_HELP; - printFlagsDesc.declaringClass = NULL; - printFlagsDesc.fieldClass = NULL; - table->add(printFlagsDesc); - - char optionsDir[JVM_MAXPATHLEN]; - const char* fileSep = os::file_separator(); - jio_snprintf(optionsDir, sizeof(optionsDir), "%s%slib%sjvmci%soptions", - Arguments::get_java_home(), fileSep, fileSep, fileSep); - DIR* dir = os::opendir(optionsDir); - if (dir != NULL) { - struct dirent *entry; - char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(optionsDir), mtInternal); - OptionDescParseClosure closure(table); - while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL && !closure.is_aborted()) { - const char* name = entry->d_name; - char optionFilePath[JVM_MAXPATHLEN]; - jio_snprintf(optionFilePath, sizeof(optionFilePath), "%s%s%s",optionsDir, fileSep, name); - JVMCIRuntime::parse_lines(optionFilePath, &closure, false); - } - FREE_C_HEAP_ARRAY(char, dbuf, mtInternal); - os::closedir(dir); - if (closure.is_aborted()) { - delete table; - return NULL; - } - return table; - } - // TODO(gd) should this be silent? - warning("Could not open jvmci options directory (%s)",optionsDir); - return table; -} - -OptionDesc* OptionDescsTable::get(const char* name, size_t arglen) { - char nameOnly[256]; - guarantee(arglen < 256, "Max supported option name len is 256"); - strncpy(nameOnly, name, arglen); - nameOnly[arglen] = '\0'; - return JVMCIHashtable<const char*, OptionDesc>::get(nameOnly); -} - -// Compute string similarity based on Dice's coefficient -static float str_similar(const char* str1, const char* str2) { - size_t len1 = strlen(str1); - size_t len2 = strlen(str2); - - if (len1 == 0 || len2 == 0) { - return 0; - } - - int hits = 0; - for (size_t i = 0; i < len1 - 1; ++i) { - for (size_t j = 0; j < len2 -1; ++j) { - if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) { - ++hits; - break; - } - } - } - - size_t total = len1 + len2; - return 2.0f * (float) hits / (float) total; -} - -float VMOptionsFuzzyMatchSimilarity = 0.7f; - -class FuzzyMatchClosure : public ValueClosure<OptionDesc> { - OptionDesc* _match; - float _max_score; - const char* _name; -public: - FuzzyMatchClosure(const char* name) : _name(name), _match(NULL), _max_score(-1) {} - void do_value(OptionDesc* value) { - float score = str_similar(value->name, _name); - if (score > VMOptionsFuzzyMatchSimilarity && score > _max_score) { - _max_score = score; - _match = value; - } - } - OptionDesc* get_match() { - return _match; - } -}; - -OptionDesc * OptionDescsTable::fuzzy_match(const char* name, size_t length) { - FuzzyMatchClosure closure(name); - for_each(&closure); - return closure.get_match(); -} - -class FreeStringsClosure : public ValueClosure<OptionValue> { - void do_value(OptionValue* value) { - if (value->desc.type == _string) { - FREE_C_HEAP_ARRAY(char, value->string_value, mtCompiler); - } - } -}; - -OptionValuesTable::~OptionValuesTable() { - FreeStringsClosure closure; - for_each(&closure); - delete _table; -} - - - -OptionValue* OptionValuesTable::get(const char* name, size_t arglen) { - char nameOnly[256]; - guarantee(arglen < 256, "Max supported option name len is 256"); - strncpy(nameOnly, name, arglen); - nameOnly[arglen] = '\0'; - return JVMCIHashtable<const char*, OptionValue>::get(nameOnly); -}
--- a/src/share/vm/jvmci/jvmciOptions.hpp Mon Aug 03 15:19:14 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * Copyright (c) 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. - */ - -#ifndef SHARE_VM_JVMCI_JVMCI_OPTIONS_HPP -#define SHARE_VM_JVMCI_JVMCI_OPTIONS_HPP - -#include "memory/allocation.hpp" -#include "utilities/exceptions.hpp" -#include "jvmci/jvmciHashtable.hpp" - -#define PRINT_FLAGS_ARG "PrintFlags" -#define PRINT_FLAGS_HELP "Prints all JVMCI flags (similar to XX's PrintFlagsFinal)" - -enum OptionType { - _string, - _int, - _long, - _float, - _double, - _boolean -}; - -struct OptionDesc { - const char* name; - const char* help; - OptionType type; - const char* declaringClass; - const char* fieldClass; -}; - -inline unsigned int compute_string_hash(const char *s, int n) { - unsigned int val = 0; - while (--n >= 0) { - val = *s++ + 31 * val; - } - return val; -} - -class OptionDescsTable : public JVMCIHashtable<const char*, OptionDesc> { -protected: - unsigned int compute_hash(const char* key) { return compute_string_hash(key, (int)strlen(key)); } - bool key_equals(const char* k1, const char* k2) { return strcmp(k1, k2) == 0; } - const char* get_key(OptionDesc value) { return value.name; } ; - const char* get_key(OptionDesc* value) { return value->name; } ; -public: - OptionDescsTable() : JVMCIHashtable<const char*, OptionDesc>(100) {} - ~OptionDescsTable(); - using JVMCIHashtable<const char*, OptionDesc>::get; - OptionDesc* get(const char* name, size_t arglen); - OptionDesc * fuzzy_match(const char* name, size_t length); - - static OptionDescsTable* load_options(); -}; - -struct OptionValue { - OptionDesc desc; - union { - const char* string_value; - jint int_value; - jlong long_value; - jfloat float_value; - jdouble double_value; - jboolean boolean_value; - }; -}; - -class OptionValuesTable : public JVMCIHashtable<const char*, OptionValue> { - OptionDescsTable* _table; -protected: - unsigned int compute_hash(const char* key) { return compute_string_hash(key, (int)strlen(key)); } - bool key_equals(const char* k1, const char* k2) { return strcmp(k1, k2) == 0; } - const char* get_key(OptionValue value) { return value.desc.name; } ; - const char* get_key(OptionValue* value) { return value->desc.name; } ; -public: - OptionValuesTable(OptionDescsTable* table) : _table(table), JVMCIHashtable<const char*, OptionValue>(100) {} - ~OptionValuesTable(); - using JVMCIHashtable<const char*, OptionValue>::get; - OptionValue* get(const char* name, size_t arglen); - OptionDescsTable* options_table() { return _table; } -}; - - -#endif // SHARE_VM_JVMCI_JVMCI_OPTIONS_HPP
--- a/src/share/vm/jvmci/jvmciRuntime.cpp Mon Aug 03 15:19:14 2015 +0200 +++ b/src/share/vm/jvmci/jvmciRuntime.cpp Tue Aug 04 00:47:34 2015 +0200 @@ -44,6 +44,7 @@ jobject JVMCIRuntime::_HotSpotJVMCIRuntime_instance = NULL; bool JVMCIRuntime::_HotSpotJVMCIRuntime_initialized = false; +const char* JVMCIRuntime::_options = NULL; bool JVMCIRuntime::_shutdown_called = false; void JVMCIRuntime::initialize_natives(JNIEnv *env, jclass c2vmClass) { @@ -622,7 +623,7 @@ return value; JRT_END -// private static void JVMCIClassLoaderFactory.init() +// private static void JVMCIClassLoaderFactory.init(ClassLoader loader) JVM_ENTRY(void, JVM_InitJVMCIClassLoader(JNIEnv *env, jclass c, jobject loader_handle)) SystemDictionary::init_jvmci_loader(JNIHandles::resolve(loader_handle)); SystemDictionary::WKID scan = SystemDictionary::FIRST_JVMCI_WKID; @@ -643,30 +644,43 @@ return JNIHandles::make_local(THREAD, JVMCIRuntime::get_service_impls(serviceKlass, THREAD)()); JVM_END -Handle JVMCIRuntime::callInitializer(const char* className, const char* methodName, const char* returnType) { +Handle JVMCIRuntime::callInitializer(const char* className, const char* methodName, const char* signature, JavaCallArguments* args) { guarantee(!_HotSpotJVMCIRuntime_initialized, "cannot reinitialize HotSpotJVMCIRuntime"); Thread* THREAD = Thread::current(); TempNewSymbol name = SymbolTable::new_symbol(className, CHECK_ABORT_(Handle())); KlassHandle klass = load_required_class(name); TempNewSymbol runtime = SymbolTable::new_symbol(methodName, CHECK_ABORT_(Handle())); - TempNewSymbol sig = SymbolTable::new_symbol(returnType, CHECK_ABORT_(Handle())); + TempNewSymbol sig = SymbolTable::new_symbol(signature, CHECK_ABORT_(Handle())); JavaValue result(T_OBJECT); - JavaCalls::call_static(&result, klass, runtime, sig, CHECK_ABORT_(Handle())); + if (args == NULL) { + JavaCalls::call_static(&result, klass, runtime, sig, CHECK_ABORT_(Handle())); + } else { + JavaCalls::call_static(&result, klass, runtime, sig, args, CHECK_ABORT_(Handle())); + } return Handle((oop)result.get_jobject()); } void JVMCIRuntime::initialize_HotSpotJVMCIRuntime() { if (JNIHandles::resolve(_HotSpotJVMCIRuntime_instance) == NULL) { + Thread* THREAD = Thread::current(); #ifdef ASSERT // This should only be called in the context of the JVMCI class being initialized - Thread* THREAD = Thread::current(); TempNewSymbol name = SymbolTable::new_symbol("jdk/internal/jvmci/runtime/JVMCI", CHECK_ABORT); instanceKlassHandle klass = InstanceKlass::cast(load_required_class(name)); assert(klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD), "HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization"); #endif + if (_options != NULL) { + JavaCallArguments args; + oop options = java_lang_String::create_oop_from_str(_options, CHECK_ABORT); + args.push_oop(options); + callInitializer("jdk/internal/jvmci/options/OptionsParser", + "parseOptionsFromVM", + "(Ljava/lang/String;)Ljava/lang/Boolean;", &args); + } + Handle result = callInitializer("jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime", "runtime", "()Ljdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime;"); _HotSpotJVMCIRuntime_initialized = true; @@ -782,159 +796,6 @@ } } -OptionValuesTable* JVMCIRuntime::parse_arguments() { - OptionDescsTable* table = OptionDescsTable::load_options(); - if (table == NULL) { - return NULL; - } - - OptionValuesTable* options = new OptionValuesTable(table); - - // Process option overrides from jvmci.options first - parse_jvmci_options_file(options); - - // Now process options on the command line - int numOptions = Arguments::num_jvmci_args(); - for (int i = 0; i < numOptions; i++) { - char* arg = Arguments::jvmci_args_array()[i]; - if (!parse_argument(options, arg)) { - delete options; - return NULL; - } - } - return options; -} - -void not_found(OptionDescsTable* table, const char* argname, size_t namelen) { - jio_fprintf(defaultStream::error_stream(),"Unrecognized VM option '%.*s'\n", namelen, argname); - OptionDesc* fuzzy_matched = table->fuzzy_match(argname, strlen(argname)); - if (fuzzy_matched != NULL) { - jio_fprintf(defaultStream::error_stream(), - "Did you mean '%s%s%s'?\n", - (fuzzy_matched->type == _boolean) ? "(+/-)" : "", - fuzzy_matched->name, - (fuzzy_matched->type == _boolean) ? "" : "=<value>"); - } -} - -bool JVMCIRuntime::parse_argument(OptionValuesTable* options, const char* arg) { - OptionDescsTable* table = options->options_table(); - char first = arg[0]; - const char* name; - size_t name_len; - if (first == '+' || first == '-') { - name = arg + 1; - OptionDesc* optionDesc = table->get(name); - if (optionDesc == NULL) { - not_found(table, name, strlen(name)); - return false; - } - if (optionDesc->type != _boolean) { - jio_fprintf(defaultStream::error_stream(), "Unexpected +/- setting in VM option '%s'\n", name); - return false; - } - OptionValue value; - value.desc = *optionDesc; - value.boolean_value = first == '+'; - options->put(value); - return true; - } else { - const char* sep = strchr(arg, '='); - name = arg; - const char* value = NULL; - if (sep != NULL) { - name_len = sep - name; - value = sep + 1; - } else { - name_len = strlen(name); - } - OptionDesc* optionDesc = table->get(name, name_len); - if (optionDesc == NULL) { - not_found(table, name, name_len); - return false; - } - if (optionDesc->type == _boolean) { - jio_fprintf(defaultStream::error_stream(), "Missing +/- setting for VM option '%s'\n", name); - return false; - } - if (value == NULL) { - jio_fprintf(defaultStream::error_stream(), "Must use '-G:%.*s=<value>' format for %.*s option", name_len, name, name_len, name); - return false; - } - OptionValue optionValue; - optionValue.desc = *optionDesc; - char* check; - errno = 0; - switch(optionDesc->type) { - case _int: { - long int int_value = ::strtol(value, &check, 10); - if (*check != '\0' || errno == ERANGE || int_value > max_jint || int_value < min_jint) { - jio_fprintf(defaultStream::error_stream(), "Expected int value for VM option '%s'\n", name); - return false; - } - optionValue.int_value = int_value; - break; - } - case _long: { - long long int long_value = ::strtoll(value, &check, 10); - if (*check != '\0' || errno == ERANGE || long_value > max_jlong || long_value < min_jlong) { - jio_fprintf(defaultStream::error_stream(), "Expected long value for VM option '%s'\n", name); - return false; - } - optionValue.long_value = long_value; - break; - } - case _float: { - optionValue.float_value = (float)::strtod(value, &check); //strtof not available in Windows SDK yet - if (*check != '\0' || errno == ERANGE) { - jio_fprintf(defaultStream::error_stream(), "Expected float value for VM option '%s'\n", name); - return false; - } - break; - } - case _double: { - optionValue.double_value = ::strtod(value, &check); - if (*check != '\0' || errno == ERANGE) { - jio_fprintf(defaultStream::error_stream(), "Expected double value for VM option '%s'\n", name); - return false; - } - break; - } - case _string: { - char* copy = NEW_C_HEAP_ARRAY(char, strlen(value) + 1, mtCompiler); - strcpy(copy, value); - optionValue.string_value = copy; - break; - } - default: - ShouldNotReachHere(); - } - options->put(optionValue); - return true; - } -} - -class JVMCIOptionParseClosure : public ParseClosure { - OptionValuesTable* _options; -public: - JVMCIOptionParseClosure(OptionValuesTable* options) : _options(options) {} - void do_line(char* line) { - if (!JVMCIRuntime::parse_argument(_options, line)) { - warn("There was an error parsing an argument. Skipping it."); - } - } -}; - -void JVMCIRuntime::parse_jvmci_options_file(OptionValuesTable* options) { - const char* home = Arguments::get_java_home(); - size_t path_len = strlen(home) + strlen("/lib/jvmci.options") + 1; - char path[JVM_MAXPATHLEN]; - char sep = os::file_separator()[0]; - jio_snprintf(path, JVM_MAXPATHLEN, "%s%clib%cjvmci.options", home, sep, sep); - JVMCIOptionParseClosure closure(options); - parse_lines(path, &closure, false); -} - #define CHECK_WARN_ABORT_(message) THREAD); \ if (HAS_PENDING_EXCEPTION) { \ warning(message); \ @@ -945,149 +806,10 @@ } \ (void)(0 -class SetOptionClosure : public ValueClosure<OptionValue> { - Thread* _thread; -public: - SetOptionClosure(TRAPS) : _thread(THREAD) {} - void do_value(OptionValue* optionValue) { - TRAPS = _thread; - const char* declaringClass = optionValue->desc.declaringClass; - if (declaringClass == NULL) { - // skip PrintFlags pseudo-option - return; - } - const char* fieldName = optionValue->desc.name; - const char* fieldClass = optionValue->desc.fieldClass; - - size_t fieldSigLen = 2 + strlen(fieldClass); - char* fieldSig = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, fieldSigLen + 1); - jio_snprintf(fieldSig, fieldSigLen + 1, "L%s;", fieldClass); - for (size_t i = 0; i < fieldSigLen; ++i) { - if (fieldSig[i] == '.') { - fieldSig[i] = '/'; - } - } - fieldSig[fieldSigLen] = '\0'; - size_t declaringClassLen = strlen(declaringClass); - char* declaringClassBinary = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, declaringClassLen + 1); - for (size_t i = 0; i < declaringClassLen; ++i) { - if (declaringClass[i] == '.') { - declaringClassBinary[i] = '/'; - } else { - declaringClassBinary[i] = declaringClass[i]; - } - } - declaringClassBinary[declaringClassLen] = '\0'; - - TempNewSymbol name = SymbolTable::new_symbol(declaringClassBinary, CHECK_WARN_ABORT_("Declaring class could not be found")); - Klass* klass = JVMCIRuntime::resolve_or_null(name, CHECK_WARN_ABORT_("Declaring class could not be resolved")); - - if (klass == NULL) { - warning("Declaring class for option %s could not be resolved", declaringClass); - abort(); - return; - } - - // The class has been loaded so the field and signature should already be in the symbol - // table. If they're not there, the field doesn't exist. - TempNewSymbol fieldname = SymbolTable::probe(fieldName, (int)strlen(fieldName)); - TempNewSymbol signame = SymbolTable::probe(fieldSig, (int)fieldSigLen); - if (fieldname == NULL || signame == NULL) { - warning("Symbols for field for option %s not found (in %s)", fieldName, declaringClass); - abort(); - return; - } - // Make sure class is initialized before handing id's out to fields - klass->initialize(CHECK_WARN_ABORT_("Error while initializing declaring class for option")); - - fieldDescriptor fd; - if (!InstanceKlass::cast(klass)->find_field(fieldname, signame, true, &fd)) { - warning("Field for option %s not found (in %s)", fieldName, declaringClass); - abort(); - return; - } - oop value; - switch(optionValue->desc.type) { - case _boolean: { - jvalue jv; - jv.z = optionValue->boolean_value; - value = java_lang_boxing_object::create(T_BOOLEAN, &jv, THREAD); - break; - } - case _int: { - jvalue jv; - jv.i = optionValue->int_value; - value = java_lang_boxing_object::create(T_INT, &jv, THREAD); - break; - } - case _long: { - jvalue jv; - jv.j = optionValue->long_value; - value = java_lang_boxing_object::create(T_LONG, &jv, THREAD); - break; - } - case _float: { - jvalue jv; - jv.f = optionValue->float_value; - value = java_lang_boxing_object::create(T_FLOAT, &jv, THREAD); - break; - } - case _double: { - jvalue jv; - jv.d = optionValue->double_value; - value = java_lang_boxing_object::create(T_DOUBLE, &jv, THREAD); - break; - } - case _string: - value = java_lang_String::create_from_str(optionValue->string_value, THREAD)(); - break; - default: - ShouldNotReachHere(); - } - - oop optionValueOop = klass->java_mirror()->obj_field(fd.offset()); - - if (optionValueOop == NULL) { - warning("Option field was null, can not set %s", fieldName); - abort(); - return; - } - - if (!InstanceKlass::cast(optionValueOop->klass())->find_field(vmSymbols::value_name(), vmSymbols::object_signature(), false, &fd)) { - warning("'Object value' field not found in option class %s, can not set option %s", fieldClass, fieldName); - abort(); - return; - } - - optionValueOop->obj_field_put(fd.offset(), value); - } -}; - -void JVMCIRuntime::set_options(OptionValuesTable* options, TRAPS) { - ensure_jvmci_class_loader_is_initialized(); - { - ResourceMark rm; - SetOptionClosure closure(THREAD); - options->for_each(&closure); - if (closure.is_aborted()) { - vm_abort(false); - } - } - OptionValue* printFlags = options->get(PRINT_FLAGS_ARG); - if (printFlags != NULL && printFlags->boolean_value) { - print_flags_helper(CHECK_ABORT); - } -} - -void JVMCIRuntime::print_flags_helper(TRAPS) { - // TODO(gd) write this in C++? - HandleMark hm(THREAD); - TempNewSymbol name = SymbolTable::new_symbol("jdk/internal/jvmci/hotspot/HotSpotOptions", CHECK_ABORT); - KlassHandle hotSpotOptionsClass = load_required_class(name); - TempNewSymbol setOption = SymbolTable::new_symbol("printFlags", CHECK); - JavaValue result(T_VOID); - JavaCallArguments args; - JavaCalls::call_static(&result, hotSpotOptionsClass, setOption, vmSymbols::void_method_signature(), &args, CHECK); +void JVMCIRuntime::save_options(const char* options) { + assert(options != NULL, "npe"); + assert(_options == NULL, "cannot reassign JVMCI options"); + _options = options; } Handle JVMCIRuntime::create_Service(const char* name, TRAPS) {
--- a/src/share/vm/jvmci/jvmciRuntime.hpp Mon Aug 03 15:19:14 2015 +0200 +++ b/src/share/vm/jvmci/jvmciRuntime.hpp Tue Aug 04 00:47:34 2015 +0200 @@ -28,7 +28,6 @@ #include "memory/allocation.hpp" #include "runtime/arguments.hpp" #include "runtime/deoptimization.hpp" -#include "jvmci/jvmciOptions.hpp" class ParseClosure : public StackObj { int _lineNo; @@ -59,20 +58,11 @@ private: static jobject _HotSpotJVMCIRuntime_instance; static bool _HotSpotJVMCIRuntime_initialized; + static const char* _options; static bool _shutdown_called; /** - * Loads default option value overrides from a <jre_home>/lib/jvmci.options if it exists. Each - * line in this file must have the format of a JVMCI command line option without the - * leading "-G:" prefix. These option values are set prior to processing of any JVMCI - * options present on the command line. - */ - static void parse_jvmci_options_file(OptionValuesTable* options); - - static void print_flags_helper(TRAPS); - - /** * Instantiates a service object, calls its default constructor and returns it. * * @param name the name of a class implementing jdk.internal.jvmci.service.Service @@ -87,14 +77,10 @@ static void parse_properties(SystemProperty** plist); /** - * Parses the JVMCI specific VM options that were presented by the launcher and sets - * the relevants Java fields. + * Saves the value of the "jvmci.options" system property for processing + * when JVMCI is initialized. */ - static OptionValuesTable* parse_arguments(); - - static bool parse_argument(OptionValuesTable* options, const char* arg); - - static void set_options(OptionValuesTable* options, TRAPS); + static void save_options(const char* options); /** * Ensures that the JVMCI class loader is initialized and the well known JVMCI classes are loaded. @@ -119,7 +105,7 @@ return _HotSpotJVMCIRuntime_instance; } - static Handle callInitializer(const char* className, const char* methodName, const char* returnType); + static Handle callInitializer(const char* className, const char* methodName, const char* returnType, JavaCallArguments* args = NULL); /** * Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime()
--- a/src/share/vm/runtime/arguments.cpp Mon Aug 03 15:19:14 2015 +0200 +++ b/src/share/vm/runtime/arguments.cpp Tue Aug 04 00:47:34 2015 +0200 @@ -98,10 +98,6 @@ int Arguments::_num_jvm_flags = 0; char** Arguments::_jvm_args_array = NULL; int Arguments::_num_jvm_args = 0; -#if INCLUDE_JVMCI -char** Arguments::_jvmci_args_array = NULL; -int Arguments::_num_jvmci_args = 0; -#endif char* Arguments::_java_command = NULL; SystemProperty* Arguments::_system_properties = NULL; const char* Arguments::_gc_log_filename = NULL; @@ -817,11 +813,6 @@ void Arguments::build_jvm_flags(const char* arg) { add_string(&_jvm_flags_array, &_num_jvm_flags, arg); } -#if INCLUDE_JVMCI -void Arguments::add_jvmci_arg(const char* arg) { - add_string(&_jvmci_args_array, &_num_jvmci_args, arg); -} -#endif // utility function to return a string that concatenates all // strings in a given char** array @@ -3389,17 +3380,6 @@ } } } -#if INCLUDE_JVMCI - else if (match_option(option, "-G:", &tail)) { // -G:XXX - // Option for the JVMCI compiler. - if (PrintVMOptions) { - tty->print_cr("JVMCI option %s", tail); - } - Arguments::add_jvmci_arg(tail); - - // Unknown option - } -#endif else if (is_bad_option(option, args->ignoreUnrecognized)) { return JNI_ERR; }
--- a/src/share/vm/runtime/arguments.hpp Mon Aug 03 15:19:14 2015 +0200 +++ b/src/share/vm/runtime/arguments.hpp Tue Aug 04 00:47:34 2015 +0200 @@ -246,11 +246,6 @@ // an array containing all jvm arguments specified in the command line static char** _jvm_args_array; static int _num_jvm_args; -#if INCLUDE_JVMCI - // an array containing all JVMCI arguments specified in the command line - static char** _jvmci_args_array; - static int _num_jvmci_args; -#endif // string containing all java command (class/jarfile name and app args) static char* _java_command; @@ -410,9 +405,6 @@ // methods to build strings from individual args static void build_jvm_args(const char* arg); static void build_jvm_flags(const char* arg); -#if INCLUDE_JVMCI - static void add_jvmci_arg(const char* arg); -#endif static void add_string(char*** bldarray, int* count, const char* arg); static const char* build_resource_string(char** args, int count); @@ -492,10 +484,6 @@ // return a char* array containing all options static char** jvm_flags_array() { return _jvm_flags_array; } static char** jvm_args_array() { return _jvm_args_array; } -#if INCLUDE_JVMCI - static char** jvmci_args_array() { return _jvmci_args_array; } - static int num_jvmci_args() { return _num_jvmci_args; } -#endif static int num_jvm_flags() { return _num_jvm_flags; } static int num_jvm_args() { return _num_jvm_args; } // return the arguments passed to the Java application
--- a/src/share/vm/runtime/thread.cpp Mon Aug 03 15:19:14 2015 +0200 +++ b/src/share/vm/runtime/thread.cpp Tue Aug 04 00:47:34 2015 +0200 @@ -3395,13 +3395,6 @@ jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; -#if INCLUDE_JVMCI - OptionValuesTable* options = JVMCIRuntime::parse_arguments(); - if (options == NULL) { - return JNI_ERR; - } -#endif - os::init_before_ergo(); jint ergo_result = Arguments::apply_ergo(); @@ -3710,8 +3703,10 @@ } #if INCLUDE_JVMCI - JVMCIRuntime::set_options(options, main_thread); - delete options; + const char* jvmciOptions = Arguments::PropertyList_get_value(Arguments::system_properties(), "jvmci.options"); + if (jvmciOptions != NULL) { + JVMCIRuntime::save_options(jvmciOptions); + } #endif // initialize compiler(s)