diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java index f385d95c4c9..90d0d590697 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java @@ -25,25 +25,25 @@ package java.lang.invoke; -import static jdk.internal.org.objectweb.asm.Opcodes.*; -import static java.lang.invoke.LambdaForm.*; -import static java.lang.invoke.LambdaForm.BasicType.*; -import static java.lang.invoke.MethodHandleStatics.*; +import jdk.internal.vm.annotation.Stable; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.FieldVisitor; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import sun.invoke.util.ValueConversions; +import sun.invoke.util.Wrapper; import java.lang.invoke.LambdaForm.NamedFunction; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; import java.util.Arrays; -import java.util.function.Function; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.Function; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import sun.invoke.util.ValueConversions; -import sun.invoke.util.Wrapper; - -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.MethodVisitor; +import static java.lang.invoke.LambdaForm.BasicType; +import static java.lang.invoke.LambdaForm.BasicType.*; +import static java.lang.invoke.MethodHandleStatics.*; +import static jdk.internal.org.objectweb.asm.Opcodes.*; /** * The flavor of method handle which emulates an invoke instruction @@ -459,7 +459,7 @@ import jdk.internal.org.objectweb.asm.MethodVisitor; static final String BMH_SIG = "L"+BMH+";"; static final String SPECIES_DATA = "java/lang/invoke/BoundMethodHandle$SpeciesData"; static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";"; - static final String STABLE_SIG = "Ljava/lang/invoke/Stable;"; + static final String STABLE_SIG = "Ljdk/internal/vm/annotation/Stable;"; static final String SPECIES_PREFIX_NAME = "Species_"; static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java index 54cbb4b3038..21e45d85663 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -26,20 +26,24 @@ package java.lang.invoke; import jdk.internal.misc.Unsafe; -import java.lang.reflect.Method; -import java.util.Arrays; -import sun.invoke.util.VerifyAccess; -import static java.lang.invoke.MethodHandleNatives.Constants.*; -import static java.lang.invoke.LambdaForm.*; -import static java.lang.invoke.MethodTypeForm.*; -import static java.lang.invoke.MethodHandleStatics.*; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.util.Objects; +import jdk.internal.vm.annotation.ForceInline; import sun.invoke.util.ValueConversions; +import sun.invoke.util.VerifyAccess; import sun.invoke.util.VerifyType; import sun.invoke.util.Wrapper; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Objects; + +import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.MethodHandleNatives.Constants.*; +import static java.lang.invoke.MethodHandleStatics.UNSAFE; +import static java.lang.invoke.MethodHandleStatics.newInternalError; +import static java.lang.invoke.MethodTypeForm.*; + /** * The flavor of method handle which implements a constant reference * to a class member. diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 83d66d52299..802589d727f 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -608,9 +608,9 @@ class InvokerBytecodeGenerator { if (lambdaForm.forceInline) { // Force inlining of this invoker method. - mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); + mv.visitAnnotation("Ljdk/internal/vm/annotation/ForceInline;", true); } else { - mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true); + mv.visitAnnotation("Ljdk/internal/vm/annotation/DontInline;", true); } if (lambdaForm.customized != null) { @@ -1292,7 +1292,7 @@ class InvokerBytecodeGenerator { mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true); // Don't inline the interpreter entry. - mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true); + mv.visitAnnotation("Ljdk/internal/vm/annotation/DontInline;", true); // create parameter array emitIconstInsn(invokerType.parameterCount()); @@ -1351,7 +1351,7 @@ class InvokerBytecodeGenerator { mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true); // Force inlining of this invoker method. - mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); + mv.visitAnnotation("Ljdk/internal/vm/annotation/ForceInline;", true); // Load receiver emitAloadInsn(0); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java index add42889bac..32a96ebea7e 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java @@ -25,6 +25,10 @@ package java.lang.invoke; +import jdk.internal.vm.annotation.DontInline; +import jdk.internal.vm.annotation.ForceInline; +import jdk.internal.vm.annotation.Stable; + import java.lang.reflect.Array; import java.util.Arrays; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java index 438b4256c09..45818bbf24a 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java @@ -25,18 +25,24 @@ package java.lang.invoke; -import java.lang.annotation.*; +import jdk.internal.vm.annotation.DontInline; +import jdk.internal.vm.annotation.Stable; +import sun.invoke.util.Wrapper; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.List; import java.util.Arrays; import java.util.HashMap; - -import sun.invoke.util.Wrapper; -import java.lang.reflect.Field; +import java.util.List; import static java.lang.invoke.LambdaForm.BasicType.*; -import static java.lang.invoke.MethodHandleStatics.*; -import static java.lang.invoke.MethodHandleNatives.Constants.*; +import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; +import static java.lang.invoke.MethodHandleStatics.debugEnabled; +import static java.lang.invoke.MethodHandleStatics.newInternalError; /** * The symbolic, non-executable form of a method handle's invocation semantics. diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index 7ad49cd38aa..c522b03486d 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -32,8 +32,8 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.function.Function; -import java.util.stream.Collectors; +import jdk.internal.vm.annotation.Stable; import sun.invoke.empty.Empty; import sun.invoke.util.ValueConversions; import sun.invoke.util.VerifyType; @@ -1483,7 +1483,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } private static final int LEFT_ARGS = FILL_ARRAYS_COUNT - 1; - private static final @Stable MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1]; + private static final @Stable MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY + 1]; /** fill_array_to_right(N).invoke(a, argL..arg[N-1]) * fills a[L]..a[N-1] with corresponding arguments, * and then returns a. The value L is a global constant (LEFT_ARGS). diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java index d75bad58a36..71690e5c439 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java @@ -25,6 +25,7 @@ package java.lang.invoke; +import jdk.internal.vm.annotation.Stable; import sun.invoke.util.Wrapper; import java.lang.ref.WeakReference; import java.lang.ref.Reference; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java index 0c4cf9bd4e1..e988252c8bc 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java @@ -25,6 +25,7 @@ package java.lang.invoke; +import jdk.internal.vm.annotation.Stable; import sun.invoke.util.Wrapper; import java.lang.ref.SoftReference; import static java.lang.invoke.MethodHandleStatics.*; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DontInline.java b/jdk/src/java.base/share/classes/jdk/internal/vm/annotation/DontInline.java similarity index 59% rename from jdk/src/java.base/share/classes/java/lang/invoke/DontInline.java rename to jdk/src/java.base/share/classes/jdk/internal/vm/annotation/DontInline.java index 1bd969efb8a..d39dccffbad 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DontInline.java +++ b/jdk/src/java.base/share/classes/jdk/internal/vm/annotation/DontInline.java @@ -23,15 +23,28 @@ * questions. */ -package java.lang.invoke; +package jdk.internal.vm.annotation; import java.lang.annotation.*; /** - * Internal marker for some methods in the JSR 292 implementation. + * A method or constructor may be annotated as "don't inline" if the inlining of + * this method should not be performed by the HotSpot VM. + *

+ * This annotation must be used sparingly. It is useful when the only + * reasonable alternative is to bind the name of a specific method or + * constructor into the HotSpot VM for special handling by the inlining policy. + * This annotation must not be relied on as an alternative to avoid tuning the + * VM's inlining policy. In a few cases, it may act as a temporary workaround + * until the profiling and inlining performed by the HotSpot VM is sufficiently + * improved. + * + * @implNote + * This annotation only takes effect for methods or constructors of classes + * loaded by the boot loader. Annotations on methods or constructors of classes + * loaded outside of the boot loader are ignored. */ -/*non-public*/ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.RUNTIME) -@interface DontInline { +public @interface DontInline { } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/ForceInline.java b/jdk/src/java.base/share/classes/jdk/internal/vm/annotation/ForceInline.java similarity index 58% rename from jdk/src/java.base/share/classes/java/lang/invoke/ForceInline.java rename to jdk/src/java.base/share/classes/jdk/internal/vm/annotation/ForceInline.java index bbac427efb7..e8253db04a1 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/ForceInline.java +++ b/jdk/src/java.base/share/classes/jdk/internal/vm/annotation/ForceInline.java @@ -23,15 +23,29 @@ * questions. */ -package java.lang.invoke; +package jdk.internal.vm.annotation; import java.lang.annotation.*; /** - * Internal marker for some methods in the JSR 292 implementation. + * A method or constructor may be annotated as "force inline" if the standard + * inlining metrics are to be ignored when the HotSpot VM inlines the method + * or constructor. + *

+ * This annotation must be used sparingly. It is useful when the only + * reasonable alternative is to bind the name of a specific method or + * constructor into the HotSpot VM for special handling by the inlining policy. + * This annotation must not be relied on as an alternative to avoid tuning the + * VM's inlining policy. In a few cases, it may act as a temporary workaround + * until the profiling and inlining performed by the HotSpot VM is sufficiently + * improved. + * + * @implNote + * This annotation only takes effect for methods or constructors of classes + * loaded by the boot loader. Annotations on methods or constructors of classes + * loaded outside of the boot loader are ignored. */ -/*non-public*/ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.RUNTIME) -@interface ForceInline { +public @interface ForceInline { } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/Stable.java b/jdk/src/java.base/share/classes/jdk/internal/vm/annotation/Stable.java similarity index 65% rename from jdk/src/java.base/share/classes/java/lang/invoke/Stable.java rename to jdk/src/java.base/share/classes/jdk/internal/vm/annotation/Stable.java index a0a413e2a79..2ba6e992adf 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/Stable.java +++ b/jdk/src/java.base/share/classes/jdk/internal/vm/annotation/Stable.java @@ -23,7 +23,7 @@ * questions. */ -package java.lang.invoke; +package jdk.internal.vm.annotation; import java.lang.annotation.*; @@ -57,17 +57,34 @@ import java.lang.annotation.*; *

* Fields which are declared {@code final} may also be annotated as stable. * Since final fields already behave as stable values, such an annotation - * indicates no additional information, unless the type of the field is - * an array type. + * conveys no additional information regarding change of the field's value, but + * still conveys information regarding change of additional components values if + * the type of the field is an array type (as described above). + *

+ * The HotSpot VM relies on this annotation to promote a non-null (resp., + * non-zero) component value to a constant, thereby enabling superior + * optimizations of code depending on such a value (such as constant folding). + * More specifically, the HotSpot VM will process non-null stable fields (final + * or otherwise) in a similar manner to static final fields with respect to + * promoting the field's value to a constant. Thus, placing aside the + * differences for null/non-null values and arrays, a final stable field is + * treated as if it is really final from both the Java language and the HotSpot + * VM. *

* It is (currently) undefined what happens if a field annotated as stable - * is given a third value. In practice, if the JVM relies on this annotation - * to promote a field reference to a constant, it may be that the Java memory - * model would appear to be broken, if such a constant (the second value of the field) - * is used as the value of the field even after the field value has changed. + * is given a third value (by explicitly updating a stable field, a component of + * a stable array, or a final stable field via reflection or other means). + * Since the HotSpot VM promotes a non-null component value to constant, it may + * be that the Java memory model would appear to be broken, if such a constant + * (the second value of the field) is used as the value of the field even after + * the field value has changed (to a third value). + * + * @implNote + * This annotation only takes effect for fields of classes loaded by the boot + * loader. Annoations on fields of classes loaded outside of the boot loader + * are ignored. */ -/* package-private */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) -@interface Stable { +public @interface Stable { }