Merge
This commit is contained in:
commit
3968717f42
@ -377,3 +377,4 @@ d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
|
||||
a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
|
||||
be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133
|
||||
065724348690eda41fc69112278d8da6dcde548c jdk-9+134
|
||||
82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135
|
||||
|
@ -377,3 +377,4 @@ f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131
|
||||
1ab4b9399c4cba584f66c1c088188f2f565fbf9c jdk-9+132
|
||||
2021bfedf1c478a4808a7711a6090682a12f4c0e jdk-9+133
|
||||
1a497f5ca0cfd88115cc7daa8af8a62b8741caf2 jdk-9+134
|
||||
094d0db606db976045f594dba47d4593b715cc81 jdk-9+135
|
||||
|
@ -537,3 +537,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
|
||||
713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132
|
||||
a25e0fb6033245ab075136e744d362ce765464cd jdk-9+133
|
||||
b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134
|
||||
3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135
|
||||
|
@ -377,3 +377,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123
|
||||
d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
|
||||
3cdae27c90b5e41afe75eab904fda19fac076330 jdk-9+133
|
||||
803adcd526d74ae0b64948d1f8260c2dbe514779 jdk-9+134
|
||||
021369229cfd0b5feb76834b2ea498f47f43c0f3 jdk-9+135
|
||||
|
@ -81,7 +81,7 @@ UNICODEDATA := $(JDK_TOPDIR)/make/data/unicodedata/UnicodeData.txt
|
||||
|
||||
# output
|
||||
BASE_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/java.base/sun/text/resources
|
||||
LD_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/jdk.localedata/sun/text/resources
|
||||
LD_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/jdk.localedata/sun/text/resources/ext
|
||||
BIFILES := $(BASE_DATA_PKG_DIR)/CharacterBreakIteratorData \
|
||||
$(BASE_DATA_PKG_DIR)/WordBreakIteratorData \
|
||||
$(BASE_DATA_PKG_DIR)/LineBreakIteratorData \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
@ -476,7 +476,8 @@ class Package {
|
||||
} else if (localICs.isEmpty()) {
|
||||
// It was a non-empty diff, but the local ICs were absent.
|
||||
actualICs = null;
|
||||
changed = 0; // [] => null, no tuple change
|
||||
// [] => null, no tuple change, but attribute deletion.
|
||||
changed = -1;
|
||||
} else {
|
||||
// Non-trivial diff was transmitted.
|
||||
actualICs = computeICdiff();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
@ -1193,18 +1193,21 @@ class PackageReader extends BandStructure {
|
||||
cls.visitRefs(VRM_CLASSIC, cpRefs);
|
||||
|
||||
ArrayList<BootstrapMethodEntry> bsms = new ArrayList<>();
|
||||
/*
|
||||
* BootstrapMethod(BSMs) are added here before InnerClasses(ICs),
|
||||
* so as to ensure the order. Noting that the BSMs may be
|
||||
* removed if they are not found in the CP, after the ICs expansion.
|
||||
*/
|
||||
cls.addAttribute(Package.attrBootstrapMethodsEmpty.canonicalInstance());
|
||||
|
||||
// flesh out the local constant pool
|
||||
ConstantPool.completeReferencesIn(cpRefs, true, bsms);
|
||||
|
||||
// add the bsm and references as required
|
||||
if (!bsms.isEmpty()) {
|
||||
cls.addAttribute(Package.attrBootstrapMethodsEmpty.canonicalInstance());
|
||||
cpRefs.add(Package.getRefString("BootstrapMethods"));
|
||||
Collections.sort(bsms);
|
||||
cls.setBootstrapMethods(bsms);
|
||||
}
|
||||
|
||||
// Now that we know all our local class references,
|
||||
// compute the InnerClasses attribute.
|
||||
// An InnerClasses attribute usually gets added here,
|
||||
// although it might already have been present.
|
||||
int changed = cls.expandLocalICs();
|
||||
|
||||
if (changed != 0) {
|
||||
@ -1221,16 +1224,6 @@ class PackageReader extends BandStructure {
|
||||
ConstantPool.completeReferencesIn(cpRefs, true, bsms);
|
||||
}
|
||||
|
||||
// remove the attr previously set, otherwise add the bsm and
|
||||
// references as required
|
||||
if (bsms.isEmpty()) {
|
||||
cls.attributes.remove(Package.attrBootstrapMethodsEmpty.canonicalInstance());
|
||||
} else {
|
||||
cpRefs.add(Package.getRefString("BootstrapMethods"));
|
||||
Collections.sort(bsms);
|
||||
cls.setBootstrapMethods(bsms);
|
||||
}
|
||||
|
||||
// construct a local constant pool
|
||||
int numDoubles = 0;
|
||||
for (Entry e : cpRefs) {
|
||||
|
@ -18,7 +18,7 @@ pack.class.attribute.CompilationID = RUH
|
||||
pack.class.attribute.Module = NH[RUHFH]NH[RUHNH[RUH]]NH[RCH]NH[RCHRCH]
|
||||
pack.class.attribute.ConcealedPackages = NH[RUH]
|
||||
pack.class.attribute.Version = RUH
|
||||
pack.class.attribute.MainClass = RUH
|
||||
pack.class.attribute.MainClass = RCH
|
||||
pack.class.attribute.TargetPlatform = RUHRUHRUH
|
||||
pack.class.attribute.Hashes = RUHNH[RUHRUH]
|
||||
|
||||
|
@ -27,6 +27,7 @@ package java.lang;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
@ -46,12 +47,16 @@ import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.Stack;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Vector;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import jdk.internal.perf.PerfCounter;
|
||||
import jdk.internal.module.ServicesCatalog;
|
||||
@ -1167,17 +1172,7 @@ public abstract class ClassLoader {
|
||||
protected final Class<?> findSystemClass(String name)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
ClassLoader system = getSystemClassLoader();
|
||||
if (system == null) {
|
||||
if (!checkName(name))
|
||||
throw new ClassNotFoundException(name);
|
||||
Class<?> cls = findBootstrapClass(name);
|
||||
if (cls == null) {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
return system.loadClass(name);
|
||||
return getSystemClassLoader().loadClass(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1353,6 +1348,57 @@ public abstract class ClassLoader {
|
||||
return new CompoundEnumeration<>(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream whose elements are the URLs of all the resources with
|
||||
* the given name. A resource is some data (images, audio, text, etc) that
|
||||
* can be accessed by class code in a way that is independent of the
|
||||
* location of the code.
|
||||
*
|
||||
* Resources in a named module are private to that module. This method does
|
||||
* not find resources in named modules.
|
||||
*
|
||||
* <p> The name of a resource is a {@code /}-separated path name that
|
||||
* identifies the resource.
|
||||
*
|
||||
* <p> The search order is described in the documentation for {@link
|
||||
* #getResource(String)}.
|
||||
*
|
||||
* <p> The resources will be located when the returned stream is evaluated.
|
||||
* If the evaluation results in an {@code IOException} then the I/O
|
||||
* exception is wrapped in an {@link UncheckedIOException} that is then
|
||||
* thrown.
|
||||
*
|
||||
* @apiNote When overriding this method it is recommended that an
|
||||
* implementation ensures that any delegation is consistent with the {@link
|
||||
* #getResource(java.lang.String) getResource(String)} method. This should
|
||||
* ensure that the first element returned by the stream is the same
|
||||
* resource that the {@code getResource(String)} method would return.
|
||||
*
|
||||
* @param name
|
||||
* The resource name
|
||||
*
|
||||
* @return A stream of resource {@link java.net.URL URL} objects. If no
|
||||
* resources could be found, the stream will be empty. Resources
|
||||
* that the class loader doesn't have access to will not be in the
|
||||
* stream.
|
||||
*
|
||||
* @see #findResources(String)
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public Stream<URL> resources(String name) {
|
||||
int characteristics = Spliterator.NONNULL | Spliterator.IMMUTABLE;
|
||||
Supplier<Spliterator<URL>> si = () -> {
|
||||
try {
|
||||
return Spliterators.spliteratorUnknownSize(
|
||||
getResources(name).asIterator(), characteristics);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
};
|
||||
return StreamSupport.stream(si, characteristics, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the resource with the given name. Class loader implementations
|
||||
* should override this method to specify where to find resources.
|
||||
@ -1437,11 +1483,7 @@ public abstract class ClassLoader {
|
||||
* @since 1.1
|
||||
*/
|
||||
public static URL getSystemResource(String name) {
|
||||
ClassLoader system = getSystemClassLoader();
|
||||
if (system == null) {
|
||||
return BootLoader.findResource(name);
|
||||
}
|
||||
return system.getResource(name);
|
||||
return getSystemClassLoader().getResource(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1464,17 +1506,13 @@ public abstract class ClassLoader {
|
||||
*
|
||||
* @throws IOException
|
||||
* If I/O errors occur
|
||||
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public static Enumeration<URL> getSystemResources(String name)
|
||||
throws IOException
|
||||
{
|
||||
ClassLoader system = getSystemClassLoader();
|
||||
if (system == null) {
|
||||
return BootLoader.findResources(name);
|
||||
}
|
||||
return system.getResources(name);
|
||||
return getSystemClassLoader().getResources(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1631,8 +1669,7 @@ public abstract class ClassLoader {
|
||||
* this method during startup should take care not to cache the return
|
||||
* value until the system is fully initialized.
|
||||
*
|
||||
* @return The system <tt>ClassLoader</tt> for delegation, or
|
||||
* <tt>null</tt> if none
|
||||
* @return The system <tt>ClassLoader</tt> for delegation
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager is present, and the caller's class loader
|
||||
@ -1941,9 +1978,14 @@ public abstract class ClassLoader {
|
||||
* @return The {@code Package} of the given name defined by this class loader,
|
||||
* or {@code null} if not found
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* if {@code name} is {@code null}.
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public final Package getDefinedPackage(String name) {
|
||||
Objects.requireNonNull(name, "name cannot be null");
|
||||
|
||||
NamedPackage p = packages.get(name);
|
||||
if (p == null)
|
||||
return null;
|
||||
@ -1981,6 +2023,9 @@ public abstract class ClassLoader {
|
||||
* @return The {@code Package} corresponding to the given name defined by
|
||||
* this class loader or its ancestors, or {@code null} if not found.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* if {@code name} is {@code null}.
|
||||
*
|
||||
* @deprecated
|
||||
* If multiple class loaders delegate to each other and define classes
|
||||
* with the same package name, and one such loader relies on the lookup
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 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
|
||||
@ -29,21 +29,18 @@ package java.lang;
|
||||
* The {@code Compiler} class is provided to support Java-to-native-code
|
||||
* compilers and related services. By design, the {@code Compiler} class does
|
||||
* nothing; it serves as a placeholder for a JIT compiler implementation.
|
||||
* If no compiler is available, these methods do nothing.
|
||||
*
|
||||
* <p> When the Java Virtual Machine first starts, it determines if the system
|
||||
* property {@code java.compiler} exists. (System properties are accessible
|
||||
* through {@link System#getProperty(String)} and {@link
|
||||
* System#getProperty(String, String)}. If so, it is assumed to be the name of
|
||||
* a library (with a platform-dependent exact location and type); {@link
|
||||
* System#loadLibrary} is called to load that library. If this loading
|
||||
* succeeds, the function named {@code java_lang_Compiler_start()} in that
|
||||
* library is called.
|
||||
*
|
||||
* <p> If no compiler is available, these methods do nothing.
|
||||
* @deprecated JIT compilers and their technologies vary too widely to
|
||||
* be controlled effectively by a standardized interface. As such, many
|
||||
* JIT compiler implementations ignore this interface, and are instead
|
||||
* controllable by implementation-specific mechanisms such as command-line
|
||||
* options. This class is subject to removal in a future version of Java SE.
|
||||
*
|
||||
* @author Frank Yellin
|
||||
* @since 1.0
|
||||
*/
|
||||
@Deprecated(since="9", forRemoval=true)
|
||||
public final class Compiler {
|
||||
private Compiler() {} // don't make instances
|
||||
|
||||
|
@ -317,6 +317,9 @@ public class Package extends NamedPackage implements java.lang.reflect.Annotated
|
||||
* @return The {@code Package} of the given name defined by the caller's
|
||||
* class loader or its ancestors, or {@code null} if not found.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* if {@code name} is {@code null}.
|
||||
*
|
||||
* @deprecated
|
||||
* If multiple class loaders delegate to each other and define classes
|
||||
* with the same package name, and one such loader relies on the lookup
|
||||
|
@ -733,6 +733,7 @@ public class Runtime {
|
||||
* @deprecated
|
||||
* This method was intended to control instruction tracing.
|
||||
* It has been superseded by JVM-specific tracing mechanisms.
|
||||
* This method is subject to removal in a future version of Java SE.
|
||||
*
|
||||
* @param on ignored
|
||||
*/
|
||||
@ -745,6 +746,7 @@ public class Runtime {
|
||||
* @deprecated
|
||||
* This method was intended to control method call tracing.
|
||||
* It has been superseded by JVM-specific tracing mechanisms.
|
||||
* This method is subject to removal in a future version of Java SE.
|
||||
*
|
||||
* @param on ignored
|
||||
*/
|
||||
|
@ -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
|
||||
@ -323,11 +323,9 @@ import java.util.StringTokenizer;
|
||||
* <td>usePolicy</td>
|
||||
* <td>Granting this permission disables the Java Plug-In's default
|
||||
* security prompting behavior.</td>
|
||||
* <td>For more information, refer to Java Plug-In's guides, <a href=
|
||||
* "../../../technotes/guides/plugin/developer_guide/security.html">
|
||||
* Applet Security Basics</a> and <a href=
|
||||
* "../../../technotes/guides/plugin/developer_guide/rsa_how.html#use">
|
||||
* usePolicy Permission</a>.</td>
|
||||
* <td>For more information, refer to the <a href=
|
||||
* "../../../technotes/guides/deploy/index.html">deployment guide</a>.
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>manageProcess</td>
|
||||
|
@ -334,11 +334,15 @@ final class StringConcatHelper {
|
||||
/**
|
||||
* Instantiates the String with given buffer and coder
|
||||
* @param buf buffer to use
|
||||
* @param index remaining index
|
||||
* @param coder coder to use
|
||||
* @return String resulting string
|
||||
*/
|
||||
static String newString(byte[] buf, byte coder) {
|
||||
static String newString(byte[] buf, int index, byte coder) {
|
||||
// Use the private, non-copying constructor (unsafe!)
|
||||
if (index != 0) {
|
||||
throw new InternalError("Storage is not completely initialized, " + index + " bytes left");
|
||||
}
|
||||
return new String(buf, coder);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,9 @@ class LambdaFormEditor {
|
||||
FOLD_ARGS = 11,
|
||||
FOLD_ARGS_TO_VOID = 12,
|
||||
PERMUTE_ARGS = 13,
|
||||
LOCAL_TYPES = 14;
|
||||
LOCAL_TYPES = 14,
|
||||
FOLD_SELECT_ARGS = 15,
|
||||
FOLD_SELECT_ARGS_TO_VOID = 16;
|
||||
|
||||
private static final boolean STRESS_TEST = false; // turn on to disable most packing
|
||||
private static final int
|
||||
@ -695,6 +697,72 @@ class LambdaFormEditor {
|
||||
return buf.endEdit();
|
||||
}
|
||||
|
||||
private LambdaForm makeArgumentCombinationForm(int pos,
|
||||
MethodType combinerType,
|
||||
int[] argPositions,
|
||||
boolean keepArguments,
|
||||
boolean dropResult) {
|
||||
LambdaFormBuffer buf = buffer();
|
||||
buf.startEdit();
|
||||
int combinerArity = combinerType.parameterCount();
|
||||
assert(combinerArity == argPositions.length);
|
||||
|
||||
int resultArity = (dropResult ? 0 : 1);
|
||||
|
||||
assert(pos <= lambdaForm.arity);
|
||||
assert(pos > 0); // cannot filter the MH arg itself
|
||||
assert(combinerType == combinerType.basicType());
|
||||
assert(combinerType.returnType() != void.class || dropResult);
|
||||
|
||||
BoundMethodHandle.SpeciesData oldData = oldSpeciesData();
|
||||
BoundMethodHandle.SpeciesData newData = newSpeciesData(L_TYPE);
|
||||
|
||||
// The newly created LF will run with a different BMH.
|
||||
// Switch over any pre-existing BMH field references to the new BMH class.
|
||||
Name oldBaseAddress = lambdaForm.parameter(0); // BMH holding the values
|
||||
buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress);
|
||||
Name newBaseAddress = oldBaseAddress.withConstraint(newData);
|
||||
buf.renameParameter(0, newBaseAddress);
|
||||
|
||||
Name getCombiner = new Name(newData.getterFunction(oldData.fieldCount()), newBaseAddress);
|
||||
Object[] combinerArgs = new Object[1 + combinerArity];
|
||||
combinerArgs[0] = getCombiner;
|
||||
Name[] newParams;
|
||||
if (keepArguments) {
|
||||
newParams = new Name[0];
|
||||
for (int i = 0; i < combinerArity; i++) {
|
||||
combinerArgs[i + 1] = lambdaForm.parameter(1 + argPositions[i]);
|
||||
assert (basicType(combinerType.parameterType(i)) == lambdaForm.parameterType(1 + argPositions[i]));
|
||||
}
|
||||
} else {
|
||||
newParams = new Name[combinerArity];
|
||||
for (int i = 0; i < newParams.length; i++) {
|
||||
newParams[i] = lambdaForm.parameter(1 + argPositions[i]);
|
||||
assert (basicType(combinerType.parameterType(i)) == lambdaForm.parameterType(1 + argPositions[i]));
|
||||
}
|
||||
System.arraycopy(newParams, 0,
|
||||
combinerArgs, 1, combinerArity);
|
||||
}
|
||||
Name callCombiner = new Name(combinerType, combinerArgs);
|
||||
|
||||
// insert the two new expressions
|
||||
int exprPos = lambdaForm.arity();
|
||||
buf.insertExpression(exprPos+0, getCombiner);
|
||||
buf.insertExpression(exprPos+1, callCombiner);
|
||||
|
||||
// insert new arguments, if needed
|
||||
int argPos = pos + resultArity; // skip result parameter
|
||||
for (Name newParam : newParams) {
|
||||
buf.insertParameter(argPos++, newParam);
|
||||
}
|
||||
assert(buf.lastIndexOf(callCombiner) == exprPos+1+newParams.length);
|
||||
if (!dropResult) {
|
||||
buf.replaceParameterByCopy(pos, exprPos+1+newParams.length);
|
||||
}
|
||||
|
||||
return buf.endEdit();
|
||||
}
|
||||
|
||||
LambdaForm filterReturnForm(BasicType newType, boolean constantZero) {
|
||||
byte kind = (constantZero ? Transform.FILTER_RETURN_TO_ZERO : Transform.FILTER_RETURN);
|
||||
Transform key = Transform.of(kind, newType.ordinal());
|
||||
@ -759,6 +827,21 @@ class LambdaFormEditor {
|
||||
return putInCache(key, form);
|
||||
}
|
||||
|
||||
LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType, int ... argPositions) {
|
||||
byte kind = (dropResult ? Transform.FOLD_SELECT_ARGS_TO_VOID
|
||||
: Transform.FOLD_SELECT_ARGS);
|
||||
int[] keyArgs = Arrays.copyOf(argPositions, argPositions.length + 1);
|
||||
keyArgs[argPositions.length] = foldPos;
|
||||
Transform key = Transform.of(kind, keyArgs);
|
||||
LambdaForm form = getInCache(key);
|
||||
if (form != null) {
|
||||
assert(form.arity == lambdaForm.arity - (kind == Transform.FOLD_SELECT_ARGS ? 1 : 0));
|
||||
return form;
|
||||
}
|
||||
form = makeArgumentCombinationForm(foldPos, combinerType, argPositions, true, dropResult);
|
||||
return putInCache(key, form);
|
||||
}
|
||||
|
||||
LambdaForm permuteArgumentsForm(int skip, int[] reorder) {
|
||||
assert(skip == 1); // skip only the leading MH argument, names[0]
|
||||
int length = lambdaForm.names.length;
|
||||
|
@ -3943,6 +3943,33 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
return rtype;
|
||||
}
|
||||
|
||||
private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType, int ... argPos) {
|
||||
int foldArgs = combinerType.parameterCount();
|
||||
if (argPos.length != foldArgs) {
|
||||
throw newIllegalArgumentException("combiner and argument map must be equal size", combinerType, argPos.length);
|
||||
}
|
||||
Class<?> rtype = combinerType.returnType();
|
||||
int foldVals = rtype == void.class ? 0 : 1;
|
||||
boolean ok = true;
|
||||
for (int i = 0; i < foldArgs; i++) {
|
||||
int arg = argPos[i];
|
||||
if (arg < 0 || arg > targetType.parameterCount()) {
|
||||
throw newIllegalArgumentException("arg outside of target parameterRange", targetType, arg);
|
||||
}
|
||||
if (combinerType.parameterType(i) != targetType.parameterType(arg)) {
|
||||
throw newIllegalArgumentException("target argument type at position " + arg
|
||||
+ " must match combiner argument type at index " + i + ": " + targetType
|
||||
+ " -> " + combinerType + ", map: " + Arrays.toString(argPos));
|
||||
}
|
||||
}
|
||||
if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos)) {
|
||||
ok = false;
|
||||
}
|
||||
if (!ok)
|
||||
throw misMatchedTypes("target and combiner types", targetType, combinerType);
|
||||
return rtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a method handle which adapts a target method handle,
|
||||
* by guarding it with a test, a boolean-valued method handle.
|
||||
@ -4949,6 +4976,27 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* As {@see foldArguments(MethodHandle, int, MethodHandle)}, but with the
|
||||
* added capability of selecting the arguments from the targets parameters
|
||||
* to call the combiner with. This allows us to avoid some simple cases of
|
||||
* permutations and padding the combiner with dropArguments to select the
|
||||
* right argument, which may ultimately produce fewer intermediaries.
|
||||
*/
|
||||
static MethodHandle foldArguments(MethodHandle target, int pos, MethodHandle combiner, int ... argPositions) {
|
||||
MethodType targetType = target.type();
|
||||
MethodType combinerType = combiner.type();
|
||||
Class<?> rtype = foldArgumentChecks(pos, targetType, combinerType, argPositions);
|
||||
BoundMethodHandle result = target.rebind();
|
||||
boolean dropResult = rtype == void.class;
|
||||
LambdaForm lform = result.editor().foldArgumentsForm(1 + pos, dropResult, combinerType.basicType(), argPositions);
|
||||
MethodType newType = targetType;
|
||||
if (!dropResult) {
|
||||
newType = newType.dropParameterTypes(pos, pos + 1);
|
||||
}
|
||||
result = result.copyWithExtendL(newType, lform, combiner);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void checkLoop0(MethodHandle[][] clauses) {
|
||||
if (clauses == null || clauses.length == 0) {
|
||||
|
@ -563,9 +563,8 @@ public final class StringConcatFactory {
|
||||
}
|
||||
|
||||
if ((lookup.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) {
|
||||
throw new StringConcatException(String.format(
|
||||
"Invalid caller: %s",
|
||||
lookup.lookupClass().getName()));
|
||||
throw new StringConcatException("Invalid caller: " +
|
||||
lookup.lookupClass().getName());
|
||||
}
|
||||
|
||||
int cCount = 0;
|
||||
@ -1494,51 +1493,41 @@ public final class StringConcatFactory {
|
||||
// Drop all remaining parameter types, leave only helper arguments:
|
||||
MethodHandle mh;
|
||||
|
||||
mh = MethodHandles.dropArguments(NEW_STRING, 2, ptypes);
|
||||
mh = MethodHandles.dropArguments(mh, 0, int.class);
|
||||
mh = MethodHandles.dropArguments(NEW_STRING, 3, ptypes);
|
||||
|
||||
// Safety: check that remaining index is zero -- that would mean the storage is completely
|
||||
// overwritten, and no leakage of uninitialized data occurred.
|
||||
mh = MethodHandles.filterArgument(mh, 0, CHECK_INDEX);
|
||||
|
||||
// Mix in prependers. This happens when (int, byte[], byte) = (index, storage, coder) is already
|
||||
// Mix in prependers. This happens when (byte[], int, byte) = (storage, index, coder) is already
|
||||
// known from the combinators below. We are assembling the string backwards, so "index" is the
|
||||
// *ending* index.
|
||||
for (RecipeElement el : recipe.getElements()) {
|
||||
MethodHandle prepender;
|
||||
// Do the prepend, and put "new" index at index 1
|
||||
mh = MethodHandles.dropArguments(mh, 2, int.class);
|
||||
switch (el.getTag()) {
|
||||
case TAG_CONST:
|
||||
case TAG_CONST: {
|
||||
Object cnst = el.getValue();
|
||||
prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
|
||||
MethodHandle prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
|
||||
mh = MethodHandles.foldArguments(mh, 1, prepender,
|
||||
2, 0, 3 // index, storage, coder
|
||||
);
|
||||
break;
|
||||
case TAG_ARG:
|
||||
}
|
||||
case TAG_ARG: {
|
||||
int pos = el.getArgPos();
|
||||
prepender = selectArgument(prepender(ptypes[pos]), 3, ptypes, pos);
|
||||
MethodHandle prepender = prepender(ptypes[pos]);
|
||||
mh = MethodHandles.foldArguments(mh, 1, prepender,
|
||||
2, 0, 3, // index, storage, coder
|
||||
4 + pos // selected argument
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new StringConcatException("Unhandled tag: " + el.getTag());
|
||||
}
|
||||
|
||||
// Remove "old" index from arguments
|
||||
mh = MethodHandles.dropArguments(mh, 1, int.class);
|
||||
|
||||
// Do the prepend, and put "new" index at index 0
|
||||
mh = MethodHandles.foldArguments(mh, prepender);
|
||||
}
|
||||
|
||||
// Prepare the argument list for prepending. The tree below would instantiate
|
||||
// the storage byte[] into argument 0, so we need to swap "storage" and "index".
|
||||
// The index at this point equals to "size", and resides at argument 1.
|
||||
{
|
||||
MethodType nmt = mh.type()
|
||||
.changeParameterType(0, byte[].class)
|
||||
.changeParameterType(1, int.class);
|
||||
mh = MethodHandles.permuteArguments(mh, nmt, swap10(nmt.parameterCount()));
|
||||
}
|
||||
|
||||
// Fold in byte[] instantiation at argument 0.
|
||||
MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypes);
|
||||
mh = MethodHandles.foldArguments(mh, combiner);
|
||||
// Fold in byte[] instantiation at argument 0
|
||||
mh = MethodHandles.foldArguments(mh, 0, NEW_ARRAY,
|
||||
1, 2 // index, coder
|
||||
);
|
||||
|
||||
// Start combining length and coder mixers.
|
||||
//
|
||||
@ -1567,12 +1556,8 @@ public final class StringConcatFactory {
|
||||
int ac = el.getArgPos();
|
||||
|
||||
Class<?> argClass = ptypes[ac];
|
||||
MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypes, ac);
|
||||
lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
|
||||
lm = MethodHandles.dropArguments(lm, 2, byte.class);
|
||||
|
||||
MethodHandle cm = selectArgument(coderMixer(argClass), 1, ptypes, ac);
|
||||
cm = MethodHandles.dropArguments(cm, 0, int.class); // (**)
|
||||
MethodHandle lm = lengthMixer(argClass);
|
||||
MethodHandle cm = coderMixer(argClass);
|
||||
|
||||
// Read this bottom up:
|
||||
|
||||
@ -1580,12 +1565,18 @@ public final class StringConcatFactory {
|
||||
mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
|
||||
|
||||
// 3. Compute "new-index", producing ("new-index", "new-coder", "old-index", "old-coder", <args>)
|
||||
// Length mixer ignores both "new-coder" and "old-coder" due to dropArguments above (*)
|
||||
mh = MethodHandles.foldArguments(mh, lm);
|
||||
// Length mixer needs old index, plus the appropriate argument
|
||||
mh = MethodHandles.foldArguments(mh, 0, lm,
|
||||
2, // old-index
|
||||
4 + ac // selected argument
|
||||
);
|
||||
|
||||
// 2. Compute "new-coder", producing ("new-coder", "old-index", "old-coder", <args>)
|
||||
// Coder mixer ignores the "old-index" arg due to dropArguments above (**)
|
||||
mh = MethodHandles.foldArguments(mh, cm);
|
||||
// Coder mixer needs old coder, plus the appropriate argument.
|
||||
mh = MethodHandles.foldArguments(mh, 0, cm,
|
||||
2, // old-coder
|
||||
3 + ac // selected argument
|
||||
);
|
||||
|
||||
// 1. The mh shape here is ("old-index", "old-coder", <args>)
|
||||
break;
|
||||
@ -1606,41 +1597,11 @@ public final class StringConcatFactory {
|
||||
return mh;
|
||||
}
|
||||
|
||||
private static int[] swap10(int count) {
|
||||
int[] perm = new int[count];
|
||||
perm[0] = 1;
|
||||
perm[1] = 0;
|
||||
for (int i = 2; i < count; i++) {
|
||||
perm[i] = i;
|
||||
}
|
||||
return perm;
|
||||
}
|
||||
|
||||
// Adapts: (...prefix..., parameter[pos])R -> (...prefix..., ...parameters...)R
|
||||
private static MethodHandle selectArgument(MethodHandle mh, int prefix, Class<?>[] ptypes, int pos) {
|
||||
if (pos == 0) {
|
||||
return MethodHandles.dropArguments(mh, prefix + 1, Arrays.copyOfRange(ptypes, 1, ptypes.length));
|
||||
} else if (pos == ptypes.length - 1) {
|
||||
return MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, ptypes.length - 1));
|
||||
} else { // 0 < pos < ptypes.size() - 1
|
||||
MethodHandle t = MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, pos));
|
||||
return MethodHandles.dropArguments(t, prefix + 1 + pos, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
private static byte[] newArray(int length, byte coder) {
|
||||
return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, length << coder);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
private static int checkIndex(int index) {
|
||||
if (index != 0) {
|
||||
throw new IllegalStateException("Storage is not completely initialized, " + index + " bytes left");
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private static MethodHandle prepender(Class<?> cl) {
|
||||
return PREPENDERS.computeIfAbsent(cl, PREPEND);
|
||||
}
|
||||
@ -1678,7 +1639,6 @@ public final class StringConcatFactory {
|
||||
};
|
||||
|
||||
private static final MethodHandle NEW_STRING;
|
||||
private static final MethodHandle CHECK_INDEX;
|
||||
private static final MethodHandle NEW_ARRAY;
|
||||
private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS;
|
||||
private static final ConcurrentMap<Class<?>, MethodHandle> LENGTH_MIXERS;
|
||||
@ -1699,9 +1659,8 @@ public final class StringConcatFactory {
|
||||
LENGTH_MIXERS = new ConcurrentHashMap<>();
|
||||
CODER_MIXERS = new ConcurrentHashMap<>();
|
||||
|
||||
NEW_STRING = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newString", String.class, byte[].class, byte.class);
|
||||
NEW_STRING = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newString", String.class, byte[].class, int.class, byte.class);
|
||||
NEW_ARRAY = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "newArray", byte[].class, int.class, byte.class);
|
||||
CHECK_INDEX = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "checkIndex", int.class, int.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,6 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
||||
* {@link #getAndAdd getAndAdd},
|
||||
* {@link #getAndAddAcquire getAndAddAcquire},
|
||||
* {@link #getAndAddRelease getAndAddRelease},
|
||||
* {@link #addAndGet addAndGet}.
|
||||
* <li>bitwise atomic update access modes that, for example, atomically get and
|
||||
* bitwise OR the value of a variable under specified memory ordering
|
||||
* effects.
|
||||
|
@ -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
|
||||
@ -43,8 +43,7 @@
|
||||
* implementing memory-sensitive caches, weak references are for
|
||||
* implementing canonicalizing mappings that do not prevent their keys
|
||||
* (or values) from being reclaimed, and phantom references are for
|
||||
* scheduling pre-mortem cleanup actions in a more flexible way than
|
||||
* is possible with the Java finalization mechanism.
|
||||
* scheduling post-mortem cleanup actions.
|
||||
* Post-mortem cleanup actions can be registered and managed by a
|
||||
* {@link java.lang.ref.Cleaner}.
|
||||
*
|
||||
|
@ -52,7 +52,7 @@ import java.io.ByteArrayInputStream;
|
||||
* {@link MessageDigest}),
|
||||
* so that in order to compute intermediate digests, a caller should
|
||||
* retain a handle onto the digest object, and clone it for each
|
||||
* digest to be computed, leaving the orginal digest untouched.
|
||||
* digest to be computed, leaving the original digest untouched.
|
||||
*
|
||||
* @see MessageDigest
|
||||
*
|
||||
|
@ -76,7 +76,7 @@ import sun.security.util.Debug;
|
||||
* {@code g} parameters. If the modulus size is not one of the above
|
||||
* values, the <i>Sun</i> provider creates a new set of parameters. Other
|
||||
* providers might have precomputed parameter sets for more than just the
|
||||
* three modulus sizes mentioned above. Still others might not have a list of
|
||||
* modulus sizes mentioned above. Still others might not have a list of
|
||||
* precomputed parameters at all and instead always create new parameter sets.
|
||||
*
|
||||
* <li><b>Algorithm-Specific Initialization</b>
|
||||
@ -393,7 +393,7 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
* of randomness.
|
||||
* (If none of the installed providers supply an implementation of
|
||||
* {@code SecureRandom}, a system-provided source of randomness is
|
||||
* used.).
|
||||
* used.)
|
||||
*
|
||||
* <p>This concrete method has been added to this previously-defined
|
||||
* abstract class.
|
||||
|
@ -38,7 +38,7 @@ import sun.security.jca.JCAUtil;
|
||||
* for the {@code Signature} class, which is used to provide the
|
||||
* functionality of a digital signature algorithm. Digital signatures are used
|
||||
* for authentication and integrity assurance of digital data.
|
||||
*.
|
||||
*
|
||||
* <p> All the abstract methods in this class must be implemented by each
|
||||
* cryptographic service provider who wishes to supply the implementation
|
||||
* of a particular signature algorithm.
|
||||
|
@ -81,8 +81,8 @@ import java.util.function.Consumer;
|
||||
* Java Collections Framework</a>.
|
||||
*
|
||||
* @author Josh Bloch and Doug Lea
|
||||
* @since 1.6
|
||||
* @param <E> the type of elements held in this deque
|
||||
* @since 1.6
|
||||
*/
|
||||
public class ArrayDeque<E> extends AbstractCollection<E>
|
||||
implements Deque<E>, Cloneable, Serializable
|
||||
|
@ -31,6 +31,10 @@ import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* Container class for immutable collections. Not part of the public API.
|
||||
@ -61,9 +65,25 @@ class ImmutableCollections {
|
||||
*/
|
||||
static final double EXPAND_FACTOR = 2.0;
|
||||
|
||||
static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
|
||||
|
||||
// ---------- List Implementations ----------
|
||||
|
||||
static final class List0<E> extends AbstractList<E> implements RandomAccess, Serializable {
|
||||
abstract static class AbstractImmutableList<E> extends AbstractList<E>
|
||||
implements RandomAccess, Serializable {
|
||||
@Override public boolean add(E e) { throw uoe(); }
|
||||
@Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
|
||||
@Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
|
||||
@Override public void clear() { throw uoe(); }
|
||||
@Override public boolean remove(Object o) { throw uoe(); }
|
||||
@Override public boolean removeAll(Collection<?> c) { throw uoe(); }
|
||||
@Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
|
||||
@Override public void replaceAll(UnaryOperator<E> operator) { throw uoe(); }
|
||||
@Override public boolean retainAll(Collection<?> c) { throw uoe(); }
|
||||
@Override public void sort(Comparator<? super E> c) { throw uoe(); }
|
||||
}
|
||||
|
||||
static final class List0<E> extends AbstractImmutableList<E> {
|
||||
List0() { }
|
||||
|
||||
@Override
|
||||
@ -86,7 +106,7 @@ class ImmutableCollections {
|
||||
}
|
||||
}
|
||||
|
||||
static final class List1<E> extends AbstractList<E> implements RandomAccess, Serializable {
|
||||
static final class List1<E> extends AbstractImmutableList<E> {
|
||||
private final E e0;
|
||||
|
||||
List1(E e0) {
|
||||
@ -114,7 +134,7 @@ class ImmutableCollections {
|
||||
}
|
||||
}
|
||||
|
||||
static final class List2<E> extends AbstractList<E> implements RandomAccess, Serializable {
|
||||
static final class List2<E> extends AbstractImmutableList<E> {
|
||||
private final E e0;
|
||||
private final E e1;
|
||||
|
||||
@ -147,7 +167,7 @@ class ImmutableCollections {
|
||||
}
|
||||
}
|
||||
|
||||
static final class ListN<E> extends AbstractList<E> implements RandomAccess, Serializable {
|
||||
static final class ListN<E> extends AbstractImmutableList<E> {
|
||||
private final E[] elements;
|
||||
|
||||
@SafeVarargs
|
||||
@ -183,7 +203,17 @@ class ImmutableCollections {
|
||||
|
||||
// ---------- Set Implementations ----------
|
||||
|
||||
static final class Set0<E> extends AbstractSet<E> implements Serializable {
|
||||
abstract static class AbstractImmutableSet<E> extends AbstractSet<E> implements Serializable {
|
||||
@Override public boolean add(E e) { throw uoe(); }
|
||||
@Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
|
||||
@Override public void clear() { throw uoe(); }
|
||||
@Override public boolean remove(Object o) { throw uoe(); }
|
||||
@Override public boolean removeAll(Collection<?> c) { throw uoe(); }
|
||||
@Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
|
||||
@Override public boolean retainAll(Collection<?> c) { throw uoe(); }
|
||||
}
|
||||
|
||||
static final class Set0<E> extends AbstractImmutableSet<E> {
|
||||
Set0() { }
|
||||
|
||||
@Override
|
||||
@ -210,7 +240,7 @@ class ImmutableCollections {
|
||||
}
|
||||
}
|
||||
|
||||
static final class Set1<E> extends AbstractSet<E> implements Serializable {
|
||||
static final class Set1<E> extends AbstractImmutableSet<E> {
|
||||
private final E e0;
|
||||
|
||||
Set1(E e0) {
|
||||
@ -241,7 +271,7 @@ class ImmutableCollections {
|
||||
}
|
||||
}
|
||||
|
||||
static final class Set2<E> extends AbstractSet<E> implements Serializable {
|
||||
static final class Set2<E> extends AbstractImmutableSet<E> {
|
||||
private final E e0;
|
||||
private final E e1;
|
||||
|
||||
@ -312,7 +342,7 @@ class ImmutableCollections {
|
||||
* least one null is always present.
|
||||
* @param <E> the element type
|
||||
*/
|
||||
static final class SetN<E> extends AbstractSet<E> implements Serializable {
|
||||
static final class SetN<E> extends AbstractImmutableSet<E> {
|
||||
private final E[] elements;
|
||||
private final int size;
|
||||
|
||||
@ -403,7 +433,23 @@ class ImmutableCollections {
|
||||
|
||||
// ---------- Map Implementations ----------
|
||||
|
||||
static final class Map0<K,V> extends AbstractMap<K,V> implements Serializable {
|
||||
abstract static class AbstractImmutableMap<K,V> extends AbstractMap<K,V> implements Serializable {
|
||||
@Override public void clear() { throw uoe(); }
|
||||
@Override public V compute(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
|
||||
@Override public V computeIfAbsent(K key, Function<? super K,? extends V> mf) { throw uoe(); }
|
||||
@Override public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
|
||||
@Override public V merge(K key, V value, BiFunction<? super V,? super V,? extends V> rf) { throw uoe(); }
|
||||
@Override public V put(K key, V value) { throw uoe(); }
|
||||
@Override public void putAll(Map<? extends K,? extends V> m) { throw uoe(); }
|
||||
@Override public V putIfAbsent(K key, V value) { throw uoe(); }
|
||||
@Override public V remove(Object key) { throw uoe(); }
|
||||
@Override public boolean remove(Object key, Object value) { throw uoe(); }
|
||||
@Override public V replace(K key, V value) { throw uoe(); }
|
||||
@Override public boolean replace(K key, V oldValue, V newValue) { throw uoe(); }
|
||||
@Override public void replaceAll(BiFunction<? super K,? super V,? extends V> f) { throw uoe(); }
|
||||
}
|
||||
|
||||
static final class Map0<K,V> extends AbstractImmutableMap<K,V> {
|
||||
Map0() { }
|
||||
|
||||
@Override
|
||||
@ -430,7 +476,7 @@ class ImmutableCollections {
|
||||
}
|
||||
}
|
||||
|
||||
static final class Map1<K,V> extends AbstractMap<K,V> implements Serializable {
|
||||
static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
|
||||
private final K k0;
|
||||
private final V v0;
|
||||
|
||||
@ -472,7 +518,7 @@ class ImmutableCollections {
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
*/
|
||||
static final class MapN<K,V> extends AbstractMap<K,V> implements Serializable {
|
||||
static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
|
||||
private final Object[] table; // pairs of key, value
|
||||
private final int size; // number of pairs
|
||||
|
||||
|
@ -94,7 +94,8 @@ import java.util.function.UnaryOperator;
|
||||
*
|
||||
* <ul>
|
||||
* <li>They are <em>structurally immutable</em>. Elements cannot be added, removed,
|
||||
* or replaced. Attempts to do so result in {@code UnsupportedOperationException}.
|
||||
* or replaced. Calling any mutator method will always cause
|
||||
* {@code UnsupportedOperationException} to be thrown.
|
||||
* However, if the contained elements are themselves mutable,
|
||||
* this may cause the List's contents to appear to change.
|
||||
* <li>They disallow {@code null} elements. Attempts to create them with
|
||||
|
@ -119,7 +119,8 @@ import java.io.Serializable;
|
||||
*
|
||||
* <ul>
|
||||
* <li>They are <em>structurally immutable</em>. Keys and values cannot be added,
|
||||
* removed, or updated. Attempts to do so result in {@code UnsupportedOperationException}.
|
||||
* removed, or updated. Calling any mutator method will always cause
|
||||
* {@code UnsupportedOperationException} to be thrown.
|
||||
* However, if the contained keys or values are themselves mutable, this may cause the
|
||||
* Map to behave inconsistently or its contents to appear to change.
|
||||
* <li>They disallow {@code null} keys and values. Attempts to create them with
|
||||
|
@ -749,11 +749,11 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
||||
/**
|
||||
* Saves this queue to a stream (that is, serializes it).
|
||||
*
|
||||
* @param s the stream
|
||||
* @throws java.io.IOException if an I/O error occurs
|
||||
* @serialData The length of the array backing the instance is
|
||||
* emitted (int), followed by all of its elements
|
||||
* (each an {@code Object}) in the proper order.
|
||||
* @param s the stream
|
||||
* @throws java.io.IOException if an I/O error occurs
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException {
|
||||
|
@ -70,7 +70,8 @@ package java.util;
|
||||
*
|
||||
* <ul>
|
||||
* <li>They are <em>structurally immutable</em>. Elements cannot be added or
|
||||
* removed. Attempts to do so result in {@code UnsupportedOperationException}.
|
||||
* removed. Calling any mutator method will always cause
|
||||
* {@code UnsupportedOperationException} to be thrown.
|
||||
* However, if the contained elements are themselves mutable, this may cause the
|
||||
* Set to behave inconsistently or its contents to appear to change.
|
||||
* <li>They disallow {@code null} elements. Attempts to create them with
|
||||
|
@ -136,9 +136,9 @@ import java.util.function.Supplier;
|
||||
* }}</pre>
|
||||
*
|
||||
* @author Doug Lea
|
||||
* @since 1.8
|
||||
* @param <T> The result type returned by this future's {@code join}
|
||||
* and {@code get} methods
|
||||
* @since 1.8
|
||||
*/
|
||||
public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
||||
|
||||
|
@ -120,102 +120,114 @@ import java.lang.invoke.VarHandle;
|
||||
* to complete for some elements than others, either because of
|
||||
* intrinsic variation (for example I/O) or auxiliary effects such as
|
||||
* garbage collection. Because CountedCompleters provide their own
|
||||
* continuations, other threads need not block waiting to perform
|
||||
* them.
|
||||
* continuations, other tasks need not block waiting to perform them.
|
||||
*
|
||||
* <p>For example, here is an initial version of a class that uses
|
||||
* divide-by-two recursive decomposition to divide work into single
|
||||
* pieces (leaf tasks). Even when work is split into individual calls,
|
||||
* tree-based techniques are usually preferable to directly forking
|
||||
* leaf tasks, because they reduce inter-thread communication and
|
||||
* improve load balancing. In the recursive case, the second of each
|
||||
* pair of subtasks to finish triggers completion of its parent
|
||||
* <p>For example, here is an initial version of a utility method that
|
||||
* uses divide-by-two recursive decomposition to divide work into
|
||||
* single pieces (leaf tasks). Even when work is split into individual
|
||||
* calls, tree-based techniques are usually preferable to directly
|
||||
* forking leaf tasks, because they reduce inter-thread communication
|
||||
* and improve load balancing. In the recursive case, the second of
|
||||
* each pair of subtasks to finish triggers completion of their parent
|
||||
* (because no result combination is performed, the default no-op
|
||||
* implementation of method {@code onCompletion} is not overridden).
|
||||
* A static utility method sets up the base task and invokes it
|
||||
* (here, implicitly using the {@link ForkJoinPool#commonPool()}).
|
||||
* The utility method sets up the root task and invokes it (here,
|
||||
* implicitly using the {@link ForkJoinPool#commonPool()}). It is
|
||||
* straightforward and reliable (but not optimal) to always set the
|
||||
* pending count to the number of child tasks and call {@code
|
||||
* tryComplete()} immediately before returning.
|
||||
*
|
||||
* <pre> {@code
|
||||
* class MyOperation<E> { void apply(E e) { ... } }
|
||||
*
|
||||
* class ForEach<E> extends CountedCompleter<Void> {
|
||||
*
|
||||
* public static <E> void forEach(E[] array, MyOperation<E> op) {
|
||||
* new ForEach<E>(null, array, op, 0, array.length).invoke();
|
||||
* }
|
||||
*
|
||||
* final E[] array; final MyOperation<E> op; final int lo, hi;
|
||||
* ForEach(CountedCompleter<?> p, E[] array, MyOperation<E> op, int lo, int hi) {
|
||||
* super(p);
|
||||
* this.array = array; this.op = op; this.lo = lo; this.hi = hi;
|
||||
* }
|
||||
*
|
||||
* public void compute() { // version 1
|
||||
* if (hi - lo >= 2) {
|
||||
* int mid = (lo + hi) >>> 1;
|
||||
* setPendingCount(2); // must set pending count before fork
|
||||
* new ForEach(this, array, op, mid, hi).fork(); // right child
|
||||
* new ForEach(this, array, op, lo, mid).fork(); // left child
|
||||
* public static <E> void forEach(E[] array, Consumer<E> action) {
|
||||
* class Task extends CountedCompleter<Void> {
|
||||
* final int lo, hi;
|
||||
* Task(Task parent, int lo, int hi) {
|
||||
* super(parent); this.lo = lo; this.hi = hi;
|
||||
* }
|
||||
*
|
||||
* public void compute() {
|
||||
* if (hi - lo >= 2) {
|
||||
* int mid = (lo + hi) >>> 1;
|
||||
* // must set pending count before fork
|
||||
* setPendingCount(2);
|
||||
* new Task(this, mid, hi).fork(); // right child
|
||||
* new Task(this, lo, mid).fork(); // left child
|
||||
* }
|
||||
* else if (hi > lo)
|
||||
* action.accept(array[lo]);
|
||||
* tryComplete();
|
||||
* }
|
||||
* else if (hi > lo)
|
||||
* op.apply(array[lo]);
|
||||
* tryComplete();
|
||||
* }
|
||||
* new Task(null, 0, array.length).invoke();
|
||||
* }}</pre>
|
||||
*
|
||||
* This design can be improved by noticing that in the recursive case,
|
||||
* the task has nothing to do after forking its right task, so can
|
||||
* directly invoke its left task before returning. (This is an analog
|
||||
* of tail recursion removal.) Also, because the task returns upon
|
||||
* executing its left task (rather than falling through to invoke
|
||||
* {@code tryComplete}) the pending count is set to one:
|
||||
* of tail recursion removal.) Also, when the last action in a task
|
||||
* is to fork or invoke a subtask (a "tail call"), the call to {@code
|
||||
* tryComplete()} can be optimized away, at the cost of making the
|
||||
* pending count look "off by one".
|
||||
*
|
||||
* <pre> {@code
|
||||
* class ForEach<E> ... {
|
||||
* ...
|
||||
* public void compute() { // version 2
|
||||
* if (hi - lo >= 2) {
|
||||
* int mid = (lo + hi) >>> 1;
|
||||
* setPendingCount(1); // only one pending
|
||||
* new ForEach(this, array, op, mid, hi).fork(); // right child
|
||||
* new ForEach(this, array, op, lo, mid).compute(); // direct invoke
|
||||
* }
|
||||
* else {
|
||||
* if (hi > lo)
|
||||
* op.apply(array[lo]);
|
||||
* tryComplete();
|
||||
* }
|
||||
* }
|
||||
* }}</pre>
|
||||
* public void compute() {
|
||||
* if (hi - lo >= 2) {
|
||||
* int mid = (lo + hi) >>> 1;
|
||||
* setPendingCount(1); // looks off by one, but correct!
|
||||
* new Task(this, mid, hi).fork(); // right child
|
||||
* new Task(this, lo, mid).compute(); // direct invoke
|
||||
* } else {
|
||||
* if (hi > lo)
|
||||
* action.accept(array[lo]);
|
||||
* tryComplete();
|
||||
* }
|
||||
* }}</pre>
|
||||
*
|
||||
* As a further optimization, notice that the left task need not even exist.
|
||||
* Instead of creating a new one, we can iterate using the original task,
|
||||
* Instead of creating a new one, we can continue using the original task,
|
||||
* and add a pending count for each fork. Additionally, because no task
|
||||
* in this tree implements an {@link #onCompletion(CountedCompleter)} method,
|
||||
* {@code tryComplete()} can be replaced with {@link #propagateCompletion}.
|
||||
* {@code tryComplete} can be replaced with {@link #propagateCompletion}.
|
||||
*
|
||||
* <pre> {@code
|
||||
* class ForEach<E> ... {
|
||||
* ...
|
||||
* public void compute() { // version 3
|
||||
* int l = lo, h = hi;
|
||||
* while (h - l >= 2) {
|
||||
* int mid = (l + h) >>> 1;
|
||||
* addToPendingCount(1);
|
||||
* new ForEach(this, array, op, mid, h).fork(); // right child
|
||||
* h = mid;
|
||||
* public void compute() {
|
||||
* int n = hi - lo;
|
||||
* for (; n >= 2; n /= 2) {
|
||||
* addToPendingCount(1);
|
||||
* new Task(this, lo + n/2, lo + n).fork();
|
||||
* }
|
||||
* if (n > 0)
|
||||
* action.accept(array[lo]);
|
||||
* propagateCompletion();
|
||||
* }}</pre>
|
||||
*
|
||||
* When pending counts can be precomputed, they can be established in
|
||||
* the constructor:
|
||||
*
|
||||
* <pre> {@code
|
||||
* public static <E> void forEach(E[] array, Consumer<E> action) {
|
||||
* class Task extends CountedCompleter<Void> {
|
||||
* final int lo, hi;
|
||||
* Task(Task parent, int lo, int hi) {
|
||||
* super(parent, 31 - Integer.numberOfLeadingZeros(hi - lo));
|
||||
* this.lo = lo; this.hi = hi;
|
||||
* }
|
||||
*
|
||||
* public void compute() {
|
||||
* for (int n = hi - lo; n >= 2; n /= 2)
|
||||
* new Task(this, lo + n/2, lo + n).fork();
|
||||
* action.accept(array[lo]);
|
||||
* propagateCompletion();
|
||||
* }
|
||||
* if (h > l)
|
||||
* op.apply(array[l]);
|
||||
* propagateCompletion();
|
||||
* }
|
||||
* if (array.length > 0)
|
||||
* new Task(null, 0, array.length).invoke();
|
||||
* }}</pre>
|
||||
*
|
||||
* Additional optimizations of such classes might entail precomputing
|
||||
* pending counts so that they can be established in constructors,
|
||||
* specializing classes for leaf steps, subdividing by say, four,
|
||||
* instead of two per iteration, and using an adaptive threshold
|
||||
* instead of always subdividing down to single elements.
|
||||
* Additional optimizations of such classes might entail specializing
|
||||
* classes for leaf steps, subdividing by say, four, instead of two
|
||||
* per iteration, and using an adaptive threshold instead of always
|
||||
* subdividing down to single elements.
|
||||
*
|
||||
* <p><b>Searching.</b> A tree of CountedCompleters can search for a
|
||||
* value or property in different parts of a data structure, and
|
||||
|
@ -132,10 +132,10 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
* <i>happen-before</i> actions following a successful return from the
|
||||
* corresponding {@code await()} in other threads.
|
||||
*
|
||||
* @since 1.5
|
||||
* @see CountDownLatch
|
||||
*
|
||||
* @author Doug Lea
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CyclicBarrier {
|
||||
/**
|
||||
|
@ -68,7 +68,7 @@ package java.util.concurrent;
|
||||
* private boolean subscribed; // true after first subscribe
|
||||
* public synchronized void subscribe(Subscriber<? super Boolean> subscriber) {
|
||||
* if (subscribed)
|
||||
* subscriber.onError(new IllegalStateException()); // only one allowed
|
||||
* subscriber.onError(new IllegalStateException()); // only one allowed
|
||||
* else {
|
||||
* subscribed = true;
|
||||
* subscriber.onSubscribe(new OneShotSubscription(subscriber, executor));
|
||||
|
@ -130,7 +130,7 @@ import java.util.concurrent.locks.LockSupport;
|
||||
* </table>
|
||||
*
|
||||
* <p>The common pool is by default constructed with default
|
||||
* parameters, but these may be controlled by setting three
|
||||
* parameters, but these may be controlled by setting the following
|
||||
* {@linkplain System#getProperty system properties}:
|
||||
* <ul>
|
||||
* <li>{@code java.util.concurrent.ForkJoinPool.common.parallelism}
|
||||
@ -3241,7 +3241,7 @@ public class ForkJoinPool extends AbstractExecutorService {
|
||||
* An ACC to restrict permissions for the factory itself.
|
||||
* The constructed workers have no permissions set.
|
||||
*/
|
||||
private static final AccessControlContext innocuousAcc;
|
||||
private static final AccessControlContext INNOCUOUS_ACC;
|
||||
static {
|
||||
Permissions innocuousPerms = new Permissions();
|
||||
innocuousPerms.add(modifyThreadPermission);
|
||||
@ -3249,7 +3249,7 @@ public class ForkJoinPool extends AbstractExecutorService {
|
||||
"enableContextClassLoaderOverride"));
|
||||
innocuousPerms.add(new RuntimePermission(
|
||||
"modifyThreadGroup"));
|
||||
innocuousAcc = new AccessControlContext(new ProtectionDomain[] {
|
||||
INNOCUOUS_ACC = new AccessControlContext(new ProtectionDomain[] {
|
||||
new ProtectionDomain(null, innocuousPerms)
|
||||
});
|
||||
}
|
||||
@ -3260,7 +3260,7 @@ public class ForkJoinPool extends AbstractExecutorService {
|
||||
public ForkJoinWorkerThread run() {
|
||||
return new ForkJoinWorkerThread.
|
||||
InnocuousForkJoinWorkerThread(pool);
|
||||
}}, innocuousAcc);
|
||||
}}, INNOCUOUS_ACC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,8 @@ import java.util.concurrent.locks.AbstractQueuedSynchronizer;
|
||||
* protected synchronized Object getNextAvailableItem() {
|
||||
* for (int i = 0; i < MAX_AVAILABLE; ++i) {
|
||||
* if (!used[i]) {
|
||||
* used[i] = true;
|
||||
* return items[i];
|
||||
* used[i] = true;
|
||||
* return items[i];
|
||||
* }
|
||||
* }
|
||||
* return null; // not reached
|
||||
@ -82,11 +82,11 @@ import java.util.concurrent.locks.AbstractQueuedSynchronizer;
|
||||
* protected synchronized boolean markAsUnused(Object item) {
|
||||
* for (int i = 0; i < MAX_AVAILABLE; ++i) {
|
||||
* if (item == items[i]) {
|
||||
* if (used[i]) {
|
||||
* used[i] = false;
|
||||
* return true;
|
||||
* } else
|
||||
* return false;
|
||||
* if (used[i]) {
|
||||
* used[i] = false;
|
||||
* return true;
|
||||
* } else
|
||||
* return false;
|
||||
* }
|
||||
* }
|
||||
* return false;
|
||||
|
@ -554,8 +554,9 @@ public class SubmissionPublisher<T> implements Flow.Publisher<T>,
|
||||
while (r != null) {
|
||||
BufferedSubscription<T> nextRetry = r.nextRetry;
|
||||
r.nextRetry = null;
|
||||
int stat = (nanos > 0L) ? r.timedOffer(item, nanos) :
|
||||
r.offer(item);
|
||||
int stat = (nanos > 0L)
|
||||
? r.timedOffer(item, nanos)
|
||||
: r.offer(item);
|
||||
if (stat == 0 && onDrop != null &&
|
||||
onDrop.test(r.subscriber, item))
|
||||
stat = r.offer(item);
|
||||
|
@ -617,6 +617,9 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||
/** Per-thread task counter */
|
||||
volatile long completedTasks;
|
||||
|
||||
// TODO: switch to AbstractQueuedLongSynchronizer and move
|
||||
// completedTasks into the lock word.
|
||||
|
||||
/**
|
||||
* Creates with given first task and thread from ThreadFactory.
|
||||
* @param firstTask the first task (null if none)
|
||||
|
@ -193,7 +193,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
|
||||
/**
|
||||
* Atomically increments the current value,
|
||||
* with memory effects as specified by {@link VarHandle#addAndGet}.
|
||||
* with memory effects as specified by {@link VarHandle#getAndAdd}.
|
||||
*
|
||||
* <p>Equivalent to {@code addAndGet(1)}.
|
||||
*
|
||||
@ -205,7 +205,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
|
||||
/**
|
||||
* Atomically decrements the current value,
|
||||
* with memory effects as specified by {@link VarHandle#addAndGet}.
|
||||
* with memory effects as specified by {@link VarHandle#getAndAdd}.
|
||||
*
|
||||
* <p>Equivalent to {@code addAndGet(-1)}.
|
||||
*
|
||||
|
@ -154,13 +154,13 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
|
||||
* long stamp = sl.tryOptimisticRead();
|
||||
* double currentX = x, currentY = y;
|
||||
* if (!sl.validate(stamp)) {
|
||||
* stamp = sl.readLock();
|
||||
* try {
|
||||
* currentX = x;
|
||||
* currentY = y;
|
||||
* } finally {
|
||||
* sl.unlockRead(stamp);
|
||||
* }
|
||||
* stamp = sl.readLock();
|
||||
* try {
|
||||
* currentX = x;
|
||||
* currentY = y;
|
||||
* } finally {
|
||||
* sl.unlockRead(stamp);
|
||||
* }
|
||||
* }
|
||||
* return Math.sqrt(currentX * currentX + currentY * currentY);
|
||||
* }
|
||||
|
@ -836,18 +836,25 @@ class JarFile extends ZipFile {
|
||||
private static final byte[] CLASSPATH_CHARS =
|
||||
{'C','L','A','S','S','-','P','A','T','H', ':', ' '};
|
||||
|
||||
// The bad character shift for "class-path:"
|
||||
// The bad character shift for "class-path: "
|
||||
private static final byte[] CLASSPATH_LASTOCC;
|
||||
|
||||
// The good suffix shift for "class-path: "
|
||||
private static final byte[] CLASSPATH_OPTOSFT;
|
||||
|
||||
private static final byte[] MULTIRELEASE_CHARS =
|
||||
{'M','U','L','T','I','-','R','E','L','E', 'A', 'S', 'E', ':',
|
||||
' ', 'T', 'R', 'U', 'E'};
|
||||
|
||||
// The bad character shift for "multi-release: "
|
||||
// The bad character shift for "multi-release: true"
|
||||
private static final byte[] MULTIRELEASE_LASTOCC;
|
||||
|
||||
// The good suffix shift for "multi-release: true"
|
||||
private static final byte[] MULTIRELEASE_OPTOSFT;
|
||||
|
||||
static {
|
||||
CLASSPATH_LASTOCC = new byte[64];
|
||||
CLASSPATH_OPTOSFT = new byte[12];
|
||||
CLASSPATH_LASTOCC[(int)'C' - 32] = 1;
|
||||
CLASSPATH_LASTOCC[(int)'L' - 32] = 2;
|
||||
CLASSPATH_LASTOCC[(int)'S' - 32] = 5;
|
||||
@ -858,8 +865,13 @@ class JarFile extends ZipFile {
|
||||
CLASSPATH_LASTOCC[(int)'H' - 32] = 10;
|
||||
CLASSPATH_LASTOCC[(int)':' - 32] = 11;
|
||||
CLASSPATH_LASTOCC[(int)' ' - 32] = 12;
|
||||
for (int i = 0; i < 11; i++) {
|
||||
CLASSPATH_OPTOSFT[i] = 12;
|
||||
}
|
||||
CLASSPATH_OPTOSFT[11] = 1;
|
||||
|
||||
MULTIRELEASE_LASTOCC = new byte[64];
|
||||
MULTIRELEASE_OPTOSFT = new byte[19];
|
||||
MULTIRELEASE_LASTOCC[(int)'M' - 32] = 1;
|
||||
MULTIRELEASE_LASTOCC[(int)'I' - 32] = 5;
|
||||
MULTIRELEASE_LASTOCC[(int)'-' - 32] = 6;
|
||||
@ -872,6 +884,11 @@ class JarFile extends ZipFile {
|
||||
MULTIRELEASE_LASTOCC[(int)'R' - 32] = 17;
|
||||
MULTIRELEASE_LASTOCC[(int)'U' - 32] = 18;
|
||||
MULTIRELEASE_LASTOCC[(int)'E' - 32] = 19;
|
||||
for (int i = 0; i < 17; i++) {
|
||||
MULTIRELEASE_OPTOSFT[i] = 19;
|
||||
}
|
||||
MULTIRELEASE_OPTOSFT[17] = 6;
|
||||
MULTIRELEASE_OPTOSFT[18] = 1;
|
||||
}
|
||||
|
||||
private JarEntry getManEntry() {
|
||||
@ -913,7 +930,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 int match(byte[] src, byte[] b, byte[] lastOcc) {
|
||||
private int match(byte[] src, byte[] b, byte[] lastOcc, byte[] optoSft) {
|
||||
int len = src.length;
|
||||
int last = b.length - len;
|
||||
int i = 0;
|
||||
@ -926,9 +943,8 @@ class JarFile extends ZipFile {
|
||||
|
||||
if (c != src[j]) {
|
||||
// no match
|
||||
int goodShift = (j < len - 1) ? len : 1;
|
||||
int badShift = lastOcc[c - 32];
|
||||
i += Math.max(j + 1 - badShift, goodShift);
|
||||
i += Math.max(j + 1 - badShift, optoSft[j]);
|
||||
continue next;
|
||||
}
|
||||
} else {
|
||||
@ -958,10 +974,11 @@ class JarFile extends ZipFile {
|
||||
if (manEntry != null) {
|
||||
byte[] b = getBytes(manEntry);
|
||||
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
|
||||
CLASSPATH_LASTOCC) != -1;
|
||||
CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT) != -1;
|
||||
// is this a multi-release jar file
|
||||
if (MULTI_RELEASE_ENABLED) {
|
||||
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
|
||||
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC,
|
||||
MULTIRELEASE_OPTOSFT);
|
||||
if (i != -1) {
|
||||
i += MULTIRELEASE_CHARS.length;
|
||||
if (i < b.length) {
|
||||
|
@ -567,19 +567,23 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @param <R> type of the result
|
||||
* @param supplier a function that creates a new result container. For a
|
||||
* parallel execution, this function may be called
|
||||
* @param <R> the type of the mutable result container
|
||||
* @param supplier a function that creates a new mutable result container.
|
||||
* For a parallel execution, this function may be called
|
||||
* multiple times and must return a fresh value each time.
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
|
||||
* <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* function for incorporating an additional element into a result
|
||||
* function that must fold an element into a result
|
||||
* container.
|
||||
* @param combiner an <a href="package-summary.html#Associativity">associative</a>,
|
||||
* <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* function for combining two values, which must be
|
||||
* compatible with the accumulator function
|
||||
* function that accepts two partial result containers
|
||||
* and merges them, which must be compatible with the
|
||||
* accumulator function. The combiner function must fold
|
||||
* the elements from the second result container into the
|
||||
* first result container.
|
||||
* @return the result of the reduction
|
||||
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
|
||||
*/
|
||||
@ -947,6 +951,12 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
* position {@code n}, will be the result of applying the function {@code f}
|
||||
* to the element at position {@code n - 1}.
|
||||
*
|
||||
* <p>The action of applying {@code f} for one element
|
||||
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
|
||||
* the action of applying {@code f} for subsequent elements. For any given
|
||||
* element the action may be performed in whatever thread the library
|
||||
* chooses.
|
||||
*
|
||||
* @param seed the initial element
|
||||
* @param f a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
@ -978,37 +988,44 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
|
||||
/**
|
||||
* Returns a sequential ordered {@code DoubleStream} produced by iterative
|
||||
* application of a function to an initial element, conditioned on
|
||||
* satisfying the supplied predicate. The stream terminates as soon as
|
||||
* the predicate returns false.
|
||||
* application of the given {@code next} function to an initial element,
|
||||
* conditioned on satisfying the given {@code hasNext} predicate. The
|
||||
* stream terminates as soon as the {@code hasNext} predicate returns false.
|
||||
*
|
||||
* <p>
|
||||
* {@code DoubleStream.iterate} should produce the same sequence of
|
||||
* elements as produced by the corresponding for-loop:
|
||||
* <p>{@code DoubleStream.iterate} should produce the same sequence of elements as
|
||||
* produced by the corresponding for-loop:
|
||||
* <pre>{@code
|
||||
* for (double index=seed; predicate.test(index); index = f.applyAsDouble(index)) {
|
||||
* for (double index=seed; hasNext.test(index); index = next.applyAsDouble(index)) {
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* The resulting sequence may be empty if the predicate does not hold on
|
||||
* the seed value. Otherwise the first element will be the supplied seed
|
||||
* value, the next element (if present) will be the result of applying the
|
||||
* function f to the seed value, and so on iteratively until the predicate
|
||||
* indicates that the stream should terminate.
|
||||
* <p>The resulting sequence may be empty if the {@code hasNext} predicate
|
||||
* does not hold on the seed value. Otherwise the first element will be the
|
||||
* supplied {@code seed} value, the next element (if present) will be the
|
||||
* result of applying the {@code next} function to the {@code seed} value,
|
||||
* and so on iteratively until the {@code hasNext} predicate indicates that
|
||||
* the stream should terminate.
|
||||
*
|
||||
* <p>The action of applying the {@code hasNext} predicate to an element
|
||||
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
|
||||
* the action of applying the {@code next} function to that element. The
|
||||
* action of applying the {@code next} function for one element
|
||||
* <i>happens-before</i> the action of applying the {@code hasNext}
|
||||
* predicate for subsequent elements. For any given element an action may
|
||||
* be performed in whatever thread the library chooses.
|
||||
*
|
||||
* @param seed the initial element
|
||||
* @param predicate a predicate to apply to elements to determine when the
|
||||
* stream must terminate.
|
||||
* @param f a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
* @param hasNext a predicate to apply to elements to determine when the
|
||||
* stream must terminate.
|
||||
* @param next a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
* @return a new sequential {@code DoubleStream}
|
||||
* @since 9
|
||||
*/
|
||||
public static DoubleStream iterate(double seed, DoublePredicate predicate, DoubleUnaryOperator f) {
|
||||
Objects.requireNonNull(f);
|
||||
Objects.requireNonNull(predicate);
|
||||
public static DoubleStream iterate(double seed, DoublePredicate hasNext, DoubleUnaryOperator next) {
|
||||
Objects.requireNonNull(next);
|
||||
Objects.requireNonNull(hasNext);
|
||||
Spliterator.OfDouble spliterator = new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||
double prev;
|
||||
@ -1021,12 +1038,12 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
return false;
|
||||
double t;
|
||||
if (started)
|
||||
t = f.applyAsDouble(prev);
|
||||
t = next.applyAsDouble(prev);
|
||||
else {
|
||||
t = seed;
|
||||
started = true;
|
||||
}
|
||||
if (!predicate.test(t)) {
|
||||
if (!hasNext.test(t)) {
|
||||
finished = true;
|
||||
return false;
|
||||
}
|
||||
@ -1040,10 +1057,10 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
||||
if (finished)
|
||||
return;
|
||||
finished = true;
|
||||
double t = started ? f.applyAsDouble(prev) : seed;
|
||||
while (predicate.test(t)) {
|
||||
double t = started ? next.applyAsDouble(prev) : seed;
|
||||
while (hasNext.test(t)) {
|
||||
action.accept(t);
|
||||
t = f.applyAsDouble(t);
|
||||
t = next.applyAsDouble(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -562,19 +562,23 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @param <R> type of the result
|
||||
* @param supplier a function that creates a new result container. For a
|
||||
* parallel execution, this function may be called
|
||||
* @param <R> the type of the mutable result container
|
||||
* @param supplier a function that creates a new mutable result container.
|
||||
* For a parallel execution, this function may be called
|
||||
* multiple times and must return a fresh value each time.
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
|
||||
* <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* function for incorporating an additional element into a result
|
||||
* function that must fold an element into a result
|
||||
* container.
|
||||
* @param combiner an <a href="package-summary.html#Associativity">associative</a>,
|
||||
* <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* function for combining two values, which must be
|
||||
* compatible with the accumulator function
|
||||
* function that accepts two partial result containers
|
||||
* and merges them, which must be compatible with the
|
||||
* accumulator function. The combiner function must fold
|
||||
* the elements from the second result container into the
|
||||
* first result container.
|
||||
* @return the result of the reduction
|
||||
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
|
||||
*/
|
||||
@ -887,6 +891,12 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
* {@code n}, will be the result of applying the function {@code f} to the
|
||||
* element at position {@code n - 1}.
|
||||
*
|
||||
* <p>The action of applying {@code f} for one element
|
||||
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
|
||||
* the action of applying {@code f} for subsequent elements. For any given
|
||||
* element the action may be performed in whatever thread the library
|
||||
* chooses.
|
||||
*
|
||||
* @param seed the initial element
|
||||
* @param f a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
@ -918,37 +928,44 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
|
||||
/**
|
||||
* Returns a sequential ordered {@code IntStream} produced by iterative
|
||||
* application of a function to an initial element, conditioned on
|
||||
* satisfying the supplied predicate. The stream terminates as soon as
|
||||
* the predicate returns false.
|
||||
* application of the given {@code next} function to an initial element,
|
||||
* conditioned on satisfying the given {@code hasNext} predicate. The
|
||||
* stream terminates as soon as the {@code hasNext} predicate returns false.
|
||||
*
|
||||
* <p>
|
||||
* {@code IntStream.iterate} should produce the same sequence of elements
|
||||
* as produced by the corresponding for-loop:
|
||||
* <p>{@code IntStream.iterate} should produce the same sequence of elements as
|
||||
* produced by the corresponding for-loop:
|
||||
* <pre>{@code
|
||||
* for (int index=seed; predicate.test(index); index = f.applyAsInt(index)) {
|
||||
* for (int index=seed; hasNext.test(index); index = next.applyAsInt(index)) {
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* The resulting sequence may be empty if the predicate does not hold on
|
||||
* the seed value. Otherwise the first element will be the supplied seed
|
||||
* value, the next element (if present) will be the result of applying the
|
||||
* function f to the seed value, and so on iteratively until the predicate
|
||||
* indicates that the stream should terminate.
|
||||
* <p>The resulting sequence may be empty if the {@code hasNext} predicate
|
||||
* does not hold on the seed value. Otherwise the first element will be the
|
||||
* supplied {@code seed} value, the next element (if present) will be the
|
||||
* result of applying the {@code next} function to the {@code seed} value,
|
||||
* and so on iteratively until the {@code hasNext} predicate indicates that
|
||||
* the stream should terminate.
|
||||
*
|
||||
* <p>The action of applying the {@code hasNext} predicate to an element
|
||||
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
|
||||
* the action of applying the {@code next} function to that element. The
|
||||
* action of applying the {@code next} function for one element
|
||||
* <i>happens-before</i> the action of applying the {@code hasNext}
|
||||
* predicate for subsequent elements. For any given element an action may
|
||||
* be performed in whatever thread the library chooses.
|
||||
*
|
||||
* @param seed the initial element
|
||||
* @param predicate a predicate to apply to elements to determine when the
|
||||
* stream must terminate.
|
||||
* @param f a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
* @param hasNext a predicate to apply to elements to determine when the
|
||||
* stream must terminate.
|
||||
* @param next a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
* @return a new sequential {@code IntStream}
|
||||
* @since 9
|
||||
*/
|
||||
public static IntStream iterate(int seed, IntPredicate predicate, IntUnaryOperator f) {
|
||||
Objects.requireNonNull(f);
|
||||
Objects.requireNonNull(predicate);
|
||||
public static IntStream iterate(int seed, IntPredicate hasNext, IntUnaryOperator next) {
|
||||
Objects.requireNonNull(next);
|
||||
Objects.requireNonNull(hasNext);
|
||||
Spliterator.OfInt spliterator = new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||
int prev;
|
||||
@ -961,12 +978,12 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
return false;
|
||||
int t;
|
||||
if (started)
|
||||
t = f.applyAsInt(prev);
|
||||
t = next.applyAsInt(prev);
|
||||
else {
|
||||
t = seed;
|
||||
started = true;
|
||||
}
|
||||
if (!predicate.test(t)) {
|
||||
if (!hasNext.test(t)) {
|
||||
finished = true;
|
||||
return false;
|
||||
}
|
||||
@ -980,10 +997,10 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
||||
if (finished)
|
||||
return;
|
||||
finished = true;
|
||||
int t = started ? f.applyAsInt(prev) : seed;
|
||||
while (predicate.test(t)) {
|
||||
int t = started ? next.applyAsInt(prev) : seed;
|
||||
while (hasNext.test(t)) {
|
||||
action.accept(t);
|
||||
t = f.applyAsInt(t);
|
||||
t = next.applyAsInt(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -564,19 +564,23 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">terminal
|
||||
* operation</a>.
|
||||
*
|
||||
* @param <R> type of the result
|
||||
* @param supplier a function that creates a new result container. For a
|
||||
* parallel execution, this function may be called
|
||||
* @param <R> the type of the mutable result container
|
||||
* @param supplier a function that creates a new mutable result container.
|
||||
* For a parallel execution, this function may be called
|
||||
* multiple times and must return a fresh value each time.
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
|
||||
* <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* function for incorporating an additional element into a result
|
||||
* function that must fold an element into a result
|
||||
* container.
|
||||
* @param combiner an <a href="package-summary.html#Associativity">associative</a>,
|
||||
* <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* function for combining two values, which must be
|
||||
* compatible with the accumulator function
|
||||
* function that accepts two partial result containers
|
||||
* and merges them, which must be compatible with the
|
||||
* accumulator function. The combiner function must fold
|
||||
* the elements from the second result container into the
|
||||
* first result container.
|
||||
* @return the result of the reduction
|
||||
* @see Stream#collect(Supplier, BiConsumer, BiConsumer)
|
||||
*/
|
||||
@ -877,6 +881,12 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
* {@code n}, will be the result of applying the function {@code f} to the
|
||||
* element at position {@code n - 1}.
|
||||
*
|
||||
* <p>The action of applying {@code f} for one element
|
||||
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
|
||||
* the action of applying {@code f} for subsequent elements. For any given
|
||||
* element the action may be performed in whatever thread the library
|
||||
* chooses.
|
||||
*
|
||||
* @param seed the initial element
|
||||
* @param f a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
@ -908,37 +918,44 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
|
||||
/**
|
||||
* Returns a sequential ordered {@code LongStream} produced by iterative
|
||||
* application of a function to an initial element, conditioned on
|
||||
* satisfying the supplied predicate. The stream terminates as soon as
|
||||
* the predicate returns false.
|
||||
* application of the given {@code next} function to an initial element,
|
||||
* conditioned on satisfying the given {@code hasNext} predicate. The
|
||||
* stream terminates as soon as the {@code hasNext} predicate returns false.
|
||||
*
|
||||
* <p>
|
||||
* {@code LongStream.iterate} should produce the same sequence of elements
|
||||
* as produced by the corresponding for-loop:
|
||||
* <p>{@code LongStream.iterate} should produce the same sequence of elements as
|
||||
* produced by the corresponding for-loop:
|
||||
* <pre>{@code
|
||||
* for (long index=seed; predicate.test(index); index = f.applyAsLong(index)) {
|
||||
* for (long index=seed; hasNext.test(index); index = next.applyAsLong(index)) {
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* The resulting sequence may be empty if the predicate does not hold on
|
||||
* the seed value. Otherwise the first element will be the supplied seed
|
||||
* value, the next element (if present) will be the result of applying the
|
||||
* function f to the seed value, and so on iteratively until the predicate
|
||||
* indicates that the stream should terminate.
|
||||
* <p>The resulting sequence may be empty if the {@code hasNext} predicate
|
||||
* does not hold on the seed value. Otherwise the first element will be the
|
||||
* supplied {@code seed} value, the next element (if present) will be the
|
||||
* result of applying the {@code next} function to the {@code seed} value,
|
||||
* and so on iteratively until the {@code hasNext} predicate indicates that
|
||||
* the stream should terminate.
|
||||
*
|
||||
* <p>The action of applying the {@code hasNext} predicate to an element
|
||||
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
|
||||
* the action of applying the {@code next} function to that element. The
|
||||
* action of applying the {@code next} function for one element
|
||||
* <i>happens-before</i> the action of applying the {@code hasNext}
|
||||
* predicate for subsequent elements. For any given element an action may
|
||||
* be performed in whatever thread the library chooses.
|
||||
*
|
||||
* @param seed the initial element
|
||||
* @param predicate a predicate to apply to elements to determine when the
|
||||
* stream must terminate.
|
||||
* @param f a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
* @param hasNext a predicate to apply to elements to determine when the
|
||||
* stream must terminate.
|
||||
* @param next a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
* @return a new sequential {@code LongStream}
|
||||
* @since 9
|
||||
*/
|
||||
public static LongStream iterate(long seed, LongPredicate predicate, LongUnaryOperator f) {
|
||||
Objects.requireNonNull(f);
|
||||
Objects.requireNonNull(predicate);
|
||||
public static LongStream iterate(long seed, LongPredicate hasNext, LongUnaryOperator next) {
|
||||
Objects.requireNonNull(next);
|
||||
Objects.requireNonNull(hasNext);
|
||||
Spliterator.OfLong spliterator = new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||
long prev;
|
||||
@ -951,12 +968,12 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
return false;
|
||||
long t;
|
||||
if (started)
|
||||
t = f.applyAsLong(prev);
|
||||
t = next.applyAsLong(prev);
|
||||
else {
|
||||
t = seed;
|
||||
started = true;
|
||||
}
|
||||
if (!predicate.test(t)) {
|
||||
if (!hasNext.test(t)) {
|
||||
finished = true;
|
||||
return false;
|
||||
}
|
||||
@ -970,10 +987,10 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
||||
if (finished)
|
||||
return;
|
||||
finished = true;
|
||||
long t = started ? f.applyAsLong(prev) : seed;
|
||||
while (predicate.test(t)) {
|
||||
long t = started ? next.applyAsLong(prev) : seed;
|
||||
while (hasNext.test(t)) {
|
||||
action.accept(t);
|
||||
t = f.applyAsLong(t);
|
||||
t = next.applyAsLong(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -882,19 +882,23 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* .toString();
|
||||
* }</pre>
|
||||
*
|
||||
* @param <R> type of the result
|
||||
* @param supplier a function that creates a new result container. For a
|
||||
* parallel execution, this function may be called
|
||||
* @param <R> the type of the mutable result container
|
||||
* @param supplier a function that creates a new mutable result container.
|
||||
* For a parallel execution, this function may be called
|
||||
* multiple times and must return a fresh value each time.
|
||||
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
|
||||
* <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* function for incorporating an additional element into a result
|
||||
* function that must fold an element into a result
|
||||
* container.
|
||||
* @param combiner an <a href="package-summary.html#Associativity">associative</a>,
|
||||
* <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* function for combining two values, which must be
|
||||
* compatible with the accumulator function
|
||||
* function that accepts two partial result containers
|
||||
* and merges them, which must be compatible with the
|
||||
* accumulator function. The combiner function must fold
|
||||
* the elements from the second result container into the
|
||||
* first result container.
|
||||
* @return the result of the reduction
|
||||
*/
|
||||
<R> R collect(Supplier<R> supplier,
|
||||
@ -1194,6 +1198,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
* {@code n}, will be the result of applying the function {@code f} to the
|
||||
* element at position {@code n - 1}.
|
||||
*
|
||||
* <p>The action of applying {@code f} for one element
|
||||
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
|
||||
* the action of applying {@code f} for subsequent elements. For any given
|
||||
* element the action may be performed in whatever thread the library
|
||||
* chooses.
|
||||
*
|
||||
* @param <T> the type of stream elements
|
||||
* @param seed the initial element
|
||||
* @param f a function to be applied to the previous element to produce
|
||||
@ -1226,38 +1236,45 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
|
||||
/**
|
||||
* Returns a sequential ordered {@code Stream} produced by iterative
|
||||
* application of a function to an initial element, conditioned on
|
||||
* satisfying the supplied predicate. The stream terminates as soon as
|
||||
* the predicate returns false.
|
||||
* application of the given {@code next} function to an initial element,
|
||||
* conditioned on satisfying the given {@code hasNext} predicate. The
|
||||
* stream terminates as soon as the {@code hasNext} predicate returns false.
|
||||
*
|
||||
* <p>
|
||||
* {@code Stream.iterate} should produce the same sequence of elements as
|
||||
* <p>{@code Stream.iterate} should produce the same sequence of elements as
|
||||
* produced by the corresponding for-loop:
|
||||
* <pre>{@code
|
||||
* for (T index=seed; predicate.test(index); index = f.apply(index)) {
|
||||
* for (T index=seed; hasNext.test(index); index = next.apply(index)) {
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* The resulting sequence may be empty if the predicate does not hold on
|
||||
* the seed value. Otherwise the first element will be the supplied seed
|
||||
* value, the next element (if present) will be the result of applying the
|
||||
* function f to the seed value, and so on iteratively until the predicate
|
||||
* indicates that the stream should terminate.
|
||||
* <p>The resulting sequence may be empty if the {@code hasNext} predicate
|
||||
* does not hold on the seed value. Otherwise the first element will be the
|
||||
* supplied {@code seed} value, the next element (if present) will be the
|
||||
* result of applying the {@code next} function to the {@code seed} value,
|
||||
* and so on iteratively until the {@code hasNext} predicate indicates that
|
||||
* the stream should terminate.
|
||||
*
|
||||
* <p>The action of applying the {@code hasNext} predicate to an element
|
||||
* <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a>
|
||||
* the action of applying the {@code next} function to that element. The
|
||||
* action of applying the {@code next} function for one element
|
||||
* <i>happens-before</i> the action of applying the {@code hasNext}
|
||||
* predicate for subsequent elements. For any given element an action may
|
||||
* be performed in whatever thread the library chooses.
|
||||
*
|
||||
* @param <T> the type of stream elements
|
||||
* @param seed the initial element
|
||||
* @param predicate a predicate to apply to elements to determine when the
|
||||
* stream must terminate.
|
||||
* @param f a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
* @param hasNext a predicate to apply to elements to determine when the
|
||||
* stream must terminate.
|
||||
* @param next a function to be applied to the previous element to produce
|
||||
* a new element
|
||||
* @return a new sequential {@code Stream}
|
||||
* @since 9
|
||||
*/
|
||||
public static<T> Stream<T> iterate(T seed, Predicate<? super T> predicate, UnaryOperator<T> f) {
|
||||
Objects.requireNonNull(f);
|
||||
Objects.requireNonNull(predicate);
|
||||
public static<T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) {
|
||||
Objects.requireNonNull(next);
|
||||
Objects.requireNonNull(hasNext);
|
||||
Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE) {
|
||||
T prev;
|
||||
@ -1270,12 +1287,12 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
return false;
|
||||
T t;
|
||||
if (started)
|
||||
t = f.apply(prev);
|
||||
t = next.apply(prev);
|
||||
else {
|
||||
t = seed;
|
||||
started = true;
|
||||
}
|
||||
if (!predicate.test(t)) {
|
||||
if (!hasNext.test(t)) {
|
||||
prev = null;
|
||||
finished = true;
|
||||
return false;
|
||||
@ -1290,11 +1307,11 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
||||
if (finished)
|
||||
return;
|
||||
finished = true;
|
||||
T t = started ? f.apply(prev) : seed;
|
||||
T t = started ? next.apply(prev) : seed;
|
||||
prev = null;
|
||||
while (predicate.test(t)) {
|
||||
while (hasNext.test(t)) {
|
||||
action.accept(t);
|
||||
t = f.apply(t);
|
||||
t = next.apply(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -80,7 +80,7 @@ import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
* ClassWriter cw = new ClassWriter(...);
|
||||
* ClassVisitor sv = new SerialVersionUIDAdder(cw);
|
||||
* ClassVisitor ca = new MyClassAdapter(sv);
|
||||
* new ClassReader(orginalClass).accept(ca, false);
|
||||
* new ClassReader(originalClass).accept(ca, false);
|
||||
* </pre>
|
||||
*
|
||||
* The SVUID algorithm can be found <a href=
|
||||
|
@ -1185,7 +1185,7 @@ final class ClientHandshaker extends Handshaker {
|
||||
/*
|
||||
* FOURTH, if we sent a Certificate, we need to send a signed
|
||||
* CertificateVerify (unless the key in the client's certificate
|
||||
* was a Diffie-Hellman key).).
|
||||
* was a Diffie-Hellman key).
|
||||
*
|
||||
* This uses a hash of the previous handshake messages ... either
|
||||
* a nonfinal one (if the particular implementation supports it)
|
||||
|
@ -149,7 +149,10 @@ class BreakDictionary {
|
||||
BufferedInputStream in;
|
||||
try {
|
||||
PrivilegedExceptionAction<BufferedInputStream> pa = () -> {
|
||||
InputStream is = module.getResourceAsStream("sun/text/resources/" + dictionaryName);
|
||||
String pathName = "jdk.localedata".equals(module.getName()) ?
|
||||
"sun/text/resources/ext/" :
|
||||
"sun/text/resources/";
|
||||
InputStream is = module.getResourceAsStream(pathName + dictionaryName);
|
||||
if (is == null) {
|
||||
// Try to load the file with "java.base" module instance. Assumption
|
||||
// here is that the fall back data files to be read should reside in
|
||||
|
@ -444,7 +444,10 @@ class RuleBasedBreakIterator extends BreakIterator {
|
||||
BufferedInputStream is;
|
||||
try {
|
||||
PrivilegedExceptionAction<BufferedInputStream> pa = () -> {
|
||||
InputStream in = module.getResourceAsStream("sun/text/resources/" + datafile);
|
||||
String pathName = "jdk.localedata".equals(module.getName()) ?
|
||||
"sun/text/resources/ext/" :
|
||||
"sun/text/resources/";
|
||||
InputStream in = module.getResourceAsStream(pathName + datafile);
|
||||
if (in == null) {
|
||||
// Try to load the file with "java.base" module instance. Assumption
|
||||
// here is that the fall back data files to be read should reside in
|
||||
|
@ -52,6 +52,10 @@
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(_AIX)
|
||||
#include <string.h>
|
||||
#endif
|
||||
@ -157,14 +161,11 @@ static int fstatat64_wrapper(int dfd, const char *path,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(__x86_64__)
|
||||
#if defined(__linux__) && defined(_LP64) && defined(__NR_newfstatat)
|
||||
#define FSTATAT64_SYSCALL_AVAILABLE
|
||||
static int fstatat64_wrapper(int dfd, const char *path,
|
||||
struct stat64 *statbuf, int flag)
|
||||
{
|
||||
#ifndef __NR_newfstatat
|
||||
#define __NR_newfstatat 262
|
||||
#endif
|
||||
return syscall(__NR_newfstatat, dfd, path, statbuf, flag);
|
||||
}
|
||||
#endif
|
||||
|
@ -95,7 +95,7 @@ public final class DLSInfo {
|
||||
public String subject = null;
|
||||
/**
|
||||
* (ISRC) Name of person or orginization who supplied
|
||||
* orginal material for the file.
|
||||
* original material for the file.
|
||||
*/
|
||||
public String source = null;
|
||||
/**
|
||||
|
@ -105,6 +105,10 @@ method is not invoked.
|
||||
The agent class will be loaded by the system class loader
|
||||
(see {@link java.lang.ClassLoader#getSystemClassLoader ClassLoader.getSystemClassLoader}). This is
|
||||
the class loader which typically loads the class containing the application <code>main</code> method.
|
||||
The system class loader must support a mechanism to add an agent JAR file to the system class path.
|
||||
If it is a custom system class loader then it must define the
|
||||
<code>appendToClassPathForInstrumentation</code> method as specified in
|
||||
{@link Instrumentation#appendToSystemClassLoaderSearch appendToSystemClassLoaderSearch}.
|
||||
The <code>premain</code> methods will be run under the same security and classloader
|
||||
rules as the application <code>main</code> method.
|
||||
There are no modeling restrictions on what the agent <code>premain</code> method may do.
|
||||
@ -140,7 +144,10 @@ supports the starting of agents after the VM has started the following applies:
|
||||
|
||||
<li><p>The system class loader (
|
||||
{@link java.lang.ClassLoader#getSystemClassLoader ClassLoader.getSystemClassLoader}) must
|
||||
support a mechanism to add an agent JAR file to the system class path.</li>
|
||||
support a mechanism to add an agent JAR file to the system class path.
|
||||
If it is a custom system class loader then it must define the
|
||||
<code>appendToClassPathForInstrumentation</code> method as specified in
|
||||
{@link Instrumentation#appendToSystemClassLoaderSearch appendToSystemClassLoaderSearch}.</li>
|
||||
</ol>
|
||||
|
||||
<P>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -190,10 +190,8 @@ DEF_Agent_OnLoad(JavaVM *vm, char *tail, void * reserved) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add to the jarfile
|
||||
*/
|
||||
appendClassPath(agent, jarfile);
|
||||
/* Save the jarfile name */
|
||||
agent->mJarfile = jarfile;
|
||||
|
||||
/*
|
||||
* The value of the Premain-Class attribute becomes the agent
|
||||
@ -241,7 +239,6 @@ DEF_Agent_OnLoad(JavaVM *vm, char *tail, void * reserved) {
|
||||
/*
|
||||
* Clean-up
|
||||
*/
|
||||
free(jarfile);
|
||||
if (options != NULL) free(options);
|
||||
freeAttributes(attributes);
|
||||
free(premainClass);
|
||||
@ -459,7 +456,23 @@ eventHandlerVMInit( jvmtiEnv * jvmtienv,
|
||||
|
||||
/* process the premain calls on the all the JPL agents */
|
||||
if ( environment != NULL ) {
|
||||
jthrowable outstandingException = preserveThrowable(jnienv);
|
||||
jthrowable outstandingException = NULL;
|
||||
/*
|
||||
* Add the jarfile to the system class path
|
||||
*/
|
||||
JPLISAgent * agent = environment->mAgent;
|
||||
if (appendClassPath(agent, agent->mJarfile)) {
|
||||
fprintf(stderr, "Unable to add %s to system class path - "
|
||||
"the system class loader does not define the "
|
||||
"appendToClassPathForInstrumentation method or the method failed\n",
|
||||
agent->mJarfile);
|
||||
free((void *)agent->mJarfile);
|
||||
abortJVM(jnienv, JPLIS_ERRORMESSAGE_CANNOTSTART);
|
||||
}
|
||||
free((void *)agent->mJarfile);
|
||||
agent->mJarfile = NULL;
|
||||
|
||||
outstandingException = preserveThrowable(jnienv);
|
||||
success = processJavaStart( environment->mAgent,
|
||||
jnienv);
|
||||
restoreThrowable(jnienv, outstandingException);
|
||||
@ -631,32 +644,19 @@ appendClassPath( JPLISAgent* agent,
|
||||
jvmtierr = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, jarfile);
|
||||
check_phase_ret_1(jvmtierr);
|
||||
|
||||
if (jvmtierr == JVMTI_ERROR_NONE) {
|
||||
return 0;
|
||||
} else {
|
||||
jvmtiPhase phase;
|
||||
jvmtiError err;
|
||||
|
||||
err = (*jvmtienv)->GetPhase(jvmtienv, &phase);
|
||||
/* can be called from any phase */
|
||||
jplis_assert(err == JVMTI_ERROR_NONE);
|
||||
|
||||
if (phase == JVMTI_PHASE_LIVE) {
|
||||
switch (jvmtierr) {
|
||||
case JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED :
|
||||
fprintf(stderr, "System class loader does not support adding "
|
||||
"JAR file to system class path during the live phase!\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unexpected error (%d) returned by "
|
||||
"AddToSystemClassLoaderSearch\n", jvmtierr);
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
jplis_assert(0);
|
||||
switch (jvmtierr) {
|
||||
case JVMTI_ERROR_NONE :
|
||||
return 0;
|
||||
case JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED :
|
||||
fprintf(stderr, "System class loader does not define "
|
||||
"the appendToClassPathForInstrumentation method\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unexpected error (%d) returned by "
|
||||
"AddToSystemClassLoaderSearch\n", jvmtierr);
|
||||
break;
|
||||
}
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -272,6 +272,7 @@ initializeJPLISAgent( JPLISAgent * agent,
|
||||
agent->mNativeMethodPrefixAdded = JNI_FALSE;
|
||||
agent->mAgentClassName = NULL;
|
||||
agent->mOptionsString = NULL;
|
||||
agent->mJarfile = NULL;
|
||||
|
||||
/* make sure we can recover either handle in either direction.
|
||||
* the agent has a ref to the jvmti; make it mutual
|
||||
|
@ -107,6 +107,7 @@ struct _JPLISAgent {
|
||||
jboolean mNativeMethodPrefixAdded; /* indicates if can_set_native_method_prefix capability has been added */
|
||||
char const * mAgentClassName; /* agent class name */
|
||||
char const * mOptionsString; /* -javaagent options string */
|
||||
const char * mJarfile; /* agent jar file name */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -189,12 +189,12 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
storeFiles(modules, release);
|
||||
|
||||
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
|
||||
// launchers in the bin directory need execute permission
|
||||
// launchers in the bin directory need execute permission.
|
||||
// On Windows, "bin" also subdirectories containing jvm.dll.
|
||||
if (Files.isDirectory(bin)) {
|
||||
Files.list(bin)
|
||||
.filter(f -> !f.toString().endsWith(".diz"))
|
||||
.filter(f -> Files.isRegularFile(f))
|
||||
.forEach(this::setExecutable);
|
||||
Files.find(bin, 2, (path, attrs) -> {
|
||||
return attrs.isRegularFile() && !path.toString().endsWith(".diz");
|
||||
}).forEach(this::setExecutable);
|
||||
}
|
||||
|
||||
// jspawnhelper is in lib or lib/<arch>
|
||||
|
@ -103,7 +103,9 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
List<ResourcePoolEntry> ret = javaBase.entries().filter((t) -> {
|
||||
String path = t.path();
|
||||
for (String jvmlib : jvmlibs) {
|
||||
return t.path().endsWith("/" + jvmlib);
|
||||
if (t.path().endsWith("/" + jvmlib)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).collect(Collectors.toList());
|
||||
|
@ -264,8 +264,8 @@ public final class IncludeLocalesPlugin implements Plugin, ResourcePrevisitor {
|
||||
|
||||
// Add Thai BreakIterator related data files
|
||||
if (tag.equals("th")) {
|
||||
files.add(".+sun/text/resources/thai_dict");
|
||||
files.add(".+sun/text/resources/[^_]+BreakIteratorData_th");
|
||||
files.add(".+sun/text/resources/ext/thai_dict");
|
||||
files.add(".+sun/text/resources/ext/[^_]+BreakIteratorData_th");
|
||||
}
|
||||
|
||||
// Add Taiwan resource bundles for Hong Kong
|
||||
|
@ -310,8 +310,6 @@ sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java 8157338 generic-
|
||||
|
||||
tools/pack200/CommandLineTests.java 7143279,8059906 generic-all
|
||||
|
||||
tools/pack200/Pack200Test.java 8059906,8151901 generic-all
|
||||
|
||||
tools/launcher/FXLauncherTest.java 8068049 linux-all,macosx-all
|
||||
|
||||
tools/pack200/Pack200Props.java 8155857 generic-all
|
||||
|
57
jdk/test/java/lang/ClassLoader/GetDefinedPackage.java
Normal file
57
jdk/test/java/lang/ClassLoader/GetDefinedPackage.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* @bug 8165346
|
||||
* @summary Basic test for ClassLoader::getDefinedPackage
|
||||
*/
|
||||
|
||||
public class GetDefinedPackage {
|
||||
public static void main(String... args) {
|
||||
TestClassLoader loader = new TestClassLoader();
|
||||
Package pkg = loader.getDefinedPackage(TestClassLoader.PKG_NAME);
|
||||
if (pkg == null) {
|
||||
throw new RuntimeException("package foo not found");
|
||||
}
|
||||
|
||||
try {
|
||||
loader.getDefinedPackage(null);
|
||||
throw new RuntimeException("NullPointerException not thrown");
|
||||
} catch (NullPointerException e) {
|
||||
}
|
||||
}
|
||||
|
||||
static class TestClassLoader extends ClassLoader {
|
||||
public static final String PKG_NAME = "foo";
|
||||
|
||||
public TestClassLoader() {
|
||||
super();
|
||||
definePackage(PKG_NAME);
|
||||
}
|
||||
|
||||
public Package definePackage(String name) {
|
||||
return definePackage(name, null, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
90
jdk/test/java/lang/ClassLoader/ResourcesStreamTest.java
Normal file
90
jdk/test/java/lang/ClassLoader/ResourcesStreamTest.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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8161230
|
||||
* @summary Test java.lang.ClassLoader.resources() method
|
||||
*
|
||||
* @build ResourcesStreamTest
|
||||
* @run main ResourcesStreamTest
|
||||
*/
|
||||
public class ResourcesStreamTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
testSuccess();
|
||||
testFailure();
|
||||
}
|
||||
|
||||
public static void testSuccess() throws Exception {
|
||||
// failing part first
|
||||
try {
|
||||
ClassLoader cl = new FailingClassLoader();
|
||||
// should create the stream pipe
|
||||
Stream<URL> stream = cl.resources("the name");
|
||||
// expect function to throw an exception when calling the method
|
||||
stream.forEach(System.out::println);
|
||||
throw new Exception("expected UncheckedIOException not thrown");
|
||||
} catch (UncheckedIOException uio) {
|
||||
String causeMessage = uio.getCause().getMessage();
|
||||
if (!"the name".equals(causeMessage))
|
||||
throw new Exception("unexpected cause message: " + causeMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public static void testFailure() throws Exception {
|
||||
ClassLoader cl = new SuccessClassLoader();
|
||||
long count = cl.resources("the name").count();
|
||||
if (count != 1)
|
||||
throw new Exception("expected resource is null or empty");
|
||||
|
||||
cl.resources("the name")
|
||||
.filter(url -> "file:/somefile".equals(url.toExternalForm()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new Exception("correct URL not found"));
|
||||
}
|
||||
|
||||
public static class SuccessClassLoader extends ClassLoader {
|
||||
@Override
|
||||
public Enumeration<URL> getResources(String name) throws IOException {
|
||||
URL url = new URL("file:/somefile");
|
||||
return Collections.enumeration(Collections.singleton(url));
|
||||
}
|
||||
}
|
||||
|
||||
public static class FailingClassLoader extends ClassLoader {
|
||||
@Override
|
||||
public Enumeration<URL> getResources(String name) throws IOException {
|
||||
throw new IOException(name);
|
||||
}
|
||||
}
|
||||
}
|
55
jdk/test/java/lang/instrument/CustomSystemLoader/Agent.java
Normal file
55
jdk/test/java/lang/instrument/CustomSystemLoader/Agent.java
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.lang.instrument.*;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8160950
|
||||
* @summary test for custom system class loader
|
||||
*
|
||||
* @run build App Agent CustomLoader
|
||||
* @run shell ../MakeJAR3.sh Agent 'Can-Retransform-Classes: true'
|
||||
* @run main/othervm -javaagent:Agent.jar -Djava.system.class.loader=CustomLoader App
|
||||
*/
|
||||
|
||||
public class Agent {
|
||||
private static PrintStream err = System.err;
|
||||
private static PrintStream out = System.out;
|
||||
public static boolean failed = false;
|
||||
|
||||
public static void premain(String agentArgs, Instrumentation instrumentation) {
|
||||
ClassLoader myClassLoader = Agent.class.getClassLoader();
|
||||
out.println("Agent: started; myClassLoader: " + myClassLoader);
|
||||
try {
|
||||
Field fld = myClassLoader.getClass().getField("agentClassLoader");
|
||||
fld.set(myClassLoader.getClass(), myClassLoader);
|
||||
} catch (Exception ex) {
|
||||
failed = true;
|
||||
ex.printStackTrace();
|
||||
}
|
||||
out.println("Agent: finished");
|
||||
}
|
||||
}
|
46
jdk/test/java/lang/instrument/CustomSystemLoader/App.java
Normal file
46
jdk/test/java/lang/instrument/CustomSystemLoader/App.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class App {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
(new App()).run(args, System.out);
|
||||
}
|
||||
|
||||
public void run(String args[], PrintStream out) throws Exception {
|
||||
out.println("App: Test started");
|
||||
if (CustomLoader.agentClassLoader != CustomLoader.myself) {
|
||||
System.out.println("App: agentClassLoader: " + CustomLoader.agentClassLoader);
|
||||
System.out.println("App: CustomLoader.myself: " + CustomLoader.myself);
|
||||
System.out.println("App: myClassLoader: " + App.class.getClassLoader());
|
||||
throw new Exception("App: Agent's system class loader is not CustomLoader");
|
||||
} else if (Agent.failed) {
|
||||
throw new Exception("App: Agent failed");
|
||||
} else if (CustomLoader.failed) {
|
||||
throw new Exception("App: CustomLoader failed");
|
||||
}
|
||||
out.println("App: Test passed");
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
public class CustomLoader extends ClassLoader {
|
||||
private static PrintStream out = System.out;
|
||||
public static ClassLoader myself;
|
||||
public static ClassLoader agentClassLoader;
|
||||
public static boolean failed = true;
|
||||
|
||||
public CustomLoader(ClassLoader classLoader) {
|
||||
super(classLoader);
|
||||
myself = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
out.println("CustomLoader: loading class: " + name);
|
||||
if (name.equals("Agent")) {
|
||||
Class c = null;
|
||||
try {
|
||||
byte[] buf = locateBytes();
|
||||
c = defineClass(name, buf, 0, buf.length);
|
||||
} catch (IOException ex) {
|
||||
throw new ClassNotFoundException(ex.getMessage());
|
||||
}
|
||||
resolveClass(c);
|
||||
out.println("CustomLoader.loadClass after resolveClass: " + name +
|
||||
"; Class: " + c + "; ClassLoader: " + c.getClassLoader());
|
||||
return c;
|
||||
}
|
||||
return super.loadClass(name);
|
||||
}
|
||||
|
||||
private byte[] locateBytes() throws IOException {
|
||||
try {
|
||||
JarFile jar = new JarFile("Agent.jar");
|
||||
InputStream is = jar.getInputStream(jar.getEntry("Agent.class"));
|
||||
int len = is.available();
|
||||
byte[] buf = new byte[len];
|
||||
DataInputStream in = new DataInputStream(is);
|
||||
in.readFully(buf);
|
||||
return buf;
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
throw new IOException("Test failed due to IOException!");
|
||||
}
|
||||
}
|
||||
|
||||
void appendToClassPathForInstrumentation(String path) {
|
||||
out.println("CustomLoader.appendToClassPathForInstrumentation: " +
|
||||
this + ", jar: " + path);
|
||||
failed = false;
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
* @bug 8048052
|
||||
* @summary Test a series of methods which requires "setFactory" runtime permission
|
||||
* @modules java.rmi
|
||||
* @run main SetFactoryPermission success
|
||||
* @run main/othervm SetFactoryPermission success
|
||||
* @run main/othervm/policy=policy.fail SetFactoryPermission fail
|
||||
* @run main/othervm/policy=policy.success SetFactoryPermission success
|
||||
*/
|
||||
|
@ -45,6 +45,9 @@ public class SecureDS {
|
||||
DirectoryStream<Path> stream = newDirectoryStream(dir);
|
||||
stream.close();
|
||||
if (!(stream instanceof SecureDirectoryStream)) {
|
||||
if (System.getProperty("os.name").equals("Linux"))
|
||||
throw new AssertionError(
|
||||
"SecureDirectoryStream not supported.");
|
||||
System.out.println("SecureDirectoryStream not supported.");
|
||||
return;
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
# Threeten test uses TestNG
|
||||
TestNG.dirs = .
|
||||
othervm.dirs = tck/java/time/chrono test/java/time/chrono test/java/time/format
|
||||
modules = jdk.localedata
|
||||
lib.dirs = ../../lib/testlibrary
|
||||
lib.build = jdk.testlibrary.RandomFactory
|
||||
|
@ -24,6 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 4302966
|
||||
* @modules jdk.localedata
|
||||
* @summary In Czech Republic first day of week is Monday not Sunday
|
||||
*/
|
||||
|
||||
|
@ -112,7 +112,6 @@ public class MOAT {
|
||||
testCollection(Arrays.asList(1,2,3));
|
||||
testCollection(nCopies(25,1));
|
||||
testImmutableList(nCopies(25,1));
|
||||
testImmutableList(unmodifiableList(Arrays.asList(1,2,3)));
|
||||
|
||||
testMap(new HashMap<Integer,Integer>());
|
||||
testMap(new LinkedHashMap<Integer,Integer>());
|
||||
@ -134,6 +133,20 @@ public class MOAT {
|
||||
testMap(Collections.synchronizedSortedMap(new TreeMap<Integer,Integer>()));
|
||||
testMap(Collections.synchronizedNavigableMap(new TreeMap<Integer,Integer>()));
|
||||
|
||||
// Unmodifiable wrappers
|
||||
testImmutableSet(unmodifiableSet(new HashSet<>(Arrays.asList(1,2,3))));
|
||||
testImmutableList(unmodifiableList(Arrays.asList(1,2,3)));
|
||||
testImmutableMap(unmodifiableMap(Collections.singletonMap(1,2)));
|
||||
testCollMutatorsAlwaysThrow(unmodifiableSet(new HashSet<>(Arrays.asList(1,2,3))));
|
||||
testCollMutatorsAlwaysThrow(unmodifiableSet(Collections.emptySet()));
|
||||
testEmptyCollMutatorsAlwaysThrow(unmodifiableSet(Collections.emptySet()));
|
||||
testListMutatorsAlwaysThrow(unmodifiableList(Arrays.asList(1,2,3)));
|
||||
testListMutatorsAlwaysThrow(unmodifiableList(Collections.emptyList()));
|
||||
testEmptyListMutatorsAlwaysThrow(unmodifiableList(Collections.emptyList()));
|
||||
testMapMutatorsAlwaysThrow(unmodifiableMap(Collections.singletonMap(1,2)));
|
||||
testMapMutatorsAlwaysThrow(unmodifiableMap(Collections.emptyMap()));
|
||||
testEmptyMapMutatorsAlwaysThrow(unmodifiableMap(Collections.emptyMap()));
|
||||
|
||||
// Empty collections
|
||||
final List<Integer> emptyArray = Arrays.asList(new Integer[]{});
|
||||
testCollection(emptyArray);
|
||||
@ -196,6 +209,8 @@ public class MOAT {
|
||||
|
||||
// Immutable List
|
||||
testEmptyList(List.of());
|
||||
testListMutatorsAlwaysThrow(List.of());
|
||||
testEmptyListMutatorsAlwaysThrow(List.of());
|
||||
for (List<Integer> list : Arrays.asList(
|
||||
List.<Integer>of(),
|
||||
List.of(1),
|
||||
@ -211,10 +226,13 @@ public class MOAT {
|
||||
List.of(integerArray))) {
|
||||
testCollection(list);
|
||||
testImmutableList(list);
|
||||
testListMutatorsAlwaysThrow(list);
|
||||
}
|
||||
|
||||
// Immutable Set
|
||||
testEmptySet(Set.of());
|
||||
testCollMutatorsAlwaysThrow(Set.of());
|
||||
testEmptyCollMutatorsAlwaysThrow(Set.of());
|
||||
for (Set<Integer> set : Arrays.asList(
|
||||
Set.<Integer>of(),
|
||||
Set.of(1),
|
||||
@ -230,6 +248,7 @@ public class MOAT {
|
||||
Set.of(integerArray))) {
|
||||
testCollection(set);
|
||||
testImmutableSet(set);
|
||||
testCollMutatorsAlwaysThrow(set);
|
||||
}
|
||||
|
||||
// Immutable Map
|
||||
@ -241,6 +260,8 @@ public class MOAT {
|
||||
}
|
||||
|
||||
testEmptyMap(Map.of());
|
||||
testMapMutatorsAlwaysThrow(Map.of());
|
||||
testEmptyMapMutatorsAlwaysThrow(Map.of());
|
||||
for (Map<Integer,Integer> map : Arrays.asList(
|
||||
Map.<Integer,Integer>of(),
|
||||
Map.of(1, 101),
|
||||
@ -256,6 +277,7 @@ public class MOAT {
|
||||
Map.ofEntries(ea))) {
|
||||
testMap(map);
|
||||
testImmutableMap(map);
|
||||
testMapMutatorsAlwaysThrow(map);
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,6 +380,93 @@ public class MOAT {
|
||||
it.remove(); });
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that calling a mutator always throws UOE, even if the mutator
|
||||
* wouldn't actually do anything, given its arguments.
|
||||
*
|
||||
* @param c the collection instance to test
|
||||
*/
|
||||
private static void testCollMutatorsAlwaysThrow(Collection<Integer> c) {
|
||||
THROWS(UnsupportedOperationException.class,
|
||||
() -> c.addAll(Collections.emptyList()),
|
||||
() -> c.remove(ABSENT_VALUE),
|
||||
() -> c.removeAll(Collections.emptyList()),
|
||||
() -> c.removeIf(x -> false),
|
||||
() -> c.retainAll(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that calling a mutator always throws UOE, even if the mutator
|
||||
* wouldn't actually do anything on an empty collection.
|
||||
*
|
||||
* @param c the collection instance to test, must be empty
|
||||
*/
|
||||
private static void testEmptyCollMutatorsAlwaysThrow(Collection<Integer> c) {
|
||||
if (! c.isEmpty()) {
|
||||
fail("collection is not empty");
|
||||
}
|
||||
THROWS(UnsupportedOperationException.class,
|
||||
() -> c.clear());
|
||||
}
|
||||
|
||||
/**
|
||||
* As above, for a list.
|
||||
*
|
||||
* @param c the list instance to test
|
||||
*/
|
||||
private static void testListMutatorsAlwaysThrow(List<Integer> c) {
|
||||
testCollMutatorsAlwaysThrow(c);
|
||||
THROWS(UnsupportedOperationException.class,
|
||||
() -> c.addAll(0, Collections.emptyList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* As above, for an empty list.
|
||||
*
|
||||
* @param c the list instance to test, must be empty
|
||||
*/
|
||||
private static void testEmptyListMutatorsAlwaysThrow(List<Integer> c) {
|
||||
if (! c.isEmpty()) {
|
||||
fail("list is not empty");
|
||||
}
|
||||
testEmptyCollMutatorsAlwaysThrow(c);
|
||||
THROWS(UnsupportedOperationException.class,
|
||||
() -> c.replaceAll(x -> x),
|
||||
() -> c.sort(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* As above, for a map.
|
||||
*
|
||||
* @param m the map instance to test
|
||||
*/
|
||||
private static void testMapMutatorsAlwaysThrow(Map<Integer,Integer> m) {
|
||||
THROWS(UnsupportedOperationException.class,
|
||||
() -> m.compute(ABSENT_VALUE, (k, v) -> null),
|
||||
() -> m.computeIfAbsent(ABSENT_VALUE, k -> null),
|
||||
() -> m.computeIfPresent(ABSENT_VALUE, (k, v) -> null),
|
||||
() -> m.merge(ABSENT_VALUE, 0, (k, v) -> null),
|
||||
() -> m.putAll(Collections.emptyMap()),
|
||||
() -> m.remove(ABSENT_VALUE),
|
||||
() -> m.remove(ABSENT_VALUE, 0),
|
||||
() -> m.replace(ABSENT_VALUE, 0),
|
||||
() -> m.replace(ABSENT_VALUE, 0, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* As above, for an empty map.
|
||||
*
|
||||
* @param map the map instance to test, must be empty
|
||||
*/
|
||||
private static void testEmptyMapMutatorsAlwaysThrow(Map<Integer,Integer> m) {
|
||||
if (! m.isEmpty()) {
|
||||
fail("map is not empty");
|
||||
}
|
||||
THROWS(UnsupportedOperationException.class,
|
||||
() -> m.clear(),
|
||||
() -> m.replaceAll((k, v) -> v));
|
||||
}
|
||||
|
||||
private static void clear(Collection<Integer> c) {
|
||||
try { c.clear(); }
|
||||
catch (Throwable t) { unexpected(t); }
|
||||
|
@ -24,6 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 8135055
|
||||
* @modules java.sql
|
||||
* @summary Test java.sql.TimeStamp instance should come after java.util.Date
|
||||
* if Nanos component of TimeStamp is not equal to 0 milliseconds.
|
||||
*/
|
||||
|
@ -24,6 +24,7 @@
|
||||
/**
|
||||
* @test
|
||||
* @bug 8146156 8159548
|
||||
* @modules jdk.localedata
|
||||
* @summary test whether uppercasing follows Locale.Category.FORMAT locale.
|
||||
* @run main/othervm FormatLocale
|
||||
*/
|
||||
|
@ -38,10 +38,8 @@
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
@ -69,6 +69,7 @@ public class TestPermission {
|
||||
@Test
|
||||
public void runTest() throws Exception {
|
||||
int exitValue = executeTestJava("--module-path", MODS_DIR.toString(),
|
||||
"--add-modules", "m1",
|
||||
"-m", "test/jdk.test.Main")
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
|
@ -42,7 +42,7 @@ import static org.testng.Assert.*;
|
||||
* @test
|
||||
* @library /lib/testlibrary
|
||||
* @modules java.scripting
|
||||
jdk.compiler
|
||||
* jdk.compiler
|
||||
* @build ServicesTest CompilerUtils jdk.testlibrary.*
|
||||
* @run testng ServicesTest
|
||||
* @summary Tests ServiceLoader to locate service providers on the module path
|
||||
@ -112,6 +112,7 @@ public class ServicesTest {
|
||||
public void runWithModulePath() throws Exception {
|
||||
int exitValue
|
||||
= executeTestJava("--module-path", MODS_DIR.toString(),
|
||||
"--add-modules", "bananascript",
|
||||
"-m", "test/test.Main",
|
||||
"BananaScriptEngine")
|
||||
.outputTo(System.out)
|
||||
@ -131,6 +132,7 @@ public class ServicesTest {
|
||||
int exitValue
|
||||
= executeTestJava("--module-path", MODS_DIR.toString(),
|
||||
"-cp", CLASSES_DIR.toString(),
|
||||
"--add-modules", "bananascript",
|
||||
"-m", "test/test.Main",
|
||||
"BananaScriptEngine", "PearScriptEngine")
|
||||
.outputTo(System.out)
|
||||
|
@ -24,6 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 4487276 8008577
|
||||
* @modules jdk.localedata
|
||||
* @summary Verify that Hong Kong locale uses traditional Chinese names.
|
||||
* @run main/othervm -Djava.locale.providers=COMPAT,SPI HongKong
|
||||
*/
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -43,7 +43,6 @@ import java.util.List;
|
||||
import java.util.SplittableRandom;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.LinkedTransferQueue;
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -43,7 +43,6 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.LinkedTransferQueue;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
|
||||
public class OfferRemoveLoops {
|
||||
|
@ -22,7 +22,6 @@
|
||||
*/
|
||||
|
||||
import static java.util.concurrent.TimeUnit.NANOSECONDS;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
import java.util.concurrent.DelayQueue;
|
||||
import java.util.concurrent.Delayed;
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -33,7 +33,6 @@
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jdk.testlibrary.Utils;
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,6 @@
|
||||
|
||||
import static java.util.concurrent.TimeUnit.HOURS;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
@ -28,13 +28,13 @@
|
||||
* @library /lib/testlibrary/
|
||||
* @build jdk.testlibrary.RandomFactory
|
||||
* @run main/othervm ConfigChanges
|
||||
* @key randomness intermittent
|
||||
* @key randomness
|
||||
* @author Martin Buchholz
|
||||
*/
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static java.util.concurrent.TimeUnit.NANOSECONDS;
|
||||
|
||||
import java.security.Permission;
|
||||
import java.util.Random;
|
||||
@ -44,7 +44,6 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import jdk.testlibrary.RandomFactory;
|
||||
|
||||
public class ConfigChanges {
|
||||
@ -95,10 +94,10 @@ public class ConfigChanges {
|
||||
check(tpe.getQueue().isEmpty());
|
||||
check(tpe.isTerminated());
|
||||
check(! tpe.isTerminating());
|
||||
equal(tpe.getActiveCount(), 0);
|
||||
equal(tpe.getPoolSize(), 0);
|
||||
equal(0, tpe.getActiveCount());
|
||||
equal(0, tpe.getPoolSize());
|
||||
equal(tpe.getTaskCount(), tpe.getCompletedTaskCount());
|
||||
check(tpe.awaitTermination(0L, SECONDS));
|
||||
check(tpe.awaitTermination(0L, MINUTES));
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
}
|
||||
|
||||
@ -110,6 +109,21 @@ public class ConfigChanges {
|
||||
|
||||
static volatile Runnable runnableDuJour;
|
||||
|
||||
static void awaitIdleness(ThreadPoolExecutor tpe, long taskCount) {
|
||||
restart: for (;;) {
|
||||
// check twice to make chance of race vanishingly small
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (tpe.getQueue().size() != 0 ||
|
||||
tpe.getActiveCount() != 0 ||
|
||||
tpe.getCompletedTaskCount() != taskCount) {
|
||||
Thread.yield();
|
||||
continue restart;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static void realMain(String[] args) throws Throwable {
|
||||
if (rnd.nextBoolean())
|
||||
System.setSecurityManager(new PermissiveSecurityManger());
|
||||
@ -137,8 +151,9 @@ public class ConfigChanges {
|
||||
|
||||
if (prestart) {
|
||||
tpe.prestartAllCoreThreads();
|
||||
equal(tg.activeCount(), n);
|
||||
equal(tg.activeCount(), tpe.getCorePoolSize());
|
||||
equal(n, tg.activeCount());
|
||||
equal(n, tpe.getCorePoolSize());
|
||||
equal(n, tpe.getLargestPoolSize());
|
||||
}
|
||||
|
||||
final Runnable runRunnableDuJour =
|
||||
@ -153,7 +168,7 @@ public class ConfigChanges {
|
||||
tpe.execute(runRunnableDuJour);
|
||||
// Wait for prestarted threads to dequeue their initial tasks.
|
||||
while (! tpe.getQueue().isEmpty())
|
||||
Thread.sleep(10);
|
||||
Thread.sleep(1);
|
||||
for (int i = 0; i < 5*n; i++)
|
||||
tpe.execute(runRunnableDuJour);
|
||||
} else {
|
||||
@ -163,73 +178,76 @@ public class ConfigChanges {
|
||||
|
||||
//report("submitted", tpe);
|
||||
pumpedUp.await();
|
||||
equal(tg.activeCount(), 3*n);
|
||||
equal(tg.activeCount(), tpe.getMaximumPoolSize());
|
||||
equal(tpe.getCorePoolSize(), n);
|
||||
equal(3*n, tg.activeCount());
|
||||
equal(3*n, tpe.getMaximumPoolSize());
|
||||
equal(3*n, tpe.getLargestPoolSize());
|
||||
equal(n, tpe.getCorePoolSize());
|
||||
equal(3*n, tpe.getActiveCount());
|
||||
equal(6L*n, tpe.getTaskCount());
|
||||
equal(0L, tpe.getCompletedTaskCount());
|
||||
|
||||
//report("pumped up", tpe);
|
||||
equal(tpe.getMaximumPoolSize(), 3*n);
|
||||
tpe.setMaximumPoolSize(4*n);
|
||||
equal(tpe.getMaximumPoolSize(), 4*n);
|
||||
equal(4*n, tpe.getMaximumPoolSize());
|
||||
//report("pumped up2", tpe);
|
||||
final CyclicBarrier pumpedUp2 = new CyclicBarrier(n + 1);
|
||||
runnableDuJour = waiter(pumpedUp2);
|
||||
for (int i = 0; i < 1*n; i++)
|
||||
tpe.execute(runRunnableDuJour);
|
||||
pumpedUp2.await();
|
||||
equal(tg.activeCount(), 4*n);
|
||||
equal(tg.activeCount(), tpe.getMaximumPoolSize());
|
||||
equal(tpe.getCompletedTaskCount(), 0L);
|
||||
equal(4*n, tg.activeCount());
|
||||
equal(4*n, tpe.getMaximumPoolSize());
|
||||
equal(4*n, tpe.getLargestPoolSize());
|
||||
equal(4*n, tpe.getActiveCount());
|
||||
equal(7L*n, tpe.getTaskCount());
|
||||
equal(0L, tpe.getCompletedTaskCount());
|
||||
//report("pumped up2", tpe);
|
||||
runnableDuJour = new Runnable() { public void run() {}};
|
||||
|
||||
tpe.setMaximumPoolSize(2*n);
|
||||
//report("after set", tpe);
|
||||
//report("after setMaximumPoolSize", tpe);
|
||||
|
||||
pumpedUp2.await();
|
||||
pumpedUp.await();
|
||||
|
||||
// while (tg.activeCount() != n &&
|
||||
// tg.activeCount() != n)
|
||||
// Thread.sleep(10);
|
||||
// equal(tg.activeCount(), n);
|
||||
// equal(tg.activeCount(), tpe.getCorePoolSize());
|
||||
|
||||
while (tg.activeCount() != 2*n &&
|
||||
tg.activeCount() != 2*n)
|
||||
Thread.sleep(10);
|
||||
equal(tg.activeCount(), 2*n);
|
||||
equal(tg.activeCount(), tpe.getMaximumPoolSize());
|
||||
Thread.yield();
|
||||
equal(2*n, tg.activeCount());
|
||||
equal(2*n, tpe.getMaximumPoolSize());
|
||||
equal(4*n, tpe.getLargestPoolSize());
|
||||
|
||||
//report("draining", tpe);
|
||||
awaitIdleness(tpe, 7L*n);
|
||||
|
||||
//report("draining", tpe);
|
||||
while (tpe.getCompletedTaskCount() < 7*n &&
|
||||
tpe.getCompletedTaskCount() < 7*n)
|
||||
Thread.sleep(10);
|
||||
equal(2*n, tg.activeCount());
|
||||
equal(2*n, tpe.getMaximumPoolSize());
|
||||
equal(4*n, tpe.getLargestPoolSize());
|
||||
|
||||
//equal(tg.activeCount(), n);
|
||||
//equal(tg.activeCount(), tpe.getCorePoolSize());
|
||||
equal(tg.activeCount(), 2*n);
|
||||
equal(tg.activeCount(), tpe.getMaximumPoolSize());
|
||||
equal(7L*n, tpe.getTaskCount());
|
||||
equal(7L*n, tpe.getCompletedTaskCount());
|
||||
equal(0, tpe.getActiveCount());
|
||||
|
||||
equal(tpe.getTaskCount(), 7L*n);
|
||||
equal(tpe.getCompletedTaskCount(), 7L*n);
|
||||
|
||||
equal(tpe.getKeepAliveTime(MINUTES), 3L);
|
||||
equal(3L, tpe.getKeepAliveTime(MINUTES));
|
||||
long t0 = System.nanoTime();
|
||||
tpe.setKeepAliveTime(7L, MILLISECONDS);
|
||||
equal(tpe.getKeepAliveTime(MILLISECONDS), 7L);
|
||||
equal(7L, tpe.getKeepAliveTime(MILLISECONDS));
|
||||
while (tg.activeCount() > n &&
|
||||
tg.activeCount() > n)
|
||||
Thread.sleep(10);
|
||||
equal(tg.activeCount(), n);
|
||||
Thread.sleep(4);
|
||||
equal(n, tg.activeCount());
|
||||
check(System.nanoTime() - t0 >= tpe.getKeepAliveTime(NANOSECONDS));
|
||||
|
||||
//report("idle", tpe);
|
||||
check(! tpe.allowsCoreThreadTimeOut());
|
||||
t0 = System.nanoTime();
|
||||
tpe.allowCoreThreadTimeOut(true);
|
||||
check(tpe.allowsCoreThreadTimeOut());
|
||||
while (tg.activeCount() > 0 &&
|
||||
tg.activeCount() > 0)
|
||||
Thread.sleep(10);
|
||||
Thread.sleep(4);
|
||||
equal(tg.activeCount(), 0);
|
||||
check(System.nanoTime() - t0 >= tpe.getKeepAliveTime(NANOSECONDS));
|
||||
|
||||
//report("idle", tpe);
|
||||
|
||||
|
@ -40,7 +40,6 @@
|
||||
*/
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
@ -34,7 +34,6 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jdk.testlibrary.Utils;
|
||||
|
||||
public class TimeOutShrink {
|
||||
|
@ -22,7 +22,6 @@
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.UnaryOperator;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
|
@ -22,27 +22,35 @@
|
||||
*/
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import jdk.testlibrary.Utils;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8078490
|
||||
* @summary Test submission and execution of task without joining
|
||||
* @library /lib/testlibrary/
|
||||
*/
|
||||
public class SubmissionTest {
|
||||
static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
|
||||
|
||||
static long millisElapsedSince(long startTime) {
|
||||
return (System.nanoTime() - startTime) / (1000L * 1000L);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
final ForkJoinPool e = new ForkJoinPool(1);
|
||||
final AtomicBoolean b = new AtomicBoolean();
|
||||
final Runnable setFalse = () -> b.set(false);
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
for (int i = 0; i < 30_000; i++) {
|
||||
b.set(true);
|
||||
e.execute(setFalse);
|
||||
long st = System.nanoTime();
|
||||
long startTime = System.nanoTime();
|
||||
while (b.get()) {
|
||||
if (System.nanoTime() - st >= TimeUnit.SECONDS.toNanos(10)) {
|
||||
if (millisElapsedSince(startTime) >= LONG_DELAY_MS) {
|
||||
throw new RuntimeException("Submitted task failed to execute");
|
||||
}
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -35,7 +35,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
|
@ -43,7 +43,6 @@ import java.util.SplittableRandom;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -31,8 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Misc utilities in JSR166 performance tests
|
||||
*/
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @run main/othervm/timeout=60 ReadersUnlockAfterWriteUnlock
|
||||
* @bug 8023234
|
||||
* @summary StampedLock serializes readers on writer unlock
|
||||
* @author Dmitry Chyuko
|
||||
@ -30,26 +29,23 @@
|
||||
*/
|
||||
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.StampedLock;
|
||||
|
||||
public class ReadersUnlockAfterWriteUnlock {
|
||||
static final int RNUM = 2;
|
||||
static final StampedLock sl = new StampedLock();
|
||||
static volatile boolean isDone;
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
final int RNUM = 2;
|
||||
final int REPS = 128;
|
||||
final StampedLock sl = new StampedLock();
|
||||
final AtomicReference<Throwable> bad = new AtomicReference<>();
|
||||
|
||||
static CyclicBarrier iterationStart = new CyclicBarrier(RNUM + 1);
|
||||
static CyclicBarrier readersHaveLocks = new CyclicBarrier(RNUM);
|
||||
static CyclicBarrier writerHasLock = new CyclicBarrier(RNUM + 1);
|
||||
final CyclicBarrier iterationStart = new CyclicBarrier(RNUM + 1);
|
||||
final CyclicBarrier readersHaveLocks = new CyclicBarrier(RNUM);
|
||||
final CyclicBarrier writerHasLock = new CyclicBarrier(RNUM + 1);
|
||||
|
||||
static class Reader extends Thread {
|
||||
final String name;
|
||||
Reader(String name) {
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
public void run() {
|
||||
while (!isDone && !isInterrupted()) {
|
||||
try {
|
||||
Runnable reader = () -> {
|
||||
try {
|
||||
for (int i = 0; i < REPS; i++) {
|
||||
iterationStart.await();
|
||||
writerHasLock.await();
|
||||
long rs = sl.readLock();
|
||||
@ -59,30 +55,45 @@ public class ReadersUnlockAfterWriteUnlock {
|
||||
readersHaveLocks.await();
|
||||
|
||||
sl.unlockRead(rs);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
bad.set(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
for (int r = 0 ; r < RNUM; ++r) {
|
||||
new Reader("r" + r).start();
|
||||
Thread[] threads = new Thread[RNUM];
|
||||
for (int i = 0 ; i < RNUM; i++) {
|
||||
Thread thread = new Thread(reader, "Reader");
|
||||
threads[i] = thread;
|
||||
thread.start();
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < 1024; ++i) {
|
||||
for (int i = 0; i < REPS; i++) {
|
||||
try {
|
||||
iterationStart.await();
|
||||
long ws = sl.writeLock();
|
||||
writerHasLock.await();
|
||||
Thread.sleep(10);
|
||||
awaitWaitState(threads);
|
||||
sl.unlockWrite(ws);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
isDone = true;
|
||||
for (Thread thread : threads)
|
||||
thread.join();
|
||||
if (bad.get() != null)
|
||||
throw new AssertionError(bad.get());
|
||||
}
|
||||
|
||||
static void awaitWaitState(Thread[] threads) {
|
||||
restart: for (;;) {
|
||||
for (Thread thread : threads) {
|
||||
if (thread.getState() != Thread.State.WAITING) {
|
||||
Thread.yield();
|
||||
continue restart;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
@ -31,7 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicLongArray;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
@ -31,7 +31,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
@ -59,7 +59,6 @@ import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinTask;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiConsumer;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user