diff --git a/jdk/make/gensrc/GensrcVarHandles.gmk b/jdk/make/gensrc/GensrcVarHandles.gmk index 5d90deb1304..3ad7e630e9c 100644 --- a/jdk/make/gensrc/GensrcVarHandles.gmk +++ b/jdk/make/gensrc/GensrcVarHandles.gmk @@ -38,12 +38,14 @@ define GenerateVarHandle $1_FILENAME := $(VARHANDLES_GENSRC_DIR)/VarHandle$$($1_Type)s.java - ifneq ($$(findstring $$($1_Type), Object Int Long), ) - $1_ARGS += -KCAS + $1_ARGS += -KCAS + + ifneq ($$(findstring $$($1_Type), Byte Short Char Int Long Float Double), ) + $1_ARGS += -KAtomicAdd endif - ifneq ($$(findstring $$($1_Type), Int Long), ) - $1_ARGS += -KAtomicAdd + ifneq ($$(findstring $$($1_Type), Byte Short Char), ) + $1_ARGS += -KShorterThanInt endif $$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandle.java.template $(BUILD_TOOLS_JDK) diff --git a/jdk/src/java.base/share/classes/java/lang/ThreadGroup.java b/jdk/src/java.base/share/classes/java/lang/ThreadGroup.java index 0a97e4cad94..2315c202329 100644 --- a/jdk/src/java.base/share/classes/java/lang/ThreadGroup.java +++ b/jdk/src/java.base/share/classes/java/lang/ThreadGroup.java @@ -60,7 +60,6 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler { int maxPriority; boolean destroyed; boolean daemon; - boolean vmAllowSuspension; int nUnstartedThreads = 0; int nthreads; @@ -121,7 +120,6 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler { this.name = name; this.maxPriority = parent.maxPriority; this.daemon = parent.daemon; - this.vmAllowSuspension = parent.vmAllowSuspension; this.parent = parent; parent.add(this); } @@ -1075,10 +1073,6 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler { */ @Deprecated(since="1.2") public boolean allowThreadSuspension(boolean b) { - this.vmAllowSuspension = b; - if (!b) { - VM.unsuspendSomeThreads(); - } return true; } diff --git a/jdk/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java b/jdk/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java index 5af586c4d52..5152da23b70 100644 --- a/jdk/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java +++ b/jdk/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -44,7 +44,7 @@ public class AnnotationTypeMismatchException extends RuntimeException { /** * The {@code Method} object for the annotation element. */ - private final Method element; + private final transient Method element; /** * The (erroneous) type of data found in the annotation. This string @@ -57,10 +57,12 @@ public class AnnotationTypeMismatchException extends RuntimeException { * Constructs an AnnotationTypeMismatchException for the specified * annotation type element and found data type. * - * @param element the {@code Method} object for the annotation element + * @param element the {@code Method} object for the annotation + * element, may be {@code null} * @param foundType the (erroneous) type of data found in the annotation. * This string may, but is not required to, contain the value - * as well. The exact format of the string is unspecified. + * as well. The exact format of the string is unspecified, + * may be {@code null}. */ public AnnotationTypeMismatchException(Method element, String foundType) { super("Incorrectly typed data found for annotation element " + element @@ -71,8 +73,11 @@ public class AnnotationTypeMismatchException extends RuntimeException { /** * Returns the {@code Method} object for the incorrectly typed element. + * The value may be unavailable if this exception has been + * serialized and then read back in. * - * @return the {@code Method} object for the incorrectly typed element + * @return the {@code Method} object for the incorrectly typed + * element, or {@code null} if unavailable */ public Method element() { return this.element; @@ -81,7 +86,8 @@ public class AnnotationTypeMismatchException extends RuntimeException { /** * Returns the type of data found in the incorrectly typed element. * The returned string may, but is not required to, contain the value - * as well. The exact format of the string is unspecified. + * as well. The exact format of the string is unspecified and the string + * may be {@code null}. * * @return the type of data found in the incorrectly typed element */ 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 2df4c9d1f57..d42bad62892 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 @@ -751,11 +751,25 @@ class InvokerBytecodeGenerator { classFileEpilogue(); bogusMethod(lambdaForm); - final byte[] classFile = cw.toByteArray(); + final byte[] classFile; + try { + classFile = cw.toByteArray(); + } catch (RuntimeException e) { + // ASM throws RuntimeException if something goes wrong - capture these and wrap them in a meaningful + // exception to support falling back to LambdaForm interpretation + throw new BytecodeGenerationException(e); + } maybeDump(className, classFile); return classFile; } + @SuppressWarnings("serial") + static final class BytecodeGenerationException extends RuntimeException { + BytecodeGenerationException(Exception cause) { + super(cause); + } + } + void emitArrayLoad(Name name) { emitArrayOp(name, Opcodes.AALOAD); } void emitArrayStore(Name name) { emitArrayOp(name, Opcodes.AASTORE); } void emitArrayLength(Name name) { emitArrayOp(name, Opcodes.ARRAYLENGTH); } 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 745c38df2de..a0a04559ff9 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,6 +25,7 @@ package java.lang.invoke; +import jdk.internal.perf.PerfCounter; import jdk.internal.vm.annotation.DontInline; import jdk.internal.vm.annotation.Stable; import sun.invoke.util.Wrapper; @@ -39,8 +40,7 @@ import java.util.HashMap; import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; -import static java.lang.invoke.MethodHandleStatics.debugEnabled; -import static java.lang.invoke.MethodHandleStatics.newInternalError; +import static java.lang.invoke.MethodHandleStatics.*; /** * The symbolic, non-executable form of a method handle's invocation semantics. @@ -396,7 +396,7 @@ class LambdaForm { /** Customize LambdaForm for a particular MethodHandle */ LambdaForm customize(MethodHandle mh) { LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh); - if (COMPILE_THRESHOLD > 0 && isCompiled) { + if (COMPILE_THRESHOLD >= 0 && isCompiled) { // If shared LambdaForm has been compiled, compile customized version as well. customForm.compileToBytecode(); } @@ -411,7 +411,7 @@ class LambdaForm { } assert(transformCache != null); // Customized LambdaForm should always has a link to uncustomized version. LambdaForm uncustomizedForm = (LambdaForm)transformCache; - if (COMPILE_THRESHOLD > 0 && isCompiled) { + if (COMPILE_THRESHOLD >= 0 && isCompiled) { // If customized LambdaForm has been compiled, compile uncustomized version as well. uncustomizedForm.compileToBytecode(); } @@ -717,7 +717,7 @@ class LambdaForm { * as a sort of pre-invocation linkage step.) */ public void prepare() { - if (COMPILE_THRESHOLD == 0 && !isCompiled) { + if (COMPILE_THRESHOLD == 0 && !forceInterpretation() && !isCompiled) { compileToBytecode(); } if (this.vmentry != null) { @@ -736,10 +736,22 @@ class LambdaForm { // TO DO: Maybe add invokeGeneric, invokeWithArguments } + private static @Stable PerfCounter LF_FAILED; + + private static PerfCounter failedCompilationCounter() { + if (LF_FAILED == null) { + LF_FAILED = PerfCounter.newPerfCounter("java.lang.invoke.failedLambdaFormCompilations"); + } + return LF_FAILED; + } + /** Generate optimizable bytecode for this form. */ - MemberName compileToBytecode() { + void compileToBytecode() { + if (forceInterpretation()) { + return; // this should not be compiled + } if (vmentry != null && isCompiled) { - return vmentry; // already compiled somehow + return; // already compiled somehow } MethodType invokerType = methodType(); assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType)); @@ -748,9 +760,16 @@ class LambdaForm { if (TRACE_INTERPRETER) traceInterpreter("compileToBytecode", this); isCompiled = true; - return vmentry; - } catch (Error | Exception ex) { - throw newInternalError(this.toString(), ex); + } catch (InvokerBytecodeGenerator.BytecodeGenerationException bge) { + // bytecode generation failed - mark this LambdaForm as to be run in interpretation mode only + invocationCounter = -1; + failedCompilationCounter().increment(); + if (LOG_LF_COMPILATION_FAILURE) { + System.out.println("LambdaForm compilation failed: " + this); + bge.printStackTrace(System.out); + } + } catch (Error | Exception e) { + throw newInternalError(this.toString(), e); } } @@ -856,7 +875,11 @@ class LambdaForm { static { COMPILE_THRESHOLD = Math.max(-1, MethodHandleStatics.COMPILE_THRESHOLD); } - private int invocationCounter = 0; + private int invocationCounter = 0; // a value of -1 indicates LambdaForm interpretation mode forever + + private boolean forceInterpretation() { + return invocationCounter == -1; + } @Hidden @DontInline @@ -896,7 +919,7 @@ class LambdaForm { private void checkInvocationCounter() { if (COMPILE_THRESHOLD != 0 && - invocationCounter < COMPILE_THRESHOLD) { + !forceInterpretation() && invocationCounter < COMPILE_THRESHOLD) { invocationCounter++; // benign race if (invocationCounter >= COMPILE_THRESHOLD) { // Replace vmentry with a bytecode version of this LF. @@ -906,7 +929,7 @@ class LambdaForm { } Object interpretWithArgumentsTracing(Object... argumentValues) throws Throwable { traceInterpreter("[ interpretWithArguments", this, argumentValues); - if (invocationCounter < COMPILE_THRESHOLD) { + if (!forceInterpretation() && invocationCounter < COMPILE_THRESHOLD) { int ctr = invocationCounter++; // benign race traceInterpreter("| invocationCounter", ctr); if (invocationCounter >= COMPILE_THRESHOLD) { diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java index bfaba660776..6d1ff4d297f 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, 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 @@ -25,10 +25,11 @@ package java.lang.invoke; -import java.util.Properties; import jdk.internal.misc.Unsafe; import sun.security.action.GetPropertyAction; +import java.util.Properties; + /** * This class consists exclusively of static names internal to the * method handle implementation. @@ -46,6 +47,7 @@ import sun.security.action.GetPropertyAction; static final boolean TRACE_INTERPRETER; static final boolean TRACE_METHOD_LINKAGE; static final int COMPILE_THRESHOLD; + static final boolean LOG_LF_COMPILATION_FAILURE; static final int DONT_INLINE_THRESHOLD; static final int PROFILE_LEVEL; static final boolean PROFILE_GWT; @@ -64,6 +66,8 @@ import sun.security.action.GetPropertyAction; props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE")); COMPILE_THRESHOLD = Integer.parseInt( props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0")); + LOG_LF_COMPILATION_FAILURE = Boolean.parseBoolean( + props.getProperty("java.lang.invoke.MethodHandle.LOG_LF_COMPILATION_FAILURE", "false")); DONT_INLINE_THRESHOLD = Integer.parseInt( props.getProperty("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", "30")); PROFILE_LEVEL = Integer.parseInt( @@ -87,7 +91,8 @@ import sun.security.action.GetPropertyAction; return (DEBUG_METHOD_HANDLE_NAMES | DUMP_CLASS_FILES | TRACE_INTERPRETER | - TRACE_METHOD_LINKAGE); + TRACE_METHOD_LINKAGE | + LOG_LF_COMPILATION_FAILURE); } // handy shared exception makers (they simplify the common case code) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 8b31f502c27..1150c188b8c 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -1208,22 +1208,43 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method * *

* If the field is declared {@code volatile} then the returned VarHandle * will override access to the field (effectively ignore the * {@code volatile} declaration) in accordance to it's specified * access modes. + *

+ * If the field type is {@code float} or {@code double} then numeric + * and atomic update access modes compare values using their bitwise + * representation (see {@link Float#floatToRawIntBits} and + * {@link Double#doubleToRawLongBits}, respectively). + * @apiNote + * Bitwise comparison of {@code float} values or {@code double} values, + * as performed by the numeric and atomic update access modes, differ + * from the primitive {@code ==} operator and the {@link Float#equals} + * and {@link Double#equals} methods, specifically with respect to + * comparing NaN values or comparing {@code -0.0} with {@code +0.0}. + * Care should be taken when performing a compare and set or a compare + * and exchange operation with such values since the operation may + * unexpectedly fail. + * There are many possible NaN values that are considered to be + * {@code NaN} in Java, although no IEEE 754 floating-point operation + * provided by Java can distinguish between them. Operation failure can + * occur if the expected or witness value is a NaN value and it is + * transformed (perhaps in a platform specific manner) into another NaN + * value, and thus has a different bitwise representation (see + * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more + * details). + * The values {@code -0.0} and {@code +0.0} have different bitwise + * representations but are considered equal when using the primitive + * {@code ==} operator. Operation failure can occur if, for example, a + * numeric algorithm computes an expected value to be say {@code -0.0} + * and previously computed the witness value to be say {@code +0.0}. * @param recv the receiver class, of type {@code R}, that declares the * non-static field * @param name the field's name @@ -1306,22 +1327,43 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method *

*

* If the field is declared {@code volatile} then the returned VarHandle * will override access to the field (effectively ignore the * {@code volatile} declaration) in accordance to it's specified * access modes. + *

+ * If the field type is {@code float} or {@code double} then numeric + * and atomic update access modes compare values using their bitwise + * representation (see {@link Float#floatToRawIntBits} and + * {@link Double#doubleToRawLongBits}, respectively). + * @apiNote + * Bitwise comparison of {@code float} values or {@code double} values, + * as performed by the numeric and atomic update access modes, differ + * from the primitive {@code ==} operator and the {@link Float#equals} + * and {@link Double#equals} methods, specifically with respect to + * comparing NaN values or comparing {@code -0.0} with {@code +0.0}. + * Care should be taken when performing a compare and set or a compare + * and exchange operation with such values since the operation may + * unexpectedly fail. + * There are many possible NaN values that are considered to be + * {@code NaN} in Java, although no IEEE 754 floating-point operation + * provided by Java can distinguish between them. Operation failure can + * occur if the expected or witness value is a NaN value and it is + * transformed (perhaps in a platform specific manner) into another NaN + * value, and thus has a different bitwise representation (see + * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more + * details). + * The values {@code -0.0} and {@code +0.0} have different bitwise + * representations but are considered equal when using the primitive + * {@code ==} operator. Operation failure can occur if, for example, a + * numeric algorithm computes an expected value to be say {@code -0.0} + * and previously computed the witness value to be say {@code +0.0}. * @param decl the class that declares the static field * @param name the field's name * @param type the field's type, of type {@code T} @@ -1590,22 +1632,43 @@ return mh1; *

*

* If the field is declared {@code volatile} then the returned VarHandle * will override access to the field (effectively ignore the * {@code volatile} declaration) in accordance to it's specified * access modes. + *

+ * If the field type is {@code float} or {@code double} then numeric + * and atomic update access modes compare values using their bitwise + * representation (see {@link Float#floatToRawIntBits} and + * {@link Double#doubleToRawLongBits}, respectively). + * @apiNote + * Bitwise comparison of {@code float} values or {@code double} values, + * as performed by the numeric and atomic update access modes, differ + * from the primitive {@code ==} operator and the {@link Float#equals} + * and {@link Double#equals} methods, specifically with respect to + * comparing NaN values or comparing {@code -0.0} with {@code +0.0}. + * Care should be taken when performing a compare and set or a compare + * and exchange operation with such values since the operation may + * unexpectedly fail. + * There are many possible NaN values that are considered to be + * {@code NaN} in Java, although no IEEE 754 floating-point operation + * provided by Java can distinguish between them. Operation failure can + * occur if the expected or witness value is a NaN value and it is + * transformed (perhaps in a platform specific manner) into another NaN + * value, and thus has a different bitwise representation (see + * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more + * details). + * The values {@code -0.0} and {@code +0.0} have different bitwise + * representations but are considered equal when using the primitive + * {@code ==} operator. Operation failure can occur if, for example, a + * numeric algorithm computes an expected value to be say {@code -0.0} + * and previously computed the witness value to be say {@code +0.0}. * @param f the reflected field, with a field of type {@code T}, and * a declaring class of type {@code R} * @return a VarHandle giving access to non-static fields or a static @@ -2289,17 +2352,38 @@ return mh1; * Certain access modes of the returned VarHandle are unsupported under * the following conditions: *

+ *

+ * If the component type is {@code float} or {@code double} then numeric + * and atomic update access modes compare values using their bitwise + * representation (see {@link Float#floatToRawIntBits} and + * {@link Double#doubleToRawLongBits}, respectively). + * @apiNote + * Bitwise comparison of {@code float} values or {@code double} values, + * as performed by the numeric and atomic update access modes, differ + * from the primitive {@code ==} operator and the {@link Float#equals} + * and {@link Double#equals} methods, specifically with respect to + * comparing NaN values or comparing {@code -0.0} with {@code +0.0}. + * Care should be taken when performing a compare and set or a compare + * and exchange operation with such values since the operation may + * unexpectedly fail. + * There are many possible NaN values that are considered to be + * {@code NaN} in Java, although no IEEE 754 floating-point operation + * provided by Java can distinguish between them. Operation failure can + * occur if the expected or witness value is a NaN value and it is + * transformed (perhaps in a platform specific manner) into another NaN + * value, and thus has a different bitwise representation (see + * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more + * details). + * The values {@code -0.0} and {@code +0.0} have different bitwise + * representations but are considered equal when using the primitive + * {@code ==} operator. Operation failure can occur if, for example, a + * numeric algorithm computes an expected value to be say {@code -0.0} + * and previously computed the witness value to be say {@code +0.0}. * @param arrayClass the class of an array, of type {@code T[]} * @return a VarHandle giving access to elements of an array * @throws NullPointerException if the arrayClass is null @@ -2363,16 +2447,11 @@ return mh1; * int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT; * boolean isMisaligned = misalignedAtIndex != 0; * } - * - * @implNote - * The variable types {@code float} and {@code double} are supported as if - * by transformation to and access with the variable types {@code int} and - * {@code long} respectively. For example, the transformation of a - * {@code double} value to a long value is performed as if using - * {@link Double#doubleToRawLongBits(double)}, and the reverse - * transformation is performed as if using - * {@link Double#longBitsToDouble(long)}. - * + *

+ * If the variable type is {@code float} or {@code double} then atomic + * update access modes compare values using their bitwise representation + * (see {@link Float#floatToRawIntBits} and + * {@link Double#doubleToRawLongBits}, respectively). * @param viewArrayClass the view array class, with a component type of * type {@code T} * @param byteOrder the endianness of the view array elements, as @@ -2449,16 +2528,11 @@ return mh1; * int misalignedAtIndex = bb.alignmentOffset(index, sizeOfT); * boolean isMisaligned = misalignedAtIndex != 0; * } - * - * @implNote - * The variable types {@code float} and {@code double} are supported as if - * by transformation to and access with the variable types {@code int} and - * {@code long} respectively. For example, the transformation of a - * {@code double} value to a long value is performed as if using - * {@link Double#doubleToRawLongBits(double)}, and the reverse - * transformation is performed as if using - * {@link Double#longBitsToDouble(long)}. - * + *

+ * If the variable type is {@code float} or {@code double} then atomic + * update access modes compare values using their bitwise representation + * (see {@link Float#floatToRawIntBits} and + * {@link Double#doubleToRawLongBits}, respectively). * @param viewArrayClass the view array class, with a component type of * type {@code T} * @param byteOrder the endianness of the view array elements, as @@ -3353,7 +3427,8 @@ assertEquals("xy", h3.invoke("x", "y", 1, "a", "b", "c")); * @return a possibly adapted method handle * @throws NullPointerException if either argument is null * @throws IllegalArgumentException if any element of {@code newTypes} is {@code void.class}, - * or if either index is out of range in its corresponding list, + * or if {@code skip} is negative or greater than the arity of the target, + * or if {@code pos} is negative or greater than the newTypes list size, * or if the non-skipped target parameter types match the new types at {@code pos} * @since 9 */ diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java index f55acf251e2..f8f60c3962a 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java @@ -139,7 +139,7 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError; * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire}, * {@link #weakCompareAndSetRelease weakCompareAndSetRelease}, * {@link #compareAndExchangeAcquire compareAndExchangeAcquire}, - * {@link #compareAndExchangeVolatile compareAndExchangeVolatile}, + * {@link #compareAndExchange compareAndExchange}, * {@link #compareAndExchangeRelease compareAndExchangeRelease}, * {@link #getAndSet getAndSet}. *

  • numeric atomic update access modes that, for example, atomically get and @@ -706,9 +706,9 @@ public abstract class VarHandle { *

    The method signature is of the form {@code (CT, T expectedValue, T newValue)T}. * *

    The symbolic type descriptor at the call site of {@code - * compareAndExchangeVolatile} + * compareAndExchange} * must match the access mode type that is the result of calling - * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)} + * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)} * on this VarHandle. * * @param args the signature-polymorphic parameter list of the form @@ -729,7 +729,7 @@ public abstract class VarHandle { public final native @MethodHandle.PolymorphicSignature @HotSpotIntrinsicCandidate - Object compareAndExchangeVolatile(Object... args); + Object compareAndExchange(Object... args); /** * Atomically sets the value of a variable to the {@code newValue} with the @@ -1199,9 +1199,9 @@ public abstract class VarHandle { /** * The access mode whose access is specified by the corresponding * method - * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile} + * {@link VarHandle#compareAndExchange VarHandle.compareAndExchange} */ - COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE), + COMPARE_AND_EXCHANGE("compareAndExchange", AccessType.COMPARE_AND_EXCHANGE), /** * The access mode whose access is specified by the corresponding * method diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template index ebb6dd31b79..d6f5aaa380c 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template +++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template @@ -132,7 +132,7 @@ final class VarHandle$Type$s { } @ForceInline - static $type$ compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { + static $type$ compareAndExchange(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { return UNSAFE.compareAndExchange$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)), handle.fieldOffset, {#if[Object]?handle.fieldType.cast(expected):expected}, @@ -205,9 +205,9 @@ final class VarHandle$Type$s { @ForceInline static $type$ addAndGet(FieldInstanceReadWrite handle, Object holder, $type$ value) { - return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + return {#if[ShorterThanInt]?($type$)}(UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), handle.fieldOffset, - value) + value; + value) + value); } #end[AtomicAdd] @@ -313,7 +313,7 @@ final class VarHandle$Type$s { @ForceInline - static $type$ compareAndExchangeVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) { + static $type$ compareAndExchange(FieldStaticReadWrite handle, $type$ expected, $type$ value) { return UNSAFE.compareAndExchange$Type$Volatile(handle.base, handle.fieldOffset, {#if[Object]?handle.fieldType.cast(expected):expected}, @@ -386,9 +386,9 @@ final class VarHandle$Type$s { @ForceInline static $type$ addAndGet(FieldStaticReadWrite handle, $type$ value) { - return UNSAFE.getAndAdd$Type$(handle.base, + return {#if[ShorterThanInt]?($type$)}(UNSAFE.getAndAdd$Type$(handle.base, handle.fieldOffset, - value) + value; + value) + value); } #end[AtomicAdd] @@ -523,7 +523,7 @@ final class VarHandle$Type$s { } @ForceInline - static $type$ compareAndExchangeVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) { + static $type$ compareAndExchange(Array handle, Object oarray, int index, $type$ expected, $type$ value) { #if[Object] Object[] array = (Object[]) handle.arrayType.cast(oarray); #else[Object] @@ -646,9 +646,9 @@ final class VarHandle$Type$s { #else[Object] $type$[] array = ($type$[]) oarray; #end[Object] - return UNSAFE.getAndAdd$Type$(array, + return {#if[ShorterThanInt]?($type$)}(UNSAFE.getAndAdd$Type$(array, (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, - value) + value; + value) + value); } #end[AtomicAdd] diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template index 66bf267476e..bb2f7f0ae10 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template +++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template @@ -193,7 +193,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { } @ForceInline - static $type$ compareAndExchangeVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { + static $type$ compareAndExchange(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { byte[] ba = (byte[]) oba; return convEndian(handle.be, UNSAFE.compareAndExchange$RawType$Volatile( @@ -436,7 +436,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { } @ForceInline - static $type$ compareAndExchangeVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { + static $type$ compareAndExchange(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { ByteBuffer bb = (ByteBuffer) obb; return convEndian(handle.be, UNSAFE.compareAndExchange$RawType$Volatile( diff --git a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java index f94a94e252f..5284bcd3907 100644 --- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java +++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java @@ -418,7 +418,7 @@ public class DateFormatSymbols implements Serializable, Cloneable { * Gets short month strings. For example: "Jan", "Feb", etc. * *

    If the language requires different forms for formatting and - * stand-alone usages, This method returns short month names in + * stand-alone usages, this method returns short month names in * the formatting form. For example, the preferred abbreviation * for January in the Catalan language is de gen. in the * formatting form, while it is gen. in the stand-alone diff --git a/jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java b/jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java index b464b6c71a4..d6d6787c72f 100644 --- a/jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java +++ b/jdk/src/java.base/share/classes/java/text/SimpleDateFormat.java @@ -276,9 +276,16 @@ import sun.util.locale.provider.LocaleProviderAdapter; * it is interpreted as a number.
    *