mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-11 19:08:23 +00:00
Merge
This commit is contained in:
commit
9449ca7449
@ -224,8 +224,7 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_System_setOut0;
|
||||
Java_java_lang_Thread_registerNatives;
|
||||
Java_java_lang_Throwable_fillInStackTrace;
|
||||
Java_java_lang_Throwable_getStackTraceDepth;
|
||||
Java_java_lang_Throwable_getStackTraceElement;
|
||||
Java_java_lang_Throwable_getStackTraceElements;
|
||||
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2;
|
||||
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
|
||||
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2;
|
||||
|
||||
@ -78,8 +78,7 @@ text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_Pri
|
||||
text: .text%JNU_GetEnv;
|
||||
text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
text: .text%Java_java_lang_reflect_Array_newArray;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceDepth;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceElement;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceElements;
|
||||
text: .text%throwFileNotFoundException;
|
||||
text: .text%JNU_NotifyAll;
|
||||
# Test LoadFrame
|
||||
|
||||
@ -74,8 +74,7 @@ text: .text%Java_java_security_AccessController_doPrivileged__Ljava_security_Pri
|
||||
text: .text%JNU_GetEnv;
|
||||
text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
text: .text%Java_java_lang_reflect_Array_newArray;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceDepth;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceElement;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceElements;
|
||||
text: .text%throwFileNotFoundException: OUTPUTDIR/io_util.o;
|
||||
text: .text%JNU_NotifyAll;
|
||||
# Test LoadFrame
|
||||
|
||||
@ -78,8 +78,7 @@ text: .text%Java_java_io_UnixFileSystem_checkAccess;
|
||||
text: .text%Java_sun_reflect_NativeMethodAccessorImpl_invoke0;
|
||||
text: .text%Java_java_io_FileInputStream_available;
|
||||
text: .text%Java_java_lang_reflect_Array_newArray;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceDepth;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceElement;
|
||||
text: .text%Java_java_lang_Throwable_getStackTraceElements;
|
||||
text: .text%Java_java_lang_System_identityHashCode;
|
||||
text: .text%JNU_NotifyAll;
|
||||
# Test LoadFrame
|
||||
|
||||
@ -161,7 +161,9 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_dup;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_access0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_exists0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat1;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fstat;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;
|
||||
|
||||
@ -138,7 +138,9 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_dup;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_access0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_exists0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat1;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fstat;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;
|
||||
|
||||
@ -138,7 +138,9 @@ SUNWprivate_1.1 {
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_strerror;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_dup;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_access0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_exists0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat1;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_lstat0;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fstat;
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_fstatat0;
|
||||
|
||||
@ -56,7 +56,7 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
|
||||
private boolean ROUNDS_14 = false;
|
||||
|
||||
/** Session and Sub keys */
|
||||
private Object[] sessionK = null;
|
||||
private int[][] sessionK = null;
|
||||
private int[] K = null;
|
||||
|
||||
/** Cipher encryption/decryption key */
|
||||
@ -99,7 +99,7 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
|
||||
}
|
||||
|
||||
// set sub key to the corresponding session Key
|
||||
this.K = (int[]) sessionK[(decrypting? 1:0)];
|
||||
this.K = sessionK[(decrypting? 1:0)];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -680,7 +680,7 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
|
||||
limit = ROUNDS*4;
|
||||
|
||||
// store the expanded sub keys into 'sessionK'
|
||||
sessionK = new Object[] { expandedKe, expandedKd };
|
||||
sessionK = new int[][] { expandedKe, expandedKd };
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -64,20 +64,4 @@ public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
|
||||
public ArrayIndexOutOfBoundsException(int index) {
|
||||
super("Array index out of range: " + index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ArrayIndexOutOfBoundsException} class with
|
||||
* arguments indicating two out of bound values.
|
||||
*
|
||||
* <p>The out of bound values are included in this exception's detail
|
||||
* message. The exact presentation format of the detail message is
|
||||
* unspecified.
|
||||
*
|
||||
* @param a the first out of bound value.
|
||||
* @param b the second out of bound value.
|
||||
* @since 9
|
||||
*/
|
||||
public ArrayIndexOutOfBoundsException(int a, int b) {
|
||||
super("Array indexed access out of bounds: " + a + ", " + b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,14 +29,44 @@ import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
/**
|
||||
* A program element annotated @Deprecated is one that programmers
|
||||
* are discouraged from using, typically because it is dangerous,
|
||||
* or because a better alternative exists. Compilers warn when a
|
||||
* deprecated program element is used or overridden in non-deprecated code.
|
||||
* A program element annotated {@code @Deprecated} is one that programmers
|
||||
* are discouraged from using. An element may be deprecated for any of several
|
||||
* reasons, for example, its usage is likely to lead to errors; it may
|
||||
* be changed incompatibly or removed in a future version; it has been
|
||||
* superseded by a newer, usually preferable alternative; or it is obsolete.
|
||||
*
|
||||
* <p>Use of the @Deprecated annotation on a local variable
|
||||
* declaration or on a parameter declaration or a package declaration
|
||||
* has no effect on the warnings issued by a compiler.
|
||||
* <p>Compilers issue warnings when a deprecated program element is used or
|
||||
* overridden in non-deprecated code. Use of the {@code @Deprecated}
|
||||
* annotation on a local variable declaration or on a parameter declaration
|
||||
* or a package declaration has no effect on the warnings issued by a compiler.
|
||||
*
|
||||
* <p>This annotation type has a string-valued element {@code since}. The value
|
||||
* of this element indicates the version in which the annotated program element
|
||||
* was first deprecated.
|
||||
*
|
||||
* <p>This annotation type has a boolean-valued element {@code forRemoval}.
|
||||
* A value of {@code true} indicates intent to remove the annotated program
|
||||
* element in a future version. A value of {@code false} indicates that use of
|
||||
* the annotated program element is discouraged, but at the time the program
|
||||
* element was annotated, there was no specific intent to remove it.
|
||||
*
|
||||
* @apiNote
|
||||
* It is strongly recommended that the reason for deprecating a program element
|
||||
* be explained in the documentation, using the {@code @deprecated}
|
||||
* javadoc tag. The documentation should also suggest and link to a
|
||||
* recommended replacement API, if applicable. A replacement API often
|
||||
* has subtly different semantics, so such issues should be discussed as
|
||||
* well.
|
||||
*
|
||||
* <p>It is recommended that a {@code since} value be provided with all newly
|
||||
* annotated program elements. Note that {@code since} cannot be mandatory,
|
||||
* as there are many existing annotations that lack this element value.
|
||||
*
|
||||
* <p>There is no defined order among annotation elements. As a matter of
|
||||
* style, the {@code since} element should be placed first.
|
||||
*
|
||||
* <p>The {@code @Deprecated} annotation should always be present if
|
||||
* the {@code @deprecated} javadoc tag is present, and vice-versa.
|
||||
*
|
||||
* @author Neal Gafter
|
||||
* @since 1.5
|
||||
@ -46,4 +76,23 @@ import static java.lang.annotation.ElementType.*;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
|
||||
public @interface Deprecated {
|
||||
/**
|
||||
* Returns the version in which the annotated element became deprecated.
|
||||
* The version string is in the same format and namespace as the value of
|
||||
* the {@code @since} javadoc tag. The default value is the empty
|
||||
* string.
|
||||
*
|
||||
* @return the version string
|
||||
* @since 9
|
||||
*/
|
||||
String since() default "";
|
||||
|
||||
/**
|
||||
* Indicates whether the annotated element is subject to removal in a
|
||||
* future version. The default value is {@code false}.
|
||||
*
|
||||
* @return whether the element is subject to removal
|
||||
* @since 9
|
||||
*/
|
||||
boolean forRemoval() default false;
|
||||
}
|
||||
|
||||
@ -67,21 +67,4 @@ public class IndexOutOfBoundsException extends RuntimeException {
|
||||
public IndexOutOfBoundsException(int index) {
|
||||
super("Index out of range: " + index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code IndexOutOfBoundsException} with arguments indicating
|
||||
* two out of bound values.
|
||||
*
|
||||
* <p>The out of bound values are included in this exception's detail
|
||||
* message. The exact presentation format of the detail message is
|
||||
* unspecified.
|
||||
*
|
||||
* @param a the first out of bound value
|
||||
* @param b the second out of bound value
|
||||
* @since 9
|
||||
*/
|
||||
public IndexOutOfBoundsException(int a, int b) {
|
||||
super("Indexed access out of bounds: " + a + ", " + b);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -51,6 +51,11 @@ import static java.security.AccessController.doPrivileged;
|
||||
* @since 9
|
||||
*/
|
||||
final class ProcessHandleImpl implements ProcessHandle {
|
||||
/**
|
||||
* Default size of stack for reaper processes.
|
||||
*/
|
||||
private static long REAPER_DEFAULT_STACKSIZE = 128 * 1024;
|
||||
|
||||
/**
|
||||
* Cache the ProcessHandle of this process.
|
||||
*/
|
||||
@ -79,10 +84,12 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||
ThreadGroup tg = Thread.currentThread().getThreadGroup();
|
||||
while (tg.getParent() != null) tg = tg.getParent();
|
||||
ThreadGroup systemThreadGroup = tg;
|
||||
final long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize")
|
||||
? 0 : REAPER_DEFAULT_STACKSIZE;
|
||||
|
||||
ThreadFactory threadFactory = grimReaper -> {
|
||||
long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize") ? 0 : 32768;
|
||||
Thread t = new Thread(systemThreadGroup, grimReaper, "process reaper", stackSize);
|
||||
Thread t = new Thread(systemThreadGroup, grimReaper,
|
||||
"process reaper", stackSize, false);
|
||||
t.setDaemon(true);
|
||||
// A small attempt (probably futile) to avoid priority inversion
|
||||
t.setPriority(Thread.MAX_PRIORITY);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -112,6 +112,12 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an empty stack frame element to be filled in by Throwable.
|
||||
*/
|
||||
StackTraceElement() { }
|
||||
|
||||
/**
|
||||
* Returns the name of the source file containing the execution point
|
||||
* represented by this stack trace element. Generally, this corresponds
|
||||
|
||||
@ -67,20 +67,4 @@ public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
|
||||
public StringIndexOutOfBoundsException(int index) {
|
||||
super("String index out of range: " + index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code StringIndexOutOfBoundsException} class with
|
||||
* arguments indicating two out of bound values.
|
||||
*
|
||||
* <p>The out of bound values are included in this exception's detail
|
||||
* message. The exact presentation format of the detail message is
|
||||
* unspecified.
|
||||
*
|
||||
* @param a the first out of bound value.
|
||||
* @param b the second out of bound value.
|
||||
* @since 9
|
||||
*/
|
||||
public StringIndexOutOfBoundsException(int a, int b) {
|
||||
super("String indexed access out of bounds: " + a + ", " + b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -118,7 +118,7 @@ public class Throwable implements Serializable {
|
||||
private static final long serialVersionUID = -3042686055658047285L;
|
||||
|
||||
/**
|
||||
* Native code saves some indication of the stack backtrace in this slot.
|
||||
* The JVM saves some indication of the stack backtrace in this slot.
|
||||
*/
|
||||
private transient Object backtrace;
|
||||
|
||||
@ -211,6 +211,11 @@ public class Throwable implements Serializable {
|
||||
*/
|
||||
private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
|
||||
|
||||
/**
|
||||
* The JVM code sets the depth of the backtrace for later retrieval
|
||||
*/
|
||||
private transient int depth;
|
||||
|
||||
// Setting this static field introduces an acceptable
|
||||
// initialization dependency on a few java.util classes.
|
||||
private static final List<Throwable> SUPPRESSED_SENTINEL = Collections.emptyList();
|
||||
@ -828,10 +833,11 @@ public class Throwable implements Serializable {
|
||||
if (backtrace instanceof StackStreamFactory.StackTrace) {
|
||||
stackTrace = ((StackStreamFactory.StackTrace)backtrace).getStackTraceElements();
|
||||
} else {
|
||||
int depth = getStackTraceDepth();
|
||||
stackTrace = new StackTraceElement[depth];
|
||||
for (int i = 0; i < depth; i++)
|
||||
stackTrace[i] = getStackTraceElement(i);
|
||||
for (int i = 0; i < depth; i++) {
|
||||
stackTrace[i] = new StackTraceElement();
|
||||
}
|
||||
getStackTraceElements(stackTrace);
|
||||
}
|
||||
} else if (stackTrace == null) {
|
||||
return UNASSIGNED_STACK;
|
||||
@ -884,23 +890,11 @@ public class Throwable implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the stack trace (or 0 if the stack
|
||||
* trace is unavailable).
|
||||
*
|
||||
* package-protection for use by SharedSecrets.
|
||||
* Gets the stack trace elements.
|
||||
* @param elements
|
||||
* @throws IndexOutOfBoundsException if {@code elements.length != depth }
|
||||
*/
|
||||
native int getStackTraceDepth();
|
||||
|
||||
/**
|
||||
* Returns the specified element of the stack trace.
|
||||
*
|
||||
* package-protection for use by SharedSecrets.
|
||||
*
|
||||
* @param index index of the element to return.
|
||||
* @throws IndexOutOfBoundsException if {@code index < 0 ||
|
||||
* index >= getStackTraceDepth() }
|
||||
*/
|
||||
native StackTraceElement getStackTraceElement(int index);
|
||||
private native void getStackTraceElements(StackTraceElement[] elements);
|
||||
|
||||
/**
|
||||
* Reads a {@code Throwable} from a stream, enforcing
|
||||
|
||||
@ -89,8 +89,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
static {
|
||||
final String key = "jdk.internal.lambda.dumpProxyClasses";
|
||||
String path = AccessController.doPrivileged(
|
||||
new GetPropertyAction(key), null,
|
||||
new PropertyPermission(key , "read"));
|
||||
new GetPropertyAction(key));
|
||||
dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
|
||||
}
|
||||
|
||||
|
||||
@ -655,6 +655,8 @@ class InvokerBytecodeGenerator {
|
||||
mv.visitAnnotation(DONTINLINE_SIG, true);
|
||||
}
|
||||
|
||||
constantPlaceholder(lambdaForm); // keep LambdaForm instance & its compiled form lifetime tightly coupled.
|
||||
|
||||
if (lambdaForm.customized != null) {
|
||||
// Since LambdaForm is customized for a particular MethodHandle, it's safe to substitute
|
||||
// receiver MethodHandle (at slot #0) with an embedded constant and use it instead.
|
||||
|
||||
@ -131,11 +131,11 @@ class Invokers {
|
||||
MethodType mtype = targetType;
|
||||
MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
|
||||
|
||||
LambdaForm lform = varHandleMethodGenericInvokerHandleForm(ak.name(), mtype);
|
||||
LambdaForm lform = varHandleMethodGenericInvokerHandleForm(ak.methodName(), mtype);
|
||||
VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
|
||||
MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
|
||||
|
||||
invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.name(), mtype), false);
|
||||
invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.methodName(), mtype), false);
|
||||
assert(checkVarHandleInvoker(invoker));
|
||||
|
||||
maybeCompileToBytecode(invoker);
|
||||
@ -146,11 +146,11 @@ class Invokers {
|
||||
MethodType mtype = targetType;
|
||||
MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
|
||||
|
||||
LambdaForm lform = varHandleMethodExactInvokerHandleForm(ak.name(), mtype);
|
||||
LambdaForm lform = varHandleMethodExactInvokerHandleForm(ak.methodName(), mtype);
|
||||
VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
|
||||
MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
|
||||
|
||||
invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.name(), mtype), false);
|
||||
invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.methodName(), mtype), false);
|
||||
assert(checkVarHandleInvoker(invoker));
|
||||
|
||||
maybeCompileToBytecode(invoker);
|
||||
|
||||
@ -374,7 +374,7 @@ import java.util.Objects;
|
||||
}
|
||||
public static boolean isVarHandleMethodInvokeName(String name) {
|
||||
try {
|
||||
VarHandle.AccessMode.valueOf(name);
|
||||
VarHandle.AccessMode.valueFromMethodName(name);
|
||||
return true;
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
|
||||
@ -219,7 +219,8 @@ import static java.lang.invoke.MethodHandleStatics.*;
|
||||
* Method handles produced by lookups or constant loads from methods or
|
||||
* constructors with the variable arity modifier bit ({@code 0x0080})
|
||||
* have a corresponding variable arity, as if they were defined with
|
||||
* the help of {@link #asVarargsCollector asVarargsCollector}.
|
||||
* the help of {@link #asVarargsCollector asVarargsCollector}
|
||||
* or {@link #withVarargs withVarargs}.
|
||||
* <p>
|
||||
* A method reference may refer either to a static or non-static method.
|
||||
* In the non-static case, the method handle type includes an explicit
|
||||
@ -972,6 +973,36 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
|
||||
throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Adapts this method handle to be {@linkplain #asVarargsCollector variable arity}
|
||||
* if the boolean flag is true, else {@linkplain #asFixedArity fixed arity}.
|
||||
* If the method handle is already of the proper arity mode, it is returned
|
||||
* unchanged.
|
||||
* @apiNote
|
||||
* <p>This method is sometimes useful when adapting a method handle that
|
||||
* may be variable arity, to ensure that the resulting adapter is also
|
||||
* variable arity if and only if the original handle was. For example,
|
||||
* this code changes the first argument of a handle {@code mh} to {@code int} without
|
||||
* disturbing its variable arity property:
|
||||
* {@code mh.asType(mh.type().changeParameterType(0,int.class))
|
||||
* .withVarargs(mh.isVarargsCollector())}
|
||||
* @param makeVarargs true if the return method handle should have variable arity behavior
|
||||
* @return a method handle of the same type, with possibly adjusted variable arity behavior
|
||||
* @throws IllegalArgumentException if {@code makeVarargs} is true and
|
||||
* this method handle does not have a trailing array parameter
|
||||
* @since 9
|
||||
* @see #asVarargsCollector
|
||||
* @see #asFixedArity
|
||||
*/
|
||||
public MethodHandle withVarargs(boolean makeVarargs) {
|
||||
if (!makeVarargs) {
|
||||
return asFixedArity();
|
||||
} else if (!isVarargsCollector()) {
|
||||
return asVarargsCollector(type().lastParameterType());
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an <em>array-collecting</em> method handle, which accepts a given number of trailing
|
||||
@ -1000,7 +1031,8 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray
|
||||
* to allow the target to use a simple {@code Object} as its last parameter type.)
|
||||
* <p>
|
||||
* In order to create a collecting adapter which is not restricted to a particular
|
||||
* number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
|
||||
* number of collected arguments, use {@link #asVarargsCollector asVarargsCollector}
|
||||
* or {@link #withVarargs withVarargs} instead.
|
||||
* <p>
|
||||
* Here are some examples of array-collecting method handles:
|
||||
* <blockquote><pre>{@code
|
||||
@ -1216,7 +1248,7 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
|
||||
* <p>
|
||||
* No method handle transformations produce new method handles with
|
||||
* variable arity, unless they are documented as doing so.
|
||||
* Therefore, besides {@code asVarargsCollector},
|
||||
* Therefore, besides {@code asVarargsCollector} and {@code withVarargs},
|
||||
* all methods in {@code MethodHandle} and {@code MethodHandles}
|
||||
* will return a method handle with fixed arity,
|
||||
* except in the cases where they are specified to return their original
|
||||
@ -1273,6 +1305,7 @@ assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
|
||||
* or {@code arrayType} is not assignable to this method handle's trailing parameter type
|
||||
* @see #asCollector
|
||||
* @see #isVarargsCollector
|
||||
* @see #withVarargs
|
||||
* @see #asFixedArity
|
||||
*/
|
||||
public MethodHandle asVarargsCollector(Class<?> arrayType) {
|
||||
@ -1344,6 +1377,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
|
||||
* @return a new method handle which accepts only a fixed number of arguments
|
||||
* @see #asVarargsCollector
|
||||
* @see #isVarargsCollector
|
||||
* @see #withVarargs
|
||||
*/
|
||||
public MethodHandle asFixedArity() {
|
||||
assert(!isVarargsCollector());
|
||||
@ -1428,11 +1462,11 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
|
||||
/*non-public*/
|
||||
MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
|
||||
if (!member.isVarargs()) return this;
|
||||
Class<?> arrayType = type().lastParameterType();
|
||||
if (arrayType.isArray()) {
|
||||
return MethodHandleImpl.makeVarargsCollector(this, arrayType);
|
||||
try {
|
||||
return this.withVarargs(true);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw member.makeAccessException("cannot make variable arity", null);
|
||||
}
|
||||
throw member.makeAccessException("cannot make variable arity", null);
|
||||
}
|
||||
|
||||
/*non-public*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 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
|
||||
@ -1055,7 +1055,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
if (!method.getInvocationType().equals(mh.type()))
|
||||
throw new InternalError(method.toString());
|
||||
mh = mh.withInternalMemberName(method, false);
|
||||
mh = mh.asVarargsCollector(Object[].class);
|
||||
mh = mh.withVarargs(true);
|
||||
assert(method.isVarargs());
|
||||
FAKE_METHOD_HANDLE_INVOKE[idx] = mh;
|
||||
return mh;
|
||||
@ -1753,6 +1753,18 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
return counter + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is bound as a filter in {@linkplain MethodHandles#countedLoop(MethodHandle, MethodHandle, MethodHandle,
|
||||
* MethodHandle) counting loops} to pass the correct counter value to the body.
|
||||
*
|
||||
* @param counter the loop counter.
|
||||
*
|
||||
* @return the loop counter decremented by 1.
|
||||
*/
|
||||
static int decrementCounter(int counter) {
|
||||
return counter - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is bound to initialize the loop-local iterator in {@linkplain MethodHandles#iteratedLoop iterating loops}.
|
||||
*
|
||||
@ -1879,7 +1891,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
MH_iterateNext = 11,
|
||||
MH_tryFinallyExec = 12,
|
||||
MH_tryFinallyVoidExec = 13,
|
||||
MH_LIMIT = 14;
|
||||
MH_decrementCounter = 14,
|
||||
MH_LIMIT = 15;
|
||||
|
||||
static MethodHandle getConstantHandle(int idx) {
|
||||
MethodHandle handle = HANDLES[idx];
|
||||
@ -1949,6 +1962,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
case MH_tryFinallyVoidExec:
|
||||
return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "tryFinallyVoidExecutor",
|
||||
MethodType.methodType(void.class, MethodHandle.class, MethodHandle.class, Object[].class));
|
||||
case MH_decrementCounter:
|
||||
return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "decrementCounter",
|
||||
MethodType.methodType(int.class, int.class));
|
||||
}
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw newInternalError(ex);
|
||||
|
||||
@ -423,7 +423,7 @@ class MethodHandleNatives {
|
||||
// Get the access kind from the method name
|
||||
VarHandle.AccessMode ak;
|
||||
try {
|
||||
ak = VarHandle.AccessMode.valueOf(name);
|
||||
ak = VarHandle.AccessMode.valueFromMethodName(name);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw MethodHandleStatics.newInternalError(e);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 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
|
||||
@ -216,13 +216,7 @@ public class MethodHandleProxies {
|
||||
}
|
||||
|
||||
private static MethodHandle bindCaller(MethodHandle target, Class<?> hostClass) {
|
||||
MethodHandle cbmh = MethodHandleImpl.bindCaller(target, hostClass);
|
||||
if (target.isVarargsCollector()) {
|
||||
MethodType type = cbmh.type();
|
||||
int arity = type.parameterCount();
|
||||
return cbmh.asVarargsCollector(type.parameterType(arity-1));
|
||||
}
|
||||
return cbmh;
|
||||
return MethodHandleImpl.bindCaller(target, hostClass).withVarargs(target.isVarargsCollector());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -43,7 +43,6 @@ import sun.reflect.misc.ReflectUtil;
|
||||
import sun.security.util.SecurityConstants;
|
||||
import java.lang.invoke.LambdaForm.BasicType;
|
||||
|
||||
import static java.lang.invoke.MethodHandleStatics.*;
|
||||
import static java.lang.invoke.MethodHandleImpl.Intrinsic;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -53,8 +52,6 @@ import java.util.stream.Stream;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
|
||||
import static java.lang.invoke.MethodHandleImpl.Intrinsic;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
|
||||
|
||||
/**
|
||||
@ -952,7 +949,7 @@ assertEquals("", (String) MH_newString.invokeExact());
|
||||
}
|
||||
private MethodHandle findVirtualForVH(String name, MethodType type) {
|
||||
try {
|
||||
return varHandleInvoker(VarHandle.AccessMode.valueOf(name), type);
|
||||
return varHandleInvoker(VarHandle.AccessMode.valueFromMethodName(name), type);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
@ -1355,9 +1352,7 @@ import static java.lang.invoke.MethodType.*;
|
||||
...
|
||||
MethodHandle mh0 = lookup().findVirtual(defc, name, type);
|
||||
MethodHandle mh1 = mh0.bindTo(receiver);
|
||||
MethodType mt1 = mh1.type();
|
||||
if (mh0.isVarargsCollector())
|
||||
mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
|
||||
mh1 = mh1.withVarargs(mh0.isVarargsCollector());
|
||||
return mh1;
|
||||
* }</pre></blockquote>
|
||||
* where {@code defc} is either {@code receiver.getClass()} or a super
|
||||
@ -2954,9 +2949,55 @@ assert((int)twice.invokeExact(21) == 42);
|
||||
if (ident.type().returnType() == type)
|
||||
return ident;
|
||||
// something like identity(Foo.class); do not bother to intern these
|
||||
assert(btw == Wrapper.OBJECT);
|
||||
assert (btw == Wrapper.OBJECT);
|
||||
return makeIdentity(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a constant method handle of the requested return type which
|
||||
* returns the default value for that type every time it is invoked.
|
||||
* The resulting constant method handle will have no side effects.
|
||||
* <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
|
||||
* It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
|
||||
* since {@code explicitCastArguments} converts {@code null} to default values.
|
||||
* @param type the expected return type of the desired method handle
|
||||
* @return a constant method handle that takes no arguments
|
||||
* and returns the default value of the given type (or void, if the type is void)
|
||||
* @throws NullPointerException if the argument is null
|
||||
* @see MethodHandles#constant
|
||||
* @see MethodHandles#empty
|
||||
* @since 9
|
||||
*/
|
||||
public static MethodHandle zero(Class<?> type) {
|
||||
Objects.requireNonNull(type);
|
||||
return type.isPrimitive() ? zero(Wrapper.forPrimitiveType(type), type) : zero(Wrapper.OBJECT, type);
|
||||
}
|
||||
|
||||
private static MethodHandle identityOrVoid(Class<?> type) {
|
||||
return type == void.class ? zero(type) : identity(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a method handle of the requested type which ignores any arguments, does nothing,
|
||||
* and returns a suitable default depending on the return type.
|
||||
* That is, it returns a zero primitive value, a {@code null}, or {@code void}.
|
||||
* <p>The returned method handle is equivalent to
|
||||
* {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
|
||||
* <p>
|
||||
* @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
|
||||
* {@code guardWithTest(pred, target, empty(target.type())}.
|
||||
* @param type the type of the desired method handle
|
||||
* @return a constant method handle of the given type, which returns a default value of the given return type
|
||||
* @throws NullPointerException if the argument is null
|
||||
* @see MethodHandles#zero
|
||||
* @see MethodHandles#constant
|
||||
* @since 9
|
||||
*/
|
||||
public static MethodHandle empty(MethodType type) {
|
||||
Objects.requireNonNull(type);
|
||||
return dropArguments(zero(type.returnType()), 0, type.parameterList());
|
||||
}
|
||||
|
||||
private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.values().length];
|
||||
private static MethodHandle makeIdentity(Class<?> ptype) {
|
||||
MethodType mtype = MethodType.methodType(ptype, ptype);
|
||||
@ -3148,8 +3189,7 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
|
||||
* If {@code pos} is zero, the dummy arguments will precede
|
||||
* the target's real arguments; if {@code pos} is <i>N</i>
|
||||
* they will come after.
|
||||
* <p>
|
||||
* <b>Example:</b>
|
||||
* @apiNote
|
||||
* <blockquote><pre>{@code
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
@ -3188,6 +3228,99 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
|
||||
return dropArguments(target, pos, Arrays.asList(valueTypes));
|
||||
}
|
||||
|
||||
// private version which allows caller some freedom with error handling
|
||||
private static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos,
|
||||
boolean nullOnFailure) {
|
||||
List<Class<?>> oldTypes = target.type().parameterList();
|
||||
int match = oldTypes.size();
|
||||
if (skip != 0) {
|
||||
if (skip < 0 || skip > match) {
|
||||
throw newIllegalArgumentException("illegal skip", skip, target);
|
||||
}
|
||||
oldTypes = oldTypes.subList(skip, match);
|
||||
match -= skip;
|
||||
}
|
||||
List<Class<?>> addTypes = newTypes;
|
||||
int add = addTypes.size();
|
||||
if (pos != 0) {
|
||||
if (pos < 0 || pos > add) {
|
||||
throw newIllegalArgumentException("illegal pos", pos, newTypes);
|
||||
}
|
||||
addTypes = addTypes.subList(pos, add);
|
||||
add -= pos; assert(addTypes.size() == add);
|
||||
}
|
||||
// Do not add types which already match the existing arguments.
|
||||
if (match > add || !oldTypes.equals(addTypes.subList(0, match))) {
|
||||
if (nullOnFailure) {
|
||||
return null;
|
||||
}
|
||||
throw newIllegalArgumentException("argument lists do not match", oldTypes, newTypes);
|
||||
}
|
||||
addTypes = addTypes.subList(match, add);
|
||||
add -= match; assert(addTypes.size() == add);
|
||||
// newTypes: ( P*[pos], M*[match], A*[add] )
|
||||
// target: ( S*[skip], M*[match] )
|
||||
MethodHandle adapter = target;
|
||||
if (add > 0) {
|
||||
adapter = dropArguments(adapter, skip+ match, addTypes);
|
||||
}
|
||||
// adapter: (S*[skip], M*[match], A*[add] )
|
||||
if (pos > 0) {
|
||||
adapter = dropArguments(adapter, skip, newTypes.subList(0, pos));
|
||||
}
|
||||
// adapter: (S*[skip], P*[pos], M*[match], A*[add] )
|
||||
return adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts a target method handle to match the given parameter type list, if necessary, by adding dummy arguments.
|
||||
* Some leading parameters are first skipped; they will be left unchanged and are otherwise ignored.
|
||||
* The remaining types in the target's parameter type list must be contained as a sub-list of the given type list,
|
||||
* at the given position.
|
||||
* Any non-matching parameter types (before or after the matching sub-list) are inserted in corresponding
|
||||
* positions of the target method handle's parameters, as if by {@link #dropArguments}.
|
||||
* (More precisely, elements in the new list before {@code pos} are inserted into the target list at {@code skip},
|
||||
* while elements in the new list after the match beginning at {@code pos} are inserted at the end of the
|
||||
* target list.)
|
||||
* The target's return type will be unchanged.
|
||||
* @apiNote
|
||||
* Two method handles whose argument lists are "effectively identical" (i.e., identical
|
||||
* in a common prefix) may be mutually converted to a common type
|
||||
* by two calls to {@code dropArgumentsToMatch}, as follows:
|
||||
* <blockquote><pre>{@code
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
...
|
||||
...
|
||||
MethodHandle h0 = constant(boolean.class, true);
|
||||
MethodHandle h1 = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class));
|
||||
MethodType bigType = h1.type().insertParameterTypes(1, String.class, int.class);
|
||||
MethodHandle h2 = dropArguments(h1, 0, bigType.parameterList());
|
||||
if (h1.type().parameterCount() < h2.type().parameterCount())
|
||||
h1 = dropArgumentsToMatch(h1, 0, h2.type().parameterList(), 0); // lengthen h1
|
||||
else
|
||||
h2 = dropArgumentsToMatch(h2, 0, h1.type().parameterList(), 0); // lengthen h2
|
||||
MethodHandle h3 = guardWithTest(h0, h1, h2);
|
||||
assertEquals("xy", h3.invoke("x", "y", 1, "a", "b", "c"));
|
||||
* }</pre></blockquote>
|
||||
* @param target the method handle to adapt
|
||||
* @param skip number of targets parameters to disregard (they will be unchanged)
|
||||
* @param newTypes the desired argument list of the method handle
|
||||
* @param pos place in {@code newTypes} where the non-skipped target parameters must occur
|
||||
* @return a possibly adapted method handle
|
||||
* @throws NullPointerException if either argument is null
|
||||
* @throws IllegalArgumentException
|
||||
* if either index is out of range in its corresponding list, or
|
||||
* if the non-skipped target parameter types match the new types at {@code pos}
|
||||
* @since 9
|
||||
*/
|
||||
public static
|
||||
MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos) {
|
||||
Objects.requireNonNull(target);
|
||||
Objects.requireNonNull(newTypes);
|
||||
return dropArgumentsToMatch(target, skip, newTypes, pos, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts a target method handle by pre-processing
|
||||
* one or more of its arguments, each with its own unary filter function,
|
||||
@ -3699,13 +3832,9 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
if (gtype.returnType() != boolean.class)
|
||||
throw newIllegalArgumentException("guard type is not a predicate "+gtype);
|
||||
List<Class<?>> targs = ttype.parameterList();
|
||||
List<Class<?>> gargs = gtype.parameterList();
|
||||
if (!targs.equals(gargs)) {
|
||||
int gpc = gargs.size(), tpc = targs.size();
|
||||
if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
|
||||
throw misMatchedTypes("target and test types", ttype, gtype);
|
||||
test = dropArguments(test, gpc, targs.subList(gpc, tpc));
|
||||
gtype = test.type();
|
||||
test = dropArgumentsToMatch(test, 0, targs, 0, true);
|
||||
if (test == null) {
|
||||
throw misMatchedTypes("target and test types", ttype, gtype);
|
||||
}
|
||||
return MethodHandleImpl.makeGuardWithTest(test, target, fallback);
|
||||
}
|
||||
@ -3777,15 +3906,9 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
throw newIllegalArgumentException("handler does not accept exception type "+exType);
|
||||
if (htype.returnType() != ttype.returnType())
|
||||
throw misMatchedTypes("target and handler return types", ttype, htype);
|
||||
List<Class<?>> targs = ttype.parameterList();
|
||||
List<Class<?>> hargs = htype.parameterList();
|
||||
hargs = hargs.subList(1, hargs.size()); // omit leading parameter from handler
|
||||
if (!targs.equals(hargs)) {
|
||||
int hpc = hargs.size(), tpc = targs.size();
|
||||
if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
|
||||
throw misMatchedTypes("target and handler types", ttype, htype);
|
||||
handler = dropArguments(handler, 1+hpc, targs.subList(hpc, tpc));
|
||||
htype = handler.type();
|
||||
handler = dropArgumentsToMatch(handler, 1, ttype.parameterList(), 0, true);
|
||||
if (handler == null) {
|
||||
throw misMatchedTypes("target and handler types", ttype, htype);
|
||||
}
|
||||
return MethodHandleImpl.makeGuardWithCatch(target, exType, handler);
|
||||
}
|
||||
@ -4043,16 +4166,16 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
for (int i = 0; i < nclauses; ++i) {
|
||||
Class<?> t = iterationVariableTypes.get(i);
|
||||
if (init.get(i) == null) {
|
||||
init.set(i, zeroHandle(t));
|
||||
init.set(i, empty(MethodType.methodType(t, commonSuffix)));
|
||||
}
|
||||
if (step.get(i) == null) {
|
||||
step.set(i, dropArguments(t == void.class ? zeroHandle(t) : identity(t), 0, commonPrefix.subList(0, i)));
|
||||
step.set(i, dropArgumentsToMatch(identityOrVoid(t), 0, commonParameterSequence, i));
|
||||
}
|
||||
if (pred.get(i) == null) {
|
||||
pred.set(i, constant(boolean.class, true));
|
||||
pred.set(i, dropArguments(constant(boolean.class, true), 0, commonParameterSequence));
|
||||
}
|
||||
if (fini.get(i) == null) {
|
||||
fini.set(i, zeroHandle(t));
|
||||
fini.set(i, empty(MethodType.methodType(t, commonParameterSequence)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4146,7 +4269,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
* @since 9
|
||||
*/
|
||||
public static MethodHandle whileLoop(MethodHandle init, MethodHandle pred, MethodHandle body) {
|
||||
MethodHandle fin = init == null ? zeroHandle(void.class) : identity(init.type().returnType());
|
||||
MethodHandle fin = init == null ? zero(void.class) : identity(init.type().returnType());
|
||||
MethodHandle[] checkExit = {null, null, pred, fin};
|
||||
MethodHandle[] varBody = {init, body};
|
||||
return loop(checkExit, varBody);
|
||||
@ -4212,7 +4335,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
* @since 9
|
||||
*/
|
||||
public static MethodHandle doWhileLoop(MethodHandle init, MethodHandle body, MethodHandle pred) {
|
||||
MethodHandle fin = init == null ? zeroHandle(void.class) : identity(init.type().returnType());
|
||||
MethodHandle fin = init == null ? zero(void.class) : identity(init.type().returnType());
|
||||
MethodHandle[] clause = {init, body, pred, fin};
|
||||
return loop(clause);
|
||||
}
|
||||
@ -4322,11 +4445,13 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
* <blockquote><pre>{@code
|
||||
* MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
|
||||
* MethodHandle returnVar = dropArguments(identity(init.type().returnType()), 0, int.class, int.class);
|
||||
* // assume MH_increment and MH_lessThan are handles to x+1 and x<y of type int
|
||||
* // assume MH_increment and MH_lessThan are handles to x+1 and x<y of type int,
|
||||
* // assume MH_decrement is a handle to x-1 of type int
|
||||
* MethodHandle[]
|
||||
* indexVar = {start, MH_increment}, // i = start; i = i+1
|
||||
* loopLimit = {end, null, MH_lessThan, returnVar }, // i<end
|
||||
* bodyClause = {init, dropArguments(body, 1, int.class)}; // v = body(i, v);
|
||||
* bodyClause = {init,
|
||||
* filterArgument(dropArguments(body, 1, int.class), 0, MH_decrement}; // v = body(i-1, v)
|
||||
* return loop(indexVar, loopLimit, bodyClause);
|
||||
* }
|
||||
* }</pre></blockquote>
|
||||
@ -4347,11 +4472,13 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
* @since 9
|
||||
*/
|
||||
public static MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
|
||||
MethodHandle returnVar = dropArguments(init == null ? zeroHandle(void.class) : identity(init.type().returnType()),
|
||||
MethodHandle returnVar = dropArguments(init == null ? zero(void.class) : identity(init.type().returnType()),
|
||||
0, int.class, int.class);
|
||||
MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)};
|
||||
MethodHandle[] loopLimit = {end, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
|
||||
MethodHandle[] bodyClause = {init, dropArguments(body, 1, int.class)};
|
||||
MethodHandle[] bodyClause = {init,
|
||||
filterArgument(dropArguments(body, 1, int.class), 0,
|
||||
MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter))};
|
||||
return loop(indexVar, loopLimit, bodyClause);
|
||||
}
|
||||
|
||||
@ -4448,7 +4575,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
Class<?> ttype = body.type().parameterType(0);
|
||||
|
||||
MethodHandle returnVar =
|
||||
dropArguments(init == null ? zeroHandle(void.class) : identity(init.type().returnType()), 0, itype);
|
||||
dropArguments(init == null ? zero(void.class) : identity(init.type().returnType()), 0, itype);
|
||||
MethodHandle initnx = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iterateNext);
|
||||
MethodHandle nextVal = initnx.asType(initnx.type().changeReturnType(ttype));
|
||||
|
||||
@ -4542,15 +4669,11 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
checkTryFinally(target, cleanup);
|
||||
|
||||
// Match parameter lists: if the cleanup has a shorter parameter list than the target, add ignored arguments.
|
||||
int tpSize = targetParamTypes.size();
|
||||
int cpPrefixLength = rtype == void.class ? 1 : 2;
|
||||
int cpSize = cleanupParamTypes.size();
|
||||
MethodHandle aCleanup = cpSize - cpPrefixLength < tpSize ?
|
||||
dropArguments(cleanup, cpSize, targetParamTypes.subList(tpSize - (cpSize - cpPrefixLength), tpSize)) :
|
||||
cleanup;
|
||||
|
||||
// The cleanup parameter list (minus the leading Throwable and result parameters) must be a sublist of the
|
||||
// target parameter list.
|
||||
cleanup = dropArgumentsToMatch(cleanup, (rtype == void.class ? 1 : 2), targetParamTypes, 0);
|
||||
MethodHandle aTarget = target.asSpreader(Object[].class, target.type().parameterCount());
|
||||
aCleanup = aCleanup.asSpreader(Object[].class, tpSize);
|
||||
MethodHandle aCleanup = cleanup.asSpreader(Object[].class, targetParamTypes.size());
|
||||
|
||||
return MethodHandleImpl.makeTryFinally(aTarget, aCleanup, rtype, targetParamTypes);
|
||||
}
|
||||
@ -4641,16 +4764,6 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap creation of a proper zero handle for a given type.
|
||||
*
|
||||
* @param type the type.
|
||||
*
|
||||
* @return a zero value for the given type.
|
||||
*/
|
||||
static MethodHandle zeroHandle(Class<?> type) {
|
||||
return type.isPrimitive() ? zero(Wrapper.forPrimitiveType(type), type) : zero(Wrapper.OBJECT, type);
|
||||
}
|
||||
|
||||
private static void checkLoop0(MethodHandle[][] clauses) {
|
||||
if (clauses == null || clauses.length == 0) {
|
||||
|
||||
@ -34,11 +34,11 @@ import jdk.internal.misc.Unsafe;
|
||||
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.Function;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
@ -188,20 +188,14 @@ public final class StringConcatFactory {
|
||||
private static final ProxyClassesDumper DUMPER;
|
||||
|
||||
static {
|
||||
// Poke the privileged block once, taking everything we need:
|
||||
final Object[] values = new Object[4];
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
values[0] = System.getProperty("java.lang.invoke.stringConcat");
|
||||
values[1] = Boolean.getBoolean("java.lang.invoke.stringConcat.cache");
|
||||
values[2] = Boolean.getBoolean("java.lang.invoke.stringConcat.debug");
|
||||
values[3] = System.getProperty("java.lang.invoke.stringConcat.dumpClasses");
|
||||
return null;
|
||||
});
|
||||
|
||||
final String strategy = (String) values[0];
|
||||
CACHE_ENABLE = (Boolean) values[1];
|
||||
DEBUG = (Boolean) values[2];
|
||||
final String dumpPath = (String) values[3];
|
||||
final String strategy = AccessController.doPrivileged(
|
||||
new GetPropertyAction("java.lang.invoke.stringConcat"));
|
||||
CACHE_ENABLE = Boolean.parseBoolean(AccessController.doPrivileged(
|
||||
new GetPropertyAction("java.lang.invoke.stringConcat.cache")));
|
||||
DEBUG = Boolean.parseBoolean(AccessController.doPrivileged(
|
||||
new GetPropertyAction("java.lang.invoke.stringConcat.debug")));
|
||||
final String dumpPath = AccessController.doPrivileged(
|
||||
new GetPropertyAction("java.lang.invoke.stringConcat.dumpClasses"));
|
||||
|
||||
STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy);
|
||||
CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null;
|
||||
|
||||
@ -69,13 +69,10 @@ class VarForm {
|
||||
for (Class<?> c = implClass; c != VarHandle.class; c = c.getSuperclass()) {
|
||||
for (Method m : c.getDeclaredMethods()) {
|
||||
if (Modifier.isStatic(m.getModifiers())) {
|
||||
try {
|
||||
AccessMode am = AccessMode.valueOf(m.getName());
|
||||
AccessMode am = AccessMode.methodNameToAccessMode.get(m.getName());
|
||||
if (am != null) {
|
||||
assert table[am.ordinal()] == null;
|
||||
table[am.ordinal()] = new MemberName(m);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Ignore. Note the try/catch will be removed when
|
||||
// AccessMode enum constant names are renamed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,8 +31,12 @@ import jdk.internal.vm.annotation.ForceInline;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.lang.invoke.MethodHandleStatics.UNSAFE;
|
||||
import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
||||
@ -152,7 +156,9 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
||||
* supported, which may also include documenting restrictions based on the
|
||||
* variable type and whether a variable is read-only. If an access mode is not
|
||||
* supported then the corresponding signature-polymorphic method will on
|
||||
* invocation throw an {@code UnsupportedOperationException}.
|
||||
* invocation throw an {@code UnsupportedOperationException}. Factory methods
|
||||
* should document any additional undeclared exceptions that may be thrown by
|
||||
* access mode methods.
|
||||
* The {@link #get get} access mode is supported for all
|
||||
* VarHandle instances and the corresponding method never throws
|
||||
* {@code UnsupportedOperationException}.
|
||||
@ -166,7 +172,7 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
||||
* Unless stated otherwise in the documentation of a factory method, the access
|
||||
* modes {@code get} and {@code set} (if supported) provide atomic access for
|
||||
* reference types and all primitives types, with the exception of {@code long}
|
||||
* and {@code double} on 32-bit platforms
|
||||
* and {@code double} on 32-bit platforms.
|
||||
*
|
||||
* <p>Access modes will override any memory ordering effects specified at
|
||||
* the declaration site of a variable. For example, a VarHandle accessing a
|
||||
@ -272,7 +278,7 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
||||
* <pre> {@code
|
||||
* MethodHandle mh = MethodHandles.lookup().findVirtual(
|
||||
* VarHandle.class,
|
||||
* VarHandle.AccessMode.{access-mode}.name(),
|
||||
* VarHandle.AccessMode.{access-mode}.methodName(),
|
||||
* MethodType.methodType(R, p1, p2, ..., pN));
|
||||
*
|
||||
* R r = (R) mh.invokeExact(vh, p1, p2, ..., pN)
|
||||
@ -465,6 +471,8 @@ public abstract class VarHandle {
|
||||
* , statically represented using {@code Object}.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
*/
|
||||
public final native
|
||||
@MethodHandle.PolymorphicSignature
|
||||
@ -489,6 +497,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
*/
|
||||
public final native
|
||||
@MethodHandle.PolymorphicSignature
|
||||
@ -518,6 +528,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
*/
|
||||
public final native
|
||||
@MethodHandle.PolymorphicSignature
|
||||
@ -534,6 +546,10 @@ public abstract class VarHandle {
|
||||
* must match the access mode type that is the result of calling
|
||||
* {@code accessModeType(VarHandle.AccessMode.setVolatile)} on this VarHandle.
|
||||
*
|
||||
* @apiNote
|
||||
* Ignoring the many semantic differences from C and C++, this method has
|
||||
* memory ordering effects compatible with {@code memory_order_seq_cst}.
|
||||
*
|
||||
* @param args the signature-polymorphic parameter list of the form
|
||||
* {@code (CT, T newValue)}
|
||||
* , statically represented using varargs.
|
||||
@ -541,9 +557,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @apiNote Ignoring the many semantic differences from C and C++, this
|
||||
* method has memory ordering effects compatible with
|
||||
* {@code memory_order_seq_cst}.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
*/
|
||||
public final native
|
||||
@MethodHandle.PolymorphicSignature
|
||||
@ -571,6 +586,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
*/
|
||||
public final native
|
||||
@MethodHandle.PolymorphicSignature
|
||||
@ -595,6 +612,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
*/
|
||||
public final native
|
||||
@MethodHandle.PolymorphicSignature
|
||||
@ -614,6 +633,11 @@ public abstract class VarHandle {
|
||||
* must match the access mode type that is the result of calling
|
||||
* {@code accessModeType(VarHandle.AccessMode.getAcquire)} on this VarHandle.
|
||||
*
|
||||
* @apiNote
|
||||
* Ignoring the many semantic differences from C and C++, this method has
|
||||
* memory ordering effects compatible with {@code memory_order_acquire}
|
||||
* ordering.
|
||||
*
|
||||
* @param args the signature-polymorphic parameter list of the form
|
||||
* {@code (CT)}
|
||||
* , statically represented using varargs.
|
||||
@ -624,9 +648,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @apiNote Ignoring the many semantic differences from C and C++, this
|
||||
* method has memory ordering effects compatible with
|
||||
* {@code memory_order_acquire} ordering.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
*/
|
||||
public final native
|
||||
@MethodHandle.PolymorphicSignature
|
||||
@ -643,6 +666,11 @@ public abstract class VarHandle {
|
||||
* must match the access mode type that is the result of calling
|
||||
* {@code accessModeType(VarHandle.AccessMode.setRelease)} on this VarHandle.
|
||||
*
|
||||
* @apiNote
|
||||
* Ignoring the many semantic differences from C and C++, this method has
|
||||
* memory ordering effects compatible with {@code memory_order_release}
|
||||
* ordering.
|
||||
*
|
||||
* @param args the signature-polymorphic parameter list of the form
|
||||
* {@code (CT, T newValue)}
|
||||
* , statically represented using varargs.
|
||||
@ -650,9 +678,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @apiNote Ignoring the many semantic differences from C and C++, this
|
||||
* method has memory ordering effects compatible with
|
||||
* {@code memory_order_release} ordering.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
*/
|
||||
public final native
|
||||
@MethodHandle.PolymorphicSignature
|
||||
@ -685,6 +712,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #setVolatile(Object...)
|
||||
* @see #getVolatile(Object...)
|
||||
*/
|
||||
@ -718,6 +747,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #setVolatile(Object...)
|
||||
* @see #getVolatile(Object...)
|
||||
*/
|
||||
@ -751,6 +782,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #set(Object...)
|
||||
* @see #getAcquire(Object...)
|
||||
*/
|
||||
@ -783,6 +816,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #setRelease(Object...)
|
||||
* @see #get(Object...)
|
||||
*/
|
||||
@ -820,6 +855,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #set(Object...)
|
||||
* @see #get(Object...)
|
||||
*/
|
||||
@ -855,6 +892,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #set(Object...)
|
||||
* @see #getAcquire(Object...)
|
||||
*/
|
||||
@ -890,6 +929,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #setRelease(Object...)
|
||||
* @see #get(Object...)
|
||||
*/
|
||||
@ -920,6 +961,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #setVolatile(Object...)
|
||||
* @see #getVolatile(Object...)
|
||||
*/
|
||||
@ -954,6 +997,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #setVolatile(Object...)
|
||||
* @see #getVolatile(Object...)
|
||||
*/
|
||||
@ -984,6 +1029,8 @@ public abstract class VarHandle {
|
||||
* for this VarHandle.
|
||||
* @throws WrongMethodTypeException if the access mode type is not
|
||||
* compatible with the caller's symbolic type descriptor.
|
||||
* @throws ClassCastException if the access mode type is compatible with the
|
||||
* caller's symbolic type descriptor, but a reference cast fails.
|
||||
* @see #setVolatile(Object...)
|
||||
* @see #getVolatile(Object...)
|
||||
*/
|
||||
@ -993,11 +1040,11 @@ public abstract class VarHandle {
|
||||
Object addAndGet(Object... args);
|
||||
|
||||
enum AccessType {
|
||||
get, // 0
|
||||
set, // 1
|
||||
compareAndSwap, // 2
|
||||
compareAndExchange, // 3
|
||||
getAndUpdate; // 4
|
||||
GET, // 0
|
||||
SET, // 1
|
||||
COMPARE_AND_SWAP, // 2
|
||||
COMPARE_AND_EXCHANGE, // 3
|
||||
GET_AND_UPDATE; // 4
|
||||
|
||||
MethodType getMethodType(VarHandle vh) {
|
||||
return getMethodType(this.ordinal(), vh);
|
||||
@ -1036,126 +1083,179 @@ public abstract class VarHandle {
|
||||
* method
|
||||
* {@link VarHandle#get VarHandle.get}
|
||||
*/
|
||||
get(AccessType.get, Object.class), // 0
|
||||
GET("get", AccessType.GET, Object.class), // 0
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#set VarHandle.set}
|
||||
*/
|
||||
set(AccessType.set, void.class), // 1
|
||||
SET("set", AccessType.SET, void.class), // 1
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#getVolatile VarHandle.getVolatile}
|
||||
*/
|
||||
getVolatile(AccessType.get, Object.class), // 2
|
||||
GET_VOLATILE("getVolatile", AccessType.GET, Object.class), // 2
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#setVolatile VarHandle.setVolatile}
|
||||
*/
|
||||
setVolatile(AccessType.set, void.class), // 3
|
||||
SET_VOLATILE("setVolatile", AccessType.SET, void.class), // 3
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#getAcquire VarHandle.getAcquire}
|
||||
*/
|
||||
getAcquire(AccessType.get, Object.class), // 4
|
||||
GET_ACQUIRE("getAcquire", AccessType.GET, Object.class), // 4
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#setRelease VarHandle.setRelease}
|
||||
*/
|
||||
setRelease(AccessType.set, void.class), // 5
|
||||
SET_RELEASE("setRelease", AccessType.SET, void.class), // 5
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#getOpaque VarHandle.getOpaque}
|
||||
*/
|
||||
getOpaque(AccessType.get, Object.class), // 6
|
||||
GET_OPAQUE("getOpaque", AccessType.GET, Object.class), // 6
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#setOpaque VarHandle.setOpaque}
|
||||
*/
|
||||
setOpaque(AccessType.set, void.class), // 7
|
||||
SET_OPAQUE("setOpaque", AccessType.SET, void.class), // 7
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#compareAndSet VarHandle.compareAndSet}
|
||||
*/
|
||||
compareAndSet(AccessType.compareAndSwap, boolean.class), // 8
|
||||
COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class), // 8
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
|
||||
*/
|
||||
compareAndExchangeVolatile(AccessType.compareAndExchange, Object.class), // 9
|
||||
COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 9
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
|
||||
*/
|
||||
compareAndExchangeAcquire(AccessType.compareAndExchange, Object.class), // 10
|
||||
COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 10
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
|
||||
*/
|
||||
compareAndExchangeRelease(AccessType.compareAndExchange, Object.class), // 11
|
||||
COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 11
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
|
||||
*/
|
||||
weakCompareAndSet(AccessType.compareAndSwap, boolean.class), // 12
|
||||
WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class), // 12
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
|
||||
*/
|
||||
weakCompareAndSetAcquire(AccessType.compareAndSwap, boolean.class), // 13
|
||||
WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class), // 13
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
|
||||
*/
|
||||
weakCompareAndSetRelease(AccessType.compareAndSwap, boolean.class), // 14
|
||||
WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class), // 14
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#getAndSet VarHandle.getAndSet}
|
||||
*/
|
||||
getAndSet(AccessType.getAndUpdate, Object.class), // 15
|
||||
GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class), // 15
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#getAndAdd VarHandle.getAndAdd}
|
||||
*/
|
||||
getAndAdd(AccessType.getAndUpdate, Object.class), // 16
|
||||
GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class), // 16
|
||||
/**
|
||||
* The access mode whose access is specified by the corresponding
|
||||
* method
|
||||
* {@link VarHandle#addAndGet VarHandle.addAndGet}
|
||||
*/
|
||||
addAndGet(AccessType.getAndUpdate, Object.class), // 17
|
||||
ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class), // 17
|
||||
;
|
||||
|
||||
static final Map<String, AccessMode> methodNameToAccessMode;
|
||||
static {
|
||||
// Initial capacity of # values is sufficient to avoid resizes
|
||||
// for the smallest table size (32)
|
||||
methodNameToAccessMode = new HashMap<>(AccessMode.values().length);
|
||||
for (AccessMode am : AccessMode.values()) {
|
||||
methodNameToAccessMode.put(am.methodName, am);
|
||||
}
|
||||
}
|
||||
|
||||
final String methodName;
|
||||
final AccessType at;
|
||||
final boolean isPolyMorphicInReturnType;
|
||||
final Class<?> returnType;
|
||||
|
||||
AccessMode(AccessType at, Class<?> returnType) {
|
||||
AccessMode(final String methodName, AccessType at, Class<?> returnType) {
|
||||
this.methodName = methodName;
|
||||
this.at = at;
|
||||
|
||||
// Assert method name is correctly derived from value name
|
||||
assert methodName.equals(toMethodName(name()));
|
||||
// Assert that return type is correct
|
||||
// Otherwise, when disabled avoid using reflection
|
||||
assert returnType == getReturnType(name());
|
||||
assert returnType == getReturnType(methodName);
|
||||
|
||||
this.returnType = returnType;
|
||||
isPolyMorphicInReturnType = returnType != Object.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code VarHandle} signature-polymorphic method name
|
||||
* associated with this {@code AccessMode} value
|
||||
*
|
||||
* @return the signature-polymorphic method name
|
||||
* @see #valueFromMethodName
|
||||
*/
|
||||
public String methodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code AccessMode} value associated with the specified
|
||||
* {@code VarHandle} signature-polymorphic method name.
|
||||
*
|
||||
* @param methodName the signature-polymorphic method name
|
||||
* @return the {@code AccessMode} value
|
||||
* @throws IllegalArgumentException if there is no {@code AccessMode}
|
||||
* value associated with method name (indicating the method
|
||||
* name does not correspond to a {@code VarHandle}
|
||||
* signature-polymorphic method name).
|
||||
* @see #methodName
|
||||
*/
|
||||
public static AccessMode valueFromMethodName(String methodName) {
|
||||
AccessMode am = methodNameToAccessMode.get(methodName);
|
||||
if (am != null) return am;
|
||||
throw new IllegalArgumentException("No AccessMode value for method name " + methodName);
|
||||
}
|
||||
|
||||
private static String toMethodName(String name) {
|
||||
StringBuilder s = new StringBuilder(name.toLowerCase());
|
||||
int i;
|
||||
while ((i = s.indexOf("_")) != -1) {
|
||||
s.deleteCharAt(i);
|
||||
s.setCharAt(i, Character.toUpperCase(s.charAt(i)));
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
private static Class<?> getReturnType(String name) {
|
||||
try {
|
||||
Method m = VarHandle.class.getMethod(name, Object[].class);
|
||||
@ -1279,12 +1379,14 @@ public abstract class VarHandle {
|
||||
UNSAFE.fullFence();
|
||||
}
|
||||
|
||||
static final BiFunction<Integer, Integer, ArrayIndexOutOfBoundsException> AIOOBE_SUPPLIER = new BiFunction<>() {
|
||||
@Override
|
||||
public ArrayIndexOutOfBoundsException apply(Integer a, Integer b) {
|
||||
return new ArrayIndexOutOfBoundsException(a, b);
|
||||
}
|
||||
};
|
||||
static final BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException>
|
||||
AIOOBE_SUPPLIER = Objects.outOfBoundsExceptionFormatter(
|
||||
new Function<String, ArrayIndexOutOfBoundsException>() {
|
||||
@Override
|
||||
public ArrayIndexOutOfBoundsException apply(String s) {
|
||||
return new ArrayIndexOutOfBoundsException(s);
|
||||
}
|
||||
});
|
||||
|
||||
private static final long VFORM_OFFSET;
|
||||
|
||||
|
||||
@ -689,13 +689,14 @@ public class Proxy implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns all types referenced by all public method signatures of
|
||||
* Returns all types referenced by all public non-static method signatures of
|
||||
* the proxy interfaces
|
||||
*/
|
||||
private static Set<Class<?>> referencedTypes(ClassLoader loader,
|
||||
List<Class<?>> interfaces) {
|
||||
return interfaces.stream()
|
||||
.flatMap(intf -> Stream.of(intf.getMethods())
|
||||
.filter(m -> !Modifier.isStatic(m.getModifiers()))
|
||||
.flatMap(ProxyBuilder::methodRefTypes)
|
||||
.map(ProxyBuilder::getElementType)
|
||||
.filter(t -> !t.isPrimitive()))
|
||||
@ -795,26 +796,13 @@ public class Proxy implements java.io.Serializable {
|
||||
// map to dynamic proxy module and add reads edge and qualified exports, if necessary
|
||||
Module target = getDynamicModule(loader);
|
||||
|
||||
// set up proxy class access to proxy interfaces and superinterfaces
|
||||
Deque<Class<?>> deque = new LinkedList<>(interfaces);
|
||||
Set<Class<?>> visited = new HashSet<>();
|
||||
while (!deque.isEmpty()) {
|
||||
Class<?> c = deque.poll();
|
||||
if (!visited.add(c)) {
|
||||
continue;
|
||||
}
|
||||
// set up proxy class access to proxy interfaces and types
|
||||
// referenced in the method signature
|
||||
Set<Class<?>> types = new HashSet<>(interfaces);
|
||||
types.addAll(refTypes);
|
||||
for (Class<?> c : types) {
|
||||
ensureAccess(target, c);
|
||||
|
||||
// add all superinterfaces
|
||||
for (Class<?> intf : c.getInterfaces()) {
|
||||
deque.add(intf);
|
||||
}
|
||||
}
|
||||
|
||||
// set up proxy class access to types referenced in the method signature
|
||||
refTypes.stream()
|
||||
.filter(t -> !visited.contains(t))
|
||||
.forEach(t -> ensureAccess(target, t));
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
@ -465,23 +465,21 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a new package by name in this ClassLoader. The attributes
|
||||
* contained in the specified Manifest will be used to obtain package
|
||||
* version and sealing information. For sealed packages, the additional
|
||||
* URL specifies the code source URL from which the package was loaded.
|
||||
* Defines a new package by name in this {@code URLClassLoader}.
|
||||
* The attributes contained in the specified {@code Manifest}
|
||||
* will be used to obtain package version and sealing information.
|
||||
* For sealed packages, the additional URL specifies the code source URL
|
||||
* from which the package was loaded.
|
||||
*
|
||||
* @param name the package name
|
||||
* @param man the Manifest containing package version and sealing
|
||||
* @param man the {@code Manifest} containing package version and sealing
|
||||
* information
|
||||
* @param url the code source url for the package, or null if none
|
||||
* @exception IllegalArgumentException if the package name duplicates
|
||||
* an existing package either in this class loader or one
|
||||
* of its ancestors
|
||||
* @return the newly defined Package object
|
||||
* @throws IllegalArgumentException if the package name is
|
||||
* already defined by this class loader
|
||||
* @return the newly defined {@code Package} object
|
||||
*/
|
||||
protected Package definePackage(String name, Manifest man, URL url)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
protected Package definePackage(String name, Manifest man, URL url) {
|
||||
String path = name.replace('.', '/').concat("/");
|
||||
String specTitle = null, specVersion = null, specVendor = null;
|
||||
String implTitle = null, implVersion = null, implVendor = null;
|
||||
|
||||
@ -77,6 +77,8 @@ import java.util.function.BiPredicate;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import sun.nio.fs.AbstractFileSystemProvider;
|
||||
|
||||
/**
|
||||
* This class consists exclusively of static methods that operate on files,
|
||||
* directories, or other types of files.
|
||||
@ -2193,6 +2195,12 @@ public final class Files {
|
||||
* method denies read access to the file.
|
||||
*/
|
||||
public static boolean isDirectory(Path path, LinkOption... options) {
|
||||
if (options.length == 0) {
|
||||
FileSystemProvider provider = provider(path);
|
||||
if (provider instanceof AbstractFileSystemProvider)
|
||||
return ((AbstractFileSystemProvider)provider).isDirectory(path);
|
||||
}
|
||||
|
||||
try {
|
||||
return readAttributes(path, BasicFileAttributes.class, options).isDirectory();
|
||||
} catch (IOException ioe) {
|
||||
@ -2230,6 +2238,12 @@ public final class Files {
|
||||
* method denies read access to the file.
|
||||
*/
|
||||
public static boolean isRegularFile(Path path, LinkOption... options) {
|
||||
if (options.length == 0) {
|
||||
FileSystemProvider provider = provider(path);
|
||||
if (provider instanceof AbstractFileSystemProvider)
|
||||
return ((AbstractFileSystemProvider)provider).isRegularFile(path);
|
||||
}
|
||||
|
||||
try {
|
||||
return readAttributes(path, BasicFileAttributes.class, options).isRegularFile();
|
||||
} catch (IOException ioe) {
|
||||
@ -2385,6 +2399,12 @@ public final class Files {
|
||||
* @see #notExists
|
||||
*/
|
||||
public static boolean exists(Path path, LinkOption... options) {
|
||||
if (options.length == 0) {
|
||||
FileSystemProvider provider = provider(path);
|
||||
if (provider instanceof AbstractFileSystemProvider)
|
||||
return ((AbstractFileSystemProvider)provider).exists(path);
|
||||
}
|
||||
|
||||
try {
|
||||
if (followLinks(options)) {
|
||||
provider(path).checkAccess(path);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -140,7 +140,8 @@ public class AlgorithmParameterGenerator {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -128,7 +128,8 @@ public class AlgorithmParameters {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -155,7 +155,8 @@ public class KeyFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -197,7 +197,8 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -843,7 +843,8 @@ public class KeyStore {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 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
|
||||
@ -148,7 +148,8 @@ public abstract class MessageDigest extends MessageDigestSpi {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -357,7 +357,8 @@ public abstract class Policy {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -270,7 +270,8 @@ public class SecureRandom extends java.util.Random {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 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
|
||||
@ -205,7 +205,8 @@ public abstract class Signature extends SignatureSpi {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -144,7 +144,8 @@ public class CertPathBuilder {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -145,7 +145,8 @@ public class CertPathValidator {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -203,7 +203,8 @@ public class CertStore {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -165,7 +165,8 @@ public class CertificateFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1350,6 +1350,48 @@ public final class Duration
|
||||
return nanos;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Returns a copy of this {@code Duration} truncated to the specified unit.
|
||||
* <p>
|
||||
* Truncating the duration returns a copy of the original with conceptual fields
|
||||
* smaller than the specified unit set to zero.
|
||||
* For example, truncating with the {@link ChronoUnit#MINUTES MINUTES} unit will
|
||||
* round down to the nearest minute, setting the seconds and nanoseconds to zero.
|
||||
* <p>
|
||||
* The unit must have a {@linkplain TemporalUnit#getDuration() duration}
|
||||
* that divides into the length of a standard day without remainder.
|
||||
* This includes all supplied time units on {@link ChronoUnit} and
|
||||
* {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
* @param unit the unit to truncate to, not null
|
||||
* @return a {@code Duration} based on this duration with the time truncated, not null
|
||||
* @throws DateTimeException if the unit is invalid for truncation
|
||||
* @throws UnsupportedTemporalTypeException if the unit is not supported
|
||||
*/
|
||||
public Duration truncatedTo(TemporalUnit unit) {
|
||||
Objects.requireNonNull(unit, "unit");
|
||||
if (unit == ChronoUnit.SECONDS && (seconds >= 0 || nanos == 0)) {
|
||||
return new Duration(seconds, 0);
|
||||
} else if (unit == ChronoUnit.NANOS) {
|
||||
return this;
|
||||
}
|
||||
Duration unitDur = unit.getDuration();
|
||||
if (unitDur.getSeconds() > LocalTime.SECONDS_PER_DAY) {
|
||||
throw new UnsupportedTemporalTypeException("Unit is too large to be used for truncation");
|
||||
}
|
||||
long dur = unitDur.toNanos();
|
||||
if ((LocalTime.NANOS_PER_DAY % dur) != 0) {
|
||||
throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
|
||||
}
|
||||
long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
|
||||
long result = (nod / dur) * dur ;
|
||||
return plusNanos(result - nod);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Compares this duration to the specified {@code Duration}.
|
||||
|
||||
@ -25,26 +25,28 @@
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Supplier;
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* This class consists of {@code static} utility methods for operating
|
||||
* on objects, or checking certain conditions before operation. These utilities
|
||||
* include {@code null}-safe or {@code null}-tolerant methods for computing the
|
||||
* hash code of an object, returning a string for an object, comparing two
|
||||
* objects, and checking if indexes or sub-range values are out of bounds.
|
||||
* objects, and checking if indexes or sub-range values are out-of-bounds.
|
||||
*
|
||||
* @apiNote
|
||||
* Static methods such as {@link Objects#checkIndex},
|
||||
* {@link Objects#checkFromToIndex}, and {@link Objects#checkFromIndexSize} are
|
||||
* provided for the convenience of checking if values corresponding to indexes
|
||||
* and sub-ranges are out of bounds.
|
||||
* and sub-ranges are out-of-bounds.
|
||||
* Variations of these static methods support customization of the runtime
|
||||
* exception, and corresponding exception detail message, that is thrown when
|
||||
* values are out of bounds. Such methods accept a functional interface
|
||||
* argument, instances of {@code BiFunction}, that maps out of bound values to a
|
||||
* values are out-of-bounds. Such methods accept a functional interface
|
||||
* argument, instances of {@code BiFunction}, that maps out-of-bound values to a
|
||||
* runtime exception. Care should be taken when using such methods in
|
||||
* combination with an argument that is a lambda expression, method reference or
|
||||
* class that capture values. In such cases the cost of capture, related to
|
||||
@ -347,29 +349,176 @@ public final class Objects {
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps out of bounds values to a runtime exception.
|
||||
* Maps out-of-bounds values to a runtime exception.
|
||||
*
|
||||
* @param a the first out of bound value
|
||||
* @param b the second out of bound value
|
||||
* @param oobe the exception mapping function that when applied with out of
|
||||
* bounds arguments returns a runtime exception. If {@code null}
|
||||
* then, it is as if an exception mapping function was supplied that
|
||||
* returns {@link IndexOutOfBoundsException} for any given arguments.
|
||||
* @param checkKind the kind of bounds check, whose name may correspond
|
||||
* to the name of one of the range check methods, checkIndex,
|
||||
* checkFromToIndex, checkFromIndexSize
|
||||
* @param args the out-of-bounds arguments that failed the range check.
|
||||
* If the checkKind corresponds a the name of a range check method
|
||||
* then the bounds arguments are those that can be passed in order
|
||||
* to the method.
|
||||
* @param oobef the exception formatter that when applied with a checkKind
|
||||
* and a list out-of-bounds arguments returns a runtime exception.
|
||||
* If {@code null} then, it is as if an exception formatter was
|
||||
* supplied that returns {@link IndexOutOfBoundsException} for any
|
||||
* given arguments.
|
||||
* @return the runtime exception
|
||||
*/
|
||||
private static RuntimeException outOfBounds(
|
||||
int a, int b, BiFunction<Integer, Integer, ? extends RuntimeException> oobe) {
|
||||
RuntimeException e = oobe == null
|
||||
? null : oobe.apply(a, b);
|
||||
BiFunction<String, List<Integer>, ? extends RuntimeException> oobef,
|
||||
String checkKind,
|
||||
Integer... args) {
|
||||
List<Integer> largs = List.of(args);
|
||||
RuntimeException e = oobef == null
|
||||
? null : oobef.apply(checkKind, largs);
|
||||
return e == null
|
||||
? new IndexOutOfBoundsException(a, b) : e;
|
||||
? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e;
|
||||
}
|
||||
|
||||
// Specific out-of-bounds exception producing methods that avoid
|
||||
// the varargs-based code in the critical methods there by reducing their
|
||||
// the byte code size, and therefore less likely to peturb inlining
|
||||
|
||||
private static RuntimeException outOfBoundsCheckIndex(
|
||||
BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
|
||||
int index, int length) {
|
||||
return outOfBounds(oobe, "checkIndex", index, length);
|
||||
}
|
||||
|
||||
private static RuntimeException outOfBoundsCheckFromToIndex(
|
||||
BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
|
||||
int fromIndex, int toIndex, int length) {
|
||||
return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length);
|
||||
}
|
||||
|
||||
private static RuntimeException outOfBoundsCheckFromIndexSize(
|
||||
BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
|
||||
int fromIndex, int size, int length) {
|
||||
return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an out-of-bounds exception formatter from an given exception
|
||||
* factory. The exception formatter is a function that formats an
|
||||
* out-of-bounds message from its arguments and applies that message to the
|
||||
* given exception factory to produce and relay an exception.
|
||||
*
|
||||
* <p>The exception formatter accepts two arguments: a {@code String}
|
||||
* describing the out-of-bounds range check that failed, referred to as the
|
||||
* <em>check kind</em>; and a {@code List<Integer>} containing the
|
||||
* out-of-bound integer values that failed the check. The list of
|
||||
* out-of-bound values is not modified.
|
||||
*
|
||||
* <p>Three check kinds are supported {@code checkIndex},
|
||||
* {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding
|
||||
* respectively to the specified application of an exception formatter as an
|
||||
* argument to the out-of-bounds range check methods
|
||||
* {@link #checkIndex(int, int, BiFunction) checkIndex},
|
||||
* {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and
|
||||
* {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}.
|
||||
* Thus a supported check kind corresponds to a method name and the
|
||||
* out-of-bound integer values correspond to method argument values, in
|
||||
* order, preceding the exception formatter argument (similar in many
|
||||
* respects to the form of arguments required for a reflective invocation of
|
||||
* such a range check method).
|
||||
*
|
||||
* <p>Formatter arguments conforming to such supported check kinds will
|
||||
* produce specific exception messages describing failed out-of-bounds
|
||||
* checks. Otherwise, more generic exception messages will be produced in
|
||||
* any of the following cases: the check kind is supported but fewer
|
||||
* or more out-of-bounds values are supplied, the check kind is not
|
||||
* supported, the check kind is {@code null}, or the list of out-of-bound
|
||||
* values is {@code null}.
|
||||
*
|
||||
* @apiNote
|
||||
* This method produces an out-of-bounds exception formatter that can be
|
||||
* passed as an argument to any of the supported out-of-bounds range check
|
||||
* methods declared by {@code Objects}. For example, a formatter producing
|
||||
* an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a
|
||||
* {@code static final} field as follows:
|
||||
* <pre>{@code
|
||||
* static final
|
||||
* BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBEF =
|
||||
* outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new);
|
||||
* }</pre>
|
||||
* The formatter instance {@code AIOOBEF} may be passed as an argument to an
|
||||
* out-of-bounds range check method, such as checking if an {@code index}
|
||||
* is within the bounds of a {@code limit}:
|
||||
* <pre>{@code
|
||||
* checkIndex(index, limit, AIOOBEF);
|
||||
* }</pre>
|
||||
* If the bounds check fails then the range check method will throw an
|
||||
* {@code ArrayIndexOutOfBoundsException} with an appropriate exception
|
||||
* message that is a produced from {@code AIOOBEF} as follows:
|
||||
* <pre>{@code
|
||||
* AIOOBEF.apply("checkIndex", List.of(index, limit));
|
||||
* }</pre>
|
||||
*
|
||||
* @param f the exception factory, that produces an exception from a message
|
||||
* where the message is produced and formatted by the returned
|
||||
* exception formatter. If this factory is stateless and side-effect
|
||||
* free then so is the returned formatter.
|
||||
* Exceptions thrown by the factory are relayed to the caller
|
||||
* of the returned formatter.
|
||||
* @param <X> the type of runtime exception to be returned by the given
|
||||
* exception factory and relayed by the exception formatter
|
||||
* @return the out-of-bounds exception formatter
|
||||
*/
|
||||
public static <X extends RuntimeException>
|
||||
BiFunction<String, List<Integer>, X> outOfBoundsExceptionFormatter(Function<String, X> f) {
|
||||
// Use anonymous class to avoid bootstrap issues if this method is
|
||||
// used early in startup
|
||||
return new BiFunction<String, List<Integer>, X>() {
|
||||
@Override
|
||||
public X apply(String checkKind, List<Integer> args) {
|
||||
return f.apply(outOfBoundsMessage(checkKind, args));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String outOfBoundsMessage(String checkKind, List<Integer> args) {
|
||||
if (checkKind == null && args == null) {
|
||||
return String.format("Range check failed");
|
||||
} else if (checkKind == null) {
|
||||
return String.format("Range check failed: %s", args);
|
||||
} else if (args == null) {
|
||||
return String.format("Range check failed: %s", checkKind);
|
||||
}
|
||||
|
||||
int argSize = 0;
|
||||
switch (checkKind) {
|
||||
case "checkIndex":
|
||||
argSize = 2;
|
||||
break;
|
||||
case "checkFromToIndex":
|
||||
case "checkFromIndexSize":
|
||||
argSize = 3;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
// Switch to default if fewer or more arguments than required are supplied
|
||||
switch ((args.size() != argSize) ? "" : checkKind) {
|
||||
case "checkIndex":
|
||||
return String.format("Index %d out-of-bounds for length %d",
|
||||
args.get(0), args.get(1));
|
||||
case "checkFromToIndex":
|
||||
return String.format("Range [%d, %d) out-of-bounds for length %d",
|
||||
args.get(0), args.get(1), args.get(2));
|
||||
case "checkFromIndexSize":
|
||||
return String.format("Range [%d, %<d + %d) out-of-bounds for length %d",
|
||||
args.get(0), args.get(1), args.get(2));
|
||||
default:
|
||||
return String.format("Range check failed: %s %s", checkKind, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the {@code index} is within the bounds of the range from
|
||||
* {@code 0} (inclusive) to {@code length} (exclusive).
|
||||
*
|
||||
* <p>The {@code index} is defined to be out of bounds if any of the
|
||||
* <p>The {@code index} is defined to be out-of-bounds if any of the
|
||||
* following inequalities is true:
|
||||
* <ul>
|
||||
* <li>{@code index < 0}</li>
|
||||
@ -377,14 +526,20 @@ public final class Objects {
|
||||
* <li>{@code length < 0}, which is implied from the former inequalities</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>This method behaves as if {@link #checkIndex(int, int, BiFunction)}
|
||||
* was called with same out-of-bounds arguments and an exception formatter
|
||||
* argument produced from an invocation of
|
||||
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
|
||||
* be more efficient).
|
||||
*
|
||||
* @param index the index
|
||||
* @param length the upper-bound (exclusive) of the range
|
||||
* @return {@code index} if it is within bounds of the range
|
||||
* @throws IndexOutOfBoundsException if the {@code index} is out of bounds
|
||||
* @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
|
||||
* @since 9
|
||||
*/
|
||||
public static
|
||||
int checkIndex(int index, int length) throws IndexOutOfBoundsException {
|
||||
int checkIndex(int index, int length) {
|
||||
return checkIndex(index, length, null);
|
||||
}
|
||||
|
||||
@ -392,7 +547,7 @@ public final class Objects {
|
||||
* Checks if the {@code index} is within the bounds of the range from
|
||||
* {@code 0} (inclusive) to {@code length} (exclusive).
|
||||
*
|
||||
* <p>The {@code index} is defined to be out of bounds if any of the
|
||||
* <p>The {@code index} is defined to be out-of-bounds if any of the
|
||||
* following inequalities is true:
|
||||
* <ul>
|
||||
* <li>{@code index < 0}</li>
|
||||
@ -400,40 +555,42 @@ public final class Objects {
|
||||
* <li>{@code length < 0}, which is implied from the former inequalities</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If the {@code index} is out of bounds, then a runtime exception is
|
||||
* thrown that is the result of applying the arguments {@code index} and
|
||||
* {@code length} to the given exception mapping function.
|
||||
* <p>If the {@code index} is out-of-bounds, then a runtime exception is
|
||||
* thrown that is the result of applying the following arguments to the
|
||||
* exception formatter: the name of this method, {@code checkIndex};
|
||||
* and an unmodifiable list integers whose values are, in order, the
|
||||
* out-of-bounds arguments {@code index} and {@code length}.
|
||||
*
|
||||
* @param <T> the type of runtime exception to throw if the arguments are
|
||||
* out of bounds
|
||||
* @param <X> the type of runtime exception to throw if the arguments are
|
||||
* out-of-bounds
|
||||
* @param index the index
|
||||
* @param length the upper-bound (exclusive) of the range
|
||||
* @param oobe the exception mapping function that when applied with out
|
||||
* of bounds arguments returns a runtime exception. If {@code null}
|
||||
* or returns {@code null} then, it is as if an exception mapping
|
||||
* function was supplied that returns
|
||||
* {@link IndexOutOfBoundsException} for any given arguments.
|
||||
* Exceptions thrown by the function are relayed to the caller.
|
||||
* @param oobef the exception formatter that when applied with this
|
||||
* method name and out-of-bounds arguments returns a runtime
|
||||
* exception. If {@code null} or returns {@code null} then, it is as
|
||||
* if an exception formatter produced from an invocation of
|
||||
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
|
||||
* instead (though it may be more efficient).
|
||||
* Exceptions thrown by the formatter are relayed to the caller.
|
||||
* @return {@code index} if it is within bounds of the range
|
||||
* @throws T if the {@code index} is out of bounds, then a runtime exception
|
||||
* is thrown that is the result of applying the out of bounds
|
||||
* arguments to the exception mapping function.
|
||||
* @throws IndexOutOfBoundsException if the {@code index} is out of bounds
|
||||
* and the exception mapping function is {@code null}
|
||||
* @throws X if the {@code index} is out-of-bounds and the exception
|
||||
* formatter is non-{@code null}
|
||||
* @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
|
||||
* and the exception formatter is {@code null}
|
||||
* @since 9
|
||||
*
|
||||
* @implNote
|
||||
* This method is made intrinsic in optimizing compilers to guide
|
||||
* them to perform unsigned comparisons of the index and length
|
||||
* when it is known the length is a non-negative value (such as
|
||||
* that of an array length or from the upper bound of a loop)
|
||||
* This method is made intrinsic in optimizing compilers to guide them to
|
||||
* perform unsigned comparisons of the index and length when it is known the
|
||||
* length is a non-negative value (such as that of an array length or from
|
||||
* the upper bound of a loop)
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
public static <T extends RuntimeException>
|
||||
public static <X extends RuntimeException>
|
||||
int checkIndex(int index, int length,
|
||||
BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException {
|
||||
BiFunction<String, List<Integer>, X> oobef) {
|
||||
if (index < 0 || index >= length)
|
||||
throw outOfBounds(index, length, oobe);
|
||||
throw outOfBoundsCheckIndex(oobef, index, length);
|
||||
return index;
|
||||
}
|
||||
|
||||
@ -442,7 +599,7 @@ public final class Objects {
|
||||
* {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
|
||||
* (inclusive) to {@code length} (exclusive).
|
||||
*
|
||||
* <p>The sub-range is defined to be out of bounds if any of the following
|
||||
* <p>The sub-range is defined to be out-of-bounds if any of the following
|
||||
* inequalities is true:
|
||||
* <ul>
|
||||
* <li>{@code fromIndex < 0}</li>
|
||||
@ -451,15 +608,21 @@ public final class Objects {
|
||||
* <li>{@code length < 0}, which is implied from the former inequalities</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>This method behaves as if {@link #checkFromToIndex(int, int, int, BiFunction)}
|
||||
* was called with same out-of-bounds arguments and an exception formatter
|
||||
* argument produced from an invocation of
|
||||
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
|
||||
* be more efficient).
|
||||
*
|
||||
* @param fromIndex the lower-bound (inclusive) of the sub-range
|
||||
* @param toIndex the upper-bound (exclusive) of the sub-range
|
||||
* @param length the upper-bound (exclusive) the range
|
||||
* @return {@code fromIndex} if the sub-range within bounds of the range
|
||||
* @throws IndexOutOfBoundsException if the sub-range is out of bounds
|
||||
* @throws IndexOutOfBoundsException if the sub-range is out-of-bounds
|
||||
* @since 9
|
||||
*/
|
||||
public static
|
||||
int checkFromToIndex(int fromIndex, int toIndex, int length) throws IndexOutOfBoundsException {
|
||||
int checkFromToIndex(int fromIndex, int toIndex, int length) {
|
||||
return checkFromToIndex(fromIndex, toIndex, length, null);
|
||||
}
|
||||
|
||||
@ -468,7 +631,7 @@ public final class Objects {
|
||||
* {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
|
||||
* (inclusive) to {@code length} (exclusive).
|
||||
*
|
||||
* <p>The sub-range is defined to be out of bounds if any of the following
|
||||
* <p>The sub-range is defined to be out-of-bounds if any of the following
|
||||
* inequalities is true:
|
||||
* <ul>
|
||||
* <li>{@code fromIndex < 0}</li>
|
||||
@ -477,34 +640,36 @@ public final class Objects {
|
||||
* <li>{@code length < 0}, which is implied from the former inequalities</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If the sub-range is out of bounds, then a runtime exception is thrown
|
||||
* that is the result of applying the arguments {@code fromIndex} and
|
||||
* {@code toIndex} to the given exception mapping function.
|
||||
* <p>If the sub-range is out-of-bounds, then a runtime exception is
|
||||
* thrown that is the result of applying the following arguments to the
|
||||
* exception formatter: the name of this method, {@code checkFromToIndex};
|
||||
* and an unmodifiable list integers whose values are, in order, the
|
||||
* out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}.
|
||||
*
|
||||
* @param <T> the type of runtime exception to throw if the arguments are
|
||||
* out of bounds
|
||||
* @param <X> the type of runtime exception to throw if the arguments are
|
||||
* out-of-bounds
|
||||
* @param fromIndex the lower-bound (inclusive) of the sub-range
|
||||
* @param toIndex the upper-bound (exclusive) of the sub-range
|
||||
* @param length the upper-bound (exclusive) the range
|
||||
* @param oobe the exception mapping function that when applied with out
|
||||
* of bounds arguments returns a runtime exception. If {@code null}
|
||||
* or returns {@code null} then, it is as if an exception mapping
|
||||
* function was supplied that returns
|
||||
* {@link IndexOutOfBoundsException} for any given arguments.
|
||||
* Exceptions thrown by the function are relayed to the caller.
|
||||
* @param oobef the exception formatter that when applied with this
|
||||
* method name and out-of-bounds arguments returns a runtime
|
||||
* exception. If {@code null} or returns {@code null} then, it is as
|
||||
* if an exception formatter produced from an invocation of
|
||||
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
|
||||
* instead (though it may be more efficient).
|
||||
* Exceptions thrown by the formatter are relayed to the caller.
|
||||
* @return {@code fromIndex} if the sub-range within bounds of the range
|
||||
* @throws T if the sub-range is out of bounds, then a runtime exception is
|
||||
* thrown that is the result of applying the out of bounds arguments
|
||||
* to the exception mapping function.
|
||||
* @throws IndexOutOfBoundsException if the sub-range is out of bounds and
|
||||
* the exception mapping function is {@code null}
|
||||
* @throws X if the sub-range is out-of-bounds and the exception factory
|
||||
* function is non-{@code null}
|
||||
* @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
|
||||
* the exception factory function is {@code null}
|
||||
* @since 9
|
||||
*/
|
||||
public static <T extends RuntimeException>
|
||||
public static <X extends RuntimeException>
|
||||
int checkFromToIndex(int fromIndex, int toIndex, int length,
|
||||
BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException {
|
||||
BiFunction<String, List<Integer>, X> oobef) {
|
||||
if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
|
||||
throw outOfBounds(fromIndex, toIndex, oobe);
|
||||
throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length);
|
||||
return fromIndex;
|
||||
}
|
||||
|
||||
@ -513,7 +678,7 @@ public final class Objects {
|
||||
* {@code fromIndex + size} (exclusive) is within the bounds of range from
|
||||
* {@code 0} (inclusive) to {@code length} (exclusive).
|
||||
*
|
||||
* <p>The sub-range is defined to be out of bounds if any of the following
|
||||
* <p>The sub-range is defined to be out-of-bounds if any of the following
|
||||
* inequalities is true:
|
||||
* <ul>
|
||||
* <li>{@code fromIndex < 0}</li>
|
||||
@ -522,15 +687,21 @@ public final class Objects {
|
||||
* <li>{@code length < 0}, which is implied from the former inequalities</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>This method behaves as if {@link #checkFromIndexSize(int, int, int, BiFunction)}
|
||||
* was called with same out-of-bounds arguments and an exception formatter
|
||||
* argument produced from an invocation of
|
||||
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
|
||||
* be more efficient).
|
||||
*
|
||||
* @param fromIndex the lower-bound (inclusive) of the sub-interval
|
||||
* @param size the size of the sub-range
|
||||
* @param length the upper-bound (exclusive) of the range
|
||||
* @return {@code fromIndex} if the sub-range within bounds of the range
|
||||
* @throws IndexOutOfBoundsException if the sub-range is out of bounds
|
||||
* @throws IndexOutOfBoundsException if the sub-range is out-of-bounds
|
||||
* @since 9
|
||||
*/
|
||||
public static
|
||||
int checkFromIndexSize(int fromIndex, int size, int length) throws IndexOutOfBoundsException {
|
||||
int checkFromIndexSize(int fromIndex, int size, int length) {
|
||||
return checkFromIndexSize(fromIndex, size, length, null);
|
||||
}
|
||||
|
||||
@ -539,7 +710,7 @@ public final class Objects {
|
||||
* {@code fromIndex + size} (exclusive) is within the bounds of range from
|
||||
* {@code 0} (inclusive) to {@code length} (exclusive).
|
||||
*
|
||||
* <p>The sub-range is defined to be out of bounds if any of the following
|
||||
* <p>The sub-range is defined to be out-of-bounds if any of the following
|
||||
* inequalities is true:
|
||||
* <ul>
|
||||
* <li>{@code fromIndex < 0}</li>
|
||||
@ -548,34 +719,37 @@ public final class Objects {
|
||||
* <li>{@code length < 0}, which is implied from the former inequalities</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If the sub-range is out of bounds then, a runtime exception is thrown
|
||||
* that is the result of applying the arguments {@code fromIndex} and
|
||||
* {@code size} to the given exception mapping function.
|
||||
* <p>If the sub-range is out-of-bounds, then a runtime exception is
|
||||
* thrown that is the result of applying the following arguments to the
|
||||
* exception formatter: the name of this method, {@code checkFromIndexSize};
|
||||
* and an unmodifiable list integers whose values are, in order, the
|
||||
* out-of-bounds arguments {@code fromIndex}, {@code size}, and
|
||||
* {@code length}.
|
||||
*
|
||||
* @param <T> the type of runtime exception to throw if the arguments are
|
||||
* out of bounds
|
||||
* @param <X> the type of runtime exception to throw if the arguments are
|
||||
* out-of-bounds
|
||||
* @param fromIndex the lower-bound (inclusive) of the sub-interval
|
||||
* @param size the size of the sub-range
|
||||
* @param length the upper-bound (exclusive) of the range
|
||||
* @param oobe the exception mapping function that when applied with out
|
||||
* of bounds arguments returns a runtime exception. If {@code null}
|
||||
* or returns {@code null} then, it is as if an exception mapping
|
||||
* function was supplied that returns
|
||||
* {@link IndexOutOfBoundsException} for any given arguments.
|
||||
* Exceptions thrown by the function are relayed to the caller.
|
||||
* @param oobef the exception formatter that when applied with this
|
||||
* method name and out-of-bounds arguments returns a runtime
|
||||
* exception. If {@code null} or returns {@code null} then, it is as
|
||||
* if an exception formatter produced from an invocation of
|
||||
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
|
||||
* instead (though it may be more efficient).
|
||||
* Exceptions thrown by the formatter are relayed to the caller.
|
||||
* @return {@code fromIndex} if the sub-range within bounds of the range
|
||||
* @throws T if the sub-range is out of bounds, then a runtime exception is
|
||||
* thrown that is the result of applying the out of bounds arguments
|
||||
* to the exception mapping function.
|
||||
* @throws IndexOutOfBoundsException if the sub-range is out of bounds and
|
||||
* the exception mapping function is {@code null}
|
||||
* @throws X if the sub-range is out-of-bounds and the exception factory
|
||||
* function is non-{@code null}
|
||||
* @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
|
||||
* the exception factory function is {@code null}
|
||||
* @since 9
|
||||
*/
|
||||
public static <T extends RuntimeException>
|
||||
public static <X extends RuntimeException>
|
||||
int checkFromIndexSize(int fromIndex, int size, int length,
|
||||
BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException {
|
||||
BiFunction<String, List<Integer>, X> oobef) {
|
||||
if ((length | fromIndex | size) < 0 || size > length - fromIndex)
|
||||
throw outOfBounds(fromIndex, size, oobe);
|
||||
throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
|
||||
return fromIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -894,7 +894,8 @@ class JarFile extends ZipFile {
|
||||
private static final byte[] CLASSPATH_LASTOCC;
|
||||
|
||||
private static final byte[] MULTIRELEASE_CHARS =
|
||||
{'M','U','L','T','I','-','R','E','L','E', 'A', 'S', 'E', ':', ' '};
|
||||
{'M','U','L','T','I','-','R','E','L','E', 'A', 'S', 'E', ':',
|
||||
' ', 'T', 'R', 'U', 'E'};
|
||||
|
||||
// The bad character shift for "multi-release: "
|
||||
private static final byte[] MULTIRELEASE_LASTOCC;
|
||||
@ -914,17 +915,17 @@ class JarFile extends ZipFile {
|
||||
|
||||
MULTIRELEASE_LASTOCC = new byte[64];
|
||||
MULTIRELEASE_LASTOCC[(int)'M' - 32] = 1;
|
||||
MULTIRELEASE_LASTOCC[(int)'U' - 32] = 2;
|
||||
MULTIRELEASE_LASTOCC[(int)'T' - 32] = 4;
|
||||
MULTIRELEASE_LASTOCC[(int)'I' - 32] = 5;
|
||||
MULTIRELEASE_LASTOCC[(int)'-' - 32] = 6;
|
||||
MULTIRELEASE_LASTOCC[(int)'R' - 32] = 7;
|
||||
MULTIRELEASE_LASTOCC[(int)'L' - 32] = 9;
|
||||
MULTIRELEASE_LASTOCC[(int)'A' - 32] = 11;
|
||||
MULTIRELEASE_LASTOCC[(int)'S' - 32] = 12;
|
||||
MULTIRELEASE_LASTOCC[(int)'E' - 32] = 13;
|
||||
MULTIRELEASE_LASTOCC[(int)':' - 32] = 14;
|
||||
MULTIRELEASE_LASTOCC[(int)' ' - 32] = 15;
|
||||
MULTIRELEASE_LASTOCC[(int)'T' - 32] = 16;
|
||||
MULTIRELEASE_LASTOCC[(int)'R' - 32] = 17;
|
||||
MULTIRELEASE_LASTOCC[(int)'U' - 32] = 18;
|
||||
MULTIRELEASE_LASTOCC[(int)'E' - 32] = 19;
|
||||
}
|
||||
|
||||
private JarEntry getManEntry() {
|
||||
@ -966,7 +967,7 @@ class JarFile extends ZipFile {
|
||||
* Since there are no repeated substring in our search strings,
|
||||
* the good suffix shifts can be replaced with a comparison.
|
||||
*/
|
||||
private boolean match(byte[] src, byte[] b, byte[] lastOcc) {
|
||||
private int match(byte[] src, byte[] b, byte[] lastOcc) {
|
||||
int len = src.length;
|
||||
int last = b.length - len;
|
||||
int i = 0;
|
||||
@ -990,9 +991,9 @@ class JarFile extends ZipFile {
|
||||
continue next;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return i;
|
||||
}
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1011,11 +1012,35 @@ class JarFile extends ZipFile {
|
||||
if (manEntry != null) {
|
||||
byte[] b = getBytes(manEntry);
|
||||
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
|
||||
CLASSPATH_LASTOCC);
|
||||
CLASSPATH_LASTOCC) != -1;
|
||||
// is this a multi-release jar file
|
||||
if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) {
|
||||
isMultiRelease = match(MULTIRELEASE_CHARS, b,
|
||||
MULTIRELEASE_LASTOCC);
|
||||
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
|
||||
if (i != -1) {
|
||||
i += MULTIRELEASE_CHARS.length;
|
||||
if (i < b.length) {
|
||||
byte c = b[i++];
|
||||
// Check that the value is followed by a newline
|
||||
// and does not have a continuation
|
||||
if (c == '\n' &&
|
||||
(i == b.length || b[i] != ' ')) {
|
||||
isMultiRelease = true;
|
||||
} else if (c == '\r') {
|
||||
if (i == b.length) {
|
||||
isMultiRelease = true;
|
||||
} else {
|
||||
c = b[i++];
|
||||
if (c == '\n') {
|
||||
if (i == b.length || b[i] != ' ') {
|
||||
isMultiRelease = true;
|
||||
}
|
||||
} else if (c != ' ') {
|
||||
isMultiRelease = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hasCheckedSpecialAttributes = true;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -480,7 +480,8 @@ public class Cipher {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -114,7 +114,8 @@ public class ExemptionMechanism {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -152,7 +152,8 @@ public class KeyAgreement {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -204,7 +204,8 @@ public class KeyGenerator {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -154,7 +154,8 @@ public class Mac implements Cloneable {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -139,7 +139,8 @@ public class SecretKeyFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -118,7 +118,8 @@ public class KeyManagerFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -138,7 +138,8 @@ public class SSLContext {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -132,7 +132,8 @@ public class TrustManagerFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -313,7 +313,8 @@ public abstract class Configuration {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -288,22 +288,24 @@ public class BasicImageReader implements AutoCloseable {
|
||||
|
||||
return buffer;
|
||||
} else {
|
||||
if (channel == null) {
|
||||
throw new InternalError("Image file channel not open");
|
||||
}
|
||||
|
||||
ByteBuffer buffer = ImageBufferCache.getBuffer(size);
|
||||
int read = 0;
|
||||
|
||||
int read;
|
||||
try {
|
||||
if (channel == null) {
|
||||
throw new InternalError("Image file channel not open");
|
||||
}
|
||||
|
||||
read = channel.read(buffer, offset);
|
||||
buffer.rewind();
|
||||
} catch (IOException ex) {
|
||||
ImageBufferCache.releaseBuffer(buffer);
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
if (read != size) {
|
||||
ImageBufferCache.releaseBuffer(buffer);
|
||||
throw new RuntimeException("Short read: " + read +
|
||||
" instead of " + size + " bytes");
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
||||
@ -24,110 +24,112 @@
|
||||
*/
|
||||
package jdk.internal.jimage;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @implNote This class needs to maintain JDK 8 source compatibility.
|
||||
*
|
||||
* It is used internally in the JDK to implement jimage/jrtfs access,
|
||||
* but also compiled and delivered as part of the jrtfs.jar to support access
|
||||
* but also compiled and delivered as part of the jrt-fs.jar to support access
|
||||
* to the jimage file provided by the shipped JDK by tools running on JDK 8.
|
||||
*/
|
||||
class ImageBufferCache {
|
||||
private static final int MAX_FREE_BUFFERS = 3;
|
||||
private static final int MAX_CACHED_BUFFERS = 3;
|
||||
private static final int LARGE_BUFFER = 0x10000;
|
||||
private static final ThreadLocal<ArrayList<ImageBufferCache>>
|
||||
threadLocal = new ThreadLocal<>();
|
||||
private static final ThreadLocal<BufferReference[]> CACHE =
|
||||
new ThreadLocal<BufferReference[]>() {
|
||||
@Override
|
||||
protected BufferReference[] initialValue() {
|
||||
// 1 extra slot to simplify logic of releaseBuffer()
|
||||
return new BufferReference[MAX_CACHED_BUFFERS + 1];
|
||||
}
|
||||
};
|
||||
|
||||
private final ByteBuffer buffer;
|
||||
private boolean isUsed;
|
||||
private static ByteBuffer allocateBuffer(long size) {
|
||||
return ByteBuffer.allocateDirect((int)((size + 0xFFF) & ~0xFFF));
|
||||
}
|
||||
|
||||
static ByteBuffer getBuffer(long size) {
|
||||
if (size < 0 || Integer.MAX_VALUE < size) {
|
||||
throw new IndexOutOfBoundsException("size");
|
||||
}
|
||||
|
||||
ByteBuffer buffer = null;
|
||||
ByteBuffer result = null;
|
||||
|
||||
if (size > LARGE_BUFFER) {
|
||||
buffer = ByteBuffer.allocateDirect((int)((size + 0xFFF) & ~0xFFF));
|
||||
result = allocateBuffer(size);
|
||||
} else {
|
||||
ArrayList<ImageBufferCache> buffers = threadLocal.get();
|
||||
BufferReference[] cache = CACHE.get();
|
||||
|
||||
if (buffers == null) {
|
||||
buffers = new ArrayList<>(MAX_FREE_BUFFERS);
|
||||
threadLocal.set(buffers);
|
||||
}
|
||||
// buffers are ordered by decreasing capacity
|
||||
// cache[MAX_CACHED_BUFFERS] is always null
|
||||
for (int i = MAX_CACHED_BUFFERS - 1; i >= 0; i--) {
|
||||
BufferReference reference = cache[i];
|
||||
|
||||
int i = 0, j = buffers.size();
|
||||
for (ImageBufferCache imageBuffer : buffers) {
|
||||
if (size <= imageBuffer.capacity()) {
|
||||
j = i;
|
||||
|
||||
if (!imageBuffer.isUsed) {
|
||||
imageBuffer.isUsed = true;
|
||||
buffer = imageBuffer.buffer;
|
||||
if (reference != null) {
|
||||
ByteBuffer buffer = reference.get();
|
||||
|
||||
if (buffer != null && size <= buffer.capacity()) {
|
||||
cache[i] = null;
|
||||
result = buffer;
|
||||
result.rewind();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (buffer == null) {
|
||||
ImageBufferCache imageBuffer = new ImageBufferCache((int)size);
|
||||
buffers.add(j, imageBuffer);
|
||||
buffer = imageBuffer.buffer;
|
||||
if (result == null) {
|
||||
result = allocateBuffer(size);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.rewind();
|
||||
buffer.limit((int)size);
|
||||
result.limit((int)size);
|
||||
|
||||
return buffer;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void releaseBuffer(ByteBuffer buffer) {
|
||||
ArrayList<ImageBufferCache> buffers = threadLocal.get();
|
||||
|
||||
if (buffers == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer.capacity() > LARGE_BUFFER) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0, j = buffers.size();
|
||||
for (ImageBufferCache imageBuffer : buffers) {
|
||||
if (!imageBuffer.isUsed) {
|
||||
j = Math.min(j, i);
|
||||
}
|
||||
BufferReference[] cache = CACHE.get();
|
||||
|
||||
if (imageBuffer.buffer == buffer) {
|
||||
imageBuffer.isUsed = false;
|
||||
j = Math.min(j, i);
|
||||
|
||||
break;
|
||||
// expunge cleared BufferRef(s)
|
||||
for (int i = 0; i < MAX_CACHED_BUFFERS; i++) {
|
||||
BufferReference reference = cache[i];
|
||||
if (reference != null && reference.get() == null) {
|
||||
cache[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffers.size() > MAX_FREE_BUFFERS && j != buffers.size()) {
|
||||
buffers.remove(j);
|
||||
// insert buffer back with new BufferRef wrapping it
|
||||
cache[MAX_CACHED_BUFFERS] = new BufferReference(buffer);
|
||||
Arrays.sort(cache, DECREASING_CAPACITY_NULLS_LAST);
|
||||
// squeeze the smallest one out
|
||||
cache[MAX_CACHED_BUFFERS] = null;
|
||||
}
|
||||
|
||||
private static Comparator<BufferReference> DECREASING_CAPACITY_NULLS_LAST =
|
||||
new Comparator<BufferReference>() {
|
||||
@Override
|
||||
public int compare(BufferReference br1, BufferReference br2) {
|
||||
return Integer.compare(br2 == null ? 0 : br2.capacity,
|
||||
br1 == null ? 0 : br1.capacity);
|
||||
}
|
||||
};
|
||||
|
||||
private static class BufferReference extends WeakReference<ByteBuffer> {
|
||||
// saved capacity so that DECREASING_CAPACITY_NULLS_LAST comparator
|
||||
// is stable in the presence of GC clearing the WeakReference concurrently
|
||||
final int capacity;
|
||||
|
||||
BufferReference(ByteBuffer buffer) {
|
||||
super(buffer);
|
||||
capacity = buffer.capacity();
|
||||
}
|
||||
}
|
||||
|
||||
private ImageBufferCache(int needed) {
|
||||
this.buffer = ByteBuffer.allocateDirect((needed + 0xFFF) & ~0xFFF);
|
||||
this.isUsed = true;
|
||||
this.buffer.limit(needed);
|
||||
}
|
||||
|
||||
private long capacity() {
|
||||
return buffer.capacity();
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,9 @@
|
||||
|
||||
package sun.nio.fs;
|
||||
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.spi.FileSystemProvider;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@ -34,7 +36,7 @@ import java.util.Map;
|
||||
* Base implementation class of FileSystemProvider
|
||||
*/
|
||||
|
||||
abstract class AbstractFileSystemProvider extends FileSystemProvider {
|
||||
public abstract class AbstractFileSystemProvider extends FileSystemProvider {
|
||||
protected AbstractFileSystemProvider() { }
|
||||
|
||||
/**
|
||||
@ -107,4 +109,49 @@ abstract class AbstractFileSystemProvider extends FileSystemProvider {
|
||||
public final boolean deleteIfExists(Path file) throws IOException {
|
||||
return implDelete(file, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a file is a directory.
|
||||
*
|
||||
* @return {@code true} if the file is a directory; {@code false} if
|
||||
* the file does not exist, is not a directory, or it cannot
|
||||
* be determined if the file is a directory or not.
|
||||
*/
|
||||
public boolean isDirectory(Path file) {
|
||||
try {
|
||||
return readAttributes(file, BasicFileAttributes.class).isDirectory();
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a file is a regular file with opaque content.
|
||||
*
|
||||
* @return {@code true} if the file is a regular file; {@code false} if
|
||||
* the file does not exist, is not a regular file, or it
|
||||
* cannot be determined if the file is a regular file or not.
|
||||
*/
|
||||
public boolean isRegularFile(Path file) {
|
||||
try {
|
||||
return readAttributes(file, BasicFileAttributes.class).isRegularFile();
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the existence of a file.
|
||||
*
|
||||
* @return {@code true} if the file exists; {@code false} if the file does
|
||||
* not exist or its existence cannot be determined.
|
||||
*/
|
||||
public boolean exists(Path file) {
|
||||
try {
|
||||
checkAccess(file);
|
||||
return true;
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -171,11 +171,8 @@ JVM_IsSupportedJNIVersion(jint version);
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable);
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index);
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray elements);
|
||||
|
||||
/*
|
||||
* java.lang.StackWalker
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -50,15 +50,9 @@ Java_java_lang_Throwable_fillInStackTrace(JNIEnv *env, jobject throwable, jint d
|
||||
return throwable;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_java_lang_Throwable_getStackTraceDepth(JNIEnv *env, jobject throwable)
|
||||
JNIEXPORT void JNICALL
|
||||
Java_java_lang_Throwable_getStackTraceElements(JNIEnv *env,
|
||||
jobject throwable, jobjectArray elements)
|
||||
{
|
||||
return JVM_GetStackTraceDepth(env, throwable);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_java_lang_Throwable_getStackTraceElement(JNIEnv *env,
|
||||
jobject throwable, jint index)
|
||||
{
|
||||
return JVM_GetStackTraceElement(env, throwable, index);
|
||||
JVM_GetStackTraceElements(env, throwable, elements);
|
||||
}
|
||||
|
||||
@ -499,6 +499,29 @@ public abstract class UnixFileSystemProvider
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isDirectory(Path obj) {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
file.checkRead();
|
||||
int mode = UnixNativeDispatcher.stat(file);
|
||||
return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isRegularFile(Path obj) {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
file.checkRead();
|
||||
int mode = UnixNativeDispatcher.stat(file);
|
||||
return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean exists(Path obj) {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
file.checkRead();
|
||||
return UnixNativeDispatcher.exists(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code FileTypeDetector} for this platform.
|
||||
*/
|
||||
|
||||
@ -296,6 +296,23 @@ class UnixNativeDispatcher {
|
||||
private static native void stat0(long pathAddress, UnixFileAttributes attrs)
|
||||
throws UnixException;
|
||||
|
||||
|
||||
/**
|
||||
* stat(const char* path, struct stat* buf)
|
||||
*
|
||||
* @return st_mode (file type and mode) or 0 if an error occurs.
|
||||
*/
|
||||
static int stat(UnixPath path) {
|
||||
NativeBuffer buffer = copyToNativeBuffer(path);
|
||||
try {
|
||||
return stat1(buffer.address());
|
||||
} finally {
|
||||
buffer.release();
|
||||
}
|
||||
}
|
||||
private static native int stat1(long pathAddress);
|
||||
|
||||
|
||||
/**
|
||||
* lstat(const char* path, struct stat* buf)
|
||||
*/
|
||||
@ -458,6 +475,22 @@ class UnixNativeDispatcher {
|
||||
}
|
||||
private static native void access0(long pathAddress, int amode) throws UnixException;
|
||||
|
||||
/**
|
||||
* access(constant char* path, F_OK)
|
||||
*
|
||||
* @return true if the file exists, false otherwise
|
||||
*/
|
||||
static boolean exists(UnixPath path) {
|
||||
NativeBuffer buffer = copyToNativeBuffer(path);
|
||||
try {
|
||||
return exists0(buffer.address());
|
||||
} finally {
|
||||
buffer.release();
|
||||
}
|
||||
}
|
||||
private static native boolean exists0(long pathAddress);
|
||||
|
||||
|
||||
/**
|
||||
* struct passwd *getpwuid(uid_t uid);
|
||||
*
|
||||
|
||||
@ -114,12 +114,9 @@ class UnixUriUtils {
|
||||
|
||||
// trailing slash if directory
|
||||
if (sb.charAt(sb.length()-1) != '/') {
|
||||
try {
|
||||
if (UnixFileAttributes.get(up, true).isDirectory())
|
||||
sb.append('/');
|
||||
} catch (UnixException x) {
|
||||
// ignore
|
||||
}
|
||||
int mode = UnixNativeDispatcher.stat(up);
|
||||
if ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR)
|
||||
sb.append('/');
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@ -483,6 +483,20 @@ Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_stat1(JNIEnv* env, jclass this, jlong pathAddress) {
|
||||
int err;
|
||||
struct stat64 buf;
|
||||
const char* path = (const char*)jlong_to_ptr(pathAddress);
|
||||
|
||||
RESTARTABLE(stat64(path, &buf), err);
|
||||
if (err == -1) {
|
||||
return 0;
|
||||
} else {
|
||||
return (jint)buf.st_mode;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this,
|
||||
jlong pathAddress, jobject attrs)
|
||||
@ -897,6 +911,14 @@ Java_sun_nio_fs_UnixNativeDispatcher_access0(JNIEnv* env, jclass this,
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_exists0(JNIEnv* env, jclass this, jlong pathAddress) {
|
||||
int err;
|
||||
const char* path = (const char*)jlong_to_ptr(pathAddress);
|
||||
RESTARTABLE(access(path, F_OK), err);
|
||||
return (err == 0) ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
|
||||
jlong pathAddress, jobject attrs)
|
||||
|
||||
@ -26,6 +26,7 @@ package java.net;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* This class defines a factory for creating DatagramSocketImpls. It defaults
|
||||
@ -47,64 +48,30 @@ class DefaultDatagramSocketImplFactory
|
||||
{
|
||||
private static final Class<?> prefixImplClass;
|
||||
|
||||
/* the windows version. */
|
||||
private static float version;
|
||||
|
||||
/* java.net.preferIPv4Stack */
|
||||
private static boolean preferIPv4Stack = false;
|
||||
|
||||
/* If the version supports a dual stack TCP implementation */
|
||||
private static final boolean useDualStackImpl;
|
||||
|
||||
/* sun.net.useExclusiveBind */
|
||||
private static String exclBindProp;
|
||||
private static final boolean preferIPv4Stack;
|
||||
|
||||
/* True if exclusive binding is on for Windows */
|
||||
private static final boolean exclusiveBind;
|
||||
|
||||
static {
|
||||
Class<?> prefixImplClassLocal = null;
|
||||
boolean useDualStackImplLocal = false;
|
||||
boolean exclusiveBindLocal = true;
|
||||
|
||||
// Determine Windows Version.
|
||||
java.security.AccessController.doPrivileged(
|
||||
new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
version = 0;
|
||||
try {
|
||||
version = Float.parseFloat(System.getProperties()
|
||||
.getProperty("os.version"));
|
||||
preferIPv4Stack = Boolean.parseBoolean(
|
||||
System.getProperties()
|
||||
.getProperty(
|
||||
"java.net.preferIPv4Stack"));
|
||||
exclBindProp = System.getProperty(
|
||||
"sun.net.useExclusiveBind");
|
||||
} catch (NumberFormatException e) {
|
||||
assert false : e;
|
||||
}
|
||||
return null; // nothing to return
|
||||
}
|
||||
});
|
||||
preferIPv4Stack = Boolean.parseBoolean(
|
||||
AccessController.doPrivileged(
|
||||
new GetPropertyAction("java.net.preferIPv4Stack")));
|
||||
|
||||
// (version >= 6.0) implies Vista or greater.
|
||||
if (version >= 6.0 && !preferIPv4Stack) {
|
||||
useDualStackImplLocal = true;
|
||||
}
|
||||
if (exclBindProp != null) {
|
||||
// sun.net.useExclusiveBind is true
|
||||
exclusiveBindLocal = exclBindProp.length() == 0 ? true
|
||||
: Boolean.parseBoolean(exclBindProp);
|
||||
} else if (version < 6.0) {
|
||||
exclusiveBindLocal = false;
|
||||
}
|
||||
String exclBindProp = AccessController.doPrivileged(
|
||||
new GetPropertyAction("sun.net.useExclusiveBind", ""));
|
||||
exclusiveBind = (exclBindProp.isEmpty())
|
||||
? true
|
||||
: Boolean.parseBoolean(exclBindProp);
|
||||
|
||||
// impl.prefix
|
||||
String prefix = null;
|
||||
try {
|
||||
prefix = AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("impl.prefix", null));
|
||||
new GetPropertyAction("impl.prefix", null));
|
||||
if (prefix != null)
|
||||
prefixImplClassLocal = Class.forName("java.net."+prefix+"DatagramSocketImpl");
|
||||
} catch (Exception e) {
|
||||
@ -114,8 +81,6 @@ class DefaultDatagramSocketImplFactory
|
||||
}
|
||||
|
||||
prefixImplClass = prefixImplClassLocal;
|
||||
useDualStackImpl = useDualStackImplLocal;
|
||||
exclusiveBind = exclusiveBindLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,7 +98,7 @@ class DefaultDatagramSocketImplFactory
|
||||
throw new SocketException("can't instantiate DatagramSocketImpl");
|
||||
}
|
||||
} else {
|
||||
if (useDualStackImpl && !isMulticast)
|
||||
if (!preferIPv4Stack && !isMulticast)
|
||||
return new DualStackPlainDatagramSocketImpl(exclusiveBind);
|
||||
else
|
||||
return new TwoStacksPlainDatagramSocketImpl(exclusiveBind && !isMulticast);
|
||||
|
||||
@ -79,7 +79,7 @@ class WindowsFileAttributeViews {
|
||||
long handle = -1L;
|
||||
try {
|
||||
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
if (!followLinks && file.getFileSystem().supportsLinks())
|
||||
if (!followLinks)
|
||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
|
||||
handle = CreateFile(file.getPathForWin32Calls(),
|
||||
|
||||
@ -168,9 +168,7 @@ class WindowsFileCopy {
|
||||
|
||||
// Use CopyFileEx if the file is not a directory or junction
|
||||
if (!sourceAttrs.isDirectory() && !sourceAttrs.isDirectoryLink()) {
|
||||
final int flags =
|
||||
(source.getFileSystem().supportsLinks() && !followLinks) ?
|
||||
COPY_FILE_COPY_SYMLINK : 0;
|
||||
final int flags = (!followLinks) ? COPY_FILE_COPY_SYMLINK : 0;
|
||||
|
||||
if (interruptible) {
|
||||
// interruptible copy
|
||||
|
||||
@ -78,14 +78,7 @@ class WindowsFileStore
|
||||
// if the file is a link then GetVolumePathName returns the
|
||||
// volume that the link is on so we need to call it with the
|
||||
// final target
|
||||
String target;
|
||||
if (file.getFileSystem().supportsLinks()) {
|
||||
target = WindowsLinkSupport.getFinalPath(file, true);
|
||||
} else {
|
||||
// file must exist
|
||||
WindowsFileAttributes.get(file, true);
|
||||
target = file.getPathForWin32Calls();
|
||||
}
|
||||
String target = WindowsLinkSupport.getFinalPath(file, true);
|
||||
try {
|
||||
return createFromPath(target);
|
||||
} catch (WindowsException e) {
|
||||
|
||||
@ -31,9 +31,6 @@ import java.nio.file.spi.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
class WindowsFileSystem
|
||||
extends FileSystem
|
||||
@ -44,9 +41,6 @@ class WindowsFileSystem
|
||||
private final String defaultDirectory;
|
||||
private final String defaultRoot;
|
||||
|
||||
private final boolean supportsLinks;
|
||||
private final boolean supportsStreamEnumeration;
|
||||
|
||||
// package-private
|
||||
WindowsFileSystem(WindowsFileSystemProvider provider,
|
||||
String dir)
|
||||
@ -61,18 +55,6 @@ class WindowsFileSystem
|
||||
throw new AssertionError("Default directory is not an absolute path");
|
||||
this.defaultDirectory = result.path();
|
||||
this.defaultRoot = result.root();
|
||||
|
||||
PrivilegedAction<String> pa = new GetPropertyAction("os.version");
|
||||
String osversion = AccessController.doPrivileged(pa);
|
||||
String[] vers = Util.split(osversion, '.');
|
||||
int major = Integer.parseInt(vers[0]);
|
||||
int minor = Integer.parseInt(vers[1]);
|
||||
|
||||
// symbolic links available on Vista and newer
|
||||
supportsLinks = (major >= 6);
|
||||
|
||||
// enumeration of data streams available on Windows Server 2003 and newer
|
||||
supportsStreamEnumeration = (major >= 6) || (major == 5 && minor >= 2);
|
||||
}
|
||||
|
||||
// package-private
|
||||
@ -84,14 +66,6 @@ class WindowsFileSystem
|
||||
return defaultRoot;
|
||||
}
|
||||
|
||||
boolean supportsLinks() {
|
||||
return supportsLinks;
|
||||
}
|
||||
|
||||
boolean supportsStreamEnumeration() {
|
||||
return supportsStreamEnumeration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSystemProvider provider() {
|
||||
return provider;
|
||||
|
||||
@ -526,11 +526,6 @@ public class WindowsFileSystemProvider
|
||||
WindowsPath link = WindowsPath.toWindowsPath(obj1);
|
||||
WindowsPath target = WindowsPath.toWindowsPath(obj2);
|
||||
|
||||
if (!link.getFileSystem().supportsLinks()) {
|
||||
throw new UnsupportedOperationException("Symbolic links not supported "
|
||||
+ "on this operating system");
|
||||
}
|
||||
|
||||
// no attributes allowed
|
||||
if (attrs.length > 0) {
|
||||
WindowsSecurityDescriptor.fromAttribute(attrs); // may throw NPE or UOE
|
||||
@ -614,9 +609,6 @@ public class WindowsFileSystemProvider
|
||||
public Path readSymbolicLink(Path obj1) throws IOException {
|
||||
WindowsPath link = WindowsPath.toWindowsPath(obj1);
|
||||
WindowsFileSystem fs = link.getFileSystem();
|
||||
if (!fs.supportsLinks()) {
|
||||
throw new UnsupportedOperationException("symbolic links not supported");
|
||||
}
|
||||
|
||||
// permission check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
|
||||
@ -96,7 +96,7 @@ class WindowsLinkSupport {
|
||||
WindowsFileSystem fs = input.getFileSystem();
|
||||
try {
|
||||
// if not following links then don't need final path
|
||||
if (!followLinks || !fs.supportsLinks())
|
||||
if (!followLinks)
|
||||
return input.getPathForWin32Calls();
|
||||
|
||||
// if file is not a sym link then don't need final path
|
||||
@ -157,8 +157,6 @@ class WindowsLinkSupport {
|
||||
throws IOException
|
||||
{
|
||||
WindowsFileSystem fs = input.getFileSystem();
|
||||
if (resolveLinks && !fs.supportsLinks())
|
||||
resolveLinks = false;
|
||||
|
||||
// Start with absolute path
|
||||
String path = null;
|
||||
|
||||
@ -1071,54 +1071,6 @@ class WindowsNativeDispatcher {
|
||||
static native int GetOverlappedResult(long hFile, long lpOverlapped)
|
||||
throws WindowsException;
|
||||
|
||||
/**
|
||||
* BackupRead(
|
||||
* HANDLE hFile,
|
||||
* LPBYTE lpBuffer,
|
||||
* DWORD nNumberOfBytesToRead,
|
||||
* LPDWORD lpNumberOfBytesRead,
|
||||
* BOOL bAbort,
|
||||
* BOOL bProcessSecurity,
|
||||
* LPVOID* lpContext
|
||||
* )
|
||||
*/
|
||||
static BackupResult BackupRead(long hFile,
|
||||
long bufferAddress,
|
||||
int bufferSize,
|
||||
boolean abort,
|
||||
long context)
|
||||
throws WindowsException
|
||||
{
|
||||
BackupResult result = new BackupResult();
|
||||
BackupRead0(hFile, bufferAddress, bufferSize, abort, context, result);
|
||||
return result;
|
||||
}
|
||||
static class BackupResult {
|
||||
private int bytesTransferred;
|
||||
private long context;
|
||||
private BackupResult() { }
|
||||
|
||||
int bytesTransferred() { return bytesTransferred; }
|
||||
long context() { return context; }
|
||||
}
|
||||
private static native void BackupRead0(long hFile, long bufferAddress,
|
||||
int bufferSize, boolean abort, long context, BackupResult result)
|
||||
throws WindowsException;
|
||||
|
||||
/**
|
||||
* BackupSeek(
|
||||
* HANDLE hFile,
|
||||
* DWORD dwLowBytesToSeek,
|
||||
* DWORD dwHighBytesToSeek,
|
||||
* LPDWORD lpdwLowByteSeeked,
|
||||
* LPDWORD lpdwHighByteSeeked,
|
||||
* LPVOID* lpContext
|
||||
* )
|
||||
*/
|
||||
static native void BackupSeek(long hFile, long bytesToSeek, long context)
|
||||
throws WindowsException;
|
||||
|
||||
|
||||
// -- support for copying String with a NativeBuffer --
|
||||
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
@ -780,7 +780,7 @@ class WindowsPath implements Path {
|
||||
throws WindowsException
|
||||
{
|
||||
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
if (!followLinks && getFileSystem().supportsLinks())
|
||||
if (!followLinks)
|
||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
return CreateFile(getPathForWin32Calls(),
|
||||
FILE_READ_ATTRIBUTES,
|
||||
|
||||
@ -91,121 +91,11 @@ class WindowsUserDefinedFileAttributeView
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
// enumerates the file streams by reading the stream headers using
|
||||
// BackupRead
|
||||
private List<String> listUsingBackupRead() throws IOException {
|
||||
long handle = -1L;
|
||||
try {
|
||||
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
if (!followLinks && file.getFileSystem().supportsLinks())
|
||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
|
||||
handle = CreateFile(file.getPathForWin32Calls(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ, // no write as we depend on file size
|
||||
OPEN_EXISTING,
|
||||
flags);
|
||||
} catch (WindowsException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
}
|
||||
|
||||
// buffer to read stream header and stream name.
|
||||
final int BUFFER_SIZE = 4096;
|
||||
NativeBuffer buffer = null;
|
||||
|
||||
// result with names of alternative data streams
|
||||
final List<String> list = new ArrayList<>();
|
||||
|
||||
try {
|
||||
buffer = NativeBuffers.getNativeBuffer(BUFFER_SIZE);
|
||||
long address = buffer.address();
|
||||
|
||||
/**
|
||||
* typedef struct _WIN32_STREAM_ID {
|
||||
* DWORD dwStreamId;
|
||||
* DWORD dwStreamAttributes;
|
||||
* LARGE_INTEGER Size;
|
||||
* DWORD dwStreamNameSize;
|
||||
* WCHAR cStreamName[ANYSIZE_ARRAY];
|
||||
* } WIN32_STREAM_ID;
|
||||
*/
|
||||
final int SIZEOF_STREAM_HEADER = 20;
|
||||
final int OFFSETOF_STREAM_ID = 0;
|
||||
final int OFFSETOF_STREAM_SIZE = 8;
|
||||
final int OFFSETOF_STREAM_NAME_SIZE = 16;
|
||||
|
||||
long context = 0L;
|
||||
try {
|
||||
for (;;) {
|
||||
// read stream header
|
||||
BackupResult result = BackupRead(handle, address,
|
||||
SIZEOF_STREAM_HEADER, false, context);
|
||||
context = result.context();
|
||||
if (result.bytesTransferred() == 0)
|
||||
break;
|
||||
|
||||
int streamId = unsafe.getInt(address + OFFSETOF_STREAM_ID);
|
||||
long streamSize = unsafe.getLong(address + OFFSETOF_STREAM_SIZE);
|
||||
int nameSize = unsafe.getInt(address + OFFSETOF_STREAM_NAME_SIZE);
|
||||
|
||||
// read stream name
|
||||
if (nameSize > 0) {
|
||||
result = BackupRead(handle, address, nameSize, false, context);
|
||||
if (result.bytesTransferred() != nameSize)
|
||||
break;
|
||||
}
|
||||
|
||||
// check for alternative data stream
|
||||
if (streamId == BACKUP_ALTERNATE_DATA) {
|
||||
char[] nameAsArray = new char[nameSize/2];
|
||||
unsafe.copyMemory(null, address, nameAsArray,
|
||||
Unsafe.ARRAY_CHAR_BASE_OFFSET, nameSize);
|
||||
|
||||
String[] segs = new String(nameAsArray).split(":");
|
||||
if (segs.length == 3)
|
||||
list.add(segs[1]);
|
||||
}
|
||||
|
||||
// sparse blocks not currently handled as documentation
|
||||
// is not sufficient on how the spase block can be skipped.
|
||||
if (streamId == BACKUP_SPARSE_BLOCK) {
|
||||
throw new IOException("Spare blocks not handled");
|
||||
}
|
||||
|
||||
// seek to end of stream
|
||||
if (streamSize > 0L) {
|
||||
BackupSeek(handle, streamSize, context);
|
||||
}
|
||||
}
|
||||
} catch (WindowsException x) {
|
||||
// failed to read or seek
|
||||
throw new IOException(x.errorString());
|
||||
} finally {
|
||||
// release context
|
||||
if (context != 0L) {
|
||||
try {
|
||||
BackupRead(handle, 0L, 0, true, context);
|
||||
} catch (WindowsException ignore) { }
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (buffer != null)
|
||||
buffer.release();
|
||||
CloseHandle(handle);
|
||||
}
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> list() throws IOException {
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), true, false);
|
||||
// use stream APIs on Windows Server 2003 and newer
|
||||
if (file.getFileSystem().supportsStreamEnumeration()) {
|
||||
return listUsingStreamEnumeration();
|
||||
} else {
|
||||
return listUsingBackupRead();
|
||||
}
|
||||
return listUsingStreamEnumeration();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -69,10 +69,6 @@ static jfieldID completionStatus_error;
|
||||
static jfieldID completionStatus_bytesTransferred;
|
||||
static jfieldID completionStatus_completionKey;
|
||||
|
||||
static jfieldID backupResult_bytesTransferred;
|
||||
static jfieldID backupResult_context;
|
||||
|
||||
|
||||
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
|
||||
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
|
||||
"(I)V", lastError);
|
||||
@ -148,13 +144,6 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
|
||||
CHECK_NULL(completionStatus_bytesTransferred);
|
||||
completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J");
|
||||
CHECK_NULL(completionStatus_completionKey);
|
||||
|
||||
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$BackupResult");
|
||||
CHECK_NULL(clazz);
|
||||
backupResult_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
|
||||
CHECK_NULL(backupResult_bytesTransferred);
|
||||
backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
|
||||
CHECK_NULL(backupResult_context);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
@ -1228,52 +1217,3 @@ Java_sun_nio_fs_WindowsNativeDispatcher_ReadDirectoryChangesW(JNIEnv* env, jclas
|
||||
throwWindowsException(env, GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_WindowsNativeDispatcher_BackupRead0(JNIEnv* env, jclass this,
|
||||
jlong hFile, jlong bufferAddress, jint bufferSize, jboolean abort,
|
||||
jlong context, jobject obj)
|
||||
{
|
||||
BOOL res;
|
||||
DWORD bytesTransferred;
|
||||
BOOL a = (abort == JNI_TRUE) ? TRUE : FALSE;
|
||||
VOID* pContext = (VOID*)jlong_to_ptr(context);
|
||||
|
||||
res = BackupRead((HANDLE)jlong_to_ptr(hFile),
|
||||
(LPBYTE)jlong_to_ptr(bufferAddress),
|
||||
(DWORD)bufferSize,
|
||||
&bytesTransferred,
|
||||
a,
|
||||
FALSE,
|
||||
&pContext);
|
||||
if (res == 0) {
|
||||
throwWindowsException(env, GetLastError());
|
||||
} else {
|
||||
(*env)->SetIntField(env, obj, backupResult_bytesTransferred,
|
||||
bytesTransferred);
|
||||
(*env)->SetLongField(env, obj, backupResult_context,
|
||||
ptr_to_jlong(pContext));
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_WindowsNativeDispatcher_BackupSeek(JNIEnv* env, jclass this,
|
||||
jlong hFile, jlong bytesToSeek, jlong context)
|
||||
{
|
||||
BOOL res;
|
||||
jint lowBytesToSeek = (jint)bytesToSeek;
|
||||
jint highBytesToSeek = (jint)(bytesToSeek >> 32);
|
||||
DWORD lowBytesSeeked;
|
||||
DWORD highBytesSeeked;
|
||||
VOID* pContext = jlong_to_ptr(context);
|
||||
|
||||
res = BackupSeek((HANDLE)jlong_to_ptr(hFile),
|
||||
(DWORD)lowBytesToSeek,
|
||||
(DWORD)highBytesToSeek,
|
||||
&lowBytesSeeked,
|
||||
&highBytesSeeked,
|
||||
&pContext);
|
||||
if (res == 0) {
|
||||
throwWindowsException(env, GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,10 +34,15 @@ import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.BitSet;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
@ -236,10 +241,13 @@ public class JMXServiceURL implements Serializable {
|
||||
* @param protocol the protocol part of the URL. If null, defaults
|
||||
* to <code>jmxmp</code>.
|
||||
*
|
||||
* @param host the host part of the URL. If null, defaults to the
|
||||
* local host name, as determined by
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code>. If it
|
||||
* is a numeric IPv6 address, it can optionally be enclosed in
|
||||
* @param host the host part of the URL. If host is null and if
|
||||
* local host name can be resolved to an IP, then host defaults
|
||||
* to local host name as determined by
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code>. If host is null
|
||||
* and if local host name cannot be resolved to an IP, then host
|
||||
* defaults to numeric IP address of one of the active network interfaces.
|
||||
* If host is a numeric IPv6 address, it can optionally be enclosed in
|
||||
* square brackets <code>[]</code>.
|
||||
*
|
||||
* @param port the port part of the URL.
|
||||
@ -260,10 +268,13 @@ public class JMXServiceURL implements Serializable {
|
||||
* @param protocol the protocol part of the URL. If null, defaults
|
||||
* to <code>jmxmp</code>.
|
||||
*
|
||||
* @param host the host part of the URL. If null, defaults to the
|
||||
* local host name, as determined by
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code>. If it
|
||||
* is a numeric IPv6 address, it can optionally be enclosed in
|
||||
* @param host the host part of the URL. If host is null and if
|
||||
* local host name can be resolved to an IP, then host defaults
|
||||
* to local host name as determined by
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code>. If host is null
|
||||
* and if local host name cannot be resolved to an IP, then host
|
||||
* defaults to numeric IP address of one of the active network interfaces.
|
||||
* If host is a numeric IPv6 address, it can optionally be enclosed in
|
||||
* square brackets <code>[]</code>.
|
||||
*
|
||||
* @param port the port part of the URL.
|
||||
@ -286,32 +297,45 @@ public class JMXServiceURL implements Serializable {
|
||||
InetAddress local;
|
||||
try {
|
||||
local = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new MalformedURLException("Local host name unknown: " +
|
||||
e);
|
||||
}
|
||||
host = local.getHostName();
|
||||
|
||||
host = local.getHostName();
|
||||
|
||||
/* We might have a hostname that violates DNS naming
|
||||
rules, for example that contains an `_'. While we
|
||||
could be strict and throw an exception, this is rather
|
||||
user-hostile. Instead we use its numerical IP address.
|
||||
We can only reasonably do this for the host==null case.
|
||||
If we're given an explicit host name that is illegal we
|
||||
have to reject it. (Bug 5057532.) */
|
||||
try {
|
||||
validateHost(host, port);
|
||||
} catch (MalformedURLException e) {
|
||||
if (logger.fineOn()) {
|
||||
/* We might have a hostname that violates DNS naming
|
||||
rules, for example that contains an `_'. While we
|
||||
could be strict and throw an exception, this is rather
|
||||
user-hostile. Instead we use its numerical IP address.
|
||||
We can only reasonably do this for the host==null case.
|
||||
If we're given an explicit host name that is illegal we
|
||||
have to reject it. (Bug 5057532.) */
|
||||
try {
|
||||
validateHost(host, port);
|
||||
} catch (MalformedURLException e) {
|
||||
if (logger.fineOn()) {
|
||||
logger.fine("JMXServiceURL",
|
||||
"Replacing illegal local host name " +
|
||||
host + " with numeric IP address " +
|
||||
"(see RFC 1034)", e);
|
||||
}
|
||||
host = local.getHostAddress();
|
||||
/* Use the numeric address, which could be either IPv4
|
||||
or IPv6. validateHost will accept either. */
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
try {
|
||||
/*
|
||||
If hostname cannot be resolved, we will try and use numeric
|
||||
IPv4/IPv6 address. If host=null while starting agent,
|
||||
we know that it will be started on all interfaces - 0.0.0.0.
|
||||
Hence we will use IP address of first active non-loopback
|
||||
interface
|
||||
*/
|
||||
host = getActiveNetworkInterfaceIP();
|
||||
if (host == null) {
|
||||
throw new MalformedURLException("Unable"
|
||||
+ " to resolve hostname or "
|
||||
+ "get valid IP address");
|
||||
}
|
||||
} catch (SocketException ex) {
|
||||
throw new MalformedURLException("Unable"
|
||||
+ " to resolve hostname or get valid IP address");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,6 +364,33 @@ public class JMXServiceURL implements Serializable {
|
||||
validate();
|
||||
}
|
||||
|
||||
private String getActiveNetworkInterfaceIP() throws SocketException {
|
||||
Enumeration<NetworkInterface>
|
||||
networkInterface = NetworkInterface.getNetworkInterfaces();
|
||||
String ipv6AddrStr = null;
|
||||
while (networkInterface.hasMoreElements()) {
|
||||
NetworkInterface nic = networkInterface.nextElement();
|
||||
if (nic.isUp() && !nic.isLoopback()) {
|
||||
Enumeration<InetAddress> inet = nic.getInetAddresses();
|
||||
while (inet.hasMoreElements()) {
|
||||
InetAddress addr = inet.nextElement();
|
||||
if (addr instanceof Inet4Address
|
||||
&& !addr.isLinkLocalAddress()) {
|
||||
return addr.getHostAddress();
|
||||
}else if (addr instanceof Inet6Address
|
||||
&& !addr.isLinkLocalAddress()) {
|
||||
/*
|
||||
We save last seen IPv6 address which we will return
|
||||
if we do not find any interface with IPv4 address.
|
||||
*/
|
||||
ipv6AddrStr = addr.getHostAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ipv6AddrStr;
|
||||
}
|
||||
|
||||
private static final String INVALID_INSTANCE_MSG =
|
||||
"Trying to deserialize an invalid instance of JMXServiceURL";
|
||||
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
|
||||
@ -540,7 +591,9 @@ public class JMXServiceURL implements Serializable {
|
||||
* constructor that takes a separate host parameter, the result is
|
||||
* the string that was specified. If that string was null, the
|
||||
* result is
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code>.</p>
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code> if local host name
|
||||
* can be resolved to an IP. Else numeric IP address of an active
|
||||
* network interface will be used.</p>
|
||||
*
|
||||
* <p>In either case, if the host was specified using the
|
||||
* <code>[...]</code> syntax for numeric IPv6 addresses, the
|
||||
|
||||
@ -99,30 +99,7 @@ public final class JdpBroadcaster {
|
||||
throw new JdpException("Unable to bind to source address");
|
||||
}
|
||||
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
|
||||
} else {
|
||||
Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces();
|
||||
boolean succeed = false;
|
||||
|
||||
while (nics.hasMoreElements()) {
|
||||
NetworkInterface nic = nics.nextElement();
|
||||
|
||||
if (nic.isUp() && nic.supportsMulticast()) {
|
||||
try {
|
||||
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, nic);
|
||||
succeed = true;
|
||||
} catch (IOException ex) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!succeed) {
|
||||
throw new JdpException("Unable to bind to any interfaces.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -312,7 +312,8 @@ public class Sasl {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
@ -461,7 +462,8 @@ public class Sasl {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 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
|
||||
@ -231,7 +231,8 @@ public final class TerminalFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 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
|
||||
@ -138,7 +138,8 @@ public abstract class TransformService implements Transform {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 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
|
||||
@ -175,7 +175,8 @@ public abstract class XMLSignatureFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 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
|
||||
@ -131,7 +131,8 @@ public abstract class KeyInfoFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
@ -272,7 +273,8 @@ public abstract class KeyInfoFactory {
|
||||
*
|
||||
* @implNote
|
||||
* The JDK Reference Implementation additionally uses the
|
||||
* {@code jdk.security.provider.preferred} property to determine
|
||||
* {@code jdk.security.provider.preferred}
|
||||
* {@link Security#getProperty(String) Security} property to determine
|
||||
* the preferred provider order for the specified algorithm. This
|
||||
* may be different than the order of providers returned by
|
||||
* {@link Security#getProviders() Security.getProviders()}.
|
||||
|
||||
@ -125,6 +125,24 @@ ifdef TESTNATIVE_DIR
|
||||
JTREG_NATIVE_PATH = -nativepath:$(shell $(GETMIXEDPATH) "$(TESTNATIVE_DIR)/jdk/jtreg/native")
|
||||
endif
|
||||
|
||||
# jtreg failure handler config
|
||||
ifeq ($(FAILURE_HANDLER_DIR), )
|
||||
ifneq ($(TESTNATIVE_DIR), )
|
||||
FAILURE_HANDLER_DIR := $(TESTNATIVE_DIR)/failure_handler
|
||||
endif
|
||||
endif
|
||||
ifneq ($(FAILURE_HANDLER_DIR), )
|
||||
FAILURE_HANDLER_DIR_MIXED := $(shell $(GETMIXEDPATH) "$(FAILURE_HANDLER_DIR)")
|
||||
JTREG_FAILURE_HANDLER_OPTIONS := \
|
||||
-timeoutHandlerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
|
||||
-observerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \
|
||||
-timeoutHandler:jdk.test.failurehandler.jtreg.GatherProcessInfoTimeoutHandler \
|
||||
-observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver
|
||||
ifeq ($(UNAME_S), CYGWIN)
|
||||
JTREG_FAILURE_HANDLER_OPTIONS += -J-Djava.library.path="$(FAILURE_HANDLER_DIR_MIXED)"
|
||||
endif
|
||||
endif
|
||||
|
||||
# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
|
||||
ifdef JPRT_ARCHIVE_BUNDLE
|
||||
ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
|
||||
@ -329,6 +347,7 @@ jtreg_tests: prep $(PRODUCT_HOME) $(JTREG)
|
||||
-w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork") \
|
||||
-jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \
|
||||
$(JTREG_NATIVE_PATH) \
|
||||
$(JTREG_FAILURE_HANDLER_OPTIONS) \
|
||||
$(JTREG_EXCLUSIONS) \
|
||||
$(JTREG_TEST_OPTIONS) \
|
||||
$(TEST_SELECTION) \
|
||||
|
||||
@ -153,8 +153,6 @@ javax/management/MBeanServer/OldMBeanServerTest.java 8030957 aix-all
|
||||
|
||||
javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java 8042215 generic-all
|
||||
|
||||
sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java 8147985 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_net
|
||||
@ -236,7 +234,7 @@ sun/security/pkcs11/MessageDigest/DigestKAT.java 8077138,8023434
|
||||
sun/security/pkcs11/MessageDigest/ReinitDigest.java 8077138,8023434 windows-all
|
||||
sun/security/pkcs11/MessageDigest/TestCloning.java 8077138,8023434 windows-all
|
||||
sun/security/pkcs11/Provider/ConfigQuotedString.sh 8077138,8023434 windows-all
|
||||
sun/security/pkcs11/Provider/Login.sh 8077138,8023434,8153545 windows-all,linux-all
|
||||
sun/security/pkcs11/Provider/Login.sh 8077138,8023434 windows-all
|
||||
sun/security/pkcs11/SampleTest.java 8077138,8023434 windows-all
|
||||
sun/security/pkcs11/Secmod/AddPrivateKey.java 8077138,8023434 windows-all
|
||||
sun/security/pkcs11/Secmod/AddTrustedCert.java 8077138,8023434 windows-all
|
||||
@ -337,6 +335,10 @@ com/sun/jdi/CatchPatternTest.sh 8068645 generic-
|
||||
|
||||
com/sun/jdi/GetLocalVariables4Test.sh 8067354 windows-all
|
||||
|
||||
com/sun/jdi/InterfaceMethodsTest.java 8152586 generic-all
|
||||
|
||||
com/sun/jdi/InvokeTest.java 8152586 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_util
|
||||
|
||||
@ -153,14 +153,17 @@ public class InterruptHangTest extends TestScaffold {
|
||||
timerThread = new Thread("test timer") {
|
||||
public void run() {
|
||||
int mySteps = 0;
|
||||
float timeoutFactor = Float.parseFloat(System.getProperty("test.timeout.factor", "1.0"));
|
||||
long sleepSeconds = (long)(20 * timeoutFactor);
|
||||
println("Timer watching for steps every " + sleepSeconds + " seconds");
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(20000);
|
||||
Thread.sleep(sleepSeconds * 1000);
|
||||
synchronized(sync) {
|
||||
System.out.println("steps = " + nSteps);
|
||||
println("steps = " + nSteps);
|
||||
if (mySteps == nSteps) {
|
||||
// no step for 10 secs
|
||||
failure("failure: Debuggee appears to be hung");
|
||||
// no step for a long time
|
||||
failure("failure: Debuggee appears to be hung (no steps for " + sleepSeconds + "s)");
|
||||
vm().exit(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -131,6 +131,9 @@ killcmd=kill
|
||||
|
||||
# This can be increased if timing seems to be an issue.
|
||||
sleep_seconds=1
|
||||
if [ -n "$TIMEOUT_FACTOR" ] ; then
|
||||
sleep_seconds=$(echo $TIMEOUT_FACTOR $sleep_seconds | awk '{printf "%d\n", int($1 * $2)}')
|
||||
fi
|
||||
|
||||
echo "ShellScaffold.sh: Version" >& 2
|
||||
topPid=$$
|
||||
|
||||
@ -64,6 +64,7 @@ abstract public class TestScaffold extends TargetAdapter {
|
||||
boolean vmDisconnected = false;
|
||||
final String[] args;
|
||||
protected boolean testFailed = false;
|
||||
protected long startTime;
|
||||
|
||||
static private class ArgInfo {
|
||||
String targetVMArgs = "";
|
||||
@ -425,6 +426,7 @@ abstract public class TestScaffold extends TargetAdapter {
|
||||
abstract protected void runTests() throws Exception;
|
||||
|
||||
final public void startTests() throws Exception {
|
||||
startTime = System.currentTimeMillis();
|
||||
try {
|
||||
runTests();
|
||||
} finally {
|
||||
@ -433,7 +435,8 @@ abstract public class TestScaffold extends TargetAdapter {
|
||||
}
|
||||
|
||||
protected void println(String str) {
|
||||
System.err.println(str);
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
System.err.println("[" + elapsed + "ms] " + str);
|
||||
}
|
||||
|
||||
protected void print(String str) {
|
||||
|
||||
83
jdk/test/java/lang/invoke/ConstantIdentityMHTest.java
Normal file
83
jdk/test/java/lang/invoke/ConstantIdentityMHTest.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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
|
||||
* @summary unit tests for java.lang.invoke.MethodHandles
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.ConstantIdentityMHTest
|
||||
*/
|
||||
package test.java.lang.invoke;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.List;
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
import static org.testng.AssertJUnit.*;
|
||||
import org.testng.annotations.*;
|
||||
|
||||
public class ConstantIdentityMHTest {
|
||||
|
||||
@DataProvider(name = "testZeroData")
|
||||
private Object[][] testZeroData() {
|
||||
return new Object[][] {
|
||||
{void.class, "()void"},
|
||||
{int.class, "()int"},
|
||||
{byte.class, "()byte"},
|
||||
{short.class, "()short"},
|
||||
{long.class, "()long"},
|
||||
{float.class, "()float"},
|
||||
{double.class, "()double"},
|
||||
{boolean.class, "()boolean"},
|
||||
{char.class, "()char"},
|
||||
{Integer.class, "()Integer"}
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "testZeroData")
|
||||
public void testZero(Class<?> expectedtype, String expected) throws Throwable {
|
||||
assertEquals(MethodHandles.zero(expectedtype).type().toString(), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectedExceptions(NullPointerException.class)
|
||||
public void testZeroNPE() {
|
||||
MethodHandle mh = MethodHandles.zero(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEmpty() throws Throwable {
|
||||
MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class));
|
||||
assertEquals("xy", (String)cat.invoke("x","y"));
|
||||
MethodHandle mhEmpty = MethodHandles.empty(cat.type());
|
||||
assertEquals(null, (String)mhEmpty.invoke("x","y"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectedExceptions(NullPointerException.class)
|
||||
void testEmptyNPE() {
|
||||
MethodHandle lenEmptyMH = MethodHandles.empty(null);
|
||||
}
|
||||
}
|
||||
90
jdk/test/java/lang/invoke/DropArgumentsTest.java
Normal file
90
jdk/test/java/lang/invoke/DropArgumentsTest.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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
|
||||
* @summary unit tests for java.lang.invoke.MethodHandles
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.DropArgumentsTest
|
||||
*/
|
||||
package test.java.lang.invoke;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.List;
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
import static org.testng.AssertJUnit.*;
|
||||
import org.testng.annotations.*;
|
||||
|
||||
public class DropArgumentsTest {
|
||||
|
||||
@Test
|
||||
public void testDropArgumentsToMatch() throws Throwable {
|
||||
MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class));
|
||||
MethodType bigType = cat.type().insertParameterTypes(0, String.class, String.class, int.class);
|
||||
MethodHandle d0 = MethodHandles.dropArgumentsToMatch(cat, 0, bigType.parameterList(), 3);
|
||||
assertEquals("xy",(String)d0.invokeExact("m", "n", 1, "x", "y"));
|
||||
MethodHandle d1 = MethodHandles.dropArgumentsToMatch(cat, 0, bigType.parameterList(), 0);
|
||||
assertEquals("mn",(String)d1.invokeExact("m", "n", 1, "x", "y"));
|
||||
MethodHandle d2 = MethodHandles.dropArgumentsToMatch(cat, 1, bigType.parameterList(), 4);
|
||||
assertEquals("xy",(String)d2.invokeExact("x", "b", "c", 1, "a", "y"));
|
||||
|
||||
}
|
||||
|
||||
@DataProvider(name = "dropArgumentsToMatchNPEData")
|
||||
private Object[][] dropArgumentsToMatchNPEData()
|
||||
throws NoSuchMethodException, IllegalAccessException {
|
||||
MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class));
|
||||
return new Object[][] {
|
||||
{ (MethodHandle) null, 0, cat.type().parameterList(), 0 },
|
||||
{ cat, 0, null, 0 }
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "dropArgumentsToMatchNPEData")
|
||||
@ExpectedExceptions(NullPointerException.class)
|
||||
public void dropArgumentsToMatchNPE(MethodHandle target, int pos, List<Class<?>> valueType, int skip) {
|
||||
MethodHandles.dropArgumentsToMatch(target, pos, valueType , skip);
|
||||
}
|
||||
|
||||
@DataProvider(name = "dropArgumentsToMatchIAEData")
|
||||
private Object[][] dropArgumentsToMatchIAEData()
|
||||
throws NoSuchMethodException, IllegalAccessException {
|
||||
MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class));
|
||||
MethodType bigType = cat.type().insertParameterTypes(0, String.class, String.class, int.class);
|
||||
return new Object[][] {
|
||||
{cat, -1, bigType.parameterList(), 0},
|
||||
{cat, 0, bigType.parameterList(), -1},
|
||||
{cat, 3, bigType.parameterList(), 0},
|
||||
{cat, 0, bigType.parameterList(), 2}
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "dropArgumentsToMatchIAEData")
|
||||
@ExpectedExceptions(IllegalArgumentException.class)
|
||||
public void dropArgumentsToMatchIAE(MethodHandle target, int pos, List<Class<?>> valueType, int skip) {
|
||||
MethodHandles.dropArgumentsToMatch(target, pos, valueType , skip);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 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
|
||||
@ -57,7 +57,9 @@ public class JavaDocExamplesTest {
|
||||
testFindVirtual();
|
||||
testFindSpecial();
|
||||
testPermuteArguments();
|
||||
testZero();
|
||||
testDropArguments();
|
||||
testDropArgumentsToMatch();
|
||||
testFilterArguments();
|
||||
testFoldArguments();
|
||||
testFoldArguments2();
|
||||
@ -235,6 +237,17 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
|
||||
}}
|
||||
}
|
||||
|
||||
@Test public void testZero() throws Throwable {
|
||||
{{
|
||||
{} /// JAVADOC
|
||||
Class<?> type = Double.class;
|
||||
MethodHandle mh1 = MethodHandles.explicitCastArguments(MethodHandles.constant(Object.class, null), methodType(type));
|
||||
assertEquals("()Double", mh1.type().toString());
|
||||
MethodHandle mh2 = MethodHandles.empty(methodType(type));
|
||||
assertEquals("()Double", mh2.type().toString());
|
||||
}}
|
||||
}
|
||||
|
||||
@Test public void testDropArguments() throws Throwable {
|
||||
{{
|
||||
{} /// JAVADOC
|
||||
@ -262,6 +275,24 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
|
||||
}}
|
||||
}
|
||||
|
||||
@Test public void testDropArgumentsToMatch() throws Throwable {
|
||||
{{
|
||||
{} /// JAVADOC
|
||||
MethodHandle h0= constant(boolean.class, true);
|
||||
MethodHandle h1 = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class));
|
||||
MethodType bigType = h1.type().insertParameterTypes(1, String.class, int.class);
|
||||
MethodHandle h2 = dropArguments(h1, 0, bigType.parameterList());
|
||||
if (h1.type().parameterCount() < h2.type().parameterCount()) {
|
||||
h1 = dropArgumentsToMatch(h1, 0, h2.type().parameterList(), 0); // lengthen h1
|
||||
}
|
||||
else {
|
||||
h2 = dropArgumentsToMatch(h2, 0, h1.type().parameterList(), 0); // lengthen h2
|
||||
}
|
||||
MethodHandle h3 = guardWithTest(h0, h1, h2);
|
||||
assertEquals("xy", h3.invoke("x", "y", 1, "a", "b", "c"));
|
||||
}}
|
||||
}
|
||||
|
||||
@Test public void testFilterArguments() throws Throwable {
|
||||
{{
|
||||
{} /// JAVADOC
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
/* @test
|
||||
* @bug 8139885
|
||||
* @bug 8150635
|
||||
* @bug 8150957
|
||||
* @bug 8153637
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest
|
||||
*/
|
||||
|
||||
@ -301,6 +303,18 @@ public class LoopCombinatorTest {
|
||||
assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void testCountedLoopCounterInit() throws Throwable {
|
||||
// int x = 0; for (int i = 0; i < 5; ++i) { x += i; } return x; => 10
|
||||
// (only if counter's first value in body is 0)
|
||||
MethodHandle iter = MethodHandles.constant(int.class, 5);
|
||||
MethodHandle init = MethodHandles.constant(int.class, 0);
|
||||
MethodHandle body = Counted.MH_addCounter;
|
||||
MethodHandle loop = MethodHandles.countedLoop(iter, init, body);
|
||||
assertEquals(Counted.MT_counterInit, loop.type());
|
||||
assertEquals(10, loop.invoke());
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void testIterateSum() throws Throwable {
|
||||
// Integer[] a = new Integer[]{1,2,3,4,5,6}; int sum = 0; for (int e : a) { sum += e; } return sum; => 21
|
||||
@ -667,12 +681,17 @@ public class LoopCombinatorTest {
|
||||
System.out.print("hello");
|
||||
}
|
||||
|
||||
static int addCounter(int counter, int x) {
|
||||
return x + counter;
|
||||
}
|
||||
|
||||
static final Class<Counted> COUNTED = Counted.class;
|
||||
|
||||
static final MethodType MT_start = methodType(String.class, String.class);
|
||||
static final MethodType MT_step = methodType(String.class, int.class, String.class, String.class);
|
||||
static final MethodType MT_stepUpdateArray = methodType(void.class, int.class, int[].class);
|
||||
static final MethodType MT_printHello = methodType(void.class, int.class);
|
||||
static final MethodType MT_addCounter = methodType(int.class, int.class, int.class);
|
||||
|
||||
static final MethodHandle MH_13;
|
||||
static final MethodHandle MH_m5;
|
||||
@ -681,10 +700,12 @@ public class LoopCombinatorTest {
|
||||
static final MethodHandle MH_step;
|
||||
static final MethodHandle MH_stepUpdateArray;
|
||||
static final MethodHandle MH_printHello;
|
||||
static final MethodHandle MH_addCounter;
|
||||
|
||||
static final MethodType MT_counted = methodType(String.class, String.class);
|
||||
static final MethodType MT_arrayCounted = methodType(void.class, int[].class);
|
||||
static final MethodType MT_countedPrinting = methodType(void.class);
|
||||
static final MethodType MT_counterInit = methodType(int.class);
|
||||
|
||||
static {
|
||||
try {
|
||||
@ -695,6 +716,7 @@ public class LoopCombinatorTest {
|
||||
MH_step = LOOKUP.findStatic(COUNTED, "step", MT_step);
|
||||
MH_stepUpdateArray = LOOKUP.findStatic(COUNTED, "stepUpdateArray", MT_stepUpdateArray);
|
||||
MH_printHello = LOOKUP.findStatic(COUNTED, "printHello", MT_printHello);
|
||||
MH_addCounter = LOOKUP.findStatic(COUNTED, "addCounter", MT_addCounter);
|
||||
} catch (Exception e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
/* @test
|
||||
* @bug 8139885
|
||||
* @bug 8150824
|
||||
* @bug 8150825
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.TryFinallyTest
|
||||
*/
|
||||
@ -70,6 +71,24 @@ public class TryFinallyTest {
|
||||
assertEquals("Hello, world and universe (but world first)!", helloMore.invoke("world", "universe"));
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
static Object[][] omitTrailingArguments() {
|
||||
MethodHandle c = TryFinally.MH_voidCleanup;
|
||||
return new Object[][]{
|
||||
{c},
|
||||
{MethodHandles.dropArguments(c, 1, int.class)},
|
||||
{MethodHandles.dropArguments(c, 1, int.class, long.class)},
|
||||
{MethodHandles.dropArguments(c, 1, int.class, long.class, Object.class, int.class)},
|
||||
{MethodHandles.dropArguments(c, 1, int.class, long.class, Object.class, int.class, long.class)}
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "omitTrailingArguments")
|
||||
public static void testTryFinallyOmitTrailingArguments(MethodHandle cleanup) throws Throwable {
|
||||
MethodHandle tf = MethodHandles.tryFinally(TryFinally.MH_dummyTarget, cleanup);
|
||||
tf.invoke(1, 2L, "a", 23, 42L, "b");
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
static Object[][] negativeTestData() {
|
||||
MethodHandle intid = MethodHandles.identity(int.class);
|
||||
@ -77,6 +96,8 @@ public class TryFinallyTest {
|
||||
MethodHandle errTarget = MethodHandles.dropArguments(intco, 0, int.class, double.class, String.class, int.class);
|
||||
MethodHandle errCleanup = MethodHandles.dropArguments(MethodHandles.constant(int.class, 0), 0, Throwable.class,
|
||||
int.class, double.class, Object.class);
|
||||
MethodHandle voidTarget = TryFinally.MH_voidTarget;
|
||||
MethodHandle voidICleanup = MethodHandles.dropArguments(TryFinally.MH_voidCleanup, 1, int.class);
|
||||
return new Object[][]{
|
||||
{intid, MethodHandles.identity(double.class),
|
||||
"target and return types must match: double != int"},
|
||||
@ -87,9 +108,9 @@ public class TryFinallyTest {
|
||||
{errTarget, errCleanup,
|
||||
"cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
|
||||
errCleanup.type() + " != " + errTarget.type()},
|
||||
{TryFinally.MH_voidTarget, TryFinally.MH_voidCleanup,
|
||||
{voidTarget, voidICleanup,
|
||||
"cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
|
||||
TryFinally.MH_voidCleanup.type() + " != " + TryFinally.MH_voidTarget.type()}
|
||||
voidICleanup.type() + " != " + voidTarget.type()}
|
||||
};
|
||||
}
|
||||
|
||||
@ -133,7 +154,7 @@ public class TryFinallyTest {
|
||||
|
||||
static void voidTarget() {}
|
||||
|
||||
static void voidCleanup(Throwable t, int a) {}
|
||||
static void voidCleanup(Throwable t) {}
|
||||
|
||||
static final Class<TryFinally> TRY_FINALLY = TryFinally.class;
|
||||
|
||||
@ -144,7 +165,7 @@ public class TryFinallyTest {
|
||||
static final MethodType MT_greetMore = methodType(String.class, String.class, String.class);
|
||||
static final MethodType MT_exclaimMore = methodType(String.class, Throwable.class, String.class, String.class);
|
||||
static final MethodType MT_voidTarget = methodType(void.class);
|
||||
static final MethodType MT_voidCleanup = methodType(void.class, Throwable.class, int.class);
|
||||
static final MethodType MT_voidCleanup = methodType(void.class, Throwable.class);
|
||||
|
||||
static final MethodHandle MH_greet;
|
||||
static final MethodHandle MH_exclaim;
|
||||
@ -155,6 +176,8 @@ public class TryFinallyTest {
|
||||
static final MethodHandle MH_voidTarget;
|
||||
static final MethodHandle MH_voidCleanup;
|
||||
|
||||
static final MethodHandle MH_dummyTarget;
|
||||
|
||||
static final MethodType MT_hello = methodType(String.class, String.class);
|
||||
static final MethodType MT_printHello = methodType(void.class, String.class);
|
||||
static final MethodType MT_moreHello = methodType(String.class, String.class, String.class);
|
||||
@ -169,6 +192,8 @@ public class TryFinallyTest {
|
||||
MH_exclaimMore = LOOKUP.findStatic(TRY_FINALLY, "exclaimMore", MT_exclaimMore);
|
||||
MH_voidTarget = LOOKUP.findStatic(TRY_FINALLY, "voidTarget", MT_voidTarget);
|
||||
MH_voidCleanup = LOOKUP.findStatic(TRY_FINALLY, "voidCleanup", MT_voidCleanup);
|
||||
MH_dummyTarget = MethodHandles.dropArguments(MH_voidTarget, 0, int.class, long.class, Object.class,
|
||||
int.class, long.class, Object.class);
|
||||
} catch (Exception e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
80
jdk/test/java/lang/invoke/VarArgsTest.java
Normal file
80
jdk/test/java/lang/invoke/VarArgsTest.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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
|
||||
* @summary unit tests for java.lang.invoke.MethodHandles
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.VarArgsTest
|
||||
*/
|
||||
package test.java.lang.invoke;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
import static java.lang.invoke.MethodType.*;
|
||||
import static org.testng.AssertJUnit.*;
|
||||
import org.testng.annotations.*;
|
||||
|
||||
public class VarArgsTest {
|
||||
|
||||
@Test
|
||||
public void testWithVarargs() throws Throwable {
|
||||
MethodHandle deepToString = publicLookup()
|
||||
.findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
|
||||
assertFalse(deepToString.isVarargsCollector());
|
||||
MethodHandle ts = deepToString.withVarargs(false);
|
||||
assertFalse(ts.isVarargsCollector());
|
||||
MethodHandle ts1 = deepToString.withVarargs(true);
|
||||
assertTrue(ts1.isVarargsCollector());
|
||||
assertEquals("[won]", (String) ts1.invokeExact(new Object[]{"won"}));
|
||||
assertEquals("[won]", (String) ts1.invoke(new Object[]{"won"}));
|
||||
assertEquals("[won]", (String) ts1.invoke("won"));
|
||||
assertEquals("[won, won]", (String) ts1.invoke("won", "won"));
|
||||
assertEquals("[won, won]", (String) ts1.invoke(new Object[]{"won", "won"}));
|
||||
assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithVarargs2() throws Throwable {
|
||||
MethodHandle asList = publicLookup()
|
||||
.findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
|
||||
MethodHandle asListWithVarargs = asList.withVarargs(asList.isVarargsCollector());
|
||||
assert(asListWithVarargs.isVarargsCollector());
|
||||
assertEquals("[]", asListWithVarargs.invoke().toString());
|
||||
assertEquals("[1]", asListWithVarargs.invoke(1).toString());
|
||||
assertEquals("[two, too]", asListWithVarargs.invoke("two", "too").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectedExceptions(IllegalArgumentException.class)
|
||||
public void testWithVarargsIAE() throws Throwable {
|
||||
MethodHandle lenMH = publicLookup()
|
||||
.findVirtual(String.class, "length", methodType(int.class));
|
||||
MethodHandle lenMHWithVarargs = lenMH.withVarargs(true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -126,33 +126,33 @@ abstract class VarHandleBaseTest {
|
||||
|
||||
|
||||
enum TestAccessType {
|
||||
get,
|
||||
set,
|
||||
compareAndSet,
|
||||
compareAndExchange,
|
||||
getAndSet,
|
||||
getAndAdd;
|
||||
GET,
|
||||
SET,
|
||||
COMPARE_AND_SET,
|
||||
COMPARE_AND_EXCHANGE,
|
||||
GET_AND_SET,
|
||||
GET_AND_ADD;
|
||||
}
|
||||
|
||||
enum TestAccessMode {
|
||||
get(TestAccessType.get),
|
||||
set(TestAccessType.set),
|
||||
getVolatile(TestAccessType.get),
|
||||
setVolatile(TestAccessType.set),
|
||||
getAcquire(TestAccessType.get),
|
||||
setRelease(TestAccessType.set),
|
||||
getOpaque(TestAccessType.get),
|
||||
setOpaque(TestAccessType.set),
|
||||
compareAndSet(TestAccessType.compareAndSet),
|
||||
compareAndExchangeVolatile(TestAccessType.compareAndExchange),
|
||||
compareAndExchangeAcquire(TestAccessType.compareAndExchange),
|
||||
compareAndExchangeRelease(TestAccessType.compareAndExchange),
|
||||
weakCompareAndSet(TestAccessType.compareAndSet),
|
||||
weakCompareAndSetAcquire(TestAccessType.compareAndSet),
|
||||
weakCompareAndSetRelease(TestAccessType.compareAndSet),
|
||||
getAndSet(TestAccessType.getAndSet),
|
||||
getAndAdd(TestAccessType.getAndAdd),
|
||||
addAndGet(TestAccessType.getAndAdd),;
|
||||
GET(TestAccessType.GET),
|
||||
SET(TestAccessType.SET),
|
||||
GET_VOLATILE(TestAccessType.GET),
|
||||
SET_VOLATILE(TestAccessType.SET),
|
||||
GET_ACQUIRE(TestAccessType.GET),
|
||||
SET_RELEASE(TestAccessType.SET),
|
||||
GET_OPAQUE(TestAccessType.GET),
|
||||
SET_OPAQUE(TestAccessType.SET),
|
||||
COMPARE_AND_SET(TestAccessType.COMPARE_AND_SET),
|
||||
COMPARE_AND_EXCHANGE_VOLATILE(TestAccessType.COMPARE_AND_EXCHANGE),
|
||||
COMPARE_AND_EXCHANGE_ACQUIRE(TestAccessType.COMPARE_AND_EXCHANGE),
|
||||
COMPARE_AND_EXCHANGE_RELEASE(TestAccessType.COMPARE_AND_EXCHANGE),
|
||||
WEAK_COMPARE_AND_SET(TestAccessType.COMPARE_AND_SET),
|
||||
WEAK_COMPARE_AND_SET_ACQUIRE(TestAccessType.COMPARE_AND_SET),
|
||||
WEAK_COMPARE_AND_SET_RELEASE(TestAccessType.COMPARE_AND_SET),
|
||||
GET_AND_SET(TestAccessType.GET_AND_SET),
|
||||
GET_AND_ADD(TestAccessType.GET_AND_ADD),
|
||||
ADD_AND_GET(TestAccessType.GET_AND_ADD),;
|
||||
|
||||
final TestAccessType at;
|
||||
final boolean isPolyMorphicInReturnType;
|
||||
@ -162,7 +162,8 @@ abstract class VarHandleBaseTest {
|
||||
this.at = at;
|
||||
|
||||
try {
|
||||
Method m = VarHandle.class.getMethod(name(), Object[].class);
|
||||
VarHandle.AccessMode vh_am = toAccessMode();
|
||||
Method m = VarHandle.class.getMethod(vh_am.methodName(), Object[].class);
|
||||
this.returnType = m.getReturnType();
|
||||
isPolyMorphicInReturnType = returnType != Object.class;
|
||||
}
|
||||
@ -214,7 +215,7 @@ abstract class VarHandleBaseTest {
|
||||
try {
|
||||
mh = MethodHandles.publicLookup().
|
||||
findVirtual(VarHandle.class,
|
||||
tam.name(),
|
||||
tam.toAccessMode().methodName(),
|
||||
mt);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -441,33 +442,33 @@ abstract class VarHandleBaseTest {
|
||||
assertEquals(amt.parameterList().subList(0, pts.size()), pts);
|
||||
}
|
||||
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.get)) {
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.GET)) {
|
||||
MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
|
||||
assertEquals(mt.returnType(), vh.varType());
|
||||
assertEquals(mt.parameterList(), pts);
|
||||
}
|
||||
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.set)) {
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.SET)) {
|
||||
MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
|
||||
assertEquals(mt.returnType(), void.class);
|
||||
assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
|
||||
}
|
||||
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.compareAndSet)) {
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
|
||||
MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
|
||||
assertEquals(mt.returnType(), boolean.class);
|
||||
assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
|
||||
assertEquals(mt.parameterType(mt.parameterCount() - 2), vh.varType());
|
||||
}
|
||||
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.compareAndExchange)) {
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
|
||||
MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
|
||||
assertEquals(mt.returnType(), vh.varType());
|
||||
assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
|
||||
assertEquals(mt.parameterType(mt.parameterCount() - 2), vh.varType());
|
||||
}
|
||||
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.getAndSet, TestAccessType.getAndAdd)) {
|
||||
for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.GET_AND_SET, TestAccessType.GET_AND_ADD)) {
|
||||
MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
|
||||
assertEquals(mt.returnType(), vh.varType());
|
||||
assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
|
||||
|
||||
@ -90,27 +90,27 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest {
|
||||
|
||||
@Test(dataProvider = "varHandlesProvider")
|
||||
public void testIsAccessModeSupported(VarHandle vh) {
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -90,27 +90,27 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest {
|
||||
|
||||
@Test(dataProvider = "varHandlesProvider")
|
||||
public void testIsAccessModeSupported(VarHandle vh) {
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -90,27 +90,27 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest {
|
||||
|
||||
@Test(dataProvider = "varHandlesProvider")
|
||||
public void testIsAccessModeSupported(VarHandle vh) {
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -90,27 +90,27 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest {
|
||||
|
||||
@Test(dataProvider = "varHandlesProvider")
|
||||
public void testIsAccessModeSupported(VarHandle vh) {
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -90,27 +90,27 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest {
|
||||
|
||||
@Test(dataProvider = "varHandlesProvider")
|
||||
public void testIsAccessModeSupported(VarHandle vh) {
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
|
||||
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
|
||||
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
|
||||
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user