Merge
authorlana
Thu, 18 Aug 2016 21:34:03 +0000
changeset 40412 30db85b72746
parent 40388 f68535d073dc (current diff)
parent 40411 e936d2ba0281 (diff)
child 40413 14b3d338ebe0
Merge
--- a/jdk/make/copy/Copy-java.base.gmk	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/make/copy/Copy-java.base.gmk	Thu Aug 18 21:34:03 2016 +0000
@@ -183,7 +183,7 @@
 
 DEF_POLICY_SRC_LIST := $(DEF_POLICY_SRC)
 
-ifeq ($(OPENJDK_TARGET_OS), windows)
+ifneq ($(filter $(OPENJDK_TARGET_OS), windows solaris), )
   DEF_POLICY_SRC_LIST += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/lib/security/default.policy
 endif
 
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -107,7 +107,7 @@
             throw new InvalidKeySpecException("Key length is negative");
         }
         try {
-            this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance());
+            this.prf = Mac.getInstance(prfAlgo);
         } catch (NoSuchAlgorithmException nsae) {
             // not gonna happen; re-throw just in case
             InvalidKeySpecException ike = new InvalidKeySpecException();
--- a/jdk/src/java.base/share/classes/java/io/BufferedReader.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/BufferedReader.java	Thu Aug 18 21:34:03 2016 +0000
@@ -560,7 +560,7 @@
      * @since 1.8
      */
     public Stream<String> lines() {
-        Iterator<String> iter = new Iterator<String>() {
+        Iterator<String> iter = new Iterator<>() {
             String nextLine = null;
 
             @Override
--- a/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ByteArrayOutputStream.java	Thu Aug 18 21:34:03 2016 +0000
@@ -187,7 +187,7 @@
      * @return  the current contents of this output stream, as a byte array.
      * @see     java.io.ByteArrayOutputStream#size()
      */
-    public synchronized byte toByteArray()[] {
+    public synchronized byte[] toByteArray() {
         return Arrays.copyOf(buf, count);
     }
 
--- a/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java	Thu Aug 18 21:34:03 2016 +0000
@@ -165,7 +165,7 @@
      *
      * @param  csq
      *         The character sequence to append.  If {@code csq} is
-     *         {@code null}, then the four characters "{@code null}" are
+     *         {@code null}, then the four characters {@code "null"} are
      *         appended to this writer.
      *
      * @return  This writer
@@ -173,7 +173,7 @@
      * @since  1.5
      */
     public CharArrayWriter append(CharSequence csq) {
-        String s = (csq == null ? "null" : csq.toString());
+        String s = String.valueOf(csq);
         write(s, 0, s.length());
         return this;
     }
@@ -193,7 +193,7 @@
      *         The character sequence from which a subsequence will be
      *         appended.  If {@code csq} is {@code null}, then characters
      *         will be appended as if {@code csq} contained the four
-     *         characters "{@code null}".
+     *         characters {@code "null"}.
      *
      * @param  start
      *         The index of the first character in the subsequence
@@ -212,9 +212,8 @@
      * @since  1.5
      */
     public CharArrayWriter append(CharSequence csq, int start, int end) {
-        String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
-        write(s, 0, s.length());
-        return this;
+        if (csq == null) csq = "null";
+        return append(csq.subSequence(start, end));
     }
 
     /**
@@ -251,7 +250,7 @@
      *
      * @return an array of chars copied from the input data.
      */
-    public char toCharArray()[] {
+    public char[] toCharArray() {
         synchronized (lock) {
             return Arrays.copyOf(buf, count);
         }
--- a/jdk/src/java.base/share/classes/java/io/FileSystem.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/FileSystem.java	Thu Aug 18 21:34:03 2016 +0000
@@ -228,13 +228,8 @@
     static boolean useCanonPrefixCache = true;
 
     private static boolean getBooleanProperty(String prop, boolean defaultVal) {
-        String val = System.getProperty(prop);
-        if (val == null) return defaultVal;
-        if (val.equalsIgnoreCase("true")) {
-            return true;
-        } else {
-            return false;
-        }
+        return Boolean.parseBoolean(System.getProperty(prop,
+                String.valueOf(defaultVal)));
     }
 
     static {
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1265,22 +1265,21 @@
         WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
         Boolean result = Caches.subclassAudits.get(key);
         if (result == null) {
-            result = Boolean.valueOf(auditSubclass(cl));
+            result = auditSubclass(cl);
             Caches.subclassAudits.putIfAbsent(key, result);
         }
-        if (result.booleanValue()) {
-            return;
+        if (!result) {
+            sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
         }
-        sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
     }
 
     /**
      * Performs reflective checks on given subclass to verify that it doesn't
-     * override security-sensitive non-final methods.  Returns true if subclass
-     * is "safe", false otherwise.
+     * override security-sensitive non-final methods.  Returns TRUE if subclass
+     * is "safe", FALSE otherwise.
      */
-    private static boolean auditSubclass(final Class<?> subcl) {
-        Boolean result = AccessController.doPrivileged(
+    private static Boolean auditSubclass(Class<?> subcl) {
+        return AccessController.doPrivileged(
             new PrivilegedAction<>() {
                 public Boolean run() {
                     for (Class<?> cl = subcl;
@@ -1303,7 +1302,6 @@
                 }
             }
         );
-        return result.booleanValue();
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1050,22 +1050,21 @@
         WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
         Boolean result = Caches.subclassAudits.get(key);
         if (result == null) {
-            result = Boolean.valueOf(auditSubclass(cl));
+            result = auditSubclass(cl);
             Caches.subclassAudits.putIfAbsent(key, result);
         }
-        if (result.booleanValue()) {
-            return;
+        if (!result) {
+            sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
         }
-        sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
     }
 
     /**
      * Performs reflective checks on given subclass to verify that it doesn't
-     * override security-sensitive non-final methods.  Returns true if subclass
-     * is "safe", false otherwise.
+     * override security-sensitive non-final methods.  Returns TRUE if subclass
+     * is "safe", FALSE otherwise.
      */
-    private static boolean auditSubclass(final Class<?> subcl) {
-        Boolean result = AccessController.doPrivileged(
+    private static Boolean auditSubclass(Class<?> subcl) {
+        return AccessController.doPrivileged(
             new PrivilegedAction<>() {
                 public Boolean run() {
                     for (Class<?> cl = subcl;
@@ -1088,7 +1087,6 @@
                 }
             }
         );
-        return result.booleanValue();
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1509,11 +1509,9 @@
     private static String getPackageName(Class<?> cl) {
         String s = cl.getName();
         int i = s.lastIndexOf('[');
-        if (i >= 0) {
-            s = s.substring(i + 2);
-        }
-        i = s.lastIndexOf('.');
-        return (i >= 0) ? s.substring(0, i) : "";
+        i = (i < 0) ? 0 : i + 2;
+        int j = s.lastIndexOf('.');
+        return (i < j) ? s.substring(i, j) : "";
     }
 
     /**
@@ -1535,14 +1533,14 @@
     private static String getMethodSignature(Class<?>[] paramTypes,
                                              Class<?> retType)
     {
-        StringBuilder sbuf = new StringBuilder();
-        sbuf.append('(');
+        StringBuilder sb = new StringBuilder();
+        sb.append('(');
         for (int i = 0; i < paramTypes.length; i++) {
-            appendClassSignature(sbuf, paramTypes[i]);
+            appendClassSignature(sb, paramTypes[i]);
         }
-        sbuf.append(')');
-        appendClassSignature(sbuf, retType);
-        return sbuf.toString();
+        sb.append(')');
+        appendClassSignature(sb, retType);
+        return sb.toString();
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java	Thu Aug 18 21:34:03 2016 +0000
@@ -233,22 +233,16 @@
 
     @Override
     public Writer append(CharSequence csq, int start, int end) throws IOException {
-        if (csq == null) {
-            write("null".subSequence(start, end).toString());
-            return this;
-        } else {
-            return append(csq.subSequence(start, end));
-        }
+        if (csq == null) csq = "null";
+        return append(csq.subSequence(start, end));
     }
 
     @Override
     public Writer append(CharSequence csq) throws IOException {
-        if (csq == null) {
-            se.write("null");
-        } else if (csq instanceof CharBuffer) {
+        if (csq instanceof CharBuffer) {
             se.write((CharBuffer) csq);
         } else {
-            se.write(csq.toString());
+            se.write(String.valueOf(csq));
         }
         return this;
     }
--- a/jdk/src/java.base/share/classes/java/io/PrintStream.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/PrintStream.java	Thu Aug 18 21:34:03 2016 +0000
@@ -568,7 +568,7 @@
      * @param      b   The {@code boolean} to be printed
      */
     public void print(boolean b) {
-        write(b ? "true" : "false");
+        write(String.valueOf(b));
     }
 
     /**
@@ -663,10 +663,7 @@
      * @param      s   The {@code String} to be printed
      */
     public void print(String s) {
-        if (s == null) {
-            s = "null";
-        }
-        write(s);
+        write(String.valueOf(s));
     }
 
     /**
@@ -1068,10 +1065,7 @@
      * @since  1.5
      */
     public PrintStream append(CharSequence csq) {
-        if (csq == null)
-            print("null");
-        else
-            print(csq.toString());
+        print(String.valueOf(csq));
         return this;
     }
 
@@ -1111,9 +1105,8 @@
      * @since  1.5
      */
     public PrintStream append(CharSequence csq, int start, int end) {
-        CharSequence cs = (csq == null ? "null" : csq);
-        write(cs.subSequence(start, end).toString());
-        return this;
+        if (csq == null) csq = "null";
+        return append(csq.subSequence(start, end));
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/PrintWriter.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/PrintWriter.java	Thu Aug 18 21:34:03 2016 +0000
@@ -504,7 +504,7 @@
      * @param      b   The {@code boolean} to be printed
      */
     public void print(boolean b) {
-        write(b ? "true" : "false");
+        write(String.valueOf(b));
     }
 
     /**
@@ -599,10 +599,7 @@
      * @param      s   The {@code String} to be printed
      */
     public void print(String s) {
-        if (s == null) {
-            s = "null";
-        }
-        write(s);
+        write(String.valueOf(s));
     }
 
     /**
@@ -1005,10 +1002,7 @@
      * @since  1.5
      */
     public PrintWriter append(CharSequence csq) {
-        if (csq == null)
-            write("null");
-        else
-            write(csq.toString());
+        write(String.valueOf(csq));
         return this;
     }
 
@@ -1047,9 +1041,8 @@
      * @since  1.5
      */
     public PrintWriter append(CharSequence csq, int start, int end) {
-        CharSequence cs = (csq == null ? "null" : csq);
-        write(cs.subSequence(start, end).toString());
-        return this;
+        if (csq == null) csq = "null";
+        return append(csq.subSequence(start, end));
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/SequenceInputStream.java	Thu Aug 18 21:34:03 2016 +0000
@@ -65,12 +65,7 @@
      */
     public SequenceInputStream(Enumeration<? extends InputStream> e) {
         this.e = e;
-        try {
-            nextStream();
-        } catch (IOException ex) {
-            // This should never happen
-            throw new Error("panic");
-        }
+        peekNextStream();
     }
 
     /**
@@ -86,16 +81,10 @@
      */
     public SequenceInputStream(InputStream s1, InputStream s2) {
         Vector<InputStream> v = new Vector<>(2);
-
         v.addElement(s1);
         v.addElement(s2);
         e = v.elements();
-        try {
-            nextStream();
-        } catch (IOException ex) {
-            // This should never happen
-            throw new Error("panic");
-        }
+        peekNextStream();
     }
 
     /**
@@ -105,14 +94,17 @@
         if (in != null) {
             in.close();
         }
+        peekNextStream();
+    }
 
+    private void peekNextStream() {
         if (e.hasMoreElements()) {
             in = (InputStream) e.nextElement();
             if (in == null)
                 throw new NullPointerException();
+        } else {
+            in = null;
         }
-        else in = null;
-
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java	Thu Aug 18 21:34:03 2016 +0000
@@ -108,6 +108,7 @@
      *             <code>-1</code> if there is no more data because the end of
      *             the stream has been reached.
      */
+    @SuppressWarnings("deprecation")
     public synchronized int read(byte b[], int off, int len) {
         if (b == null) {
             throw new NullPointerException();
@@ -126,12 +127,8 @@
         if (len <= 0) {
             return 0;
         }
-        String  s = buffer;
-        int cnt = len;
-        while (--cnt >= 0) {
-            b[off++] = (byte)s.charAt(pos++);
-        }
-
+        buffer.getBytes(pos, pos + len, b, off);
+        pos += len;
         return len;
     }
 
--- a/jdk/src/java.base/share/classes/java/io/StringReader.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/StringReader.java	Thu Aug 18 21:34:03 2016 +0000
@@ -142,8 +142,8 @@
      */
     public boolean ready() throws IOException {
         synchronized (lock) {
-        ensureOpen();
-        return true;
+            ensureOpen();
+            return true;
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/io/StringWriter.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/StringWriter.java	Thu Aug 18 21:34:03 2016 +0000
@@ -139,7 +139,7 @@
      *
      * @param  csq
      *         The character sequence to append.  If {@code csq} is
-     *         {@code null}, then the four characters "{@code null}" are
+     *         {@code null}, then the four characters {@code "null"} are
      *         appended to this writer.
      *
      * @return  This writer
@@ -147,10 +147,7 @@
      * @since  1.5
      */
     public StringWriter append(CharSequence csq) {
-        if (csq == null)
-            write("null");
-        else
-            write(csq.toString());
+        write(String.valueOf(csq));
         return this;
     }
 
@@ -170,7 +167,7 @@
      *         The character sequence from which a subsequence will be
      *         appended.  If {@code csq} is {@code null}, then characters
      *         will be appended as if {@code csq} contained the four
-     *         characters "{@code null}".
+     *         characters {@code "null"}.
      *
      * @param  start
      *         The index of the first character in the subsequence
@@ -189,9 +186,8 @@
      * @since  1.5
      */
     public StringWriter append(CharSequence csq, int start, int end) {
-        CharSequence cs = (csq == null ? "null" : csq);
-        write(cs.subSequence(start, end).toString());
-        return this;
+        if (csq == null) csq = "null";
+        return append(csq.subSequence(start, end));
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/io/Writer.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/Writer.java	Thu Aug 18 21:34:03 2016 +0000
@@ -221,7 +221,7 @@
      *
      * @param  csq
      *         The character sequence to append.  If {@code csq} is
-     *         {@code null}, then the four characters "{@code null}" are
+     *         {@code null}, then the four characters {@code "null"} are
      *         appended to this writer.
      *
      * @return  This writer
@@ -232,10 +232,7 @@
      * @since  1.5
      */
     public Writer append(CharSequence csq) throws IOException {
-        if (csq == null)
-            write("null");
-        else
-            write(csq.toString());
+        write(String.valueOf(csq));
         return this;
     }
 
@@ -256,7 +253,7 @@
      *         The character sequence from which a subsequence will be
      *         appended.  If {@code csq} is {@code null}, then characters
      *         will be appended as if {@code csq} contained the four
-     *         characters "{@code null}".
+     *         characters {@code "null"}.
      *
      * @param  start
      *         The index of the first character in the subsequence
@@ -278,9 +275,8 @@
      * @since  1.5
      */
     public Writer append(CharSequence csq, int start, int end) throws IOException {
-        CharSequence cs = (csq == null ? "null" : csq);
-        write(cs.subSequence(start, end).toString());
-        return this;
+        if (csq == null) csq = "null";
+        return append(csq.subSequence(start, end));
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Thu Aug 18 21:34:03 2016 +0000
@@ -36,7 +36,6 @@
 import java.lang.invoke.LambdaForm.NamedFunction;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.Field;
-import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.Function;
@@ -308,7 +307,7 @@
         /*non-public*/ char fieldTypeChar(int i) {
             return typeChars.charAt(i);
         }
-        Object fieldSignature() {
+        String fieldSignature() {
             return typeChars;
         }
         public Class<? extends BoundMethodHandle> fieldHolder() {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java	Thu Aug 18 21:34:03 2016 +0000
@@ -27,6 +27,7 @@
 
 import java.util.Arrays;
 import static java.lang.invoke.LambdaForm.*;
+import static java.lang.invoke.LambdaForm.Kind.*;
 import static java.lang.invoke.MethodHandleStatics.*;
 
 /**
@@ -96,14 +97,8 @@
                                         int whichCache,
                                         Object constraint,
                                         NamedFunction getTargetFn) {
-        String debugString;
-        switch(whichCache) {
-            case MethodTypeForm.LF_REBIND:            debugString = "BMH.reinvoke";      break;
-            case MethodTypeForm.LF_DELEGATE:          debugString = "MH.delegate";       break;
-            default:                                  debugString = "MH.reinvoke";       break;
-        }
         // No pre-action needed.
-        return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null);
+        return makeReinvokerForm(target, whichCache, constraint, null, true, getTargetFn, null);
     }
     /** Create a LF which simply reinvokes a target of the given basic type. */
     static LambdaForm makeReinvokerForm(MethodHandle target,
@@ -114,6 +109,10 @@
                                         NamedFunction getTargetFn,
                                         NamedFunction preActionFn) {
         MethodType mtype = target.type().basicType();
+        Kind kind = whichKind(whichCache);
+        if (debugString == null) {
+            debugString = kind.defaultLambdaName;
+        }
         boolean customized = (whichCache < 0 ||
                 mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY);
         boolean hasPreAction = (preActionFn != null);
@@ -145,13 +144,21 @@
             targetArgs[0] = names[NEXT_MH];  // overwrite this MH with next MH
             names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs);
         }
-        form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline);
+        form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline, kind);
         if (!customized) {
             form = mtype.form().setCachedLambdaForm(whichCache, form);
         }
         return form;
     }
 
+    private static Kind whichKind(int whichCache) {
+        switch(whichCache) {
+            case MethodTypeForm.LF_REBIND:   return BOUND_REINVOKER;
+            case MethodTypeForm.LF_DELEGATE: return DELEGATE;
+            default:                         return REINVOKER;
+        }
+    }
+
     static final NamedFunction NF_getTarget;
     static {
         try {
@@ -160,5 +167,13 @@
         } catch (ReflectiveOperationException ex) {
             throw newInternalError(ex);
         }
+        // The Holder class will contain pre-generated DelegatingMethodHandles resolved
+        // speculatively using MemberName.getFactory().resolveOrNull. However, that
+        // doesn't initialize the class, which subtly breaks inlining etc. By forcing
+        // initialization of the Holder class we avoid these issues.
+        UNSAFE.ensureClassInitialized(Holder.class);
     }
+
+    /* Placeholder class for DelegatingMethodHandles generated ahead of time */
+    final class Holder {}
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Thu Aug 18 21:34:03 2016 +0000
@@ -38,6 +38,7 @@
 import java.util.Objects;
 
 import static java.lang.invoke.LambdaForm.*;
+import static java.lang.invoke.LambdaForm.Kind.*;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
 import static java.lang.invoke.MethodHandleStatics.newInternalError;
@@ -189,14 +190,15 @@
     static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
         boolean needsInit = (which == LF_INVSTATIC_INIT);
         boolean doesAlloc = (which == LF_NEWINVSPECIAL);
-        String linkerName, lambdaName;
+        String linkerName;
+        LambdaForm.Kind kind;
         switch (which) {
-        case LF_INVVIRTUAL:    linkerName = "linkToVirtual";    lambdaName = "DMH.invokeVirtual";    break;
-        case LF_INVSTATIC:     linkerName = "linkToStatic";     lambdaName = "DMH.invokeStatic";     break;
-        case LF_INVSTATIC_INIT:linkerName = "linkToStatic";     lambdaName = "DMH.invokeStaticInit"; break;
-        case LF_INVSPECIAL:    linkerName = "linkToSpecial";    lambdaName = "DMH.invokeSpecial";    break;
-        case LF_INVINTERFACE:  linkerName = "linkToInterface";  lambdaName = "DMH.invokeInterface";  break;
-        case LF_NEWINVSPECIAL: linkerName = "linkToSpecial";    lambdaName = "DMH.newInvokeSpecial"; break;
+        case LF_INVVIRTUAL:    linkerName = "linkToVirtual";   kind = DIRECT_INVOKE_VIRTUAL;     break;
+        case LF_INVSTATIC:     linkerName = "linkToStatic";    kind = DIRECT_INVOKE_STATIC;      break;
+        case LF_INVSTATIC_INIT:linkerName = "linkToStatic";    kind = DIRECT_INVOKE_STATIC_INIT; break;
+        case LF_INVSPECIAL:    linkerName = "linkToSpecial";   kind = DIRECT_INVOKE_SPECIAL;     break;
+        case LF_INVINTERFACE:  linkerName = "linkToInterface"; kind = DIRECT_INVOKE_INTERFACE;   break;
+        case LF_NEWINVSPECIAL: linkerName = "linkToSpecial";   kind = DIRECT_NEW_INVOKE_SPECIAL; break;
         default:  throw new InternalError("which="+which);
         }
 
@@ -240,11 +242,11 @@
             result = NEW_OBJ;
         }
         names[LINKER_CALL] = new Name(linker, outArgs);
-        lambdaName += "_" + shortenSignature(basicTypeSignature(mtype));
-        LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
+        String lambdaName = kind.defaultLambdaName + "_" + shortenSignature(basicTypeSignature(mtype));
+        LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result, kind);
 
         // This is a tricky bit of code.  Don't send it through the LF interpreter.
-        lform.compileToBytecode(Holder.class);
+        lform.compileToBytecode();
         return lform;
     }
 
@@ -705,7 +707,7 @@
     }
 
     static {
-        // The DMH class will contain pre-generated DirectMethodHandles resolved
+        // The Holder class will contain pre-generated DirectMethodHandles resolved
         // speculatively using MemberName.getFactory().resolveOrNull. However, that
         // doesn't initialize the class, which subtly breaks inlining etc. By forcing
         // initialization of the Holder class we avoid these issues.
@@ -713,5 +715,5 @@
     }
 
     /* Placeholder class for DirectMethodHandles generated ahead of time */
-    private final class Holder {}
+    final class Holder {}
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java	Thu Aug 18 21:34:03 2016 +0000
@@ -29,21 +29,56 @@
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Opcodes;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+
 /**
  * Helper class to assist the GenerateJLIClassesPlugin to get access to
  * generate classes ahead of time.
  */
 class GenerateJLIClassesHelper {
 
-    static byte[] generateDMHClassBytes(String className,
+    static byte[] generateDirectMethodHandleHolderClassBytes(String className,
             MethodType[] methodTypes, int[] types) {
         LambdaForm[] forms = new LambdaForm[methodTypes.length];
+        String[] names = new String[methodTypes.length];
         for (int i = 0; i < forms.length; i++) {
             forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
                                                                  types[i]);
-            methodTypes[i] = forms[i].methodType();
+            names[i] = forms[i].kind.defaultLambdaName;
         }
-        return generateCodeBytesForLFs(className, forms, methodTypes);
+        return generateCodeBytesForLFs(className, names, forms);
+    }
+
+    static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
+            MethodType[] methodTypes) {
+
+        HashSet<MethodType> dedupSet = new HashSet<>();
+        ArrayList<LambdaForm> forms = new ArrayList<>();
+        ArrayList<String> names = new ArrayList<>();
+        for (int i = 0; i < methodTypes.length; i++) {
+            // generate methods representing the DelegatingMethodHandle
+            if (dedupSet.add(methodTypes[i])) {
+                // reinvokers are variant with the associated SpeciesData
+                // and shape of the target LF, but we can easily pregenerate
+                // the basic reinvokers associated with Species_L. Ultimately we
+                // may want to consider pregenerating more of these, which will
+                // require an even more complex naming scheme
+                LambdaForm reinvoker = makeReinvokerFor(methodTypes[i]);
+                forms.add(reinvoker);
+                String speciesSig = BoundMethodHandle
+                        .speciesData(reinvoker).fieldSignature();
+                assert(speciesSig.equals("L"));
+                names.add(reinvoker.kind.defaultLambdaName + "_" + speciesSig);
+
+                LambdaForm delegate = makeDelegateFor(methodTypes[i]);
+                forms.add(delegate);
+                names.add(delegate.kind.defaultLambdaName);
+            }
+        }
+        return generateCodeBytesForLFs(className,
+                names.toArray(new String[0]),
+                forms.toArray(new LambdaForm[0]));
     }
 
     /*
@@ -51,22 +86,45 @@
      * a class with a specified name.
      */
     private static byte[] generateCodeBytesForLFs(String className,
-            LambdaForm[] forms, MethodType[] types) {
-        assert(forms.length == types.length);
+            String[] names, LambdaForm[] forms) {
 
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
         cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
                 className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null);
         cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
+
         for (int i = 0; i < forms.length; i++) {
-            InvokerBytecodeGenerator g
-                    = new InvokerBytecodeGenerator(className, forms[i], types[i]);
-            g.setClassWriter(cw);
-            g.addMethod();
+            addMethod(className, names[i], forms[i],
+                    forms[i].methodType(), cw);
         }
         return cw.toByteArray();
     }
 
+    private static void addMethod(String className, String methodName, LambdaForm form,
+            MethodType type, ClassWriter cw) {
+        InvokerBytecodeGenerator g
+                = new InvokerBytecodeGenerator(className, methodName, form, type);
+        g.setClassWriter(cw);
+        g.addMethod();
+    }
+
+    private static LambdaForm makeReinvokerFor(MethodType type) {
+        MethodHandle emptyHandle = MethodHandles.empty(type);
+        return DelegatingMethodHandle.makeReinvokerForm(emptyHandle,
+                MethodTypeForm.LF_REBIND,
+                BoundMethodHandle.speciesData_L(),
+                BoundMethodHandle.speciesData_L().getterFunction(0));
+    }
+
+    private static LambdaForm makeDelegateFor(MethodType type) {
+        MethodHandle handle = MethodHandles.empty(type);
+        return DelegatingMethodHandle.makeReinvokerForm(
+                handle,
+                MethodTypeForm.LF_DELEGATE,
+                DelegatingMethodHandle.class,
+                DelegatingMethodHandle.NF_getTarget);
+    }
+
     static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
             final String types) {
         for (char c : types.toCharArray()) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Thu Aug 18 21:34:03 2016 +0000
@@ -46,6 +46,7 @@
 
 import static java.lang.invoke.LambdaForm.*;
 import static java.lang.invoke.LambdaForm.BasicType.*;
+import static java.lang.invoke.LambdaForm.Kind.*;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandleStatics.*;
 
@@ -125,9 +126,15 @@
     }
 
     /** For generating customized code for a single LambdaForm. */
-    InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
+    private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
+        this(className, form.debugName, form, invokerType);
+    }
+
+    /** For generating customized code for a single LambdaForm. */
+    InvokerBytecodeGenerator(String className, String invokerName,
+            LambdaForm form, MethodType invokerType) {
         this(form, form.names.length,
-             className, form.debugName, invokerType);
+             className, invokerName, invokerType);
         // Create an array to map name indexes to locals indexes.
         Name[] names = form.names;
         for (int i = 0, index = 0; i < localsMap.length; i++) {
@@ -597,10 +604,42 @@
         return c.getName().replace('.', '/');
     }
 
+    private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
+        MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
+        MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
+
+        return resolvedMember;
+    }
+
+    private static MemberName lookupPregenerated(LambdaForm form) {
+        if (form.customized != null) {
+            // No pre-generated version for customized LF
+            return null;
+        }
+        MethodType invokerType = form.methodType();
+        String name = form.kind.methodName;
+        switch (form.kind) {
+            case BOUND_REINVOKER: {
+                name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature();
+                return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class);
+            }
+            case DELEGATE:                  return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class);
+            case DIRECT_INVOKE_INTERFACE:   // fall-through
+            case DIRECT_INVOKE_SPECIAL:     // fall-through
+            case DIRECT_INVOKE_STATIC:      // fall-through
+            case DIRECT_INVOKE_STATIC_INIT: // fall-through
+            case DIRECT_INVOKE_VIRTUAL:     return resolveFrom(name, invokerType, DirectMethodHandle.Holder.class);
+        }
+        return null;
+    }
+
     /**
      * Generate customized bytecode for a given LambdaForm.
      */
     static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) {
+        MemberName pregenerated = lookupPregenerated(form);
+        if (pregenerated != null)  return pregenerated; // pre-generated bytecode
+
         InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType);
         return g.loadMethod(g.generateCustomizedCodeBytes());
     }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Thu Aug 18 21:34:03 2016 +0000
@@ -41,6 +41,7 @@
 import static java.lang.invoke.LambdaForm.BasicType.*;
 import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
 import static java.lang.invoke.MethodHandleStatics.*;
+import java.util.Objects;
 
 /**
  * The symbolic, non-executable form of a method handle's invocation semantics.
@@ -127,6 +128,7 @@
     final MethodHandle customized;
     @Stable final Name[] names;
     final String debugName;
+    final Kind kind;
     MemberName vmentry;   // low-level behavior, or null if not yet prepared
     private boolean isCompiled;
 
@@ -266,12 +268,46 @@
         }
     }
 
+    enum Kind {
+        GENERIC(""),
+        BOUND_REINVOKER("BMH.reinvoke"),
+        REINVOKER("MH.reinvoke"),
+        DELEGATE("MH.delegate"),
+        DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
+        DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
+        DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
+        DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
+        DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"),
+        DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit");
+
+        final String defaultLambdaName;
+        final String methodName;
+
+        private Kind(String defaultLambdaName) {
+            this.defaultLambdaName = defaultLambdaName;
+            int p = defaultLambdaName.indexOf('.');
+            if (p > -1) {
+                this.methodName = defaultLambdaName.substring(p + 1);
+            } else {
+                this.methodName = defaultLambdaName;
+            }
+        }
+    }
+
     LambdaForm(String debugName,
                int arity, Name[] names, int result) {
-        this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null);
+        this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
+    }
+    LambdaForm(String debugName,
+               int arity, Name[] names, int result, Kind kind) {
+        this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, kind);
     }
     LambdaForm(String debugName,
                int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) {
+        this(debugName, arity, names, result, forceInline, customized, Kind.GENERIC);
+    }
+    LambdaForm(String debugName,
+               int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) {
         assert(namesOK(arity, names));
         this.arity = arity;
         this.result = fixResult(result, names);
@@ -279,6 +315,7 @@
         this.debugName = fixDebugName(debugName);
         this.forceInline = forceInline;
         this.customized = customized;
+        this.kind = kind;
         int maxOutArity = normalize();
         if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) {
             // Cannot use LF interpreter on very high arity expressions.
@@ -288,11 +325,15 @@
     }
     LambdaForm(String debugName,
                int arity, Name[] names) {
-        this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null);
+        this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
     }
     LambdaForm(String debugName,
                int arity, Name[] names, boolean forceInline) {
-        this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null);
+        this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC);
+    }
+    LambdaForm(String debugName,
+               int arity, Name[] names, boolean forceInline, Kind kind) {
+        this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, kind);
     }
     LambdaForm(String debugName,
                Name[] formals, Name[] temps, Name result) {
@@ -325,6 +366,7 @@
         this.debugName = "LF.zero";
         this.forceInline = true;
         this.customized = null;
+        this.kind = Kind.GENERIC;
         assert(nameRefsAreLegal());
         assert(isEmpty());
         String sig = null;
@@ -395,7 +437,7 @@
 
     /** Customize LambdaForm for a particular MethodHandle */
     LambdaForm customize(MethodHandle mh) {
-        LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh);
+        LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh, kind);
         if (COMPILE_THRESHOLD >= 0 && isCompiled) {
             // If shared LambdaForm has been compiled, compile customized version as well.
             customForm.compileToBytecode();
@@ -773,28 +815,6 @@
         }
     }
 
-    /**
-     * Generate optimizable bytecode for this form after first looking for a
-     * pregenerated version in a specified class.
-     */
-    void compileToBytecode(Class<?> lookupClass) {
-        if (vmentry != null && isCompiled) {
-            return;  // already compiled somehow
-        }
-        MethodType invokerType = methodType();
-        assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType));
-        int dot = debugName.indexOf('.');
-        String methodName = (dot > 0) ? debugName.substring(dot + 1) : debugName;
-        MemberName member = new MemberName(lookupClass, methodName, invokerType, REF_invokeStatic);
-        MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, lookupClass);
-        if (resolvedMember != null) {
-            vmentry = resolvedMember;
-            isCompiled = true;
-        } else {
-            compileToBytecode();
-        }
-    }
-
     private static void computeInitialPreparedForms() {
         // Find all predefined invokers and associate them with canonical empty lambda forms.
         for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1718,10 +1718,19 @@
             }
 
             @Override
-            public byte[] generateDMHClassBytes(String className,
-            MethodType[] methodTypes, int[] types) {
+            public byte[] generateDirectMethodHandleHolderClassBytes(
+                    String className, MethodType[] methodTypes, int[] types) {
                 return GenerateJLIClassesHelper
-                        .generateDMHClassBytes(className, methodTypes, types);
+                        .generateDirectMethodHandleHolderClassBytes(
+                                className, methodTypes, types);
+            }
+
+            @Override
+            public byte[] generateDelegatingMethodHandleHolderClassBytes(
+                    String className, MethodType[] methodTypes) {
+                return GenerateJLIClassesHelper
+                        .generateDelegatingMethodHandleHolderClassBytes(
+                                className, methodTypes);
             }
 
             @Override
--- a/jdk/src/java.base/share/classes/java/security/Provider.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/security/Provider.java	Thu Aug 18 21:34:03 2016 +0000
@@ -601,7 +601,7 @@
     public synchronized Object compute(Object key, BiFunction<? super Object,
             ? super Object, ? extends Object> remappingFunction) {
         check("putProviderProperty." + name);
-        check("removeProviderProperty" + name);
+        check("removeProviderProperty." + name);
 
         if (debug != null) {
             debug.println("Compute " + name + " provider property " + key);
@@ -632,7 +632,7 @@
     public synchronized Object computeIfAbsent(Object key, Function<? super Object,
             ? extends Object> mappingFunction) {
         check("putProviderProperty." + name);
-        check("removeProviderProperty" + name);
+        check("removeProviderProperty." + name);
 
         if (debug != null) {
             debug.println("ComputeIfAbsent " + name + " provider property " +
@@ -662,7 +662,7 @@
     public synchronized Object computeIfPresent(Object key, BiFunction<? super Object,
             ? super Object, ? extends Object> remappingFunction) {
         check("putProviderProperty." + name);
-        check("removeProviderProperty" + name);
+        check("removeProviderProperty." + name);
 
         if (debug != null) {
             debug.println("ComputeIfPresent " + name + " provider property " +
@@ -695,7 +695,7 @@
     public synchronized Object merge(Object key, Object value,  BiFunction<? super Object,
             ? super Object, ? extends Object>  remappingFunction) {
         check("putProviderProperty." + name);
-        check("removeProviderProperty" + name);
+        check("removeProviderProperty." + name);
 
         if (debug != null) {
             debug.println("Merge " + name + " provider property " + key);
@@ -904,8 +904,8 @@
             if (!checkLegacy(key)) {
                 return null;
             }
-            legacyStrings.computeIfAbsent((String) key,
-                    (Function<? super String, ? extends String>) remappingFunction);
+            legacyStrings.compute((String) key,
+                    (BiFunction<? super String,? super String, ? extends String>) remappingFunction);
         }
         return super.compute(key, remappingFunction);
     }
--- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java	Thu Aug 18 21:34:03 2016 +0000
@@ -399,7 +399,10 @@
      * Calendar Elements in the Unicode Locale Data Markup Language
      * (LDML) specification</a> for more details.
      *
-     * @return the month strings.
+     * @return the month strings. Use
+     * {@link java.util.Calendar#JANUARY Calendar.JANUARY},
+     * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY},
+     * etc. to index the result array.
      */
     public String[] getMonths() {
         return Arrays.copyOf(months, months.length);
@@ -407,7 +410,9 @@
 
     /**
      * Sets month strings. For example: "January", "February", etc.
-     * @param newMonths the new month strings.
+     * @param newMonths the new month strings. The array should
+     * be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY},
+     * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc.
      */
     public void setMonths(String[] newMonths) {
         months = Arrays.copyOf(newMonths, newMonths.length);
@@ -427,7 +432,10 @@
      * Calendar Elements in the Unicode Locale Data Markup Language
      * (LDML) specification</a> for more details.
      *
-     * @return the short month strings.
+     * @return the short month strings. Use
+     * {@link java.util.Calendar#JANUARY Calendar.JANUARY},
+     * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY},
+     * etc. to index the result array.
      */
     public String[] getShortMonths() {
         return Arrays.copyOf(shortMonths, shortMonths.length);
@@ -435,7 +443,9 @@
 
     /**
      * Sets short month strings. For example: "Jan", "Feb", etc.
-     * @param newShortMonths the new short month strings.
+     * @param newShortMonths the new short month strings. The array should
+     * be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY},
+     * {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc.
      */
     public void setShortMonths(String[] newShortMonths) {
         shortMonths = Arrays.copyOf(newShortMonths, newShortMonths.length);
@@ -444,8 +454,10 @@
 
     /**
      * Gets weekday strings. For example: "Sunday", "Monday", etc.
-     * @return the weekday strings. Use <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc. to index the result array.
+     * @return the weekday strings. Use
+     * {@link java.util.Calendar#SUNDAY Calendar.SUNDAY},
+     * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index
+     * the result array.
      */
     public String[] getWeekdays() {
         return Arrays.copyOf(weekdays, weekdays.length);
@@ -454,8 +466,8 @@
     /**
      * Sets weekday strings. For example: "Sunday", "Monday", etc.
      * @param newWeekdays the new weekday strings. The array should
-     * be indexed by <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc.
+     * be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY},
+     * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc.
      */
     public void setWeekdays(String[] newWeekdays) {
         weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length);
@@ -464,8 +476,10 @@
 
     /**
      * Gets short weekday strings. For example: "Sun", "Mon", etc.
-     * @return the short weekday strings. Use <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc. to index the result array.
+     * @return the short weekday strings. Use
+     * {@link java.util.Calendar#SUNDAY Calendar.SUNDAY},
+     * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index
+     * the result array.
      */
     public String[] getShortWeekdays() {
         return Arrays.copyOf(shortWeekdays, shortWeekdays.length);
@@ -474,8 +488,8 @@
     /**
      * Sets short weekday strings. For example: "Sun", "Mon", etc.
      * @param newShortWeekdays the new short weekday strings. The array should
-     * be indexed by <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc.
+     * be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY},
+     * {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc.
      */
     public void setShortWeekdays(String[] newShortWeekdays) {
         shortWeekdays = Arrays.copyOf(newShortWeekdays, newShortWeekdays.length);
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java	Thu Aug 18 21:34:03 2016 +0000
@@ -861,6 +861,13 @@
      * be enabled by default, since this list may include cipher suites which
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites might be useful in specialized applications.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @return  an array of cipher suite names
      * @see     #getEnabledCipherSuites()
@@ -880,6 +887,13 @@
      * or the requisite certificates (and private keys) for the suite are
      * not available, or an anonymous suite is enabled but authentication
      * is required.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @return  an array of cipher suite names
      * @see     #getSupportedCipherSuites()
@@ -896,6 +910,14 @@
      * fail.  Following a successful call to this method, only suites
      * listed in the {@code suites} parameter are enabled for use.
      * <P>
+     * Note that the standard list of cipher suite names may be found in the
+     * <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation.  Providers
+     * may support cipher suite names not found in this list or might not
+     * use the recommended name for a certain cipher suite.
+     * <P>
      * See {@link #getEnabledCipherSuites()} for more information
      * on why a specific cipher suite may never be used on a engine.
      *
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -108,7 +108,12 @@
      * <p>
      * Calling this constructor is equivalent to calling the no-args
      * constructor followed by
-     * {@code setCipherSuites(cipherSuites);}.
+     * {@code setCipherSuites(cipherSuites);}.  Note that the
+     * standard list of cipher suite names may be found in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation.  Providers
+     * may support cipher suite names not found in this list.
      *
      * @param cipherSuites the array of ciphersuites (or null)
      */
@@ -123,6 +128,12 @@
      * Calling this constructor is equivalent to calling the no-args
      * constructor followed by
      * {@code setCipherSuites(cipherSuites); setProtocols(protocols);}.
+     * Note that the standard list of cipher suite names may be found in the
+     * <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation.  Providers
+     * may support cipher suite names not found in this list.
      *
      * @param cipherSuites the array of ciphersuites (or null)
      * @param protocols the array of protocols (or null)
@@ -139,6 +150,13 @@
     /**
      * Returns a copy of the array of ciphersuites or null if none
      * have been set.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @return a copy of the array of ciphersuites or null if none
      * have been set.
@@ -150,7 +168,13 @@
     /**
      * Sets the array of ciphersuites.
      *
-     * @param cipherSuites the array of ciphersuites (or null)
+     * @param cipherSuites the array of ciphersuites (or null).  Note that the
+     * standard list of cipher suite names may be found in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation.  Providers
+     * may support cipher suite names not found in this list or might not
+     * use the recommended name for a certain cipher suite.
      */
     public void setCipherSuites(String[] cipherSuites) {
         this.cipherSuites = clone(cipherSuites);
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java	Thu Aug 18 21:34:03 2016 +0000
@@ -195,6 +195,13 @@
      * or the requisite certificates (and private keys) for the suite are
      * not available, or an anonymous suite is enabled but authentication
      * is required.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @return an array of cipher suites enabled
      * @see #getSupportedCipherSuites()
@@ -215,6 +222,14 @@
      * in this ServerSocket's authentication context will not be used
      * in any case, even if they are enabled.
      * <P>
+     * Note that the standard list of cipher suite names may be found in the
+     * <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation.  Providers
+     * may support cipher suite names not found in this list or might not
+     * use the recommended name for a certain cipher suite.
+     * <P>
      * <code>SSLSocket</code>s returned from <code>accept()</code>
      * inherit this setting.
      *
@@ -236,6 +251,13 @@
      * be enabled by default, since this list may include cipher suites which
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites are useful in specialized applications.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @return an array of cipher suite names
      * @see #getEnabledCipherSuites()
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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
@@ -123,6 +123,13 @@
      * will use one of these cipher suites.  The minimum quality of service
      * for these defaults requires confidentiality protection and server
      * authentication (that is, no anonymous cipher suites).
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @see #getSupportedCipherSuites()
      * @return array of the cipher suites enabled by default
@@ -137,6 +144,13 @@
      * be enabled by default, since this list may include cipher suites which
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites are useful in specialized applications.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @return an array of cipher suite names
      * @see #getDefaultCipherSuites()
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java	Thu Aug 18 21:34:03 2016 +0000
@@ -265,6 +265,13 @@
      * be enabled by default, since this list may include cipher suites which
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites might be useful in specialized applications.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @return an array of cipher suite names
      * @see #getEnabledCipherSuites()
@@ -284,6 +291,13 @@
      * or the requisite certificates (and private keys) for the suite are
      * not available, or an anonymous suite is enabled but authentication
      * is required.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @return an array of cipher suite names
      * @see #getSupportedCipherSuites()
@@ -300,6 +314,14 @@
      * fail.  Following a successful call to this method, only suites
      * listed in the <code>suites</code> parameter are enabled for use.
      * <P>
+     * Note that the standard list of cipher suite names may be found in the
+     * <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation.  Providers
+     * may support cipher suite names not found in this list or might not
+     * use the recommended name for a certain cipher suite.
+     * <P>
      * See {@link #getEnabledCipherSuites()} for more information
      * on why a specific ciphersuite may never be used on a connection.
      *
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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
@@ -148,6 +148,13 @@
      * will use one of these cipher suites.  The minimum quality of service
      * for these defaults requires confidentiality protection and server
      * authentication (that is, no anonymous cipher suites).
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @see #getSupportedCipherSuites()
      * @return array of the cipher suites enabled by default
@@ -160,6 +167,13 @@
      * be enabled by default, since this list may include cipher suites which
      * do not meet quality of service requirements for those defaults.  Such
      * cipher suites are useful in specialized applications.
+     * <P>
+     * The returned array includes cipher suites from the list of standard
+     * cipher suite names in the <a href=
+     * "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
+     * JSSE Cipher Suite Names</a> section of the Java Cryptography
+     * Architecture Standard Algorithm Name Documentation, and may also
+     * include other cipher suites that the provider supports.
      *
      * @see #getDefaultCipherSuites()
      * @return an array of cipher suite names
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu Aug 18 21:34:03 2016 +0000
@@ -51,8 +51,17 @@
      * an {@code int} representing method type.  Used by
      * GenerateJLIClassesPlugin to generate such a class during the jlink phase.
      */
-    byte[] generateDMHClassBytes(String className, MethodType[] methodTypes,
-            int[] types);
+    byte[] generateDirectMethodHandleHolderClassBytes(String className,
+            MethodType[] methodTypes, int[] types);
+
+    /**
+     * Returns a {@code byte[]} containing the bytecode for a class implementing
+     * DelegatingMethodHandles of each {@code MethodType} kind in the
+     * {@code methodTypes} argument.  Used by GenerateJLIClassesPlugin to
+     * generate such a class during the jlink phase.
+     */
+    byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
+            MethodType[] methodTypes);
 
     /**
      * Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle
--- a/jdk/src/java.base/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -24,9 +24,8 @@
  */
 
 /**
- * java.base defines and exports the core APIs of the Java SE platform.
+ * Defines the foundational APIs of the Java SE Platform.
  */
-
 module java.base {
 
     exports java.io;
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Aug 18 21:34:03 2016 +0000
@@ -3631,8 +3631,8 @@
                 if (time != null) {
                     if (time.matches("\\d\\d:\\d\\d:\\d\\d")) {
                         c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(time.substring(0, 2)));
-                        c.set(Calendar.MINUTE, Integer.valueOf(time.substring(0, 2)));
-                        c.set(Calendar.SECOND, Integer.valueOf(time.substring(0, 2)));
+                        c.set(Calendar.MINUTE, Integer.valueOf(time.substring(3, 5)));
+                        c.set(Calendar.SECOND, Integer.valueOf(time.substring(6, 8)));
                         c.set(Calendar.MILLISECOND, 0);
                     } else {
                         throw ioe;
--- a/jdk/src/java.compact1/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.compact1/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Aggregates {@code java.base}, {@code java.logging}, and {@code java.scripting}.
+ */
 module java.compact1 {
     requires public java.logging;
     requires public java.scripting;
--- a/jdk/src/java.compact2/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.compact2/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Supplements {@code java.compact1} with JDBC, JAXP, and RMI.
+ */
 module java.compact2 {
     requires public java.compact1;
     requires public java.rmi;
--- a/jdk/src/java.compact3/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.compact3/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,10 @@
  * questions.
  */
 
+/**
+ * Supplements {@code java.compact2} with JDBC RowSet, JMX, JNDI, Compiler,
+ * Instrumentation, Preferences, Security, and XML cryptography APIs.
+ */
 module java.compact3 {
     requires public java.compact2;
     requires public java.compiler;
--- a/jdk/src/java.datatransfer/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.datatransfer/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -24,10 +24,8 @@
  */
 
 /**
- * Provides interfaces and classes for transferring data between and
- * within applications.
+ * Defines an API for transferring data between and within applications.
  */
-
 module java.datatransfer {
     exports java.awt.datatransfer;
     exports sun.datatransfer to java.desktop;
--- a/jdk/src/java.desktop/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -24,9 +24,9 @@
  */
 
 /**
-  * java.desktop defines and exports the user interface, graphics
-  * and imaging APIs of the Java SE platform.
-  */
+ * Defines the AWT and Swing user interface toolkits, plus APIs for
+ * accessibility, audio, imaging, printing, and JavaBeans.
+ */
 module java.desktop {
     requires public java.datatransfer;
     requires public java.xml;
--- a/jdk/src/java.httpclient/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the high-level HTTP and WebSocket API.
+ */
 module java.httpclient {
     requires java.base;
     exports java.net.http;
--- a/jdk/src/java.instrument/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.instrument/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,10 @@
  * questions.
  */
 
+/**
+ * Defines services that allow agents to
+ * instrument programs running on the JVM.
+ */
 module java.instrument {
     exports java.lang.instrument;
 }
--- a/jdk/src/java.logging/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.logging/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the Java Logging API.
+ */
 module java.logging {
     exports java.util.logging;
     provides jdk.internal.logger.DefaultLoggerFinder with
--- a/jdk/src/java.management/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.management/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,12 @@
  * questions.
  */
 
+/**
+ * Defines the Java Management Extensions (JMX) API.
+ * <P>
+ * The JMX API consists of interfaces for monitoring and management of the
+ * JVM and other components in the Java runtime.
+ */
 module java.management {
     requires public java.rmi;
     requires java.logging;
--- a/jdk/src/java.naming/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.naming/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the Java Naming and Directory Interface (JNDI) API.
+ */
 module java.naming {
     requires java.security.sasl;
 
--- a/jdk/src/java.prefs/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.prefs/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the Preferences API.
+ */
 module java.prefs {
     requires java.xml;
 
--- a/jdk/src/java.rmi/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.rmi/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the Remote Method Invocation (RMI) API.
+ */
 module java.rmi {
     requires java.logging;
 
--- a/jdk/src/java.scripting/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.scripting/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the Scripting API.
+ */
 module java.scripting {
     exports javax.script;
     uses javax.script.ScriptEngineFactory;
--- a/jdk/src/java.se.ee/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.se.ee/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,12 @@
  * questions.
  */
 
+/**
+ * Defines the full API of the Java SE Platform.
+ * <P>
+ * This module requires {@code java.se} and supplements it with modules
+ * that define CORBA and Java EE APIs. These modules are upgradeable.
+ */
 module java.se.ee {
 
     requires public java.se;
--- a/jdk/src/java.se/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.se/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,13 @@
  * questions.
  */
 
+/**
+ * Defines the core Java SE API.
+ * <P>
+ * The modules defining
+ * CORBA and Java EE APIs are not required by this module, but they are
+ * required by {@code java.se.ee}.
+ */
 module java.se {
     requires public java.compact3;
     requires public java.datatransfer;
--- a/jdk/src/java.security.jgss/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.security.jgss/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,11 @@
  * questions.
  */
 
+/**
+ * Defines the Java binding of the IETF Generic Security Services API (GSS-API).
+ * <P>
+ * This module also contains GSS-API mechanisms including Kerberos v5 and SPNEGO.
+ */
 module java.security.jgss {
     requires java.naming;
     exports javax.security.auth.kerberos;
--- a/jdk/src/java.security.sasl/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.security.sasl/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,13 @@
  * questions.
  */
 
+/**
+ * Defines Java support for the IETF Simple Authentication and Security Layer
+ * (SASL).
+ * <P>
+ * This module also contains SASL mechanisms including DIGEST-MD5,
+ * CRAM-MD5, and NTLM.
+ */
 module java.security.sasl {
     requires java.logging;
 
--- a/jdk/src/java.smartcardio/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.smartcardio/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the Java Smart Card I/O API.
+ */
 module java.smartcardio {
     exports javax.smartcardio;
     provides java.security.Provider with sun.security.smartcardio.SunPCSC;
--- a/jdk/src/java.sql.rowset/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.sql.rowset/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the JDBC RowSet API.
+ */
 module java.sql.rowset {
     requires public java.logging;
     requires public java.naming;
--- a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java	Thu Aug 18 21:34:03 2016 +0000
@@ -64,7 +64,7 @@
  * <P>
  * A driver that is accessed via a {@code DataSource} object does not
  * register itself with the {@code DriverManager}.  Rather, a
- * {@code DataSource} object is retrieved though a lookup operation
+ * {@code DataSource} object is retrieved through a lookup operation
  * and then used to create a {@code Connection} object.  With a basic
  * implementation, the connection obtained through a {@code DataSource}
  * object is identical to a connection obtained through the
--- a/jdk/src/java.sql/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.sql/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines the JDBC API.
+ */
 module java.sql {
     requires public java.logging;
     requires public java.xml;
--- a/jdk/src/java.transaction/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.transaction/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,12 @@
  * questions.
  */
 
+/**
+ * Defines a subset of the Java Transaction API (JTA) to support CORBA interop.
+ * <P>
+ * The subset consists of RMI exception types which are mapped to CORBA system
+ * exceptions by the 'Java Language to IDL Mapping Specification'.
+ */
 module java.transaction {
     requires public java.rmi;
     exports javax.transaction;
--- a/jdk/src/java.xml.crypto/share/classes/module-info.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/java.xml.crypto/share/classes/module-info.java	Thu Aug 18 21:34:03 2016 +0000
@@ -23,6 +23,9 @@
  * questions.
  */
 
+/**
+ * Defines an API for XML cryptography.
+ */
 module java.xml.crypto {
     requires public java.xml;
     requires java.logging;
--- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/Key.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/Key.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
 /**
  * The handle for an RSA or DSA key using the Microsoft Crypto API.
  *
- * @see DSAPrivateKey
  * @see RSAPrivateKey
  * @see RSAPublicKey
  *
@@ -41,9 +40,35 @@
 {
     private static final long serialVersionUID = -1088859394025049194L;
 
-    // Native handle
-    protected long hCryptProv = 0;
-    protected long hCryptKey = 0;
+    static class NativeHandles {
+        long hCryptProv = 0;
+        long hCryptKey = 0;
+
+        public NativeHandles(long hCryptProv, long hCryptKey) {
+            this.hCryptProv = hCryptProv;
+            this.hCryptKey = hCryptKey;
+        }
+
+        /**
+         * Finalization method
+         */
+        protected void finalize() throws Throwable
+        {
+            try {
+                synchronized(this)
+                {
+                    cleanUp(hCryptProv, hCryptKey);
+                    hCryptProv = 0;
+                    hCryptKey = 0;
+                }
+
+            } finally {
+                super.finalize();
+            }
+        }
+    }
+
+    protected NativeHandles handles;
 
     // Key length
     protected int keyLength = 0;
@@ -51,29 +76,10 @@
     /**
      * Construct a Key object.
      */
-    protected Key(long hCryptProv, long hCryptKey, int keyLength)
-    {
-        this.hCryptProv = hCryptProv;
-        this.hCryptKey = hCryptKey;
-        this.keyLength = keyLength;
-    }
-
-    /**
-     * Finalization method
-     */
-    protected void finalize() throws Throwable
+    protected Key(NativeHandles handles, int keyLength)
     {
-        try {
-            synchronized(this)
-            {
-                cleanUp(hCryptProv, hCryptKey);
-                hCryptProv = 0;
-                hCryptKey = 0;
-            }
-
-        } finally {
-            super.finalize();
-        }
+        this.handles = handles;
+        this.keyLength = keyLength;
     }
 
     /**
@@ -96,7 +102,7 @@
      */
     public long getHCryptKey()
     {
-        return hCryptKey;
+        return handles.hCryptKey;
     }
 
     /**
@@ -104,12 +110,12 @@
      */
     public long getHCryptProvider()
     {
-        return hCryptProv;
+        return handles.hCryptProv;
     }
 
     /**
      * Returns the standard algorithm name for this key. For
-     * example, "DSA" would indicate that this key is a DSA key.
+     * example, "RSA" would indicate that this key is a RSA key.
      * See Appendix A in the <a href=
      * "../../../guide/security/CryptoSpec.html#AppA">
      * Java Cryptography Architecture API Specification &amp; Reference </a>
--- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java	Thu Aug 18 21:34:03 2016 +0000
@@ -168,7 +168,7 @@
             }
             certChain = chain;
         }
-    };
+    }
 
     /*
      * An X.509 certificate factory.
@@ -798,7 +798,8 @@
             }
 
             storeWithUniqueAlias(alias, new KeyEntry(alias,
-                    new RSAPrivateKey(hCryptProv, hCryptKey, keyLength),
+                    new RSAPrivateKey(new Key.NativeHandles(hCryptProv,
+                            hCryptKey), keyLength),
                     certChain));
         }
         catch (Throwable e)
@@ -854,7 +855,6 @@
      * Load keys and/or certificates from keystore into Collection.
      *
      * @param name Name of keystore.
-     * @param entries Collection of key/certificate.
      */
     private native void loadKeysOrCertificateChains(String name)
             throws KeyStoreException;
--- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPair.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPair.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,8 +41,9 @@
      */
     RSAKeyPair(long hCryptProv, long hCryptKey, int keyLength)
     {
-        privateKey = new RSAPrivateKey(hCryptProv, hCryptKey, keyLength);
-        publicKey = new RSAPublicKey(hCryptProv, hCryptKey, keyLength);
+        Key.NativeHandles handles = new Key.NativeHandles(hCryptProv, hCryptKey);
+        privateKey = new RSAPrivateKey(handles, keyLength);
+        publicKey = new RSAPublicKey(handles, keyLength);
     }
 
     public RSAPrivateKey getPrivate() {
--- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPrivateKey.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPrivateKey.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,15 @@
      */
     RSAPrivateKey(long hCryptProv, long hCryptKey, int keyLength)
     {
-        super(hCryptProv, hCryptKey, keyLength);
+        super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
+    }
+
+    /**
+     * Construct an RSAPrivateKey object.
+     */
+    RSAPrivateKey(NativeHandles handles, int keyLength)
+    {
+        super(handles, keyLength);
     }
 
     /**
@@ -63,8 +71,8 @@
     public String toString()
     {
         return "RSAPrivateKey [size=" + keyLength + " bits, type=" +
-            getKeyType(hCryptKey) + ", container=" +
-            getContainerName(hCryptProv) + "]";
+            getKeyType(handles.hCryptKey) + ", container=" +
+            getContainerName(handles.hCryptProv) + "]";
     }
 
     // This class is not serializable
--- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPublicKey.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAPublicKey.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,7 +51,15 @@
      */
     RSAPublicKey(long hCryptProv, long hCryptKey, int keyLength)
     {
-        super(hCryptProv, hCryptKey, keyLength);
+        super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
+    }
+
+    /**
+     * Construct an RSAPublicKey object.
+     */
+    RSAPublicKey(NativeHandles handles, int keyLength)
+    {
+        super(handles, keyLength);
     }
 
     /**
@@ -77,8 +85,8 @@
         StringBuffer sb = new StringBuffer();
 
         sb.append("RSAPublicKey [size=").append(keyLength)
-            .append(" bits, type=").append(getKeyType(hCryptKey))
-            .append(", container=").append(getContainerName(hCryptProv))
+            .append(" bits, type=").append(getKeyType(handles.hCryptKey))
+            .append(", container=").append(getContainerName(handles.hCryptProv))
             .append("]\n  modulus: ").append(getModulus())
             .append("\n  public exponent: ").append(getPublicExponent());
 
@@ -93,7 +101,7 @@
         if (exponent == null) {
 
             try {
-                publicKeyBlob = getPublicKeyBlob(hCryptKey);
+                publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
                 exponent = new BigInteger(1, getExponent(publicKeyBlob));
 
             } catch (KeyException e) {
@@ -112,7 +120,7 @@
         if (modulus == null) {
 
             try {
-                publicKeyBlob = getPublicKeyBlob(hCryptKey);
+                publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
                 modulus = new BigInteger(1, getModulus(publicKeyBlob));
 
             } catch (KeyException e) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java	Thu Aug 18 21:34:03 2016 +0000
@@ -55,7 +55,7 @@
 
     private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
 
-    private static final String DMH = "java/lang/invoke/DirectMethodHandle$Holder";
+    private static final String DIRECT_METHOD_HANDLE = "java/lang/invoke/DirectMethodHandle$Holder";
     private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual";
     private static final String DMH_INVOKE_STATIC = "invokeStatic";
     private static final String DMH_INVOKE_SPECIAL = "invokeSpecial";
@@ -63,6 +63,8 @@
     private static final String DMH_INVOKE_INTERFACE = "invokeInterface";
     private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit";
 
+    private static final String DELEGATING_METHOD_HANDLE = "java/lang/invoke/DelegatingMethodHandle$Holder";
+
     private static final JavaLangInvokeAccess JLIA
             = SharedSecrets.getJavaLangInvokeAccess();
 
@@ -222,7 +224,15 @@
     @Override
     public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         // Copy all but DMH_ENTRY to out
-        in.transformAndCopy(entry -> entry.path().equals(DMH_ENTRY) ? null : entry, out);
+        in.transformAndCopy(entry -> {
+                // filter out placeholder entries
+                if (entry.path().equals(DIRECT_METHOD_HANDLE_ENTRY) ||
+                    entry.path().equals(DELEGATING_METHOD_HANDLE_ENTRY)) {
+                    return null;
+                } else {
+                    return entry;
+                }
+            }, out);
         speciesTypes.forEach(types -> generateBMHClass(types, out));
         generateDMHClass(out);
         return out.build();
@@ -264,15 +274,24 @@
             }
         }
         try {
-            byte[] bytes =
-                    JLIA.generateDMHClassBytes(DMH, methodTypes, dmhTypes);
-            ResourcePoolEntry ndata = ResourcePoolEntry.create(DMH_ENTRY, bytes);
+            byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes(
+                    DIRECT_METHOD_HANDLE, methodTypes, dmhTypes);
+            ResourcePoolEntry ndata = ResourcePoolEntry
+                    .create(DIRECT_METHOD_HANDLE_ENTRY, bytes);
+            out.add(ndata);
+
+            bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes(
+                    DELEGATING_METHOD_HANDLE, methodTypes);
+            ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HANDLE_ENTRY, bytes);
             out.add(ndata);
         } catch (Exception ex) {
             throw new PluginException(ex);
         }
     }
-    private static final String DMH_ENTRY = "/java.base/" + DMH + ".class";
+    private static final String DIRECT_METHOD_HANDLE_ENTRY =
+            "/java.base/" + DIRECT_METHOD_HANDLE + ".class";
+    private static final String DELEGATING_METHOD_HANDLE_ENTRY =
+            "/java.base/" + DELEGATING_METHOD_HANDLE + ".class";
 
     // Convert LL -> LL, L3 -> LLL
     private static String expandSignature(String signature) {
@@ -310,15 +329,19 @@
         assert(parts.length == 2);
         assert(parts[1].length() == 1);
         String parameters = expandSignature(parts[0]);
-        Class<?> rtype = primitiveType(parts[1].charAt(0));
-        Class<?>[] ptypes = new Class<?>[parameters.length()];
-        for (int i = 0; i < ptypes.length; i++) {
-            ptypes[i] = primitiveType(parameters.charAt(i));
+        Class<?> rtype = simpleType(parts[1].charAt(0));
+        if (parameters.isEmpty()) {
+            return MethodType.methodType(rtype);
+        } else {
+            Class<?>[] ptypes = new Class<?>[parameters.length()];
+            for (int i = 0; i < ptypes.length; i++) {
+                ptypes[i] = simpleType(parameters.charAt(i));
+            }
+            return MethodType.methodType(rtype, ptypes);
         }
-        return MethodType.methodType(rtype, ptypes);
     }
 
-    private static Class<?> primitiveType(char c) {
+    private static Class<?> simpleType(char c) {
         switch (c) {
             case 'F':
                 return float.class;
--- a/jdk/test/Makefile	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/Makefile	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2015, 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
@@ -185,6 +185,9 @@
 ( \
   jtregExitCode=$$? && \
   _summary="$(SUMMARY_TXT)"; \
+  if [ $${jtregExitCode} = 1 ] ; then \
+    jtregExitCode=0; \
+  fi; \
   $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
   $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
   if [ -r "$${_summary}" ] ; then \
--- a/jdk/test/ProblemList.txt	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/ProblemList.txt	Thu Aug 18 21:34:03 2016 +0000
@@ -211,6 +211,8 @@
 
 java/rmi/transport/dgcDeadLock/DGCDeadLock.java                 8029360 macosx-all
 
+sun/rmi/runtime/Log/6409194/NoConsoleOutput.java                8164124 windows-all
+
 ############################################################################
 
 # jdk_security
--- a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java	Thu Aug 18 21:34:03 2016 +0000
@@ -205,8 +205,12 @@
                     .replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/")
                     .replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
                     .replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
+                    // DMHs may or may not be pre-generated, making frames differ
                     .replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
                     .replaceAll("DMH\\.invoke", "DMH/xxxxxxxx.invoke")
+                    // invoke frames may or may not have basic method type
+                    // information encoded for diagnostic purposes
+                    .replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z]+_[A-Z]", "xx.invoke$1")
                     .replaceAll("\\$[0-9]+", "\\$??");
         } else {
             return produced;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java	Thu Aug 18 21:34:03 2016 +0000
@@ -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.
+ */
+
+/**
+ * @test
+ * @bug 8163896
+ * @summary Finalizing one key of a KeyPair invalidates the other key
+ */
+
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.ProviderException;
+import java.security.Security;
+import java.util.function.Consumer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FinalizeHalf {
+
+    static int failures = 0;
+
+    public static void main(String[] args) throws Throwable {
+        List<Consumer<Key>> methods = new ArrayList<>();
+        methods.add((Key k) -> k.getEncoded());
+        methods.add((Key k) -> k.toString());
+
+        for (String algo : new String[] {"DiffieHellman", "DSA", "RSA"}) {
+            for (Provider provider : Security.getProviders()) {
+                for (boolean priv : new boolean[] {true, false}) {
+                    for (Consumer<Key> method : methods) {
+                        test(algo, provider, priv, method);
+                    }
+                }
+            }
+        }
+
+        if (failures > 0) {
+            throw new RuntimeException(failures + " test(s) failed.");
+        }
+    }
+
+    static void test(String algo, Provider provider, boolean priv,
+            Consumer<Key> method) throws Exception {
+        KeyPairGenerator generator;
+        try {
+            generator = KeyPairGenerator.getInstance(algo, provider);
+        } catch (NoSuchAlgorithmException nsae) {
+            return;
+        }
+
+        System.out.println("Checking " + provider.getName() + ", " + algo);
+
+        KeyPair pair = generator.generateKeyPair();
+        Key key = priv ? pair.getPrivate() : pair.getPublic();
+
+        pair = null;
+        for (int i = 0; i < 32; ++i) {
+            System.gc();
+        }
+
+        try {
+            method.accept(key);
+        } catch (ProviderException pe) {
+            failures++;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Security/ClassLoader/DeprivilegedModuleLoaderTest.java	Thu Aug 18 21:34:03 2016 +0000
@@ -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.File;
+import java.util.ArrayList;
+import java.util.List;
+import javax.security.auth.kerberos.KeyTab;
+import javax.xml.crypto.KeySelectorException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import com.sun.security.auth.callback.TextCallbackHandler;
+import com.sun.security.jgss.AuthorizationDataEntry;
+
+/*
+ * @test
+ * @bug 8159964
+ * @summary Classes from deprivileged modules should get loaded through
+ *          Platform Classloader.
+ * @run main DeprivilegedModuleLoaderTest
+ */
+public class DeprivilegedModuleLoaderTest {
+
+    public static void main(String[] args) {
+
+        boolean pass = true;
+        List<Class<?>> classes = getDeprivilegedClasses();
+        for (Class<?> cls : classes) {
+            try {
+                pass &= testPlatformClassLoader(cls);
+            } catch (Exception exc) {
+                exc.printStackTrace(System.out);
+                pass = false;
+            }
+        }
+
+        if (!pass) {
+            throw new RuntimeException("Atleast one test failed.");
+        }
+    }
+
+    private static List<Class<?>> getDeprivilegedClasses() {
+
+        List<Class<?>> classes = new ArrayList<Class<?>>();
+        // Test from java.xml.crypto/javax/xml/crypto/dsig package
+        classes.add(XMLSignatureFactory.class);
+        // Test from java.xml.crypto/javax/xml/crypto package
+        classes.add(KeySelectorException.class);
+        // Test From java.security.jgss/javax/security/auth/kerberos package
+        classes.add(KeyTab.class);
+        // Test from jdk.security.jgss/com/sun/security/jgss package
+        classes.add(AuthorizationDataEntry.class);
+        // Test from jdk.security.auth/com/sun/security/auth/callback package
+        classes.add(TextCallbackHandler.class);
+        return classes;
+    }
+
+    private static boolean testPlatformClassLoader(Class<?> cls) {
+
+        ClassLoader loader = cls.getClassLoader();
+        if (loader == null) {
+            throw new RuntimeException(String.format(
+                    "Loaded through Bootstrap Classloader: '%s'", cls));
+        } else if (!loader.toString().contains("PlatformClassLoader")) {
+            throw new RuntimeException(String.format(
+                    "Not loaded through Platform ClassLoader: '%s'", cls));
+        }
+        System.out.println(String.format(
+                "Pass: '%s' get loaded through PlatformClassLoader", cls));
+        return true;
+    }
+}
--- a/jdk/test/java/security/testlibrary/SimpleOCSPServer.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/java/security/testlibrary/SimpleOCSPServer.java	Thu Aug 18 21:34:03 2016 +0000
@@ -64,6 +64,8 @@
     private static final SimpleDateFormat utcDateFmt =
             new SimpleDateFormat("MMM dd yyyy, HH:mm:ss z");
 
+    static final int FREE_PORT = 0;
+
     // CertStatus values
     public static enum CertStatus {
         CERT_STATUS_GOOD,
@@ -88,7 +90,8 @@
     private volatile boolean started = false;
     private volatile boolean serverReady = false;
     private volatile boolean receivedShutdown = false;
-    private long delayMsec = 0;
+    private volatile boolean acceptConnections = true;
+    private volatile long delayMsec = 0;
 
     // Fields used in the generation of responses
     private long nextUpdateInterval = -1;
@@ -116,7 +119,7 @@
      */
     public SimpleOCSPServer(KeyStore ks, String password, String issuerAlias,
             String signerAlias) throws GeneralSecurityException, IOException {
-        this(null, 0, ks, password, issuerAlias, signerAlias);
+        this(null, FREE_PORT, ks, password, issuerAlias, signerAlias);
     }
 
     /**
@@ -230,6 +233,15 @@
                     while (!receivedShutdown) {
                         try {
                             Socket newConnection = servSocket.accept();
+                            if (!acceptConnections) {
+                                try {
+                                    log("Reject connection");
+                                    newConnection.close();
+                                } catch (IOException e) {
+                                    // ignore
+                                }
+                                continue;
+                            }
                             threadPool.submit(new OcspHandler(newConnection));
                         } catch (SocketTimeoutException timeout) {
                             // Nothing to do here.  If receivedShutdown
@@ -257,6 +269,23 @@
     }
 
     /**
+     * Make the OCSP server reject incoming connections.
+     */
+    public synchronized void rejectConnections() {
+        log("Reject OCSP connections");
+        acceptConnections = false;
+    }
+
+    /**
+     * Make the OCSP server accept incoming connections.
+     */
+    public synchronized void acceptConnections() {
+        log("Accept OCSP connections");
+        acceptConnections = true;
+    }
+
+
+    /**
      * Stop the OCSP server.
      */
     public synchronized void stop() {
@@ -499,13 +528,11 @@
      * on the incoming request.
      */
     public void setDelay(long delayMillis) {
-        if (!started) {
-            delayMsec = delayMillis > 0 ? delayMillis : 0;
-            if (delayMsec > 0) {
-                log("OCSP latency set to " + delayMsec + " milliseconds.");
-            } else {
-                log("OCSP latency disabled");
-            }
+        delayMsec = delayMillis > 0 ? delayMillis : 0;
+        if (delayMsec > 0) {
+            log("OCSP latency set to " + delayMsec + " milliseconds.");
+        } else {
+            log("OCSP latency disabled");
         }
     }
 
--- a/jdk/test/javax/net/ssl/Stapling/SSLSocketWithStapling.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/javax/net/ssl/Stapling/SSLSocketWithStapling.java	Thu Aug 18 21:34:03 2016 +0000
@@ -119,20 +119,22 @@
             System.setProperty("javax.net.debug", "ssl");
         }
 
-        // Create the PKI we will use for the test and start the OCSP servers
-        createPKI();
+        try {
+            // Create the PKI we will use for the test and start the OCSP servers
+            createPKI();
 
-        testAllDefault();
-        testPKIXParametersRevEnabled();
-        testRevokedCertificate();
-        testHardFailFallback();
-        testSoftFailFallback();
-        testLatencyNoStaple(false);
-        testLatencyNoStaple(true);
-
-        // shut down the OCSP responders before finishing the test
-        intOcsp.stop();
-        rootOcsp.stop();
+            testAllDefault();
+            testPKIXParametersRevEnabled();
+            testRevokedCertificate();
+            testHardFailFallback();
+            testSoftFailFallback();
+            testLatencyNoStaple(false);
+            testLatencyNoStaple(true);
+        } finally {
+            // shut down the OCSP responders before finishing the test
+            intOcsp.stop();
+            rootOcsp.stop();
+        }
     }
 
     /**
@@ -281,11 +283,9 @@
         ServerParameters servParams = new ServerParameters();
         serverReady = false;
 
-        // Stop the OCSP responders and give a 1 second delay before
-        // running the test.
-        intOcsp.stop();
-        rootOcsp.stop();
-        Thread.sleep(1000);
+        // make OCSP responders reject connections
+        intOcsp.rejectConnections();
+        rootOcsp.rejectConnections();
 
         System.out.println("=======================================");
         System.out.println("Stapling enbled in client and server,");
@@ -315,9 +315,9 @@
         System.out.println("                 PASS");
         System.out.println("=======================================\n");
 
-        // Start the OCSP responders up again
-        intOcsp.start();
-        rootOcsp.start();
+        // Make OCSP responders accept connections
+        intOcsp.acceptConnections();
+        rootOcsp.acceptConnections();
 
         // Wait 5 seconds for server ready
         for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) {
@@ -338,11 +338,9 @@
         ServerParameters servParams = new ServerParameters();
         serverReady = false;
 
-        // Stop the OCSP responders and give a 1 second delay before
-        // running the test.
-        intOcsp.stop();
-        rootOcsp.stop();
-        Thread.sleep(1000);
+        // make OCSP responders reject connections
+        intOcsp.rejectConnections();
+        rootOcsp.rejectConnections();
 
         System.out.println("=======================================");
         System.out.println("Stapling enbled in client and server,");
@@ -372,9 +370,9 @@
         System.out.println("                 PASS");
         System.out.println("=======================================\n");
 
-        // Start the OCSP responders up again
-        intOcsp.start();
-        rootOcsp.start();
+        // Make OCSP responders accept connections
+        intOcsp.acceptConnections();
+        rootOcsp.acceptConnections();
 
         // Wait 5 seconds for server ready
         for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) {
@@ -401,15 +399,10 @@
         ServerParameters servParams = new ServerParameters();
         serverReady = false;
 
-        // Stop the OCSP responders and give a 1 second delay before
-        // running the test.
-        intOcsp.stop();
-        rootOcsp.stop();
-        Thread.sleep(1000);
+        // Give a 1 second delay before running the test.
         intOcsp.setDelay(3000);
         rootOcsp.setDelay(3000);
-        rootOcsp.start();
-        intOcsp.start();
+        Thread.sleep(1000);
 
         // Wait 5 seconds for server ready
         for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) {
@@ -458,13 +451,9 @@
         System.out.println("========================================\n");
 
         // Remove the OCSP responder latency
-        intOcsp.stop();
-        rootOcsp.stop();
-        Thread.sleep(1000);
         intOcsp.setDelay(0);
         rootOcsp.setDelay(0);
-        rootOcsp.start();
-        intOcsp.start();
+        Thread.sleep(1000);
 
         // Wait 5 seconds for server ready
         for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) {
@@ -676,6 +665,7 @@
                          * Release the client, if not active already...
                          */
                         System.err.println("Server died...");
+                        e.printStackTrace(System.err);
                         serverReady = true;
                         serverException = e;
                     }
--- a/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/javax/xml/crypto/dsig/TransformService/NullParent.java	Thu Aug 18 21:34:03 2016 +0000
@@ -26,6 +26,7 @@
  * @bug 8022120
  * @summary check that the init and marshalParams methods throw
  *          NullPointerException when the parent parameter is null
+ * @run main/othervm/java.security.policy==test.policy NullParent
  */
 
 import javax.xml.crypto.dsig.CanonicalizationMethod;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/crypto/dsig/TransformService/test.policy	Thu Aug 18 21:34:03 2016 +0000
@@ -0,0 +1,3 @@
+grant {
+
+};
--- a/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/Marshal.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/Marshal.java	Thu Aug 18 21:34:03 2016 +0000
@@ -27,7 +27,7 @@
  * @summary Test that KeyInfo.marshal works correctly
  * @modules java.xml.crypto/org.jcp.xml.dsig.internal.dom
  * @compile -XDignore.symbol.file Marshal.java
- * @run main Marshal
+ * @run main/othervm/java.security.policy==test.policy Marshal
  * @author Sean Mullan
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/crypto/dsig/keyinfo/KeyInfo/test.policy	Thu Aug 18 21:34:03 2016 +0000
@@ -0,0 +1,3 @@
+grant {
+    permission java.lang.RuntimePermission "accessClassInPackage.org.jcp.xml.dsig.internal.dom";
+};
--- a/jdk/test/sun/misc/URLClassPath/ClassnameCharTest.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/sun/misc/URLClassPath/ClassnameCharTest.java	Thu Aug 18 21:34:03 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -103,16 +103,60 @@
 
     //--------------------- Infrastructure ---------------------------
     static volatile int passed = 0, failed = 0;
-    static boolean pass() {passed++; return true;}
-    static boolean fail() {failed++; server.stop(0); Thread.dumpStack(); return false;}
-    static boolean fail(String msg) {System.out.println(msg); return fail();}
-    static void unexpected(Throwable t) {failed++; server.stop(0); t.printStackTrace();}
-    static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
+
+    static boolean pass() {
+        passed++;
+        return true;
+    }
+
+    static boolean fail() {
+        failed++;
+        if (server != null) {
+            server.stop(0);
+        }
+        Thread.dumpStack();
+        return false;
+    }
+
+    static boolean fail(String msg) {
+        System.out.println(msg);
+        return fail();
+    }
+
+    static void unexpected(Throwable t) {
+        failed++;
+        if (server != null) {
+            server.stop(0);
+        }
+        t.printStackTrace();
+    }
+
+    static boolean check(boolean cond) {
+        if (cond) {
+            pass();
+        } else {
+            fail();
+        }
+        return cond;
+    }
+
     static boolean equal(Object x, Object y) {
-        if (x == null ? y == null : x.equals(y)) return pass();
-        else return fail(x + " not equal to " + y);}
+        if (x == null ? y == null : x.equals(y)) {
+            return pass();
+        } else {
+            return fail(x + " not equal to " + y);
+        }
+    }
+
     public static void main(String[] args) throws Throwable {
-        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        try {
+            realMain(args);
+        } catch (Throwable t) {
+            unexpected(t);
+        }
         System.out.println("\nPassed = " + passed + " failed = " + failed);
-        if (failed > 0) throw new AssertionError("Some tests failed");}
+        if (failed > 0) {
+            throw new AssertionError("Some tests failed");
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/CommMatcher.java	Thu Aug 18 21:34:03 2016 +0000
@@ -0,0 +1,86 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Matches the krb5 debug output:
+ * >>> KDCCommunication: kdc=host UDP:11555, timeout=100,Attempt =1, #bytes=138
+ *
+ * Example:
+ *   CommMatcher cm = new CommMatcher();
+ *   cm.addPort(12345).addPort(23456);
+ *   for (String line : debugOutput) {
+ *       if (cm.match(line)) {
+ *           println("KDC: %c, %s, Timeout: %d\n",
+ *              cm.kdc(), cm.protocol(), cm.timeout());
+ *       }
+ *   }
+ */
+public class CommMatcher {
+
+    static final Pattern re = Pattern.compile(
+            ">>> KDCCommunication: kdc=\\S+ (TCP|UDP):(\\d+), " +
+                    "timeout=(\\d+),Attempt\\s*=(\\d+)");
+
+    List<Integer> kdcPorts = new ArrayList<>();
+    Matcher matcher;
+
+    /**
+     * Add KDC ports one by one. The 1st KDC will be 'a' in {@link #kdc()},
+     * 2nd is 'b', etc, etc.
+     */
+    public CommMatcher addPort(int port) {
+        if (port > 0) {
+            kdcPorts.add(port);
+        } else {
+            kdcPorts.clear();
+        }
+        return this;
+    }
+
+    public boolean match(String line) {
+        matcher = re.matcher(line);
+        return matcher.find();
+    }
+
+    public String protocol() {
+        return matcher.group(1);
+    }
+
+    public char kdc() {
+        int port = Integer.parseInt(matcher.group(2));
+        return (char)(kdcPorts.indexOf(port) + 'a');
+    }
+
+    public int timeout() {
+        return BadKdc.toSymbolicSec(Integer.parseInt(matcher.group(3)));
+    }
+
+    public int attempt() {
+        return Integer.parseInt(matcher.group(4));
+    }
+}
--- a/jdk/test/sun/security/krb5/auto/MaxRetries.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/sun/security/krb5/auto/MaxRetries.java	Thu Aug 18 21:34:03 2016 +0000
@@ -30,6 +30,7 @@
  * @summary support max_retries in krb5.conf
  */
 
+import javax.security.auth.login.LoginException;
 import java.io.*;
 import java.net.DatagramSocket;
 import java.security.Security;
@@ -37,46 +38,86 @@
 public class MaxRetries {
 
     static int idlePort = -1;
+    static CommMatcher cm = new CommMatcher();
 
     public static void main(String[] args)
             throws Exception {
 
         System.setProperty("sun.security.krb5.debug", "true");
-        new OneKDC(null).writeJAASConf();
+        OneKDC kdc = new OneKDC(null).writeJAASConf();
 
         // An idle UDP socket to prevent PortUnreachableException
         DatagramSocket ds = new DatagramSocket();
         idlePort = ds.getLocalPort();
 
+        cm.addPort(idlePort);
+        cm.addPort(kdc.getPort());
+
         System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
 
-        // For tryLast
         Security.setProperty("krb5.kdc.bad.policy", "trylast");
+
+        // We always make the real timeout to be 1 second
+        BadKdc.setRatio(0.25f);
         rewriteMaxRetries(4);
-        test1(4000, 6);         // 1 1 1 1 2 2
-        test1(4000, 2);         // 2 2
 
+        // Explanation: In this case, max_retries=4 and timeout=4s.
+        // For AS-REQ without preauth, we will see 4 4s timeout on kdc#1
+        // ("a4" repeat 4 times), and one 4s timeout on kdc#2 ("b4"). For
+        // AS-REQ with preauth, one 4s timeout on kdc#2 (second "b4").
+        // we tolerate 4 real timeout on kdc#2, so make it "(b4){2,6}".
+        test1("a4a4a4a4b4b4", "a4a4a4a4(b4){2,6}");
+        test1("b4b4", "(b4){2,6}");
+
+        BadKdc.setRatio(1f);
         rewriteMaxRetries(1);
-        test1(1000, 3);         // 1 2 2
-        test1(1000, 2);         // 2 2
+        // Explanation: Since max_retries=1 only, we could fail in 1st or 2nd
+        // AS-REQ to kdc#2.
+        String actual = test1("a1b1b1", "(a1b1b1|a1b1x|a1b1b1x)");
+        if (actual.endsWith("x")) {
+            // If 1st attempt fails, all bads are back available
+            test1("a1b1b1", "(a1b1b1|a1b1x|a1b1b1x)");
+        } else {
+            test1("b1b1", "(b1b1|b1x|b1b1x)");
+        }
 
+        BadKdc.setRatio(0.2f);
         rewriteMaxRetries(-1);
-        test1(5000, 4);         // 1 1 2 2
-        test1(5000, 2);         // 2 2
+        test1("a5a5a5b5b5", "a5a5a5(b5){2,4}");
+        test1("b5b5", "(b5){2,4}");
 
-        // For tryLess
-        Security.setProperty("krb5.kdc.bad.policy", "tryless:1," + BadKdc.toReal(5000));
+        BadKdc.setRatio(0.25f);
+        Security.setProperty("krb5.kdc.bad.policy",
+                "tryless:1,1000");
         rewriteMaxRetries(4);
-        test1(4000, 7);         // 1 1 1 1 2 1 2
-        test1(4000, 4);         // 1 2 1 2
+        test1("a4a4a4a4b4a4b4", "a4a4a4a4(b4){1,3}a4(b4){1,3}");
+        test1("a4b4a4b4", "a4(b4){1,3}a4(b4){1,3}");
 
+        BadKdc.setRatio(1f);
         rewriteMaxRetries(1);
-        test1(1000, 4);         // 1 2 1 2
-        test1(1000, 4);         // 1 2 1 2
+        actual = test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)");
+        if (actual.endsWith("x")) {
+            test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)");
+        } else {
+            test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)");
+        }
+
+        BadKdc.setRatio(.2f);
+        rewriteMaxRetries(-1);
+        test1("a5a5a5b5a5b5", "a5a5a5(b5){1,2}a5(b5){1,2}");
+        test1("a5b5a5b5", "a5(b5){1,2}a5(b5){1,2}");
 
-        rewriteMaxRetries(-1);
-        test1(5000, 5);         // 1 1 2 1 2
-        test1(5000, 4);         // 1 2 1 2
+        BadKdc.setRatio(1f);
+        rewriteMaxRetries(2);
+        if (BadKdc.toReal(2000) > 1000) {
+            // Explanation: if timeout is longer than 1s in tryLess,
+            // we will see "a1" at 2nd kdc#1 access
+            test1("a2a2b2a1b2", "a2a2(b2){1,2}a1(b2){1,2}");
+        } else {
+            test1("a2a2b2a2b2", "a2a2(b2){1,2}a2(b2){1,2}");
+        }
+
+        BadKdc.setRatio(1f);
 
         rewriteUdpPrefLimit(-1, -1);    // default, no limit
         test2("UDP");
@@ -95,32 +136,52 @@
 
     /**
      * One round of test for max_retries and timeout.
-     * @param timeout the expected timeout
-     * @param count the expected total try
+     *
+     * @param exact the expected exact match, where no timeout
+     *              happens for real KDCs
+     * @param relaxed the expected relaxed match, where some timeout
+     *                could happen for real KDCs
+     * @return the actual result
      */
-    private static void test1(int timeout, int count) throws Exception {
-        String timeoutTag = "timeout=" + BadKdc.toReal(timeout);
+    private static String test1(String exact, String relaxed) throws Exception {
         ByteArrayOutputStream bo = new ByteArrayOutputStream();
         PrintStream oldout = System.out;
         System.setOut(new PrintStream(bo));
-        Context c = Context.fromJAAS("client");
+        boolean failed = false;
+        long start = System.nanoTime();
+        try {
+            Context c = Context.fromJAAS("client");
+        } catch (LoginException e) {
+            failed = true;
+        }
         System.setOut(oldout);
 
         String[] lines = new String(bo.toByteArray()).split("\n");
-        System.out.println("----------------- TEST (" + timeout + "," +
-                count + ") -----------------");
+        System.out.println("----------------- TEST (" + exact
+                + ") -----------------");
+
+        // Result, a series of timeout + kdc#
+        StringBuilder sb = new StringBuilder();
         for (String line: lines) {
-            if (line.startsWith(">>> KDCCommunication")) {
+            if (cm.match(line)) {
                 System.out.println(line);
-                if (line.indexOf(timeoutTag) < 0) {
-                    throw new Exception("Wrong timeout value" + timeoutTag);
-                }
-                count--;
+                sb.append(cm.kdc()).append(cm.timeout());
             }
         }
-        if (count != 0) {
-            throw new Exception("Retry count is " + count + " less");
+        if (failed) {
+            sb.append("x");
         }
+        System.out.println("Time: " + (System.nanoTime() - start) / 1000000000d);
+        String actual = sb.toString();
+        System.out.println("Actual: " + actual);
+        if (actual.equals(exact)) {
+            System.out.println("Exact match: " + exact);
+        } else if (actual.matches(relaxed)) {
+            System.out.println("!!!! Tolerant match: " + relaxed);
+        } else {
+            throw new Exception("Match neither " + exact + " nor " + relaxed);
+        }
+        return actual;
     }
 
     /**
@@ -138,11 +199,11 @@
         String[] lines = new String(bo.toByteArray()).split("\n");
         System.out.println("----------------- TEST -----------------");
         for (String line: lines) {
-            if (line.startsWith(">>> KDCCommunication")) {
+            if (cm.match(line)) {
                 System.out.println(line);
                 count--;
-                if (line.indexOf(proto) < 0) {
-                    throw new Exception("Wrong timeout value");
+                if (!cm.protocol().equals(proto)) {
+                    throw new Exception("Wrong protocol value");
                 }
             }
         }
@@ -165,6 +226,7 @@
             }
             if (s.startsWith("[realms]")) {
                 // Reconfig global setting
+                fw.write("kdc_timeout = 5000\n");
                 if (global != -1) {
                     fw.write("udp_preference_limit = " + global + "\n");
                 }
@@ -183,7 +245,8 @@
 
     /**
      * Set max_retries and timeout value for realm. The global value is always
-     * 2 and 5000.
+     * 3 and 5000.
+     *
      * @param value max_retries and timeout/1000 for a realm, -1 means none.
      */
     private static void rewriteMaxRetries(int value) throws Exception {
@@ -196,7 +259,7 @@
             }
             if (s.startsWith("[realms]")) {
                 // Reconfig global setting
-                fw.write("max_retries = 2\n");
+                fw.write("max_retries = 3\n");
                 fw.write("kdc_timeout = " + BadKdc.toReal(5000) + "\n");
             } else if (s.trim().startsWith("kdc = ")) {
                 if (value != -1) {
--- a/jdk/test/sun/security/tools/keytool/StartDateTest.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/sun/security/tools/keytool/StartDateTest.java	Thu Aug 18 21:34:03 2016 +0000
@@ -49,23 +49,31 @@
 
         new File("jks").delete();
 
-        run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " +
-                "-keyalg rsa -genkeypair -dname CN=Haha -startdate +1y");
-        cal.setTime(getIssueDate());
+        run("one", "+1y");
+        cal.setTime(getIssueDate("one"));
         System.out.println(cal);
         if (cal.get(Calendar.YEAR) != year + 1) {
             throw new Exception("Function check #1 fails");
         }
 
-        run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " +
-                "-selfcert -startdate +1m");
-        cal.setTime(getIssueDate());
+        run("two", "+1m");
+        cal.setTime(getIssueDate("two"));
         System.out.println(cal);
         if (cal.get(Calendar.MONTH) != (month + 1) % 12) {
             throw new Exception("Function check #2 fails");
         }
 
-        new File("jks").delete();
+        run("three", "2009/10/11 12:34:56");
+        cal.setTime(getIssueDate("three"));
+        System.out.println(cal);
+        if (cal.get(Calendar.YEAR) != 2009 ||
+                cal.get(Calendar.MONTH) != Calendar.OCTOBER ||
+                cal.get(Calendar.DAY_OF_MONTH) != 11 ||
+                cal.get(Calendar.HOUR_OF_DAY) != 12 ||
+                cal.get(Calendar.MINUTE) != 34 ||
+                cal.get(Calendar.SECOND) != 56) {
+            throw new Exception("Function check #3 fails");
+        }
 
         // Part 2: Test format
         Method m = sun.security.tools.keytool.Main.class.getDeclaredMethod(
@@ -129,16 +137,23 @@
         }
     }
 
-    static void run(String s) throws Exception {
-        sun.security.tools.keytool.Main.main((s+" -debug").split(" "));
+    // The keytool command line template, alias and startdate TBD
+    static String[] cmd = ("-alias tbd -startdate tbd -keystore jks " +
+            "-storetype jks -storepass changeit -keypass changeit " +
+            "-keyalg rsa -genkeypair -dname CN=Haha -debug").split(" ");
+
+    static void run(String alias, String startDate) throws Exception {
+        cmd[1] = alias;
+        cmd[3] = startDate;
+        sun.security.tools.keytool.Main.main(cmd);
     }
 
-    static Date getIssueDate() throws Exception {
+    static Date getIssueDate(String alias) throws Exception {
         KeyStore ks = KeyStore.getInstance("jks");
         try (FileInputStream fis = new FileInputStream("jks")) {
             ks.load(fis, "changeit".toCharArray());
         }
-        X509Certificate cert = (X509Certificate)ks.getCertificate("me");
+        X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
         return cert.getNotBefore();
     }
 }
--- a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java	Thu Aug 18 21:01:22 2016 +0000
+++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java	Thu Aug 18 21:34:03 2016 +0000
@@ -40,6 +40,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Arrays;
+import java.util.Optional;
 import jdk.testlibrary.JDKToolLauncher;
 import jdk.testlibrary.Utils;
 import jdk.testlibrary.OutputAnalyzer;
@@ -111,7 +112,8 @@
      * @param vmArgs  - vm and java arguments to launch test app
      * @return exit code of tool
      */
-    public static void launch(String expectedMessage, List<String> toolArgs)
+    public static void launch(String expectedMessage,
+                 Optional<String> unexpectedMessage, List<String> toolArgs)
         throws IOException {
 
         System.out.println("Starting LingeredApp");
@@ -131,6 +133,7 @@
             processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
             OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);;
             output.shouldContain(expectedMessage);
+            unexpectedMessage.ifPresent(output::shouldNotContain);
             output.shouldHaveExitValue(0);
 
         } catch (Exception ex) {
@@ -140,13 +143,16 @@
         }
     }
 
-    public static void launch(String expectedMessage, String... toolArgs)
+    public static void launch(String expectedMessage,
+                              String unexpectedMessage, String... toolArgs)
         throws IOException {
 
-        launch(expectedMessage, Arrays.asList(toolArgs));
+        launch(expectedMessage, Optional.ofNullable(unexpectedMessage),
+                                                       Arrays.asList(toolArgs));
     }
 
-    public static void launchNotOSX(String expectedMessage, String... toolArgs)
+    public static void launchNotOSX(String expectedMessage,
+                              String unexpectedMessage, String... toolArgs)
         throws IOException {
 
         if (Platform.isOSX()) {
@@ -154,6 +160,8 @@
             System.out.println("This test is not expected to work on OS X. Skipping");
             return;
         }
+
+        launch(expectedMessage, unexpectedMessage, toolArgs);
     }
 
     public static void testHeapDump() throws IOException {
@@ -164,7 +172,7 @@
         }
         dump.deleteOnExit();
 
-        launch("heap written to", "jmap",
+        launch("heap written to", null, "jmap",
                "--binaryheap", "--dumpfile=" + dump.getAbsolutePath());
 
         assertTrue(dump.exists() && dump.isFile(),
@@ -182,11 +190,12 @@
 
         launchCLHSDB();
 
-        launch("compiler detected", "jmap", "--clstats");
-        launchNotOSX("No deadlocks found", "jstack");
-        launch("compiler detected", "jmap");
-        launch("Java System Properties", "jinfo");
-        launch("java.threads", "jsnap");
+        launch("compiler detected", null, "jmap", "--clstats");
+        launchNotOSX("No deadlocks found", null, "jstack");
+        launch("compiler detected", null, "jmap");
+        launch("Java System Properties",
+               "System Properties info not available", "jinfo");
+        launch("java.threads", null, "jsnap");
 
         testHeapDump();