mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-29 20:48:29 +00:00
8146001: Remove support for command line options from JVMCI
Reviewed-by: twisti
This commit is contained in:
parent
ea1091ca76
commit
c1d5c540ac
@ -677,12 +677,6 @@ class JVMCIArchiveParticipant:
|
||||
assert service
|
||||
self.services.setdefault(service, []).append(provider)
|
||||
return True
|
||||
elif arcname.endswith('_OptionDescriptors.class'):
|
||||
# Need to create service files for the providers of the
|
||||
# jdk.vm.ci.options.Options service created by
|
||||
# jdk.vm.ci.options.processor.OptionProcessor.
|
||||
provider = arcname[:-len('.class'):].replace('/', '.')
|
||||
self.services.setdefault('jdk.vm.ci.options.OptionDescriptors', []).append(provider)
|
||||
return False
|
||||
|
||||
def __addsrc__(self, arcname, contents):
|
||||
@ -761,21 +755,6 @@ class JVMCI9JDKConfig(mx.JDKConfig):
|
||||
if jacocoArgs:
|
||||
args = jacocoArgs + args
|
||||
|
||||
# Support for -G: options
|
||||
def translateGOption(arg):
|
||||
if arg.startswith('-G:+'):
|
||||
if '=' in arg:
|
||||
mx.abort('Mixing + and = in -G: option specification: ' + arg)
|
||||
arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=true'
|
||||
elif arg.startswith('-G:-'):
|
||||
if '=' in arg:
|
||||
mx.abort('Mixing - and = in -G: option specification: ' + arg)
|
||||
arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=false'
|
||||
elif arg.startswith('-G:'):
|
||||
arg = '-Djvmci.option.' + arg[len('-G:'):]
|
||||
return arg
|
||||
args = map(translateGOption, args)
|
||||
|
||||
args = ['-Xbootclasspath/p:' + dep.classpath_repr() for dep in _jvmci_bootclasspath_prepends] + args
|
||||
|
||||
jvmciModeArgs = _jvmciModes[_vm.jvmciMode]
|
||||
|
||||
@ -109,7 +109,6 @@ suite = {
|
||||
"jdk.vm.ci.code",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"annotationProcessors" : ["JVMCI_OPTIONS_PROCESSOR"],
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "API,JVMCI",
|
||||
},
|
||||
@ -135,38 +134,6 @@ suite = {
|
||||
"workingSets" : "JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.options" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"dependencies" : ["jdk.vm.ci.inittimer"],
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.options.processor" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI,Codegen",
|
||||
},
|
||||
|
||||
"jdk.vm.ci.options.test" : {
|
||||
"subDir" : "test/compiler/jvmci",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options",
|
||||
"mx:JUNIT",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI",
|
||||
},
|
||||
|
||||
# ------------- JVMCI:HotSpot -------------
|
||||
|
||||
"jdk.vm.ci.aarch64" : {
|
||||
@ -200,15 +167,12 @@ suite = {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options",
|
||||
"jdk.vm.ci.hotspotvmconfig",
|
||||
"jdk.vm.ci.common",
|
||||
"jdk.vm.ci.inittimer",
|
||||
"jdk.vm.ci.runtime",
|
||||
"jdk.vm.ci.service",
|
||||
],
|
||||
"annotationProcessors" : [
|
||||
"JVMCI_OPTIONS_PROCESSOR",
|
||||
],
|
||||
"checkstyle" : "jdk.vm.ci.service",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "JVMCI",
|
||||
@ -282,11 +246,6 @@ suite = {
|
||||
"dependencies" : ["jdk.vm.ci.service"],
|
||||
},
|
||||
|
||||
"JVMCI_OPTIONS" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : ["jdk.vm.ci.options"],
|
||||
},
|
||||
|
||||
"JVMCI_API" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : [
|
||||
@ -298,7 +257,6 @@ suite = {
|
||||
"jdk.vm.ci.sparc",
|
||||
],
|
||||
"distDependencies" : [
|
||||
"JVMCI_OPTIONS",
|
||||
"JVMCI_SERVICE",
|
||||
],
|
||||
},
|
||||
@ -327,7 +285,6 @@ suite = {
|
||||
"JVMCI_TEST" : {
|
||||
"subDir" : "test/compiler/jvmci",
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options.test",
|
||||
"jdk.vm.ci.runtime.test",
|
||||
],
|
||||
"distDependencies" : [
|
||||
@ -336,13 +293,6 @@ suite = {
|
||||
"exclude" : ["mx:JUNIT"],
|
||||
},
|
||||
|
||||
"JVMCI_OPTIONS_PROCESSOR" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"dependencies" : ["jdk.vm.ci.options.processor"],
|
||||
"distDependencies" : [
|
||||
"JVMCI_OPTIONS",
|
||||
],
|
||||
},
|
||||
|
||||
"JVMCI_SERVICE_PROCESSOR" : {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
@ -358,15 +308,12 @@ suite = {
|
||||
"subDir" : "src/jdk.vm.ci/share/classes",
|
||||
"overlaps" : [
|
||||
"JVMCI_API",
|
||||
"JVMCI_OPTIONS",
|
||||
"JVMCI_SERVICE",
|
||||
"JVMCI_HOTSPOT",
|
||||
"JVMCI_HOTSPOTVMCONFIG",
|
||||
"JVMCI_SERVICE_PROCESSOR",
|
||||
"JVMCI_OPTIONS_PROCESSOR"
|
||||
],
|
||||
"dependencies" : [
|
||||
"jdk.vm.ci.options",
|
||||
"jdk.vm.ci.service",
|
||||
"jdk.vm.ci.inittimer",
|
||||
"jdk.vm.ci.runtime",
|
||||
@ -378,7 +325,6 @@ suite = {
|
||||
"jdk.vm.ci.hotspot.aarch64",
|
||||
"jdk.vm.ci.hotspot.amd64",
|
||||
"jdk.vm.ci.hotspot.sparc",
|
||||
"jdk.vm.ci.options.processor",
|
||||
"jdk.vm.ci.service.processor"
|
||||
],
|
||||
},
|
||||
|
||||
@ -36,15 +36,6 @@ SRC_DIR := $(HOTSPOT_TOPDIR)/src/jdk.vm.ci/share/classes
|
||||
################################################################################
|
||||
# Compile the annotation processor
|
||||
|
||||
$(eval $(call SetupJavaCompilation, BUILD_JVMCI_OPTIONS, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
SRC := $(SRC_DIR)/jdk.vm.ci.options/src \
|
||||
$(SRC_DIR)/jdk.vm.ci.options.processor/src \
|
||||
$(SRC_DIR)/jdk.vm.ci.inittimer/src, \
|
||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/jvmci_options, \
|
||||
JAR := $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.options.jar, \
|
||||
))
|
||||
|
||||
$(eval $(call SetupJavaCompilation, BUILD_JVMCI_SERVICE, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
SRC := $(SRC_DIR)/jdk.vm.ci.service/src \
|
||||
@ -70,11 +61,10 @@ PROC_SRCS := $(filter %.java, $(call CacheFind, $(PROC_SRC_DIRS)))
|
||||
ALL_SRC_DIRS := $(wildcard $(SRC_DIR)/*/src)
|
||||
SOURCEPATH := $(call PathList, $(ALL_SRC_DIRS))
|
||||
PROCESSOR_PATH := $(call PathList, \
|
||||
$(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.options.jar \
|
||||
$(BUILDTOOLS_OUTPUTDIR)/jdk.vm.ci.service.jar)
|
||||
|
||||
$(GENSRC_DIR)/_gensrc_proc_done: $(PROC_SRCS) \
|
||||
$(BUILD_JVMCI_OPTIONS) $(BUILD_JVMCI_SERVICE)
|
||||
$(BUILD_JVMCI_SERVICE)
|
||||
$(MKDIR) -p $(@D)
|
||||
$(eval $(call ListPathsSafely,PROC_SRCS,$(@D)/_gensrc_proc_files))
|
||||
$(JAVA_SMALL) $(NEW_JAVAC) \
|
||||
@ -92,15 +82,6 @@ TARGETS += $(GENSRC_DIR)/_gensrc_proc_done
|
||||
|
||||
################################################################################
|
||||
|
||||
$(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors: \
|
||||
$(GENSRC_DIR)/_gensrc_proc_done
|
||||
$(MKDIR) -p $(@D)
|
||||
$(FIND) $(GENSRC_DIR) -name '*_OptionDescriptors.java' | $(SED) 's:.*/jdk\.vm\.ci/\(.*\)\.java:\1:' | $(TR) '/' '.' > $@
|
||||
|
||||
TARGETS += $(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors
|
||||
|
||||
################################################################################
|
||||
|
||||
$(GENSRC_DIR)/_providers_converted: $(GENSRC_DIR)/_gensrc_proc_done
|
||||
$(MKDIR) -p $(GENSRC_DIR)/META-INF/services
|
||||
($(CD) $(GENSRC_DIR)/META-INF/jvmci.providers && \
|
||||
|
||||
@ -30,28 +30,22 @@ import java.lang.reflect.Array;
|
||||
import jdk.vm.ci.meta.Constant;
|
||||
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
||||
import jdk.vm.ci.meta.JavaConstant;
|
||||
import jdk.vm.ci.meta.JavaField;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.JavaType;
|
||||
import jdk.vm.ci.meta.MemoryAccessProvider;
|
||||
import jdk.vm.ci.meta.MethodHandleAccessProvider;
|
||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
import jdk.vm.ci.options.Option;
|
||||
import jdk.vm.ci.options.OptionType;
|
||||
import jdk.vm.ci.options.OptionValue;
|
||||
import jdk.vm.ci.options.StableOptionValue;
|
||||
|
||||
/**
|
||||
* HotSpot implementation of {@link ConstantReflectionProvider}.
|
||||
*/
|
||||
public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider, HotSpotProxified {
|
||||
|
||||
static class Options {
|
||||
//@formatter:off
|
||||
@Option(help = "Constant fold final fields with default values.", type = OptionType.Debug)
|
||||
public static final OptionValue<Boolean> TrustFinalDefaultFields = new OptionValue<>(true);
|
||||
//@formatter:on
|
||||
}
|
||||
/**
|
||||
* Determines whether to treat {@code final} fields with default values as constant.
|
||||
*/
|
||||
private static final boolean TrustFinalDefaultFields = HotSpotJVMCIRuntime.getBooleanProperty("TrustFinalDefaultFields", true);
|
||||
|
||||
protected final HotSpotJVMCIRuntimeProvider runtime;
|
||||
protected final HotSpotMethodHandleAccessProvider methodHandleAccess;
|
||||
@ -239,7 +233,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
||||
|
||||
/**
|
||||
* Determines if a static field is constant for the purpose of
|
||||
* {@link #readConstantFieldValue(JavaField, JavaConstant)}.
|
||||
* {@link #readConstantFieldValue(ResolvedJavaField, JavaConstant)}.
|
||||
*/
|
||||
protected boolean isStaticFieldConstant(HotSpotResolvedJavaField staticField) {
|
||||
if (staticField.isFinal() || (staticField.isStable() && runtime.getConfig().foldStableValues)) {
|
||||
@ -255,14 +249,14 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
||||
* Determines if a value read from a {@code final} instance field is considered constant. The
|
||||
* implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
|
||||
* not the {@link JavaConstant#isDefaultForKind default value} for its kind or if
|
||||
* {@link Options#TrustFinalDefaultFields} is true.
|
||||
* {@link #TrustFinalDefaultFields} is true.
|
||||
*
|
||||
* @param value a value read from a {@code final} instance field
|
||||
* @param receiverClass the {@link Object#getClass() class} of object from which the
|
||||
* {@code value} was read
|
||||
*/
|
||||
protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
|
||||
return !value.isDefaultForKind() || Options.TrustFinalDefaultFields.getValue();
|
||||
return !value.isDefaultForKind() || TrustFinalDefaultFields;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -278,13 +272,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
||||
return !value.isDefaultForKind();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* The {@code value} field in {@link OptionValue} is considered constant if the type of
|
||||
* {@code receiver} is (assignable to) {@link StableOptionValue}.
|
||||
*/
|
||||
public JavaConstant readConstantFieldValue(JavaField field, JavaConstant receiver) {
|
||||
public JavaConstant readConstantFieldValue(ResolvedJavaField field, JavaConstant receiver) {
|
||||
HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
|
||||
|
||||
if (hotspotField.isStatic()) {
|
||||
@ -319,21 +307,13 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
||||
return value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Class<?> clazz = object.getClass();
|
||||
if (StableOptionValue.class.isAssignableFrom(clazz)) {
|
||||
if (hotspotField.isInObject(object) && hotspotField.getName().equals("value")) {
|
||||
StableOptionValue<?> option = (StableOptionValue<?>) object;
|
||||
return HotSpotObjectConstantImpl.forObject(option.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public JavaConstant readFieldValue(JavaField field, JavaConstant receiver) {
|
||||
public JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver) {
|
||||
HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
|
||||
if (!hotspotField.isStable()) {
|
||||
return readNonStableFieldValue(field, receiver);
|
||||
@ -344,7 +324,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
||||
}
|
||||
}
|
||||
|
||||
private JavaConstant readNonStableFieldValue(JavaField field, JavaConstant receiver) {
|
||||
private JavaConstant readNonStableFieldValue(ResolvedJavaField field, JavaConstant receiver) {
|
||||
HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
|
||||
if (hotspotField.isStatic()) {
|
||||
HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
|
||||
@ -359,7 +339,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
|
||||
return null;
|
||||
}
|
||||
|
||||
public JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable) {
|
||||
public JavaConstant readStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefaultStable) {
|
||||
JavaConstant fieldValue = readNonStableFieldValue(field, receiver);
|
||||
if (fieldValue.isNonNull()) {
|
||||
JavaType declaredType = field.getType();
|
||||
|
||||
@ -49,6 +49,7 @@ import jdk.vm.ci.runtime.JVMCI;
|
||||
import jdk.vm.ci.runtime.JVMCIBackend;
|
||||
import jdk.vm.ci.runtime.JVMCICompiler;
|
||||
import jdk.vm.ci.service.Services;
|
||||
import sun.misc.VM;
|
||||
|
||||
//JaCoCo Exclude
|
||||
|
||||
@ -83,6 +84,22 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
|
||||
return DelayedInit.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a boolean value based on a system property {@linkplain VM#getSavedProperty(String)
|
||||
* saved} at system initialization time. The property name is prefixed with "{@code jvmci.}".
|
||||
*
|
||||
* @param name the name of the system property to derive a boolean value from using
|
||||
* {@link Boolean#parseBoolean(String)}
|
||||
* @param def the value to return if there is no system property corresponding to {@code name}
|
||||
*/
|
||||
public static boolean getBooleanProperty(String name, boolean def) {
|
||||
String value = VM.getSavedProperty("jvmci." + name);
|
||||
if (value == null) {
|
||||
return def;
|
||||
}
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
|
||||
public static HotSpotJVMCIBackendFactory findFactory(String architecture) {
|
||||
for (HotSpotJVMCIBackendFactory factory : Services.load(HotSpotJVMCIBackendFactory.class)) {
|
||||
if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
|
||||
|
||||
@ -35,21 +35,16 @@ import jdk.vm.ci.meta.MetaAccessProvider;
|
||||
import jdk.vm.ci.meta.ModifiersProvider;
|
||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
import jdk.vm.ci.options.Option;
|
||||
import jdk.vm.ci.options.OptionType;
|
||||
import jdk.vm.ci.options.OptionValue;
|
||||
|
||||
/**
|
||||
* Represents a field in a HotSpot type.
|
||||
*/
|
||||
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
|
||||
|
||||
static class Options {
|
||||
//@formatter:off
|
||||
@Option(help = "Mark well-known stable fields as such.", type = OptionType.Debug)
|
||||
public static final OptionValue<Boolean> ImplicitStableValues = new OptionValue<>(true);
|
||||
//@formatter:on
|
||||
}
|
||||
/**
|
||||
* Mark well-known stable fields as such.
|
||||
*/
|
||||
private static final boolean ImplicitStableValues = HotSpotJVMCIRuntime.getBooleanProperty("ImplicitStableValues", true);
|
||||
|
||||
private final HotSpotResolvedObjectTypeImpl holder;
|
||||
private final String name;
|
||||
@ -203,7 +198,7 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
|
||||
return true;
|
||||
}
|
||||
assert getAnnotation(Stable.class) == null;
|
||||
if (Options.ImplicitStableValues.getValue() && isImplicitStableField()) {
|
||||
if (ImplicitStableValues && isImplicitStableField()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -27,22 +27,12 @@ import java.lang.reflect.Modifier;
|
||||
import jdk.vm.ci.meta.JavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
import jdk.vm.ci.options.Option;
|
||||
import jdk.vm.ci.options.OptionType;
|
||||
import jdk.vm.ci.options.OptionValue;
|
||||
|
||||
/**
|
||||
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
|
||||
*/
|
||||
public interface HotSpotResolvedJavaMethod extends ResolvedJavaMethod {
|
||||
|
||||
public static class Options {
|
||||
// @formatter:off
|
||||
@Option(help = "", type = OptionType.Debug)
|
||||
public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this method has a {@code CallerSensitive} annotation.
|
||||
*
|
||||
|
||||
@ -24,7 +24,6 @@ package jdk.vm.ci.hotspot;
|
||||
|
||||
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
|
||||
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
|
||||
import static jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod.Options.UseProfilingInformation;
|
||||
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
|
||||
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
|
||||
|
||||
@ -424,7 +423,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
||||
public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
|
||||
ProfilingInfo info;
|
||||
|
||||
if (UseProfilingInformation.getValue() && methodData == null) {
|
||||
if (methodData == null) {
|
||||
long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + config().methodDataOffset);
|
||||
if (metaspaceMethodData != 0) {
|
||||
methodData = new HotSpotMethodData(metaspaceMethodData, this);
|
||||
|
||||
@ -80,29 +80,31 @@ public interface ConstantReflectionProvider {
|
||||
* @return the constant value of this field or {@code null} if this field is not considered
|
||||
* constant by the runtime
|
||||
*/
|
||||
JavaConstant readConstantFieldValue(JavaField field, JavaConstant receiver);
|
||||
JavaConstant readConstantFieldValue(ResolvedJavaField field, JavaConstant receiver);
|
||||
|
||||
/**
|
||||
* Gets the current value of this field for a given object, if available.
|
||||
*
|
||||
* There is no guarantee that the same value will be returned by this method for a field unless
|
||||
* the field is considered to be {@linkplain #readConstantFieldValue(JavaField, JavaConstant)
|
||||
* constant} by the runtime.
|
||||
* the field is considered to be
|
||||
* {@linkplain #readConstantFieldValue(ResolvedJavaField, JavaConstant) constant} by the
|
||||
* runtime.
|
||||
*
|
||||
* @param receiver object from which this field's value is to be read. This value is ignored if
|
||||
* this field is static.
|
||||
* @return the value of this field or {@code null} if the value is not available (e.g., because
|
||||
* the field holder is not yet initialized).
|
||||
*/
|
||||
JavaConstant readFieldValue(JavaField field, JavaConstant receiver);
|
||||
JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver);
|
||||
|
||||
/**
|
||||
* Gets the current value of this field for a given object, if available. Like
|
||||
* {@link #readFieldValue(JavaField, JavaConstant)} but treats array fields as stable.
|
||||
* {@link #readFieldValue(ResolvedJavaField, JavaConstant)} but treats array fields as stable.
|
||||
*
|
||||
* There is no guarantee that the same value will be returned by this method for a field unless
|
||||
* the field is considered to be {@linkplain #readConstantFieldValue(JavaField, JavaConstant)
|
||||
* constant} by the runtime.
|
||||
* the field is considered to be
|
||||
* {@linkplain #readConstantFieldValue(ResolvedJavaField, JavaConstant) constant} by the
|
||||
* runtime.
|
||||
*
|
||||
* @param receiver object from which this field's value is to be read. This value is ignored if
|
||||
* this field is static.
|
||||
@ -110,7 +112,7 @@ public interface ConstantReflectionProvider {
|
||||
* @return the value of this field or {@code null} if the value is not available (e.g., because
|
||||
* the field holder is not yet initialized).
|
||||
*/
|
||||
JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable);
|
||||
JavaConstant readStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefaultStable);
|
||||
|
||||
/**
|
||||
* Converts the given {@link JavaKind#isPrimitive() primitive} constant to a boxed
|
||||
|
||||
@ -1 +0,0 @@
|
||||
jdk.vm.ci.options.processor.OptionProcessor
|
||||
@ -1,369 +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.vm.ci.options.processor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.Filer;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import jdk.vm.ci.options.Option;
|
||||
import jdk.vm.ci.options.OptionDescriptor;
|
||||
import jdk.vm.ci.options.OptionDescriptors;
|
||||
import jdk.vm.ci.options.OptionValue;
|
||||
|
||||
/**
|
||||
* 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.vm.ci.options.Option"})
|
||||
public class OptionProcessor extends AbstractProcessor {
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latest();
|
||||
}
|
||||
|
||||
private final Set<Element> processed = new HashSet<>();
|
||||
|
||||
private void processElement(Element element, OptionsInfo info) {
|
||||
|
||||
if (!element.getModifiers().contains(Modifier.STATIC)) {
|
||||
processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element);
|
||||
return;
|
||||
}
|
||||
|
||||
Option annotation = element.getAnnotation(Option.class);
|
||||
assert annotation != null;
|
||||
assert element instanceof VariableElement;
|
||||
assert element.getKind() == ElementKind.FIELD;
|
||||
VariableElement field = (VariableElement) element;
|
||||
String fieldName = field.getSimpleName().toString();
|
||||
|
||||
Elements elements = processingEnv.getElementUtils();
|
||||
Types types = processingEnv.getTypeUtils();
|
||||
|
||||
TypeMirror fieldType = field.asType();
|
||||
if (fieldType.getKind() != TypeKind.DECLARED) {
|
||||
processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be of type " + OptionValue.class.getName(), element);
|
||||
return;
|
||||
}
|
||||
DeclaredType declaredFieldType = (DeclaredType) fieldType;
|
||||
|
||||
TypeMirror optionValueType = elements.getTypeElement(OptionValue.class.getName()).asType();
|
||||
if (!types.isSubtype(fieldType, types.erasure(optionValueType))) {
|
||||
String msg = String.format("Option field type %s is not a subclass of %s", fieldType, optionValueType);
|
||||
processingEnv.getMessager().printMessage(Kind.ERROR, msg, element);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!field.getModifiers().contains(Modifier.STATIC)) {
|
||||
processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element);
|
||||
return;
|
||||
}
|
||||
|
||||
String help = annotation.help();
|
||||
if (help.length() != 0) {
|
||||
char firstChar = help.charAt(0);
|
||||
if (!Character.isUpperCase(firstChar)) {
|
||||
processingEnv.getMessager().printMessage(Kind.ERROR, "Option help text must start with upper case letter", element);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String optionName = annotation.name();
|
||||
if (optionName.equals("")) {
|
||||
optionName = fieldName;
|
||||
}
|
||||
|
||||
DeclaredType declaredOptionValueType = declaredFieldType;
|
||||
while (!types.isSameType(types.erasure(declaredOptionValueType), types.erasure(optionValueType))) {
|
||||
List<? extends TypeMirror> directSupertypes = types.directSupertypes(declaredFieldType);
|
||||
assert !directSupertypes.isEmpty();
|
||||
declaredOptionValueType = (DeclaredType) directSupertypes.get(0);
|
||||
}
|
||||
|
||||
assert !declaredOptionValueType.getTypeArguments().isEmpty();
|
||||
String optionType = declaredOptionValueType.getTypeArguments().get(0).toString();
|
||||
if (optionType.startsWith("java.lang.")) {
|
||||
optionType = optionType.substring("java.lang.".length());
|
||||
}
|
||||
|
||||
Element enclosing = element.getEnclosingElement();
|
||||
String declaringClass = "";
|
||||
String separator = "";
|
||||
Set<Element> originatingElementsList = info.originatingElements;
|
||||
originatingElementsList.add(field);
|
||||
while (enclosing != null) {
|
||||
if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) {
|
||||
if (enclosing.getModifiers().contains(Modifier.PRIVATE)) {
|
||||
String msg = String.format("Option field cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing);
|
||||
processingEnv.getMessager().printMessage(Kind.ERROR, msg, element);
|
||||
return;
|
||||
}
|
||||
originatingElementsList.add(enclosing);
|
||||
declaringClass = enclosing.getSimpleName() + separator + declaringClass;
|
||||
separator = ".";
|
||||
} else {
|
||||
assert enclosing.getKind() == ElementKind.PACKAGE;
|
||||
}
|
||||
enclosing = enclosing.getEnclosingElement();
|
||||
}
|
||||
|
||||
info.options.add(new OptionInfo(optionName, help, optionType, declaringClass, field));
|
||||
}
|
||||
|
||||
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()]);
|
||||
|
||||
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)) {
|
||||
|
||||
out.println("// CheckStyle: stop header check");
|
||||
out.println("// CheckStyle: stop line length check");
|
||||
out.println("// GENERATED CONTENT - DO NOT EDIT");
|
||||
out.println("// Source: " + topDeclaringClass + ".java");
|
||||
out.println("package " + pkg + ";");
|
||||
out.println("");
|
||||
out.println("import java.util.*;");
|
||||
out.println("import " + OptionDescriptors.class.getPackage().getName() + ".*;");
|
||||
out.println("");
|
||||
out.println("public class " + optionsClassName + " implements " + OptionDescriptors.class.getSimpleName() + " {");
|
||||
|
||||
String desc = OptionDescriptor.class.getSimpleName();
|
||||
|
||||
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 %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue);
|
||||
} else {
|
||||
out.printf(" case \"" + name + "\": return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue);
|
||||
}
|
||||
}
|
||||
out.println(" }");
|
||||
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)) {
|
||||
needPrivateFieldAccessor = true;
|
||||
optionValue = "field(" + option.declaringClass + ".class, \"" + option.field.getSimpleName() + "\")";
|
||||
} else {
|
||||
optionValue = option.declaringClass + "." + option.field.getSimpleName();
|
||||
}
|
||||
String name = option.name;
|
||||
String type = option.type;
|
||||
String help = option.help;
|
||||
String declaringClass = option.declaringClass;
|
||||
Name fieldName = option.field.getSimpleName();
|
||||
String comma = i == info.options.size() - 1 ? "" : ",";
|
||||
out.printf(" %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s)%s\n", desc, name, type, help, declaringClass, fieldName, optionValue, comma);
|
||||
i++;
|
||||
}
|
||||
out.println(" );");
|
||||
out.println(" // CheckStyle: resume line length check");
|
||||
out.println(" return options.iterator();");
|
||||
out.println(" }");
|
||||
if (needPrivateFieldAccessor) {
|
||||
out.println(" private static " + OptionValue.class.getSimpleName() + "<?> field(Class<?> declaringClass, String fieldName) {");
|
||||
out.println(" try {");
|
||||
out.println(" java.lang.reflect.Field field = declaringClass.getDeclaredField(fieldName);");
|
||||
out.println(" field.setAccessible(true);");
|
||||
out.println(" return (" + OptionValue.class.getSimpleName() + "<?>) field.get(null);");
|
||||
out.println(" } catch (Exception e) {");
|
||||
out.println(" throw (InternalError) new InternalError().initCause(e);");
|
||||
out.println(" }");
|
||||
out.println(" }");
|
||||
}
|
||||
out.println("}");
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
JavaFileObject sourceFile = filer.createSourceFile(pkg + "." + relativeName, originatingElements);
|
||||
return new PrintWriter(sourceFile.openWriter()) {
|
||||
|
||||
@Override
|
||||
public void println() {
|
||||
print("\n");
|
||||
}
|
||||
};
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static class OptionInfo implements Comparable<OptionInfo> {
|
||||
|
||||
final String name;
|
||||
final String help;
|
||||
final String type;
|
||||
final String declaringClass;
|
||||
final VariableElement field;
|
||||
|
||||
public OptionInfo(String name, String help, String type, String declaringClass, VariableElement field) {
|
||||
this.name = name;
|
||||
this.help = help;
|
||||
this.type = type;
|
||||
this.declaringClass = declaringClass;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(OptionInfo other) {
|
||||
return name.compareTo(other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return declaringClass + "." + field;
|
||||
}
|
||||
}
|
||||
|
||||
static class OptionsInfo {
|
||||
|
||||
final Element topDeclaringType;
|
||||
final List<OptionInfo> options = new ArrayList<>();
|
||||
final Set<Element> originatingElements = new HashSet<>();
|
||||
|
||||
public OptionsInfo(Element topDeclaringType) {
|
||||
this.topDeclaringType = topDeclaringType;
|
||||
}
|
||||
}
|
||||
|
||||
private static Element topDeclaringType(Element element) {
|
||||
Element enclosing = element.getEnclosingElement();
|
||||
if (enclosing == null || enclosing.getKind() == ElementKind.PACKAGE) {
|
||||
assert element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.INTERFACE;
|
||||
return element;
|
||||
}
|
||||
return topDeclaringType(enclosing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (roundEnv.processingOver()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Map<Element, OptionsInfo> map = new HashMap<>();
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(Option.class)) {
|
||||
if (!processed.contains(element)) {
|
||||
processed.add(element);
|
||||
Element topDeclaringType = topDeclaringType(element);
|
||||
OptionsInfo options = map.get(topDeclaringType);
|
||||
if (options == null) {
|
||||
options = new OptionsInfo(topDeclaringType);
|
||||
map.put(topDeclaringType, options);
|
||||
}
|
||||
processElement(element, options);
|
||||
}
|
||||
}
|
||||
|
||||
boolean ok = true;
|
||||
Map<String, OptionInfo> uniqueness = new HashMap<>();
|
||||
for (OptionsInfo info : map.values()) {
|
||||
for (OptionInfo option : info.options) {
|
||||
OptionInfo conflict = uniqueness.put(option.name, option);
|
||||
if (conflict != null) {
|
||||
processingEnv.getMessager().printMessage(Kind.ERROR, "Duplicate option names for " + option + " and " + conflict, option.field);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
for (OptionsInfo info : map.values()) {
|
||||
createFiles(info);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,59 +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.vm.ci.options;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jdk.vm.ci.options.OptionValue.OverrideScope;
|
||||
|
||||
/**
|
||||
* A cached value that needs to be recomputed when an option changes.
|
||||
*/
|
||||
public class DerivedOptionValue<T> {
|
||||
|
||||
public interface OptionSupplier<T> extends Supplier<T>, Serializable {
|
||||
}
|
||||
|
||||
private final T initialValue;
|
||||
private final OptionSupplier<T> supplier;
|
||||
|
||||
public DerivedOptionValue(OptionSupplier<T> supplier) {
|
||||
this.supplier = supplier;
|
||||
assert OptionValue.getOverrideScope() == null : "derived option value should be initialized outside any override scope";
|
||||
this.initialValue = createValue();
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
OverrideScope overrideScope = OptionValue.getOverrideScope();
|
||||
if (overrideScope != null) {
|
||||
return overrideScope.getDerived(this);
|
||||
} else {
|
||||
return initialValue;
|
||||
}
|
||||
}
|
||||
|
||||
T createValue() {
|
||||
return supplier.get();
|
||||
}
|
||||
}
|
||||
@ -1,58 +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.
|
||||
*/
|
||||
package jdk.vm.ci.options;
|
||||
|
||||
/**
|
||||
* A nested Boolean {@link OptionValue} that can be overridden by a {@link #masterOption master
|
||||
* option}.
|
||||
* <p>
|
||||
* <li>If the option is present on the command line the specified value is used.
|
||||
* <li>Otherwise {@link #getValue()} depends on the {@link #masterOption} and evaluates as follows:
|
||||
* <ul>
|
||||
* <li>If {@link #masterOption} is set, this value equals to {@link #initialValue}.
|
||||
* <li>Otherwise, if {@link #masterOption} is {@code false}, this option is {@code false}.
|
||||
*/
|
||||
public class NestedBooleanOptionValue extends OptionValue<Boolean> {
|
||||
private final OptionValue<Boolean> masterOption;
|
||||
private final Boolean initialValue;
|
||||
|
||||
public NestedBooleanOptionValue(OptionValue<Boolean> masterOption, Boolean initialValue) {
|
||||
super(null);
|
||||
this.masterOption = masterOption;
|
||||
this.initialValue = initialValue;
|
||||
}
|
||||
|
||||
public OptionValue<Boolean> getMasterOption() {
|
||||
return masterOption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getValue() {
|
||||
Boolean v = super.getValue();
|
||||
if (v == null) {
|
||||
return initialValue && masterOption.getValue();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,55 +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.vm.ci.options;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Describes the attributes of an option whose {@link OptionValue value} is in a static field
|
||||
* annotated by this annotation type.
|
||||
*
|
||||
* @see OptionDescriptor
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Option {
|
||||
|
||||
/**
|
||||
* Gets a help message for the option. New lines can be embedded in the message with
|
||||
* {@code "%n"}.
|
||||
*/
|
||||
String help();
|
||||
|
||||
/**
|
||||
* The name of the option. By default, the name of the annotated field should be used.
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* Specifies the type of the option.
|
||||
*/
|
||||
OptionType type() default OptionType.Debug;
|
||||
}
|
||||
@ -1,102 +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.vm.ci.options;
|
||||
|
||||
/**
|
||||
* Describes the attributes of a static field {@linkplain Option option} and provides access to its
|
||||
* {@linkplain OptionValue value}.
|
||||
*/
|
||||
public final class OptionDescriptor {
|
||||
|
||||
protected final String name;
|
||||
protected final Class<?> type;
|
||||
protected final String help;
|
||||
protected final OptionValue<?> option;
|
||||
protected final Class<?> declaringClass;
|
||||
protected final String fieldName;
|
||||
|
||||
public static OptionDescriptor create(String name, Class<?> type, String help, Class<?> declaringClass, String fieldName, OptionValue<?> option) {
|
||||
OptionDescriptor result = option.getDescriptor();
|
||||
if (result == null) {
|
||||
result = new OptionDescriptor(name, type, help, declaringClass, fieldName, option);
|
||||
option.setDescriptor(result);
|
||||
}
|
||||
assert result.name.equals(name) && result.type == type && result.declaringClass == declaringClass && result.fieldName.equals(fieldName) && result.option == option;
|
||||
return result;
|
||||
}
|
||||
|
||||
private OptionDescriptor(String name, Class<?> type, String help, Class<?> declaringClass, String fieldName, OptionValue<?> option) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.help = help;
|
||||
this.option = option;
|
||||
this.declaringClass = declaringClass;
|
||||
this.fieldName = fieldName;
|
||||
assert !type.isPrimitive() : "must used boxed type instead of " + type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of values stored in the option. This will be the boxed type for a primitive
|
||||
* option.
|
||||
*/
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a descriptive help message for the option.
|
||||
*/
|
||||
public String getHelp() {
|
||||
return help;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the option. It's up to the client of this object how to use the name to get
|
||||
* a user specified value for the option from the environment.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the boxed option value.
|
||||
*/
|
||||
public OptionValue<?> getOptionValue() {
|
||||
return option;
|
||||
}
|
||||
|
||||
public Class<?> getDeclaringClass() {
|
||||
return declaringClass;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a description of the location where this option is stored.
|
||||
*/
|
||||
public String getLocation() {
|
||||
return getDeclaringClass().getName() + "." + getFieldName();
|
||||
}
|
||||
}
|
||||
@ -1,34 +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.vm.ci.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);
|
||||
}
|
||||
@ -1,44 +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.vm.ci.options;
|
||||
|
||||
/**
|
||||
* Classifies JVMCI options in several categories depending on who this option is relevant for.
|
||||
*
|
||||
*/
|
||||
public enum OptionType {
|
||||
/**
|
||||
* An option common for users to apply.
|
||||
*/
|
||||
User,
|
||||
|
||||
/**
|
||||
* An option only relevant in corner cases and for fine-tuning.
|
||||
*/
|
||||
Expert,
|
||||
|
||||
/**
|
||||
* An option only relevant when debugging the compiler.
|
||||
*/
|
||||
Debug
|
||||
}
|
||||
@ -1,484 +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.vm.ci.options;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An option value.
|
||||
*/
|
||||
public class OptionValue<T> {
|
||||
/**
|
||||
* Temporarily changes the value for an option. The {@linkplain OptionValue#getValue() value} of
|
||||
* {@code option} is set to {@code value} until {@link OverrideScope#close()} is called on the
|
||||
* object returned by this method.
|
||||
* <p>
|
||||
* Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
|
||||
* used:
|
||||
*
|
||||
* <pre>
|
||||
* try (OverrideScope s = OptionValue.override(myOption, myValue) {
|
||||
* // code that depends on myOption == myValue
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public static OverrideScope override(OptionValue<?> option, Object value) {
|
||||
OverrideScope current = getOverrideScope();
|
||||
if (current == null) {
|
||||
if (!value.equals(option.getValue())) {
|
||||
return new SingleOverrideScope(option, value);
|
||||
}
|
||||
Map<OptionValue<?>, Object> overrides = Collections.emptyMap();
|
||||
return new MultipleOverridesScope(current, overrides);
|
||||
}
|
||||
return new MultipleOverridesScope(current, option, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily changes the values for a set of options. The {@linkplain OptionValue#getValue()
|
||||
* value} of each {@code option} in {@code overrides} is set to the corresponding {@code value}
|
||||
* in {@code overrides} until {@link OverrideScope#close()} is called on the object returned by
|
||||
* this method.
|
||||
* <p>
|
||||
* Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
|
||||
* used:
|
||||
*
|
||||
* <pre>
|
||||
* Map<OptionValue, Object> overrides = new HashMap<>();
|
||||
* overrides.put(myOption1, myValue1);
|
||||
* overrides.put(myOption2, myValue2);
|
||||
* try (OverrideScope s = OptionValue.override(overrides) {
|
||||
* // code that depends on myOption == myValue
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public static OverrideScope override(Map<OptionValue<?>, Object> overrides) {
|
||||
OverrideScope current = getOverrideScope();
|
||||
if (current == null && overrides.size() == 1) {
|
||||
Entry<OptionValue<?>, Object> single = overrides.entrySet().iterator().next();
|
||||
OptionValue<?> option = single.getKey();
|
||||
Object overrideValue = single.getValue();
|
||||
if (!overrideValue.equals(option.getValue())) {
|
||||
return new SingleOverrideScope(option, overrideValue);
|
||||
}
|
||||
}
|
||||
return new MultipleOverridesScope(current, overrides);
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily changes the values for a set of options. The {@linkplain OptionValue#getValue()
|
||||
* value} of each {@code option} in {@code overrides} is set to the corresponding {@code value}
|
||||
* in {@code overrides} until {@link OverrideScope#close()} is called on the object returned by
|
||||
* this method.
|
||||
* <p>
|
||||
* Since the returned object is {@link AutoCloseable} the try-with-resource construct can be
|
||||
* used:
|
||||
*
|
||||
* <pre>
|
||||
* try (OverrideScope s = OptionValue.override(myOption1, myValue1, myOption2, myValue2) {
|
||||
* // code that depends on myOption == myValue
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param overrides overrides in the form {@code [option1, override1, option2, override2, ...]}
|
||||
*/
|
||||
public static OverrideScope override(Object... overrides) {
|
||||
OverrideScope current = getOverrideScope();
|
||||
if (current == null && overrides.length == 2) {
|
||||
OptionValue<?> option = (OptionValue<?>) overrides[0];
|
||||
Object overrideValue = overrides[1];
|
||||
if (!overrideValue.equals(option.getValue())) {
|
||||
return new SingleOverrideScope(option, overrideValue);
|
||||
}
|
||||
}
|
||||
Map<OptionValue<?>, Object> map = Collections.emptyMap();
|
||||
for (int i = 0; i < overrides.length; i += 2) {
|
||||
OptionValue<?> option = (OptionValue<?>) overrides[i];
|
||||
Object overrideValue = overrides[i + 1];
|
||||
if (!overrideValue.equals(option.getValue())) {
|
||||
if (map.isEmpty()) {
|
||||
map = new HashMap<>();
|
||||
}
|
||||
map.put(option, overrideValue);
|
||||
}
|
||||
}
|
||||
return new MultipleOverridesScope(current, map);
|
||||
}
|
||||
|
||||
private static final ThreadLocal<OverrideScope> overrideScopeTL = new ThreadLocal<>();
|
||||
|
||||
protected static OverrideScope getOverrideScope() {
|
||||
return overrideScopeTL.get();
|
||||
}
|
||||
|
||||
protected static void setOverrideScope(OverrideScope overrideScope) {
|
||||
overrideScopeTL.set(overrideScope);
|
||||
}
|
||||
|
||||
private T defaultValue;
|
||||
|
||||
/**
|
||||
* The raw option value.
|
||||
*/
|
||||
protected T value;
|
||||
|
||||
private OptionDescriptor descriptor;
|
||||
|
||||
private long reads;
|
||||
private OptionValue<?> next;
|
||||
private static OptionValue<?> head;
|
||||
|
||||
private static final boolean ShowReadsHistogram = Boolean.getBoolean("jvmci.showOptionValueReadsHistogram");
|
||||
|
||||
private static void addToHistogram(OptionValue<?> option) {
|
||||
if (ShowReadsHistogram) {
|
||||
synchronized (OptionValue.class) {
|
||||
option.next = head;
|
||||
head = option;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public OptionValue(T value) {
|
||||
this.defaultValue = value;
|
||||
this.value = (T) DEFAULT;
|
||||
addToHistogram(this);
|
||||
}
|
||||
|
||||
private static final Object DEFAULT = "DEFAULT";
|
||||
private static final Object UNINITIALIZED = "UNINITIALIZED";
|
||||
|
||||
/**
|
||||
* Creates an uninitialized option value for a subclass that initializes itself
|
||||
* {@link #defaultValue() lazily}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected OptionValue() {
|
||||
this.defaultValue = (T) UNINITIALIZED;
|
||||
this.value = (T) DEFAULT;
|
||||
addToHistogram(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy initialization of default value.
|
||||
*/
|
||||
protected T defaultValue() {
|
||||
throw new InternalError("Option without a default value value must override defaultValue()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the descriptor for this option.
|
||||
*/
|
||||
public void setDescriptor(OptionDescriptor descriptor) {
|
||||
assert this.descriptor == null : "Overwriting existing descriptor";
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor for this option, if it has been set by
|
||||
* {@link #setDescriptor(OptionDescriptor)}.
|
||||
*/
|
||||
public OptionDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this option. The name for an option value with a null
|
||||
* {@linkplain #setDescriptor(OptionDescriptor) descriptor} is the value of
|
||||
* {@link Object#toString()}.
|
||||
*/
|
||||
public String getName() {
|
||||
return descriptor == null ? super.toString() : (descriptor.getDeclaringClass().getName() + "." + descriptor.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + "=" + getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* The initial value specified in source code. The returned value is not affected by calls to
|
||||
* {@link #setValue(Object)} or registering {@link OverrideScope}s. Therefore, it is also not
|
||||
* affected by options set on the command line.
|
||||
*/
|
||||
public T getDefaultValue() {
|
||||
if (defaultValue == UNINITIALIZED) {
|
||||
defaultValue = defaultValue();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the option has the same value that was set in the source code.
|
||||
*/
|
||||
public boolean hasDefaultValue() {
|
||||
if (!(this instanceof StableOptionValue)) {
|
||||
getValue(); // ensure initialized
|
||||
}
|
||||
return value == DEFAULT || Objects.equals(value, getDefaultValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this option.
|
||||
*/
|
||||
public T getValue() {
|
||||
if (ShowReadsHistogram) {
|
||||
reads++;
|
||||
}
|
||||
if (!(this instanceof StableOptionValue)) {
|
||||
OverrideScope overrideScope = getOverrideScope();
|
||||
if (overrideScope != null) {
|
||||
T override = overrideScope.getOverride(this);
|
||||
if (override != null) {
|
||||
return override;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value != DEFAULT) {
|
||||
return value;
|
||||
} else {
|
||||
return getDefaultValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the values of this option including overridden values.
|
||||
*
|
||||
* @param c the collection to which the values are added. If null, one is allocated.
|
||||
* @return the collection to which the values were added in order from most overridden to
|
||||
* current value
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<T> getValues(Collection<T> c) {
|
||||
Collection<T> values = c == null ? new ArrayList<>() : c;
|
||||
if (!(this instanceof StableOptionValue)) {
|
||||
OverrideScope overrideScope = getOverrideScope();
|
||||
if (overrideScope != null) {
|
||||
overrideScope.getOverrides(this, (Collection<Object>) values);
|
||||
}
|
||||
}
|
||||
if (value != DEFAULT) {
|
||||
values.add(value);
|
||||
} else {
|
||||
values.add(getDefaultValue());
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this option.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setValue(Object v) {
|
||||
this.value = (T) v;
|
||||
}
|
||||
|
||||
/**
|
||||
* An object whose {@link #close()} method reverts the option value overriding initiated by
|
||||
* {@link OptionValue#override(OptionValue, Object)} or {@link OptionValue#override(Map)}.
|
||||
*/
|
||||
public abstract static class OverrideScope implements AutoCloseable {
|
||||
|
||||
private Map<DerivedOptionValue<?>, Object> derivedCache = null;
|
||||
|
||||
public <T> T getDerived(DerivedOptionValue<T> key) {
|
||||
if (derivedCache == null) {
|
||||
derivedCache = new HashMap<>();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
T ret = (T) derivedCache.get(key);
|
||||
if (ret == null) {
|
||||
ret = key.createValue();
|
||||
derivedCache.put(key, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
abstract void addToInherited(Map<OptionValue<?>, Object> inherited);
|
||||
|
||||
abstract <T> T getOverride(OptionValue<T> option);
|
||||
|
||||
abstract void getOverrides(OptionValue<?> option, Collection<Object> c);
|
||||
|
||||
public abstract void close();
|
||||
}
|
||||
|
||||
static class SingleOverrideScope extends OverrideScope {
|
||||
|
||||
private final OptionValue<?> option;
|
||||
private final Object value;
|
||||
|
||||
public SingleOverrideScope(OptionValue<?> option, Object value) {
|
||||
if (option instanceof StableOptionValue) {
|
||||
throw new IllegalArgumentException("Cannot override stable option " + option);
|
||||
}
|
||||
this.option = option;
|
||||
this.value = value;
|
||||
setOverrideScope(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
void addToInherited(Map<OptionValue<?>, Object> inherited) {
|
||||
inherited.put(option, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
<T> T getOverride(OptionValue<T> key) {
|
||||
if (key == this.option) {
|
||||
return (T) value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
void getOverrides(OptionValue<?> key, Collection<Object> c) {
|
||||
if (key == this.option) {
|
||||
c.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
setOverrideScope(null);
|
||||
}
|
||||
}
|
||||
|
||||
static class MultipleOverridesScope extends OverrideScope {
|
||||
final OverrideScope parent;
|
||||
final Map<OptionValue<?>, Object> overrides;
|
||||
|
||||
public MultipleOverridesScope(OverrideScope parent, OptionValue<?> option, Object value) {
|
||||
this.parent = parent;
|
||||
this.overrides = new HashMap<>();
|
||||
if (parent != null) {
|
||||
parent.addToInherited(overrides);
|
||||
}
|
||||
if (option instanceof StableOptionValue) {
|
||||
throw new IllegalArgumentException("Cannot override stable option " + option);
|
||||
}
|
||||
if (!value.equals(option.getValue())) {
|
||||
this.overrides.put(option, value);
|
||||
}
|
||||
if (!overrides.isEmpty()) {
|
||||
setOverrideScope(this);
|
||||
}
|
||||
}
|
||||
|
||||
MultipleOverridesScope(OverrideScope parent, Map<OptionValue<?>, Object> overrides) {
|
||||
this.parent = parent;
|
||||
if (overrides.isEmpty() && parent == null) {
|
||||
this.overrides = Collections.emptyMap();
|
||||
return;
|
||||
}
|
||||
this.overrides = new HashMap<>();
|
||||
if (parent != null) {
|
||||
parent.addToInherited(this.overrides);
|
||||
}
|
||||
for (Map.Entry<OptionValue<?>, Object> e : overrides.entrySet()) {
|
||||
OptionValue<?> option = e.getKey();
|
||||
if (option instanceof StableOptionValue) {
|
||||
throw new IllegalArgumentException("Cannot override stable option " + option);
|
||||
}
|
||||
if (!e.getValue().equals(option.getValue())) {
|
||||
this.overrides.put(option, e.getValue());
|
||||
}
|
||||
}
|
||||
if (!this.overrides.isEmpty()) {
|
||||
setOverrideScope(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void addToInherited(Map<OptionValue<?>, Object> inherited) {
|
||||
if (parent != null) {
|
||||
parent.addToInherited(inherited);
|
||||
}
|
||||
inherited.putAll(overrides);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
<T> T getOverride(OptionValue<T> option) {
|
||||
return (T) overrides.get(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
void getOverrides(OptionValue<?> option, Collection<Object> c) {
|
||||
Object v = overrides.get(option);
|
||||
if (v != null) {
|
||||
c.add(v);
|
||||
}
|
||||
if (parent != null) {
|
||||
parent.getOverrides(option, c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (!overrides.isEmpty()) {
|
||||
setOverrideScope(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
if (ShowReadsHistogram) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
ArrayList<OptionValue<?>> options = new ArrayList<>();
|
||||
for (OptionValue<?> option = head; option != null; option = option.next) {
|
||||
options.add(option);
|
||||
}
|
||||
Collections.sort(options, new Comparator<OptionValue<?>>() {
|
||||
|
||||
public int compare(OptionValue<?> o1, OptionValue<?> o2) {
|
||||
if (o1.reads < o2.reads) {
|
||||
return -1;
|
||||
} else if (o1.reads > o2.reads) {
|
||||
return 1;
|
||||
} else {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
}
|
||||
});
|
||||
PrintStream out = System.out;
|
||||
out.println("=== OptionValue reads histogram ===");
|
||||
for (OptionValue<?> option : options) {
|
||||
out.println(option.reads + "\t" + option);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,47 +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.vm.ci.options;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Helper class used to load option descriptors. Only to be used in the slow-path.
|
||||
*/
|
||||
public class OptionsLoader {
|
||||
public static final SortedMap<String, OptionDescriptor> options = new TreeMap<>();
|
||||
|
||||
/**
|
||||
* Initializes {@link #options} from {@link Options} services.
|
||||
*/
|
||||
static {
|
||||
for (OptionDescriptors opts : ServiceLoader.load(OptionDescriptors.class, OptionsLoader.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,382 +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.vm.ci.options;
|
||||
|
||||
import static jdk.vm.ci.inittimer.InitTimer.timer;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
|
||||
import jdk.vm.ci.inittimer.InitTimer;
|
||||
|
||||
/**
|
||||
* This class contains methods for parsing JVMCI options and matching them against a set of
|
||||
* {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded via a {@link ServiceLoader}.
|
||||
*/
|
||||
public class OptionsParser {
|
||||
|
||||
private static final OptionValue<Boolean> PrintFlags = new OptionValue<>(false);
|
||||
private static final OptionValue<Boolean> ShowFlags = new OptionValue<>(false);
|
||||
|
||||
/**
|
||||
* A service for looking up {@link OptionDescriptor}s.
|
||||
*/
|
||||
public interface OptionDescriptorsProvider {
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the options in {@code <jdk>/lib/jvmci.options} if {@code parseOptionsFile == true} and
|
||||
* the file exists followed by the JVMCI options in {@code options} if {@code options != null}.
|
||||
*
|
||||
* Called from VM. This method has an object return type to allow it to be called with a VM
|
||||
* utility function used to call other static initialization methods.
|
||||
*
|
||||
* @param options JVMCI options as serialized (name, value) pairs
|
||||
* @param parseOptionsFile specifies whether to look for and parse
|
||||
* {@code <jdk>/lib/jvmci.options}
|
||||
*/
|
||||
@SuppressWarnings("try")
|
||||
public static Boolean parseOptionsFromVM(String[] options, boolean parseOptionsFile) {
|
||||
|
||||
try (InitTimer t = timer("ParseOptions")) {
|
||||
|
||||
if (parseOptionsFile) {
|
||||
File javaHome = new File(System.getProperty("java.home"));
|
||||
File lib = new File(javaHome, "lib");
|
||||
File jvmciOptions = new File(lib, "jvmci.options");
|
||||
if (jvmciOptions.exists()) {
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(jvmciOptions))) {
|
||||
String optionSetting = null;
|
||||
int lineNo = 1;
|
||||
List<String> optionSettings = new ArrayList<>();
|
||||
while ((optionSetting = br.readLine()) != null) {
|
||||
if (!optionSetting.isEmpty() && optionSetting.charAt(0) != '#') {
|
||||
try {
|
||||
parseOptionSettingTo(optionSetting, optionSettings);
|
||||
} catch (Throwable e) {
|
||||
throw new InternalError("Error parsing " + jvmciOptions + ", line " + lineNo, e);
|
||||
}
|
||||
}
|
||||
lineNo++;
|
||||
}
|
||||
try {
|
||||
parseOptions(optionSettings.toArray(new String[optionSettings.size()]), null, null, null);
|
||||
} catch (Throwable e) {
|
||||
throw new InternalError("Error parsing an option from " + jvmciOptions, e);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new InternalError("Error reading " + jvmciOptions, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parseOptions(options, null, null, null);
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an ordered list of (name, value) pairs assigning values to JVMCI options.
|
||||
*
|
||||
* @param optionSettings JVMCI options as serialized (name, value) pairs
|
||||
* @param setter the object to notify of the parsed option and value
|
||||
* @param odp if non-null, the service to use for looking up {@link OptionDescriptor}s
|
||||
* @param options the options database to use if {@code odp == null}. If
|
||||
* {@code options == null && odp == null}, {@link OptionsLoader#options} is used.
|
||||
* @throws IllegalArgumentException if there's a problem parsing {@code option}
|
||||
*/
|
||||
public static void parseOptions(String[] optionSettings, OptionConsumer setter, OptionDescriptorsProvider odp, SortedMap<String, OptionDescriptor> options) {
|
||||
if (optionSettings != null && optionSettings.length != 0) {
|
||||
assert optionSettings.length % 2 == 0;
|
||||
|
||||
moveHelpFlagsToTail(optionSettings);
|
||||
|
||||
for (int i = 0; i < optionSettings.length / 2; i++) {
|
||||
String name = optionSettings[i * 2];
|
||||
String value = optionSettings[i * 2 + 1];
|
||||
parseOption(name, value, setter, odp, options);
|
||||
}
|
||||
if (PrintFlags.getValue() || ShowFlags.getValue()) {
|
||||
Set<String> explicitlyAssigned = new HashSet<>(optionSettings.length / 2);
|
||||
for (int i = 0; i < optionSettings.length / 2; i++) {
|
||||
String name = optionSettings[i * 2];
|
||||
explicitlyAssigned.add(name);
|
||||
}
|
||||
printFlags(resolveOptions(options), "JVMCI", System.out, explicitlyAssigned);
|
||||
if (PrintFlags.getValue()) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves all {@code PrintFlags} and {@code ShowFlags} option settings to the back of
|
||||
* {@code optionSettings}. This allows the help message to show which options had their value
|
||||
* explicitly set (even if to their default value).
|
||||
*/
|
||||
private static void moveHelpFlagsToTail(String[] optionSettings) {
|
||||
List<String> tail = null;
|
||||
int insert = 0;
|
||||
for (int i = 0; i < optionSettings.length / 2; i++) {
|
||||
String name = optionSettings[i * 2];
|
||||
String value = optionSettings[i * 2 + 1];
|
||||
if (name.equals("ShowFlags") || name.equals("PrintFlags")) {
|
||||
if (tail == null) {
|
||||
tail = new ArrayList<>(4);
|
||||
insert = i * 2;
|
||||
}
|
||||
tail.add(name);
|
||||
tail.add(value);
|
||||
} else if (tail != null) {
|
||||
optionSettings[insert++] = name;
|
||||
optionSettings[insert++] = value;
|
||||
}
|
||||
}
|
||||
if (tail != null) {
|
||||
assert tail.size() + insert == optionSettings.length;
|
||||
String[] tailArr = tail.toArray(new String[tail.size()]);
|
||||
System.arraycopy(tailArr, 0, optionSettings, insert, tailArr.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a given option setting string to a list of (name, value) pairs.
|
||||
*
|
||||
* @param optionSetting a string matching the pattern {@code <name>=<value>}
|
||||
*/
|
||||
public static void parseOptionSettingTo(String optionSetting, List<String> dst) {
|
||||
int eqIndex = optionSetting.indexOf('=');
|
||||
if (eqIndex == -1) {
|
||||
throw new InternalError("Option setting has does not match the pattern <name>=<value>: " + optionSetting);
|
||||
}
|
||||
dst.add(optionSetting.substring(0, eqIndex));
|
||||
dst.add(optionSetting.substring(eqIndex + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves {@code options} to a non-null value. This ensures {@link OptionsLoader#options} is
|
||||
* only loaded if necessary.
|
||||
*/
|
||||
private static SortedMap<String, OptionDescriptor> resolveOptions(SortedMap<String, OptionDescriptor> options) {
|
||||
return options != null ? options : OptionsLoader.options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a given option name and value.
|
||||
*
|
||||
* @param name the option name
|
||||
* @param valueString the option value as a string
|
||||
* @param setter the object to notify of the parsed option and value
|
||||
* @param odp if non-null, the service to use for looking up {@link OptionDescriptor}s
|
||||
* @param options the options database to use if {@code odp == null}. If
|
||||
* {@code options == null && odp == null}, {@link OptionsLoader#options} is used.
|
||||
* @throws IllegalArgumentException if there's a problem parsing {@code option}
|
||||
*/
|
||||
private static void parseOption(String name, String valueString, OptionConsumer setter, OptionDescriptorsProvider odp, SortedMap<String, OptionDescriptor> options) {
|
||||
|
||||
OptionDescriptor desc = odp != null ? odp.get(name) : resolveOptions(options).get(name);
|
||||
if (desc == null) {
|
||||
if (name.equals("PrintFlags")) {
|
||||
desc = OptionDescriptor.create("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags);
|
||||
} else if (name.equals("ShowFlags")) {
|
||||
desc = OptionDescriptor.create("ShowFlags", Boolean.class, "Prints all JVMCI flags and continues", OptionsParser.class, "ShowFlags", ShowFlags);
|
||||
}
|
||||
}
|
||||
if (desc == null) {
|
||||
List<OptionDescriptor> matches = fuzzyMatch(resolveOptions(options), name);
|
||||
Formatter msg = new Formatter();
|
||||
msg.format("Could not find option %s", name);
|
||||
if (!matches.isEmpty()) {
|
||||
msg.format("%nDid you mean one of the following?");
|
||||
for (OptionDescriptor match : matches) {
|
||||
msg.format("%n %s=<value>", match.getName());
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(msg.toString());
|
||||
}
|
||||
|
||||
Class<?> optionType = desc.getType();
|
||||
Object value;
|
||||
if (optionType == Boolean.class) {
|
||||
if ("true".equals(valueString)) {
|
||||
value = Boolean.TRUE;
|
||||
} else if ("false".equals(valueString)) {
|
||||
value = Boolean.FALSE;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Boolean option '" + name + "' must have value \"true\" or \"false\", not \"" + valueString + "\"");
|
||||
}
|
||||
} else 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 '" + name + "'");
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
private static void printFlags(SortedMap<String, OptionDescriptor> sortedOptions, String prefix, PrintStream out, Set<String> explicitlyAssigned) {
|
||||
out.println("[List of " + prefix + " options]");
|
||||
for (Map.Entry<String, OptionDescriptor> e : sortedOptions.entrySet()) {
|
||||
e.getKey();
|
||||
OptionDescriptor desc = e.getValue();
|
||||
Object value = desc.getOptionValue().getValue();
|
||||
List<String> helpLines = wrap(desc.getHelp(), 70);
|
||||
String name = e.getKey();
|
||||
String assign = explicitlyAssigned.contains(name) ? ":=" : " =";
|
||||
out.printf("%9s %-40s %s %-14s %s%n", desc.getType().getSimpleName(), name, assign, value, helpLines.get(0));
|
||||
for (int i = 1; i < helpLines.size(); i++) {
|
||||
out.printf("%67s %s%n", " ", helpLines.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(SortedMap<String, OptionDescriptor> options, String optionName) {
|
||||
List<OptionDescriptor> matches = new ArrayList<>();
|
||||
for (Map.Entry<String, OptionDescriptor> e : options.entrySet()) {
|
||||
float score = stringSimiliarity(e.getKey(), optionName);
|
||||
if (score >= FUZZY_MATCH_THRESHOLD) {
|
||||
matches.add(e.getValue());
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
@ -1,75 +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.vm.ci.options;
|
||||
|
||||
/**
|
||||
* An option that always returns the same {@linkplain #getValue() value}.
|
||||
*/
|
||||
public class StableOptionValue<T> extends OptionValue<T> {
|
||||
|
||||
/**
|
||||
* Creates a stable option value.
|
||||
*/
|
||||
public StableOptionValue(T value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to assert the invariant for stability. Without using locks, this check is not safe
|
||||
* against races and so it's only an assertion.
|
||||
*/
|
||||
private boolean getValueCalled;
|
||||
|
||||
/**
|
||||
* Creates an uninitialized stable option value for a subclass that initializes itself
|
||||
* {@link #defaultValue() lazily}.
|
||||
*/
|
||||
public StableOptionValue() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this option.
|
||||
*/
|
||||
@Override
|
||||
public final T getValue() {
|
||||
T result = super.getValue();
|
||||
assert initGetValueCalled();
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean initGetValueCalled() {
|
||||
getValueCalled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* This must only be called if {@link #getValue()} has never been called.
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(Object v) {
|
||||
assert !getValueCalled;
|
||||
super.setValue(v);
|
||||
}
|
||||
}
|
||||
@ -50,15 +50,10 @@ jobject JVMCIRuntime::_HotSpotJVMCIRuntime_instance = NULL;
|
||||
bool JVMCIRuntime::_HotSpotJVMCIRuntime_initialized = false;
|
||||
bool JVMCIRuntime::_well_known_classes_initialized = false;
|
||||
const char* JVMCIRuntime::_compiler = NULL;
|
||||
int JVMCIRuntime::_options_count = 0;
|
||||
SystemProperty** JVMCIRuntime::_options = NULL;
|
||||
int JVMCIRuntime::_trivial_prefixes_count = 0;
|
||||
char** JVMCIRuntime::_trivial_prefixes = NULL;
|
||||
bool JVMCIRuntime::_shutdown_called = false;
|
||||
|
||||
static const char* OPTION_PREFIX = "jvmci.option.";
|
||||
static const size_t OPTION_PREFIX_LEN = strlen(OPTION_PREFIX);
|
||||
|
||||
BasicType JVMCIRuntime::kindToBasicType(Handle kind, TRAPS) {
|
||||
if (kind.is_null()) {
|
||||
THROW_(vmSymbols::java_lang_NullPointerException(), T_ILLEGAL);
|
||||
@ -631,16 +626,6 @@ Handle JVMCIRuntime::callStatic(const char* className, const char* methodName, c
|
||||
return Handle((oop)result.get_jobject());
|
||||
}
|
||||
|
||||
static bool jvmci_options_file_exists() {
|
||||
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);
|
||||
struct stat st;
|
||||
return os::stat(path, &st) == 0;
|
||||
}
|
||||
|
||||
void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(TRAPS) {
|
||||
if (JNIHandles::resolve(_HotSpotJVMCIRuntime_instance) == NULL) {
|
||||
#ifdef ASSERT
|
||||
@ -652,30 +637,6 @@ void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(TRAPS) {
|
||||
"HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization");
|
||||
#endif
|
||||
|
||||
bool parseOptionsFile = jvmci_options_file_exists();
|
||||
if (_options != NULL || parseOptionsFile) {
|
||||
JavaCallArguments args;
|
||||
objArrayOop options;
|
||||
if (_options != NULL) {
|
||||
options = oopFactory::new_objArray(SystemDictionary::String_klass(), _options_count * 2, CHECK);
|
||||
for (int i = 0; i < _options_count; i++) {
|
||||
SystemProperty* prop = _options[i];
|
||||
oop name = java_lang_String::create_oop_from_str(prop->key() + OPTION_PREFIX_LEN, CHECK);
|
||||
const char* prop_value = prop->value() != NULL ? prop->value() : "";
|
||||
oop value = java_lang_String::create_oop_from_str(prop_value, CHECK);
|
||||
options->obj_at_put(i * 2, name);
|
||||
options->obj_at_put((i * 2) + 1, value);
|
||||
}
|
||||
} else {
|
||||
options = NULL;
|
||||
}
|
||||
args.push_oop(options);
|
||||
args.push_int(parseOptionsFile);
|
||||
callStatic("jdk/vm/ci/options/OptionsParser",
|
||||
"parseOptionsFromVM",
|
||||
"([Ljava/lang/String;Z)Ljava/lang/Boolean;", &args, CHECK);
|
||||
}
|
||||
|
||||
if (_compiler != NULL) {
|
||||
JavaCallArguments args;
|
||||
oop compiler = java_lang_String::create_oop_from_str(_compiler, CHECK);
|
||||
@ -893,48 +854,6 @@ void JVMCIRuntime::save_compiler(const char* compiler) {
|
||||
_compiler = compiler;
|
||||
}
|
||||
|
||||
void JVMCIRuntime::maybe_print_flags(TRAPS) {
|
||||
if (_options != NULL) {
|
||||
for (int i = 0; i < _options_count; i++) {
|
||||
SystemProperty* p = _options[i];
|
||||
const char* name = p->key() + OPTION_PREFIX_LEN;
|
||||
if (strcmp(name, "PrintFlags") == 0 || strcmp(name, "ShowFlags") == 0) {
|
||||
JVMCIRuntime::initialize_well_known_classes(CHECK);
|
||||
HandleMark hm;
|
||||
ResourceMark rm;
|
||||
JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JVMCIRuntime::save_options(SystemProperty* props) {
|
||||
int count = 0;
|
||||
SystemProperty* first = NULL;
|
||||
for (SystemProperty* p = props; p != NULL; p = p->next()) {
|
||||
if (strncmp(p->key(), OPTION_PREFIX, OPTION_PREFIX_LEN) == 0) {
|
||||
if (first == NULL) {
|
||||
first = p;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count != 0) {
|
||||
_options_count = count;
|
||||
_options = NEW_C_HEAP_ARRAY(SystemProperty*, count, mtCompiler);
|
||||
_options[0] = first;
|
||||
SystemProperty** insert_pos = _options + 1;
|
||||
for (SystemProperty* p = first->next(); p != NULL; p = p->next()) {
|
||||
if (strncmp(p->key(), OPTION_PREFIX, OPTION_PREFIX_LEN) == 0) {
|
||||
*insert_pos = p;
|
||||
insert_pos++;
|
||||
}
|
||||
}
|
||||
assert (insert_pos - _options == count, "must be");
|
||||
}
|
||||
}
|
||||
|
||||
void JVMCIRuntime::shutdown(TRAPS) {
|
||||
if (_HotSpotJVMCIRuntime_instance != NULL) {
|
||||
_shutdown_called = true;
|
||||
|
||||
@ -71,8 +71,6 @@ class JVMCIRuntime: public AllStatic {
|
||||
static bool _HotSpotJVMCIRuntime_initialized;
|
||||
static bool _well_known_classes_initialized;
|
||||
static const char* _compiler;
|
||||
static int _options_count;
|
||||
static SystemProperty** _options;
|
||||
|
||||
static int _trivial_prefixes_count;
|
||||
static char** _trivial_prefixes;
|
||||
@ -99,20 +97,6 @@ class JVMCIRuntime: public AllStatic {
|
||||
*/
|
||||
static void save_compiler(const char* compiler);
|
||||
|
||||
/**
|
||||
* Saves the value of the system properties starting with "jvmci.option." for processing
|
||||
* when JVMCI is initialized.
|
||||
*
|
||||
* @param props the head of the system property list
|
||||
*/
|
||||
static void save_options(SystemProperty* props);
|
||||
|
||||
/**
|
||||
* If either the PrintFlags or ShowFlags JVMCI option is present,
|
||||
* then JVMCI is initialized to show the help message.
|
||||
*/
|
||||
static void maybe_print_flags(TRAPS);
|
||||
|
||||
static bool is_HotSpotJVMCIRuntime_initialized() { return _HotSpotJVMCIRuntime_initialized; }
|
||||
|
||||
/**
|
||||
|
||||
@ -3344,12 +3344,6 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
|
||||
const char* fileSep = os::file_separator();
|
||||
sprintf(path, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
|
||||
|
||||
#if INCLUDE_JVMCI
|
||||
if (EnableJVMCI) {
|
||||
JVMCIRuntime::save_options(_system_properties);
|
||||
}
|
||||
#endif // INCLUDE_JVMCI
|
||||
|
||||
if (CheckEndorsedAndExtDirs) {
|
||||
int nonEmptyDirs = 0;
|
||||
// check endorsed directory
|
||||
|
||||
@ -3657,7 +3657,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
||||
if (jvmciCompiler != NULL) {
|
||||
JVMCIRuntime::save_compiler(jvmciCompiler);
|
||||
}
|
||||
JVMCIRuntime::maybe_print_flags(CHECK_JNI_ERR);
|
||||
}
|
||||
#endif // INCLUDE_JVMCI
|
||||
|
||||
|
||||
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
|
||||
* @run junit jdk.vm.ci.options.test.NestedBooleanOptionValueTest
|
||||
*/
|
||||
|
||||
package jdk.vm.ci.options.test;
|
||||
|
||||
import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.Master0;
|
||||
import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.Master1;
|
||||
import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.Master2;
|
||||
import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.NestedOption0;
|
||||
import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.NestedOption1;
|
||||
import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.NestedOption2;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import jdk.vm.ci.options.NestedBooleanOptionValue;
|
||||
import jdk.vm.ci.options.OptionDescriptor;
|
||||
import jdk.vm.ci.options.OptionValue;
|
||||
import jdk.vm.ci.options.OptionValue.OverrideScope;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class NestedBooleanOptionValueTest {
|
||||
|
||||
public static class Options {
|
||||
public static final OptionValue<Boolean> Master0 = new OptionValue<>(true);
|
||||
public static final OptionValue<Boolean> NestedOption0 = new NestedBooleanOptionValue(Master0, true);
|
||||
public static final OptionValue<Boolean> Master1 = new OptionValue<>(true);
|
||||
public static final OptionValue<Boolean> NestedOption1 = new NestedBooleanOptionValue(Master1, true);
|
||||
public static final OptionValue<Boolean> Master2 = new OptionValue<>(true);
|
||||
public static final OptionValue<Boolean> NestedOption2 = new NestedBooleanOptionValue(Master2, false);
|
||||
}
|
||||
|
||||
static final OptionDescriptor master0 = OptionDescriptor.create("Master0", Boolean.class, "", Options.class, "Master0", Master0);
|
||||
static final OptionDescriptor nestedOption0 = OptionDescriptor.create("NestedOption0", Boolean.class, "", Options.class, "NestedOption0", NestedOption0);
|
||||
static final OptionDescriptor master1 = OptionDescriptor.create("Master1", Boolean.class, "", Options.class, "Master1", Master1);
|
||||
static final OptionDescriptor nestedOption1 = OptionDescriptor.create("NestedOption1", Boolean.class, "", Options.class, "NestedOption1", NestedOption1);
|
||||
static final OptionDescriptor master2 = OptionDescriptor.create("Master2", Boolean.class, "", Options.class, "Master2", Master2);
|
||||
static final OptionDescriptor nestedOption2 = OptionDescriptor.create("NestedOption2", Boolean.class, "", Options.class, "NestedOption2", NestedOption2);
|
||||
|
||||
@SuppressWarnings("try")
|
||||
@Test
|
||||
public void runOverrides() {
|
||||
assertTrue(Master0.getValue());
|
||||
assertTrue(NestedOption0.getValue());
|
||||
try (OverrideScope s1 = OptionValue.override(Master0, false)) {
|
||||
assertFalse(Master0.getValue());
|
||||
assertFalse(NestedOption0.getValue());
|
||||
try (OverrideScope s2 = OptionValue.override(NestedOption0, false)) {
|
||||
assertFalse(NestedOption0.getValue());
|
||||
}
|
||||
try (OverrideScope s2 = OptionValue.override(NestedOption0, true)) {
|
||||
assertTrue(NestedOption0.getValue());
|
||||
}
|
||||
}
|
||||
assertTrue(Master0.getValue());
|
||||
try (OverrideScope s1 = OptionValue.override(NestedOption0, false)) {
|
||||
assertFalse(NestedOption0.getValue());
|
||||
}
|
||||
try (OverrideScope s1 = OptionValue.override(NestedOption0, true)) {
|
||||
assertTrue(NestedOption0.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runDefaultTrue() {
|
||||
Master1.setValue(true);
|
||||
assertTrue(Master1.getValue());
|
||||
assertTrue(NestedOption1.getValue());
|
||||
// nested value unset
|
||||
Master1.setValue(false);
|
||||
assertFalse(Master1.getValue());
|
||||
assertFalse(NestedOption1.getValue());
|
||||
// set false
|
||||
Master1.setValue(false);
|
||||
NestedOption1.setValue(false);
|
||||
assertFalse(Master1.getValue());
|
||||
assertFalse(NestedOption1.getValue());
|
||||
Master1.setValue(true);
|
||||
assertTrue(Master1.getValue());
|
||||
assertFalse(NestedOption1.getValue());
|
||||
// set true
|
||||
Master1.setValue(false);
|
||||
NestedOption1.setValue(true);
|
||||
assertFalse(Master1.getValue());
|
||||
assertTrue(NestedOption1.getValue());
|
||||
Master1.setValue(true);
|
||||
assertTrue(Master1.getValue());
|
||||
assertTrue(NestedOption1.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runDefaultFalse() {
|
||||
Master2.setValue(true);
|
||||
assertTrue(Master2.getValue());
|
||||
assertFalse(NestedOption2.getValue());
|
||||
// nested value unset
|
||||
Master2.setValue(false);
|
||||
assertFalse(Master2.getValue());
|
||||
assertFalse(NestedOption2.getValue());
|
||||
// set false
|
||||
Master2.setValue(false);
|
||||
NestedOption2.setValue(false);
|
||||
assertFalse(Master2.getValue());
|
||||
assertFalse(NestedOption2.getValue());
|
||||
Master2.setValue(true);
|
||||
assertTrue(Master2.getValue());
|
||||
assertFalse(NestedOption2.getValue());
|
||||
// set true
|
||||
Master2.setValue(false);
|
||||
NestedOption2.setValue(true);
|
||||
assertFalse(Master2.getValue());
|
||||
assertTrue(NestedOption2.getValue());
|
||||
Master2.setValue(true);
|
||||
assertTrue(Master2.getValue());
|
||||
assertTrue(NestedOption2.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
|
||||
* @run junit jdk.vm.ci.options.test.TestOptionValue
|
||||
*/
|
||||
|
||||
package jdk.vm.ci.options.test;
|
||||
|
||||
import static jdk.vm.ci.options.test.TestOptionValue.Options.Mutable;
|
||||
import static jdk.vm.ci.options.test.TestOptionValue.Options.SecondMutable;
|
||||
import static jdk.vm.ci.options.test.TestOptionValue.Options.Stable;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import jdk.vm.ci.options.OptionDescriptor;
|
||||
import jdk.vm.ci.options.OptionValue;
|
||||
import jdk.vm.ci.options.OptionValue.OverrideScope;
|
||||
import jdk.vm.ci.options.StableOptionValue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
@SuppressWarnings("try")
|
||||
public class TestOptionValue {
|
||||
|
||||
public static class Options {
|
||||
public static final OptionValue<Boolean> Stable = new StableOptionValue<>(true);
|
||||
public static final OptionValue<String> Mutable = new OptionValue<>("original");
|
||||
public static final OptionValue<String> SecondMutable = new OptionValue<>("second");
|
||||
}
|
||||
|
||||
static final OptionDescriptor stable = OptionDescriptor.create("Stable", Boolean.class, "", Options.class, "Stable", Stable);
|
||||
static final OptionDescriptor mutable = OptionDescriptor.create("Mutable", String.class, "", Options.class, "Mutable", Mutable);
|
||||
static final OptionDescriptor secondMutable = OptionDescriptor.create("SecondMutable", String.class, "", Options.class, "SecondMutable", SecondMutable);
|
||||
|
||||
@Test
|
||||
public void testMutable() {
|
||||
assertEquals("original", Mutable.getValue());
|
||||
try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) {
|
||||
assertEquals("override1", Mutable.getValue());
|
||||
try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) {
|
||||
assertEquals("override2", Mutable.getValue());
|
||||
}
|
||||
assertEquals("override1", Mutable.getValue());
|
||||
try (OverrideScope s3 = OptionValue.override(Mutable, "override3")) {
|
||||
assertEquals("override3", Mutable.getValue());
|
||||
}
|
||||
assertEquals("override1", Mutable.getValue());
|
||||
}
|
||||
assertEquals("original", Mutable.getValue());
|
||||
try (OverrideScope s1 = OptionValue.override(Mutable, "original")) {
|
||||
assertEquals("original", Mutable.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiple() {
|
||||
assertEquals("original", Mutable.getValue());
|
||||
assertEquals("second", SecondMutable.getValue());
|
||||
try (OverrideScope s1 = OptionValue.override(Mutable, "override1", SecondMutable, "secondOverride1")) {
|
||||
assertEquals("override1", Mutable.getValue());
|
||||
assertEquals("secondOverride1", SecondMutable.getValue());
|
||||
try (OverrideScope s2 = OptionValue.override(Mutable, "override2", SecondMutable, "secondOverride2")) {
|
||||
assertEquals("override2", Mutable.getValue());
|
||||
assertEquals("secondOverride2", SecondMutable.getValue());
|
||||
}
|
||||
assertEquals("override1", Mutable.getValue());
|
||||
assertEquals("secondOverride1", SecondMutable.getValue());
|
||||
try (OverrideScope s3 = OptionValue.override(Mutable, "override3", SecondMutable, "secondOverride3")) {
|
||||
assertEquals("override3", Mutable.getValue());
|
||||
assertEquals("secondOverride3", SecondMutable.getValue());
|
||||
}
|
||||
assertEquals("override1", Mutable.getValue());
|
||||
assertEquals("secondOverride1", SecondMutable.getValue());
|
||||
}
|
||||
assertEquals("original", Mutable.getValue());
|
||||
assertEquals("second", SecondMutable.getValue());
|
||||
try (OverrideScope s1 = OptionValue.override(Mutable, "original", SecondMutable, "second")) {
|
||||
assertEquals("original", Mutable.getValue());
|
||||
assertEquals("second", SecondMutable.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStable() {
|
||||
assertTrue(Stable.getValue());
|
||||
try (OverrideScope s = OptionValue.override(Stable, false)) {
|
||||
fail("cannot override stable option");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringTest() {
|
||||
assertEquals("jdk.vm.ci.options.test.TestOptionValue$Options.Mutable=original", Mutable.toString());
|
||||
try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) {
|
||||
assertEquals("jdk.vm.ci.options.test.TestOptionValue$Options.Mutable=override1", Mutable.toString());
|
||||
try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) {
|
||||
assertEquals("jdk.vm.ci.options.test.TestOptionValue$Options.Mutable=override2", Mutable.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getValuesTest() {
|
||||
assertEquals(Arrays.asList("original"), Mutable.getValues(null));
|
||||
assertEquals(Arrays.asList(true), Stable.getValues(null));
|
||||
try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) {
|
||||
assertEquals(Arrays.asList("override1", "original"), Mutable.getValues(null));
|
||||
try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) {
|
||||
assertEquals(Arrays.asList("override2", "override1", "original"), Mutable.getValues(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,8 +49,8 @@ import java.util.stream.Collectors;
|
||||
|
||||
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
||||
import jdk.vm.ci.meta.JavaConstant;
|
||||
import jdk.vm.ci.meta.JavaField;
|
||||
import jdk.vm.ci.meta.MetaAccessProvider;
|
||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
import jdk.vm.ci.meta.TrustedInterface;
|
||||
import jdk.vm.ci.runtime.JVMCI;
|
||||
@ -179,7 +179,7 @@ public class TypeUniverse {
|
||||
List<ConstantValue> res = new ArrayList<>();
|
||||
for (Field field : fromClass.getDeclaredFields()) {
|
||||
if (isStatic(field.getModifiers()) && isFinal(field.getModifiers())) {
|
||||
JavaField javaField = metaAccess.lookupJavaField(field);
|
||||
ResolvedJavaField javaField = metaAccess.lookupJavaField(field);
|
||||
Object boxed = field.get(null);
|
||||
if (boxed instanceof JavaConstant) {
|
||||
res.add(new ConstantValue(javaField.format("%H.%n"), (JavaConstant) boxed, boxed));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user