diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 0c614608939..c9694066072 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -377,3 +377,4 @@ d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130 a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132 be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133 065724348690eda41fc69112278d8da6dcde548c jdk-9+134 +82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 4cc7243b9ce..a52c2a2a2da 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -537,3 +537,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129 713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132 a25e0fb6033245ab075136e744d362ce765464cd jdk-9+133 b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134 +3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135 diff --git a/jdk/.hgtags b/jdk/.hgtags index 5a179a2c6bd..ff5e6944eca 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -377,3 +377,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123 d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132 3cdae27c90b5e41afe75eab904fda19fac076330 jdk-9+133 803adcd526d74ae0b64948d1f8260c2dbe514779 jdk-9+134 +021369229cfd0b5feb76834b2ea498f47f43c0f3 jdk-9+135 diff --git a/jdk/make/gendata/GendataBreakIterator.gmk b/jdk/make/gendata/GendataBreakIterator.gmk index a68786a413b..2f7f5dff981 100644 --- a/jdk/make/gendata/GendataBreakIterator.gmk +++ b/jdk/make/gendata/GendataBreakIterator.gmk @@ -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 \ diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java index 12baf44fe58..1d1a273ef7d 100644 --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java @@ -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(); diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageReader.java b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageReader.java index 1a60f9e1047..bcb6cb1eb4d 100644 --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageReader.java +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageReader.java @@ -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 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) { diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/intrinsic.properties b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/intrinsic.properties index be1687076cc..fa9ba74f047 100644 --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/intrinsic.properties +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/intrinsic.properties @@ -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] diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java index d8b2dee337d..f011aa8b47e 100644 --- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java @@ -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. + * + *

The name of a resource is a {@code /}-separated path name that + * identifies the resource. + * + *

The search order is described in the documentation for {@link + * #getResource(String)}. + * + *

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 resources(String name) { + int characteristics = Spliterator.NONNULL | Spliterator.IMMUTABLE; + Supplier> 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 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 ClassLoader for delegation, or - * null if none + * @return The system ClassLoader 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 diff --git a/jdk/src/java.base/share/classes/java/lang/Compiler.java b/jdk/src/java.base/share/classes/java/lang/Compiler.java index fd4f3045d48..1726b693219 100644 --- a/jdk/src/java.base/share/classes/java/lang/Compiler.java +++ b/jdk/src/java.base/share/classes/java/lang/Compiler.java @@ -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. * - *

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. - * - *

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 diff --git a/jdk/src/java.base/share/classes/java/lang/Package.java b/jdk/src/java.base/share/classes/java/lang/Package.java index 1aa9e98fbf2..b4ba45b8f35 100644 --- a/jdk/src/java.base/share/classes/java/lang/Package.java +++ b/jdk/src/java.base/share/classes/java/lang/Package.java @@ -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 diff --git a/jdk/src/java.base/share/classes/java/lang/Runtime.java b/jdk/src/java.base/share/classes/java/lang/Runtime.java index 43d4ef6aae0..84a599a4285 100644 --- a/jdk/src/java.base/share/classes/java/lang/Runtime.java +++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java @@ -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 */ diff --git a/jdk/src/java.base/share/classes/java/lang/RuntimePermission.java b/jdk/src/java.base/share/classes/java/lang/RuntimePermission.java index d014ddb3378..46d8ef23c08 100644 --- a/jdk/src/java.base/share/classes/java/lang/RuntimePermission.java +++ b/jdk/src/java.base/share/classes/java/lang/RuntimePermission.java @@ -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; * usePolicy * Granting this permission disables the Java Plug-In's default * security prompting behavior. - * For more information, refer to Java Plug-In's guides, - * Applet Security Basics and - * usePolicy Permission. + * For more information, refer to the deployment guide. + * * * * manageProcess diff --git a/jdk/src/java.base/share/classes/java/lang/StringConcatHelper.java b/jdk/src/java.base/share/classes/java/lang/StringConcatHelper.java index 1504e6ff37d..f3f16088f7a 100644 --- a/jdk/src/java.base/share/classes/java/lang/StringConcatHelper.java +++ b/jdk/src/java.base/share/classes/java/lang/StringConcatHelper.java @@ -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); } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java index cec4ff1ea54..ddd60ca082f 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java @@ -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; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index cec799ec1a3..86685b605de 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -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) { diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java index ed56faae579..4b336f4c6b1 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java @@ -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", ) - // 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", ) - // 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", ) 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, MethodHandle> PREPENDERS; private static final ConcurrentMap, 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); } } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java index 50e81913c16..167de41e98b 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java @@ -152,7 +152,6 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError; * {@link #getAndAdd getAndAdd}, * {@link #getAndAddAcquire getAndAddAcquire}, * {@link #getAndAddRelease getAndAddRelease}, - * {@link #addAndGet addAndGet}. *

  • bitwise atomic update access modes that, for example, atomically get and * bitwise OR the value of a variable under specified memory ordering * effects. diff --git a/jdk/src/java.base/share/classes/java/lang/ref/package-info.java b/jdk/src/java.base/share/classes/java/lang/ref/package-info.java index 1ee769d16cc..58600cba1b8 100644 --- a/jdk/src/java.base/share/classes/java/lang/ref/package-info.java +++ b/jdk/src/java.base/share/classes/java/lang/ref/package-info.java @@ -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}. * diff --git a/jdk/src/java.base/share/classes/java/security/DigestInputStream.java b/jdk/src/java.base/share/classes/java/security/DigestInputStream.java index a1bf55ac9e7..747537df253 100644 --- a/jdk/src/java.base/share/classes/java/security/DigestInputStream.java +++ b/jdk/src/java.base/share/classes/java/security/DigestInputStream.java @@ -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 * diff --git a/jdk/src/java.base/share/classes/java/security/KeyPairGenerator.java b/jdk/src/java.base/share/classes/java/security/KeyPairGenerator.java index 46686b522a1..3a241787329 100644 --- a/jdk/src/java.base/share/classes/java/security/KeyPairGenerator.java +++ b/jdk/src/java.base/share/classes/java/security/KeyPairGenerator.java @@ -76,7 +76,7 @@ import sun.security.util.Debug; * {@code g} parameters. If the modulus size is not one of the above * values, the Sun 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. * *
  • Algorithm-Specific Initialization @@ -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.) * *

    This concrete method has been added to this previously-defined * abstract class. diff --git a/jdk/src/java.base/share/classes/java/security/SignatureSpi.java b/jdk/src/java.base/share/classes/java/security/SignatureSpi.java index 7e78726f3b8..9be7701a2fa 100644 --- a/jdk/src/java.base/share/classes/java/security/SignatureSpi.java +++ b/jdk/src/java.base/share/classes/java/security/SignatureSpi.java @@ -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. - *. + * *

    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. diff --git a/jdk/src/java.base/share/classes/java/util/ArrayDeque.java b/jdk/src/java.base/share/classes/java/util/ArrayDeque.java index ca3c66b6249..5a9b8312e30 100644 --- a/jdk/src/java.base/share/classes/java/util/ArrayDeque.java +++ b/jdk/src/java.base/share/classes/java/util/ArrayDeque.java @@ -81,8 +81,8 @@ import java.util.function.Consumer; * Java Collections Framework. * * @author Josh Bloch and Doug Lea - * @since 1.6 * @param the type of elements held in this deque + * @since 1.6 */ public class ArrayDeque extends AbstractCollection implements Deque, Cloneable, Serializable diff --git a/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java b/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java index 8414311e425..494dce83a89 100644 --- a/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java +++ b/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java @@ -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 extends AbstractList implements RandomAccess, Serializable { + abstract static class AbstractImmutableList extends AbstractList + implements RandomAccess, Serializable { + @Override public boolean add(E e) { throw uoe(); } + @Override public boolean addAll(Collection c) { throw uoe(); } + @Override public boolean addAll(int index, Collection 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 filter) { throw uoe(); } + @Override public void replaceAll(UnaryOperator operator) { throw uoe(); } + @Override public boolean retainAll(Collection c) { throw uoe(); } + @Override public void sort(Comparator c) { throw uoe(); } + } + + static final class List0 extends AbstractImmutableList { List0() { } @Override @@ -86,7 +106,7 @@ class ImmutableCollections { } } - static final class List1 extends AbstractList implements RandomAccess, Serializable { + static final class List1 extends AbstractImmutableList { private final E e0; List1(E e0) { @@ -114,7 +134,7 @@ class ImmutableCollections { } } - static final class List2 extends AbstractList implements RandomAccess, Serializable { + static final class List2 extends AbstractImmutableList { private final E e0; private final E e1; @@ -147,7 +167,7 @@ class ImmutableCollections { } } - static final class ListN extends AbstractList implements RandomAccess, Serializable { + static final class ListN extends AbstractImmutableList { private final E[] elements; @SafeVarargs @@ -183,7 +203,17 @@ class ImmutableCollections { // ---------- Set Implementations ---------- - static final class Set0 extends AbstractSet implements Serializable { + abstract static class AbstractImmutableSet extends AbstractSet implements Serializable { + @Override public boolean add(E e) { throw uoe(); } + @Override public boolean addAll(Collection 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 filter) { throw uoe(); } + @Override public boolean retainAll(Collection c) { throw uoe(); } + } + + static final class Set0 extends AbstractImmutableSet { Set0() { } @Override @@ -210,7 +240,7 @@ class ImmutableCollections { } } - static final class Set1 extends AbstractSet implements Serializable { + static final class Set1 extends AbstractImmutableSet { private final E e0; Set1(E e0) { @@ -241,7 +271,7 @@ class ImmutableCollections { } } - static final class Set2 extends AbstractSet implements Serializable { + static final class Set2 extends AbstractImmutableSet { private final E e0; private final E e1; @@ -312,7 +342,7 @@ class ImmutableCollections { * least one null is always present. * @param the element type */ - static final class SetN extends AbstractSet implements Serializable { + static final class SetN extends AbstractImmutableSet { private final E[] elements; private final int size; @@ -403,7 +433,23 @@ class ImmutableCollections { // ---------- Map Implementations ---------- - static final class Map0 extends AbstractMap implements Serializable { + abstract static class AbstractImmutableMap extends AbstractMap implements Serializable { + @Override public void clear() { throw uoe(); } + @Override public V compute(K key, BiFunction rf) { throw uoe(); } + @Override public V computeIfAbsent(K key, Function mf) { throw uoe(); } + @Override public V computeIfPresent(K key, BiFunction rf) { throw uoe(); } + @Override public V merge(K key, V value, BiFunction rf) { throw uoe(); } + @Override public V put(K key, V value) { throw uoe(); } + @Override public void putAll(Map 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 f) { throw uoe(); } + } + + static final class Map0 extends AbstractImmutableMap { Map0() { } @Override @@ -430,7 +476,7 @@ class ImmutableCollections { } } - static final class Map1 extends AbstractMap implements Serializable { + static final class Map1 extends AbstractImmutableMap { private final K k0; private final V v0; @@ -472,7 +518,7 @@ class ImmutableCollections { * @param the key type * @param the value type */ - static final class MapN extends AbstractMap implements Serializable { + static final class MapN extends AbstractImmutableMap { private final Object[] table; // pairs of key, value private final int size; // number of pairs diff --git a/jdk/src/java.base/share/classes/java/util/List.java b/jdk/src/java.base/share/classes/java/util/List.java index 3819d94e831..8e97c2ea259 100644 --- a/jdk/src/java.base/share/classes/java/util/List.java +++ b/jdk/src/java.base/share/classes/java/util/List.java @@ -94,7 +94,8 @@ import java.util.function.UnaryOperator; * *