changeset 40443:4890e8b048bd

Merge
author ddehaven
date Mon, 15 Aug 2016 08:15:02 -0700
parents e97e9982be6d 2217f830ca7b
children bc9bb5f27a07
files jdk/test/sun/security/mscapi/AccessKeyStore.sh
diffstat 27 files changed, 767 insertions(+), 416 deletions(-) [+]
line wrap: on
line diff
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java	Mon Aug 15 08:15:02 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -53,10 +53,37 @@
     private final int blockLen;
 
     /**
-     * Standard constructor, creates a new HmacCore instance using the
-     * specified MessageDigest object.
+     * Standard constructor, creates a new HmacCore instance instantiating
+     * a MessageDigest of the specified name.
      */
-    HmacCore(MessageDigest md, int bl) {
+    HmacCore(String digestAlgo, int bl) throws NoSuchAlgorithmException {
+        MessageDigest md = MessageDigest.getInstance(digestAlgo);
+        if (!(md instanceof Cloneable)) {
+            // use SUN provider if the most preferred one does not support
+            // cloning
+            Provider sun = Security.getProvider("SUN");
+            if (sun != null) {
+                md = MessageDigest.getInstance(digestAlgo, sun);
+            } else {
+                String noCloneProv = md.getProvider().getName();
+                // if no Sun provider, use provider list
+                Provider[] provs = Security.getProviders();
+                for (Provider p : provs) {
+                    try {
+                        if (!p.getName().equals(noCloneProv)) {
+                            MessageDigest md2 =
+                                MessageDigest.getInstance(digestAlgo, p);
+                            if (md2 instanceof Cloneable) {
+                                md = md2;
+                                break;
+                            }
+                        }
+                    } catch (NoSuchAlgorithmException nsae) {
+                        continue;
+                    }
+                }
+            }
+        }
         this.md = md;
         this.blockLen = bl;
         this.k_ipad = new byte[blockLen];
@@ -65,14 +92,6 @@
     }
 
     /**
-     * Standard constructor, creates a new HmacCore instance instantiating
-     * a MessageDigest of the specified name.
-     */
-    HmacCore(String digestAlgorithm, int bl) throws NoSuchAlgorithmException {
-        this(MessageDigest.getInstance(digestAlgorithm), bl);
-    }
-
-    /**
      * Returns the length of the HMAC in bytes.
      *
      * @return the HMAC length in bytes.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Mon Aug 15 08:15:02 2016 -0700
@@ -846,7 +846,7 @@
         }
     }
 
-    private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
+    static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
 
     /**
      * All subclasses must provide such a value describing their type signature.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Mon Aug 15 08:15:02 2016 -0700
@@ -259,7 +259,7 @@
     }
 
     private static void maybeCompile(LambdaForm lform, MemberName m) {
-        if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
+        if (lform.vmentry == null && VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
             // Help along bootstrapping...
             lform.compileToBytecode();
     }
@@ -562,25 +562,36 @@
         return lform;
     }
 
+    private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
+
     private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
         boolean isGetter  = (formOp & 1) == (AF_GETFIELD & 1);
         boolean isStatic  = (formOp >= AF_GETSTATIC);
         boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
         boolean needsCast = (ftypeKind == FT_CHECKED_REF);
-        Wrapper fw = (needsCast ? Wrapper.OBJECT : Wrapper.values()[ftypeKind]);
+        Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
         Class<?> ft = fw.primitiveType();
         assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
-        String tname  = fw.primitiveSimpleName();
-        String ctname = Character.toUpperCase(tname.charAt(0)) + tname.substring(1);
-        if (isVolatile)  ctname += "Volatile";
-        String getOrPut = (isGetter ? "get" : "put");
-        String linkerName = (getOrPut + ctname);  // getObject, putIntVolatile, etc.
+
+        // getObject, putIntVolatile, etc.
+        StringBuilder nameBuilder = new StringBuilder();
+        if (isGetter) {
+            nameBuilder.append("get");
+        } else {
+            nameBuilder.append("put");
+        }
+        nameBuilder.append(fw.primitiveSimpleName());
+        nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3)));
+        if (isVolatile) {
+            nameBuilder.append("Volatile");
+        }
+
         MethodType linkerType;
         if (isGetter)
             linkerType = MethodType.methodType(ft, Object.class, long.class);
         else
             linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
-        MemberName linker = new MemberName(Unsafe.class, linkerName, linkerType, REF_invokeVirtual);
+        MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual);
         try {
             linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
         } catch (ReflectiveOperationException ex) {
@@ -635,11 +646,16 @@
         if (needsCast && isGetter)
             names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
         for (Name n : names)  assert(n != null);
-        String fieldOrStatic = (isStatic ? "Static" : "Field");
-        String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
-        if (needsCast)  lambdaName += "Cast";
-        if (needsInit)  lambdaName += "Init";
-        return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
+        // add some detail to the lambdaForm debugname,
+        // significant only for debugging
+        if (isStatic) {
+            nameBuilder.append("Static");
+        } else {
+            nameBuilder.append("Field");
+        }
+        if (needsCast)  nameBuilder.append("Cast");
+        if (needsInit)  nameBuilder.append("Init");
+        return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Mon Aug 15 08:15:02 2016 -0700
@@ -40,8 +40,8 @@
 import java.io.IOException;
 import java.lang.reflect.Modifier;
 import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Map;
 import java.util.stream.Stream;
 
 import static java.lang.invoke.LambdaForm.*;
@@ -68,6 +68,7 @@
     private static final String LFN_SIG = "L" + LFN + ";";
     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
     private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
+    private static final String CLASS_PREFIX = LF + "$";
 
     /** Name of its super class*/
     static final String INVOKER_SUPER_NAME = OBJ;
@@ -96,15 +97,15 @@
     /** Main constructor; other constructors delegate to this one. */
     private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
                                      String className, String invokerName, MethodType invokerType) {
-        if (invokerName.contains(".")) {
-            int p = invokerName.indexOf('.');
+        int p = invokerName.indexOf('.');
+        if (p > -1) {
             className = invokerName.substring(0, p);
-            invokerName = invokerName.substring(p+1);
+            invokerName = invokerName.substring(p + 1);
         }
         if (DUMP_CLASS_FILES) {
             className = makeDumpableClassName(className);
         }
-        this.className  = LF + "$" + className;
+        this.className  = CLASS_PREFIX + className;
         this.sourceFile = "LambdaForm$" + className;
         this.lambdaForm = lambdaForm;
         this.invokerName = invokerName;
@@ -201,38 +202,34 @@
 
     class CpPatch {
         final int index;
-        final String placeholder;
         final Object value;
-        CpPatch(int index, String placeholder, Object value) {
+        CpPatch(int index, Object value) {
             this.index = index;
-            this.placeholder = placeholder;
             this.value = value;
         }
         public String toString() {
-            return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value;
+            return "CpPatch/index="+index+",value="+value;
         }
     }
 
-    Map<Object, CpPatch> cpPatches = new HashMap<>();
+    private final ArrayList<CpPatch> cpPatches = new ArrayList<>();
 
-    int cph = 0;  // for counting constant placeholders
+    private int cph = 0;  // for counting constant placeholders
 
     String constantPlaceholder(Object arg) {
         String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
-        if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>";  // debugging aid
-        if (cpPatches.containsKey(cpPlaceholder)) {
-            throw new InternalError("observed CP placeholder twice: " + cpPlaceholder);
-        }
+        if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>";
+        // TODO check if arg is already in the constant pool
         // insert placeholder in CP and remember the patch
-        int index = cw.newConst((Object) cpPlaceholder);  // TODO check if already in the constant pool
-        cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg));
+        int index = cw.newConst((Object) cpPlaceholder);
+        cpPatches.add(new CpPatch(index, arg));
         return cpPlaceholder;
     }
 
     Object[] cpPatches(byte[] classFile) {
         int size = getConstantPoolSize(classFile);
         Object[] res = new Object[size];
-        for (CpPatch p : cpPatches.values()) {
+        for (CpPatch p : cpPatches) {
             if (p.index >= size)
                 throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
             res[p.index] = p.value;
@@ -741,7 +738,7 @@
                     continue;
                 case IDENTITY:
                     assert(name.arguments.length == 1);
-                    emitPushArguments(name);
+                    emitPushArguments(name, 0);
                     continue;
                 case ZERO:
                     assert(name.arguments.length == 0);
@@ -795,7 +792,7 @@
         assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH;
         Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
         assert elementType != null;
-        emitPushArguments(name);
+        emitPushArguments(name, 0);
         if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) {
             Wrapper w = Wrapper.forPrimitiveType(elementType);
             arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
@@ -824,7 +821,7 @@
         }
 
         // push arguments
-        emitPushArguments(name);
+        emitPushArguments(name, 0);
 
         // invocation
         MethodType type = name.function.methodType();
@@ -923,7 +920,7 @@
         assert(!(member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual));
 
         // push arguments
-        emitPushArguments(name);
+        emitPushArguments(name, 0);
 
         // invocation
         if (member.isMethod()) {
@@ -1444,13 +1441,10 @@
         }
     }
 
-    private void emitPushArguments(Name args) {
-        emitPushArguments(args, 0);
-    }
-
     private void emitPushArguments(Name args, int start) {
+        MethodType type = args.function.methodType();
         for (int i = start; i < args.arguments.length; i++) {
-            emitPushArgument(args, i);
+            emitPushArgument(type.parameterType(i), args.arguments[i]);
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Mon Aug 15 08:15:02 2016 -0700
@@ -149,9 +149,9 @@
         static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
         static final int TYPE_LIMIT = ALL_TYPES.length;
 
-        private final char btChar;
-        private final Class<?> btClass;
-        private final Wrapper btWrapper;
+        final char btChar;
+        final Class<?> btClass;
+        final Wrapper btWrapper;
 
         private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) {
             this.btChar = btChar;
@@ -1366,10 +1366,11 @@
     }
 
     public static String basicTypeSignature(MethodType type) {
-        char[] sig = new char[type.parameterCount() + 2];
+        int params = type.parameterCount();
+        char[] sig = new char[params + 2];
         int sigp = 0;
-        for (Class<?> pt : type.parameterList()) {
-            sig[sigp++] = basicTypeChar(pt);
+        while (sigp < params) {
+            sig[sigp] = basicTypeChar(type.parameterType(sigp++));
         }
         sig[sigp++] = '_';
         sig[sigp++] = basicTypeChar(type.returnType());
@@ -1407,7 +1408,7 @@
 
     static final class Name {
         final BasicType type;
-        private short index;
+        @Stable short index;
         final NamedFunction function;
         final Object constraint;  // additional type information, if not null
         @Stable final Object[] arguments;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Mon Aug 15 08:15:02 2016 -0700
@@ -78,7 +78,7 @@
     private int      flags;       // modifier bits; see reflect.Modifier
     //@Injected JVM_Method* vmtarget;
     //@Injected int         vmindex;
-    private Object   resolution;  // if null, this guy is resolved
+    Object   resolution;  // if null, this guy is resolved
 
     /** Return the declaring class of this member.
      *  In the case of a bare name and type, the declaring class will be null.
@@ -826,7 +826,7 @@
         return resolution == null;
     }
 
-    private void initResolved(boolean isResolved) {
+    void initResolved(boolean isResolved) {
         assert(this.resolution == null);  // not initialized yet!
         if (!isResolved)
             this.resolution = this;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Mon Aug 15 08:15:02 2016 -0700
@@ -40,8 +40,6 @@
 import sun.invoke.util.Wrapper;
 
 import java.lang.reflect.Array;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
@@ -60,19 +58,6 @@
  * @author jrose
  */
 /*non-public*/ abstract class MethodHandleImpl {
-    // Do not adjust this except for special platforms:
-    private static final int MAX_ARITY;
-    static {
-        final Object[] values = { 255 };
-        AccessController.doPrivileged(new PrivilegedAction<>() {
-            @Override
-            public Void run() {
-                values[0] = Integer.getInteger(MethodHandleImpl.class.getName()+".MAX_ARITY", 255);
-                return null;
-            }
-        });
-        MAX_ARITY = (Integer) values[0];
-    }
 
     /// Factory methods to create method handles:
 
@@ -652,7 +637,7 @@
         MethodType srcType = targetType                 // (a..., [b...])=>r
                 .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
         if (!retainOriginalArgs) {                      // (a..., b...)=>r
-            srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList());
+            srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterArray());
         }
         // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
         // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
@@ -1097,7 +1082,7 @@
         int arity = type.parameterCount();
         if (arity > 1) {
             MethodHandle mh = throwException(type.dropParameterTypes(1, arity));
-            mh = MethodHandles.dropArguments(mh, 1, type.parameterList().subList(1, arity));
+            mh = MethodHandles.dropArguments(mh, 1, Arrays.copyOfRange(type.parameterArray(), 1, arity));
             return mh;
         }
         return makePairwiseConvert(NF_throwException.resolvedHandle(), type, false, true);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Mon Aug 15 08:15:02 2016 -0700
@@ -53,6 +53,7 @@
     static final boolean PROFILE_GWT;
     static final int CUSTOMIZE_THRESHOLD;
     static final boolean VAR_HANDLE_GUARDS;
+    static final int MAX_ARITY;
 
     static {
         Properties props = GetPropertyAction.privilegedGetProperties();
@@ -79,6 +80,10 @@
         VAR_HANDLE_GUARDS = Boolean.parseBoolean(
                 props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
 
+        // Do not adjust this except for special platforms:
+        MAX_ARITY = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandleImpl.MAX_ARITY", "255"));
+
         if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
             throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Mon Aug 15 08:15:02 2016 -0700
@@ -77,7 +77,7 @@
 
     private MethodHandles() { }  // do not instantiate
 
-    private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+    static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 
     // See IMPL_LOOKUP below.
 
@@ -3268,12 +3268,11 @@
      */
     public static
     MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
-        return dropArguments0(target, pos, copyTypes(valueTypes));
+        return dropArguments0(target, pos, copyTypes(valueTypes.toArray()));
     }
 
-    private static List<Class<?>> copyTypes(List<Class<?>> types) {
-        Object[] a = types.toArray();
-        return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class));
+    private static List<Class<?>> copyTypes(Object[] array) {
+        return Arrays.asList(Arrays.copyOf(array, array.length, Class[].class));
     }
 
     private static
@@ -3352,13 +3351,13 @@
      */
     public static
     MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
-        return dropArguments(target, pos, Arrays.asList(valueTypes));
+        return dropArguments0(target, pos, copyTypes(valueTypes));
     }
 
     // private version which allows caller some freedom with error handling
     private static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos,
                                       boolean nullOnFailure) {
-        newTypes = copyTypes(newTypes);
+        newTypes = copyTypes(newTypes.toArray());
         List<Class<?>> oldTypes = target.type().parameterList();
         int match = oldTypes.size();
         if (skip != 0) {
@@ -3900,10 +3899,14 @@
         int foldVals = rtype == void.class ? 0 : 1;
         int afterInsertPos = foldPos + foldVals;
         boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
-        if (ok && !(combinerType.parameterList()
-                    .equals(targetType.parameterList().subList(afterInsertPos,
-                                                               afterInsertPos + foldArgs))))
-            ok = false;
+        if (ok) {
+            for (int i = 0; i < foldArgs; i++) {
+                if (combinerType.parameterType(i) != targetType.parameterType(i + afterInsertPos)) {
+                    ok = false;
+                    break;
+                }
+            }
+        }
         if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos))
             ok = false;
         if (!ok)
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java	Mon Aug 15 08:15:02 2016 -0700
@@ -539,10 +539,10 @@
             return res;
         } else {
             // insert after (if need be), then before
-            if (pos < parameterList().size() - 1) {
-                res = res.insertParameterTypes(arrayLength, parameterList().subList(pos + 1, parameterList().size()));
+            if (pos < ptypes.length - 1) {
+                res = res.insertParameterTypes(arrayLength, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
             }
-            return res.insertParameterTypes(0, parameterList().subList(0, pos));
+            return res.insertParameterTypes(0, Arrays.copyOf(ptypes, pos));
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Mon Aug 15 08:15:02 2016 -0700
@@ -285,7 +285,7 @@
                         el.add(new RecipeElement(argC++));
                     }
                 } else {
-                    // Not a special characters, this is a constant embedded into
+                    // Not a special character, this is a constant embedded into
                     // the recipe itself.
                     acc.append(c);
                 }
@@ -321,30 +321,32 @@
     private static final class RecipeElement {
         private final Object value;
         private final int argPos;
+        private final char tag;
 
         public RecipeElement(Object cnst) {
             this.value = Objects.requireNonNull(cnst);
             this.argPos = -1;
+            this.tag = TAG_CONST;
         }
 
         public RecipeElement(int arg) {
             this.value = null;
-            assert (arg >= 0);
             this.argPos = arg;
+            this.tag = TAG_ARG;
         }
 
         public Object getValue() {
-            assert (isConst());
+            assert (tag == TAG_CONST);
             return value;
         }
 
         public int getArgPos() {
-            assert (!isConst());
+            assert (tag == TAG_ARG);
             return argPos;
         }
 
-        public boolean isConst() {
-            return argPos == -1;
+        public char getTag() {
+            return tag;
         }
 
         @Override
@@ -354,16 +356,15 @@
 
             RecipeElement that = (RecipeElement) o;
 
-            boolean isConst = isConst();
-            if (isConst != that.isConst()) return false;
-            if (isConst && (!value.equals(that.value))) return false;
-            if (!isConst && (argPos != that.argPos)) return false;
+            if (this.tag != that.tag) return false;
+            if (this.tag == TAG_CONST && (!value.equals(that.value))) return false;
+            if (this.tag == TAG_ARG && (argPos != that.argPos)) return false;
             return true;
         }
 
         @Override
         public int hashCode() {
-            return argPos;
+            return (int)tag;
         }
     }
 
@@ -643,19 +644,20 @@
      * @return argument types the strategy is going to use
      */
     private static MethodType adaptType(MethodType args) {
-        Class<?>[] ptypes = args.parameterArray();
-        boolean changed = false;
-        for (int i = 0; i < ptypes.length; i++) {
-            Class<?> ptype = ptypes[i];
+        Class<?>[] ptypes = null;
+        for (int i = 0; i < args.parameterCount(); i++) {
+            Class<?> ptype = args.parameterType(i);
             if (!ptype.isPrimitive() &&
                     ptype != String.class &&
                     ptype != Object.class) { // truncate to Object
+                if (ptypes == null) {
+                    ptypes = args.parameterArray();
+                }
                 ptypes[i] = Object.class;
-                changed = true;
             }
             // else other primitives or String or Object (unchanged)
         }
-        return changed
+        return (ptypes != null)
                 ? MethodType.methodType(args.returnType(), ptypes)
                 : args;
     }
@@ -874,24 +876,29 @@
 
                 int off = 0;
                 for (RecipeElement el : recipe.getElements()) {
-                    if (el.isConst()) {
-                        // Guaranteed non-null, no null check required.
-                    } else {
-                        // Null-checks are needed only for String arguments, and when a previous stage
-                        // did not do implicit null-checks. If a String is null, we eagerly replace it
-                        // with "null" constant. Note, we omit Objects here, because we don't call
-                        // .length() on them down below.
-                        int ac = el.getArgPos();
-                        Class<?> cl = arr[ac];
-                        if (cl == String.class && !guaranteedNonNull[ac]) {
-                            Label l0 = new Label();
-                            mv.visitIntInsn(ALOAD, off);
-                            mv.visitJumpInsn(IFNONNULL, l0);
-                            mv.visitLdcInsn("null");
-                            mv.visitIntInsn(ASTORE, off);
-                            mv.visitLabel(l0);
-                        }
-                        off += getParameterSize(cl);
+                    switch (el.getTag()) {
+                        case TAG_CONST:
+                            // Guaranteed non-null, no null check required.
+                            break;
+                        case TAG_ARG:
+                            // Null-checks are needed only for String arguments, and when a previous stage
+                            // did not do implicit null-checks. If a String is null, we eagerly replace it
+                            // with "null" constant. Note, we omit Objects here, because we don't call
+                            // .length() on them down below.
+                            int ac = el.getArgPos();
+                            Class<?> cl = arr[ac];
+                            if (cl == String.class && !guaranteedNonNull[ac]) {
+                                Label l0 = new Label();
+                                mv.visitIntInsn(ALOAD, off);
+                                mv.visitJumpInsn(IFNONNULL, l0);
+                                mv.visitLdcInsn("null");
+                                mv.visitIntInsn(ASTORE, off);
+                                mv.visitLabel(l0);
+                            }
+                            off += getParameterSize(cl);
+                            break;
+                        default:
+                            throw new StringConcatException("Unhandled tag: " + el.getTag());
                     }
                 }
             }
@@ -912,30 +919,35 @@
                 mv.visitInsn(ICONST_0);
 
                 for (RecipeElement el : recipe.getElements()) {
-                    if (el.isConst()) {
-                        Object cnst = el.getValue();
-                        len += cnst.toString().length();
-                    } else {
-                        /*
-                            If an argument is String, then we can call .length() on it. Sized/Exact modes have
-                            converted arguments for us. If an argument is primitive, we can provide a guess
-                            for its String representation size.
-                        */
-                        Class<?> cl = arr[el.getArgPos()];
-                        if (cl == String.class) {
-                            mv.visitIntInsn(ALOAD, off);
-                            mv.visitMethodInsn(
-                                    INVOKEVIRTUAL,
-                                    "java/lang/String",
-                                    "length",
-                                    "()I",
-                                    false
-                            );
-                            mv.visitInsn(IADD);
-                        } else if (cl.isPrimitive()) {
-                            len += estimateSize(cl);
-                        }
-                        off += getParameterSize(cl);
+                    switch (el.getTag()) {
+                        case TAG_CONST:
+                            Object cnst = el.getValue();
+                            len += cnst.toString().length();
+                            break;
+                        case TAG_ARG:
+                            /*
+                                If an argument is String, then we can call .length() on it. Sized/Exact modes have
+                                converted arguments for us. If an argument is primitive, we can provide a guess
+                                for its String representation size.
+                            */
+                            Class<?> cl = arr[el.getArgPos()];
+                            if (cl == String.class) {
+                                mv.visitIntInsn(ALOAD, off);
+                                mv.visitMethodInsn(
+                                        INVOKEVIRTUAL,
+                                        "java/lang/String",
+                                        "length",
+                                        "()I",
+                                        false
+                                );
+                                mv.visitInsn(IADD);
+                            } else if (cl.isPrimitive()) {
+                                len += estimateSize(cl);
+                            }
+                            off += getParameterSize(cl);
+                            break;
+                        default:
+                            throw new StringConcatException("Unhandled tag: " + el.getTag());
                     }
                 }
 
@@ -967,15 +979,20 @@
                 int off = 0;
                 for (RecipeElement el : recipe.getElements()) {
                     String desc;
-                    if (el.isConst()) {
-                        Object cnst = el.getValue();
-                        mv.visitLdcInsn(cnst);
-                        desc = getSBAppendDesc(cnst.getClass());
-                    } else {
-                        Class<?> cl = arr[el.getArgPos()];
-                        mv.visitVarInsn(getLoadOpcode(cl), off);
-                        off += getParameterSize(cl);
-                        desc = getSBAppendDesc(cl);
+                    switch (el.getTag()) {
+                        case TAG_CONST:
+                            Object cnst = el.getValue();
+                            mv.visitLdcInsn(cnst);
+                            desc = getSBAppendDesc(cnst.getClass());
+                            break;
+                        case TAG_ARG:
+                            Class<?> cl = arr[el.getArgPos()];
+                            mv.visitVarInsn(getLoadOpcode(cl), off);
+                            off += getParameterSize(cl);
+                            desc = getSBAppendDesc(cl);
+                            break;
+                        default:
+                            throw new StringConcatException("Unhandled tag: " + el.getTag());
                     }
 
                     mv.visitMethodInsn(
@@ -1245,7 +1262,6 @@
                 }
             }
 
-            List<Class<?>> ptypesList = Arrays.asList(ptypes);
             MethodHandle[] lengthers = new MethodHandle[pc];
 
             // Figure out lengths: constants' lengths can be deduced on the spot.
@@ -1253,24 +1269,29 @@
             // call the usual String.length(). Primitive values string sizes can be estimated.
             int initial = 0;
             for (RecipeElement el : recipe.getElements()) {
-                if (el.isConst()) {
-                    Object cnst = el.getValue();
-                    initial += cnst.toString().length();
-                } else {
-                    final int i = el.getArgPos();
-                    Class<?> type = ptypesList.get(i);
-                    if (type.isPrimitive()) {
-                        MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
-                        est = MethodHandles.dropArguments(est, 0, type);
-                        lengthers[i] = est;
-                    } else {
-                        lengthers[i] = STRING_LENGTH;
-                    }
+                switch (el.getTag()) {
+                    case TAG_CONST:
+                        Object cnst = el.getValue();
+                        initial += cnst.toString().length();
+                        break;
+                    case TAG_ARG:
+                        final int i = el.getArgPos();
+                        Class<?> type = ptypes[i];
+                        if (type.isPrimitive()) {
+                            MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
+                            est = MethodHandles.dropArguments(est, 0, type);
+                            lengthers[i] = est;
+                        } else {
+                            lengthers[i] = STRING_LENGTH;
+                        }
+                        break;
+                    default:
+                        throw new StringConcatException("Unhandled tag: " + el.getTag());
                 }
             }
 
             // Create (StringBuilder, <args>) shape for appending:
-            MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypesList);
+            MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypes);
 
             // Compose append calls. This is done in reverse because the application order is
             // reverse as well.
@@ -1278,19 +1299,24 @@
             for (int i = elements.size() - 1; i >= 0; i--) {
                 RecipeElement el = elements.get(i);
                 MethodHandle appender;
-                if (el.isConst()) {
-                    Object constant = el.getValue();
-                    MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
-                    appender = MethodHandles.insertArguments(mh, 1, constant);
-                } else {
-                    int ac = el.getArgPos();
-                    appender = appender(ptypesList.get(ac));
+                switch (el.getTag()) {
+                    case TAG_CONST:
+                        Object constant = el.getValue();
+                        MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
+                        appender = MethodHandles.insertArguments(mh, 1, constant);
+                        break;
+                    case TAG_ARG:
+                        int ac = el.getArgPos();
+                        appender = appender(ptypes[ac]);
 
-                    // Insert dummy arguments to match the prefix in the signature.
-                    // The actual appender argument will be the ac-ith argument.
-                    if (ac != 0) {
-                        appender = MethodHandles.dropArguments(appender, 1, ptypesList.subList(0, ac));
-                    }
+                        // Insert dummy arguments to match the prefix in the signature.
+                        // The actual appender argument will be the ac-ith argument.
+                        if (ac != 0) {
+                            appender = MethodHandles.dropArguments(appender, 1, Arrays.copyOf(ptypes, ac));
+                        }
+                        break;
+                    default:
+                        throw new StringConcatException("Unhandled tag: " + el.getTag());
                 }
                 builder = MethodHandles.foldArguments(builder, appender);
             }
@@ -1460,7 +1486,6 @@
                     ptypes[i] = filter.type().returnType();
                 }
             }
-            List<Class<?>> ptypesList = Arrays.asList(ptypes);
 
             // Start building the combinator tree. The tree "starts" with (<parameters>)String, and "finishes"
             // with the (int, byte[], byte)String in String helper. The combinators are assembled bottom-up,
@@ -1481,12 +1506,17 @@
             // *ending* index.
             for (RecipeElement el : recipe.getElements()) {
                 MethodHandle prepender;
-                if (el.isConst()) {
-                    Object cnst = el.getValue();
-                    prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
-                } else {
-                    int pos = el.getArgPos();
-                    prepender = selectArgument(prepender(ptypesList.get(pos)), 3, ptypesList, pos);
+                switch (el.getTag()) {
+                    case TAG_CONST:
+                        Object cnst = el.getValue();
+                        prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
+                        break;
+                    case TAG_ARG:
+                        int pos = el.getArgPos();
+                        prepender = selectArgument(prepender(ptypes[pos]), 3, ptypes, pos);
+                        break;
+                    default:
+                        throw new StringConcatException("Unhandled tag: " + el.getTag());
                 }
 
                 // Remove "old" index from arguments
@@ -1507,7 +1537,7 @@
             }
 
             // Fold in byte[] instantiation at argument 0.
-            MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypesList);
+            MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypes);
             mh = MethodHandles.foldArguments(mh, combiner);
 
             // Start combining length and coder mixers.
@@ -1526,36 +1556,41 @@
             byte initialCoder = INITIAL_CODER;
             int initialLen = 0;    // initial length, in characters
             for (RecipeElement el : recipe.getElements()) {
-                if (el.isConst()) {
-                    Object constant = el.getValue();
-                    String s = constant.toString();
-                    initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
-                    initialLen += s.length();
-                } else {
-                    int ac = el.getArgPos();
+                switch (el.getTag()) {
+                    case TAG_CONST:
+                        Object constant = el.getValue();
+                        String s = constant.toString();
+                        initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
+                        initialLen += s.length();
+                        break;
+                    case TAG_ARG:
+                        int ac = el.getArgPos();
 
-                    Class<?> argClass = ptypesList.get(ac);
-                    MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypesList, ac);
-                    lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
-                    lm = MethodHandles.dropArguments(lm, 2, byte.class);
+                        Class<?> argClass = ptypes[ac];
+                        MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypes, ac);
+                        lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
+                        lm = MethodHandles.dropArguments(lm, 2, byte.class);
 
-                    MethodHandle cm = selectArgument(coderMixer(argClass),  1, ptypesList, ac);
-                    cm = MethodHandles.dropArguments(cm, 0, int.class);  // (**)
+                        MethodHandle cm = selectArgument(coderMixer(argClass),  1, ptypes, ac);
+                        cm = MethodHandles.dropArguments(cm, 0, int.class);  // (**)
 
-                    // Read this bottom up:
+                        // Read this bottom up:
 
-                    // 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
-                    mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
+                        // 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
+                        mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
 
-                    // 3. Compute "new-index", producing ("new-index", "new-coder", "old-index", "old-coder", <args>)
-                    //    Length mixer ignores both "new-coder" and "old-coder" due to dropArguments above (*)
-                    mh = MethodHandles.foldArguments(mh, lm);
+                        // 3. Compute "new-index", producing ("new-index", "new-coder", "old-index", "old-coder", <args>)
+                        //    Length mixer ignores both "new-coder" and "old-coder" due to dropArguments above (*)
+                        mh = MethodHandles.foldArguments(mh, lm);
 
-                    // 2. Compute "new-coder", producing ("new-coder", "old-index", "old-coder", <args>)
-                    //    Coder mixer ignores the "old-index" arg due to dropArguments above (**)
-                    mh = MethodHandles.foldArguments(mh, cm);
+                        // 2. Compute "new-coder", producing ("new-coder", "old-index", "old-coder", <args>)
+                        //    Coder mixer ignores the "old-index" arg due to dropArguments above (**)
+                        mh = MethodHandles.foldArguments(mh, cm);
 
-                    // 1. The mh shape here is ("old-index", "old-coder", <args>)
+                        // 1. The mh shape here is ("old-index", "old-coder", <args>)
+                        break;
+                    default:
+                        throw new StringConcatException("Unhandled tag: " + el.getTag());
                 }
             }
 
@@ -1582,14 +1617,14 @@
         }
 
         // Adapts: (...prefix..., parameter[pos])R -> (...prefix..., ...parameters...)R
-        private static MethodHandle selectArgument(MethodHandle mh, int prefix, List<Class<?>> ptypes, int pos) {
+        private static MethodHandle selectArgument(MethodHandle mh, int prefix, Class<?>[] ptypes, int pos) {
             if (pos == 0) {
-                return MethodHandles.dropArguments(mh, prefix + 1, ptypes.subList(1, ptypes.size()));
-            } else if (pos == ptypes.size() - 1) {
-                return MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, ptypes.size() - 1));
+                return MethodHandles.dropArguments(mh, prefix + 1, Arrays.copyOfRange(ptypes, 1, ptypes.length));
+            } else if (pos == ptypes.length - 1) {
+                return MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, ptypes.length - 1));
             } else { // 0 < pos < ptypes.size() - 1
-                MethodHandle t = MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, pos));
-                return MethodHandles.dropArguments(t, prefix + 1 + pos, ptypes.subList(pos + 1, ptypes.size()));
+                MethodHandle t = MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, pos));
+                return MethodHandles.dropArguments(t, prefix + 1 + pos, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
             }
         }
 
@@ -1648,8 +1683,8 @@
         private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS;
         private static final ConcurrentMap<Class<?>, MethodHandle> LENGTH_MIXERS;
         private static final ConcurrentMap<Class<?>, MethodHandle> CODER_MIXERS;
-        private static final Class<?> STRING_HELPER;
         private static final byte INITIAL_CODER;
+        static final Class<?> STRING_HELPER;
 
         static {
             try {
@@ -1751,7 +1786,7 @@
 
     /* ------------------------------- Common utilities ------------------------------------ */
 
-    private static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
+    static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
         try {
             return lookup.findStatic(refc, name, MethodType.methodType(rtype, ptypes));
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1759,7 +1794,7 @@
         }
     }
 
-    private static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
+    static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
         try {
             return lookup.findVirtual(refc, name, MethodType.methodType(rtype, ptypes));
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1767,7 +1802,7 @@
         }
     }
 
-    private static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) {
+    static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) {
         try {
             return lookup.findConstructor(refc, MethodType.methodType(void.class, ptypes));
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1775,7 +1810,7 @@
         }
     }
 
-    private static int estimateSize(Class<?> cl) {
+    static int estimateSize(Class<?> cl) {
         if (cl == Integer.TYPE) {
             return 11; // "-2147483648"
         } else if (cl == Boolean.TYPE) {
@@ -1797,7 +1832,7 @@
         }
     }
 
-    private static Class<?> adaptToStringBuilder(Class<?> c) {
+    static Class<?> adaptToStringBuilder(Class<?> c) {
         if (c.isPrimitive()) {
             if (c == Byte.TYPE || c == Short.TYPE) {
                 return int.class;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java	Mon Aug 15 08:15:02 2016 -0700
@@ -31,7 +31,6 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -54,7 +53,8 @@
         List<Class<?>> l = new ArrayList<>();
         if (receiver != null)
             l.add(receiver);
-        l.addAll(Arrays.asList(intermediate));
+        for (Class<?> c : intermediate)
+            l.add(c);
 
         // (Receiver, <Intermediates>)Value
         methodType_table[VarHandle.AccessType.GET.ordinal()] =
--- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Mon Aug 15 08:15:02 2016 -0700
@@ -28,6 +28,7 @@
 import java.lang.reflect.Modifier;
 import static java.lang.reflect.Modifier.*;
 import java.lang.reflect.Module;
+import java.util.Objects;
 import jdk.internal.reflect.Reflection;
 
 /**
@@ -330,15 +331,7 @@
             return true;
         if (class1.getClassLoader() != class2.getClassLoader())
             return false;
-        String name1 = class1.getName(), name2 = class2.getName();
-        int dot = name1.lastIndexOf('.');
-        if (dot != name2.lastIndexOf('.'))
-            return false;
-        for (int i = 0; i < dot; i++) {
-            if (name1.charAt(i) != name2.charAt(i))
-                return false;
-        }
-        return true;
+        return Objects.equals(class1.getPackageName(), class2.getPackageName());
     }
 
     /** Return the package name for this class.
--- a/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Mon Aug 15 08:15:02 2016 -0700
@@ -580,6 +580,9 @@
             Entry entry;
 
             if (key instanceof PrivateKey) {
+                // Check that all the certs are X.509 certs
+                checkX509Certs(chain);
+
                 PrivateKeyEntry keyEntry = new PrivateKeyEntry();
                 keyEntry.date = new Date();
 
@@ -690,6 +693,9 @@
                                   Certificate[] chain)
         throws KeyStoreException
     {
+        // Check that all the certs are X.509 certs
+        checkX509Certs(chain);
+
         // Private key must be encoded as EncryptedPrivateKeyInfo
         // as defined in PKCS#8
         try {
@@ -960,6 +966,13 @@
     private void setCertEntry(String alias, Certificate cert,
         Set<KeyStore.Entry.Attribute> attributes) throws KeyStoreException {
 
+        // Check that the cert is an X.509 cert
+        if (cert != null && (!(cert instanceof X509Certificate))) {
+            throw new KeyStoreException(
+                "Only X.509 certificates are supported - rejecting class: " +
+                cert.getClass().getName());
+        }
+
         Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
         if (entry != null && entry instanceof KeyEntry) {
             throw new KeyStoreException("Cannot overwrite own certificate");
@@ -1505,6 +1518,21 @@
         return set.size() == certChain.length;
     }
 
+    /*
+     * Check that all the certificates are X.509 certificates
+     */
+    private static void checkX509Certs(Certificate[] certs)
+            throws KeyStoreException {
+        if (certs != null) {
+            for (Certificate cert : certs) {
+                if (!(cert instanceof X509Certificate)) {
+                    throw new KeyStoreException(
+                        "Only X.509 certificates are supported - " +
+                        "rejecting class: " + cert.getClass().getName());
+                }
+            }
+        }
+    }
 
     /*
      * Create PKCS#12 Attributes, friendlyName, localKeyId and trustedKeyUsage.
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Mon Aug 15 08:15:02 2016 -0700
@@ -59,6 +59,11 @@
             "jdk.tls.client.enableStatusRequestExtension", true);
     private final boolean serverEnableStapling = Debug.getBooleanProperty(
             "jdk.tls.server.enableStatusRequestExtension", false);
+    private final static Collection<CipherSuite> clientCustomizedCipherSuites =
+            getCustomizedCipherSuites("jdk.tls.client.cipherSuites");
+    private final static Collection<CipherSuite> serverCustomizedCipherSuites =
+            getCustomizedCipherSuites("jdk.tls.server.cipherSuites");
+
     private volatile StatusResponseManager statusResponseManager;
 
     SSLContextImpl() {
@@ -336,20 +341,52 @@
         return isClient ? clientEnableStapling : serverEnableStapling;
     }
 
+
     /*
-     * Return the list of all available CipherSuites with a priority of
-     * minPriority or above.
+     * Return the list of all available CipherSuites that are supported
+     * using currently installed providers.
+     */
+    private static CipherSuiteList getApplicableSupportedCipherSuiteList(
+            ProtocolList protocols) {
+
+        return getApplicableCipherSuiteList(
+                CipherSuite.allowedCipherSuites(),
+                protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+    }
+
+    /*
+     * Return the list of all available CipherSuites that are default enabled
+     * in client or server side.
+     */
+    private static CipherSuiteList getApplicableEnabledCipherSuiteList(
+            ProtocolList protocols, boolean isClient) {
+
+        if (isClient) {
+            if (!clientCustomizedCipherSuites.isEmpty()) {
+                return getApplicableCipherSuiteList(
+                        clientCustomizedCipherSuites,
+                        protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+            }
+        } else {
+            if (!serverCustomizedCipherSuites.isEmpty()) {
+                return getApplicableCipherSuiteList(
+                        serverCustomizedCipherSuites,
+                        protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+            }
+        }
+
+        return getApplicableCipherSuiteList(
+                CipherSuite.allowedCipherSuites(),
+                protocols, CipherSuite.DEFAULT_SUITES_PRIORITY);
+    }
+
+    /*
+     * Return the list of available CipherSuites which are applicable to
+     * the specified protocols.
      */
     private static CipherSuiteList getApplicableCipherSuiteList(
-            ProtocolList protocols, boolean onlyEnabled) {
-
-        int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
-        if (onlyEnabled) {
-            minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
-        }
-
-        Collection<CipherSuite> allowedCipherSuites =
-                                    CipherSuite.allowedCipherSuites();
+            Collection<CipherSuite> allowedCipherSuites,
+            ProtocolList protocols, int minPriority) {
 
         TreeSet<CipherSuite> suites = new TreeSet<>();
         if (!(protocols.collection().isEmpty()) &&
@@ -386,6 +423,67 @@
         return new CipherSuiteList(suites);
     }
 
+    /*
+     * Get the customized cipher suites specified by the given system property.
+     */
+    private static Collection<CipherSuite> getCustomizedCipherSuites(
+            String propertyName) {
+
+        String property = GetPropertyAction.privilegedGetProperty(propertyName);
+        if (debug != null && Debug.isOn("sslctx")) {
+            System.out.println(
+                    "System property " + propertyName + " is set to '" +
+                    property + "'");
+        }
+        if (property != null && property.length() != 0) {
+            // remove double quote marks from beginning/end of the property
+            if (property.length() > 1 && property.charAt(0) == '"' &&
+                    property.charAt(property.length() - 1) == '"') {
+                property = property.substring(1, property.length() - 1);
+            }
+        }
+
+        if (property != null && property.length() != 0) {
+            String[] cipherSuiteNames = property.split(",");
+            Collection<CipherSuite> cipherSuites =
+                        new ArrayList<>(cipherSuiteNames.length);
+            for (int i = 0; i < cipherSuiteNames.length; i++) {
+                cipherSuiteNames[i] = cipherSuiteNames[i].trim();
+                if (cipherSuiteNames[i].isEmpty()) {
+                    continue;
+                }
+
+                CipherSuite suite;
+                try {
+                    suite = CipherSuite.valueOf(cipherSuiteNames[i]);
+                } catch (IllegalArgumentException iae) {
+                    if (debug != null && Debug.isOn("sslctx")) {
+                        System.out.println(
+                                "Unknown or unsupported cipher suite name: " +
+                                cipherSuiteNames[i]);
+                    }
+
+                    continue;
+                }
+
+                if (suite.isAvailable()) {
+                    cipherSuites.add(suite);
+                } else {
+                    if (debug != null && Debug.isOn("sslctx")) {
+                        System.out.println(
+                                "The current installed providers do not " +
+                                "support cipher suite: " + cipherSuiteNames[i]);
+                    }
+                }
+            }
+
+            return cipherSuites;
+        }
+
+        return Collections.emptyList();
+    }
+
+
     private static String[] getAvailableProtocols(
             ProtocolVersion[] protocolCandidates) {
 
@@ -481,10 +579,10 @@
                 }));
             }
 
-            supportedCipherSuiteList = getApplicableCipherSuiteList(
-                    supportedProtocolList, false);          // all supported
-            serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    serverDefaultProtocolList, true);       // enabled only
+            supportedCipherSuiteList = getApplicableSupportedCipherSuiteList(
+                    supportedProtocolList);
+            serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    serverDefaultProtocolList, false);
         }
 
         @Override
@@ -541,8 +639,8 @@
                 }));
             }
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
         }
 
         @Override
@@ -581,8 +679,9 @@
                 }));
             }
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
+
         }
 
         @Override
@@ -623,8 +722,8 @@
                 }));
             }
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
         }
 
         @Override
@@ -757,8 +856,9 @@
 
                 clientDefaultProtocolList = new ProtocolList(
                         getAvailableProtocols(candidates));
-                clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);   // enabled only
+                clientDefaultCipherSuiteList =
+                        getApplicableEnabledCipherSuiteList(
+                                clientDefaultProtocolList, true);
             } else {
                 clientDefaultProtocolList = null;       // unlikely to be used
                 clientDefaultCipherSuiteList = null;    // unlikely to be used
@@ -1032,10 +1132,10 @@
                 ProtocolVersion.DTLS12
             }));
 
-            supportedCipherSuiteList = getApplicableCipherSuiteList(
-                    supportedProtocolList, false);          // all supported
-            serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    serverDefaultProtocolList, true);       // enabled only
+            supportedCipherSuiteList = getApplicableSupportedCipherSuiteList(
+                    supportedProtocolList);
+            serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    serverDefaultProtocolList, false);
         }
 
         @Override
@@ -1090,8 +1190,8 @@
                 ProtocolVersion.DTLS10
             }));
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
         }
 
         @Override
@@ -1122,8 +1222,8 @@
                 ProtocolVersion.DTLS12
             }));
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
         }
 
         @Override
@@ -1187,8 +1287,9 @@
 
                 clientDefaultProtocolList = new ProtocolList(
                         getAvailableProtocols(candidates));
-                clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);   // enabled only
+                clientDefaultCipherSuiteList =
+                        getApplicableEnabledCipherSuiteList(
+                                clientDefaultProtocolList, true);
             } else {
                 clientDefaultProtocolList = null;       // unlikely to be used
                 clientDefaultCipherSuiteList = null;    // unlikely to be used
--- a/jdk/src/java.base/windows/lib/security/default.policy	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/windows/lib/security/default.policy	Mon Aug 15 08:15:02 2016 -0700
@@ -11,5 +11,6 @@
                    "clearProviderProperties.SunMSCAPI";
     permission java.security.SecurityPermission
                    "removeProviderProperty.SunMSCAPI";
+    permission java.security.SecurityPermission "authProvider.SunMSCAPI";
     permission java.util.PropertyPermission "*", "read";
 };
--- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java	Mon Aug 15 08:15:02 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, 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
@@ -118,7 +118,7 @@
     /**
      * @serial
      */
-    private volatile String actions;
+    private final String actions;
 
     /**
      * Constructs a new CardPermission with the specified actions.
@@ -143,10 +143,14 @@
             throw new NullPointerException();
         }
         mask = getMask(actions);
+        this.actions = getActions(mask);
     }
 
     private static int getMask(String actions) {
-        if ((actions == null) || (actions.length() == 0)) {
+        if (actions == null) {
+            return 0;
+        }
+        if (actions.length() == 0) {
             throw new IllegalArgumentException("actions must not be empty");
         }
 
@@ -177,6 +181,9 @@
     }
 
     private static String getActions(int mask) {
+        if (mask == 0) {
+            return null;
+        }
         if (mask == A_ALL) {
             return S_ALL;
         }
@@ -200,9 +207,6 @@
      * @return the canonical string representation of the actions.
      */
     public String getActions() {
-        if (actions == null) {
-            actions = getActions(mask);
-        }
         return actions;
     }
 
@@ -278,10 +282,6 @@
 
     private void writeObject(ObjectOutputStream s) throws IOException {
         // Write out the actions. The superclass takes care of the name.
-        // Call getActions to make sure actions field is initialized
-        if (actions == null) {
-            getActions();
-        }
         s.defaultWriteObject();
     }
 
@@ -291,5 +291,4 @@
         s.defaultReadObject();
         mask = getMask(actions);
     }
-
 }
--- a/jdk/test/ProblemList.txt	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/ProblemList.txt	Mon Aug 15 08:15:02 2016 -0700
@@ -133,15 +133,13 @@
 
 # jdk_instrument
 
-java/lang/instrument/RedefineBigClass.sh                        8061177 generic-all
-java/lang/instrument/RetransformBigClass.sh                     8061177 generic-all
+java/lang/instrument/RedefineBigClass.sh                        8065756 generic-all
+java/lang/instrument/RetransformBigClass.sh                     8065756 generic-all
 
 java/lang/instrument/BootClassPath/BootClassPathTest.sh         8072130 macosx-all
 
 java/lang/instrument/DaemonThread/TestDaemonThread.java         8161225 generic-all
 
-java/lang/management/MemoryMXBean/LowMemoryTest.java            8130339 generic-all
-
 java/lang/management/MemoryMXBean/Pending.java                  8158837 generic-all
 java/lang/management/MemoryMXBean/PendingAllGC.sh               8158760 generic-all
 
@@ -235,8 +233,8 @@
 sun/security/pkcs11/KeyAgreement/TestDH.java                    8077138,8023434 windows-all
 sun/security/pkcs11/KeyAgreement/TestInterop.java               8077138,8023434 windows-all
 sun/security/pkcs11/KeyAgreement/TestShort.java                 8077138,8023434 windows-all
-sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java           8154910 windows-all
-sun/security/pkcs11/KeyAgreement/UnsupportedDHKeys.java         8154910 windows-all
+sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java           8077138 windows-all
+sun/security/pkcs11/KeyAgreement/UnsupportedDHKeys.java         8077138 windows-all
 sun/security/pkcs11/KeyGenerator/DESParity.java                 8077138,8023434 windows-all
 sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java          8077138,8023434 windows-all
 sun/security/pkcs11/KeyPairGenerator/TestDH2048.java            8077138,8023434 windows-all
@@ -287,7 +285,6 @@
 
 sun/security/krb5/auto/HttpNegotiateServer.java                 8038079 generic-all
 
-sun/security/tools/keytool/autotest.sh                          8130302 generic-all
 sun/security/ssl/SSLSocketImpl/AsyncSSLSocketClose.java         8161232 macosx-all
 
 ############################################################################
@@ -331,14 +328,10 @@
 
 com/sun/jdi/RedefineImplementor.sh                              8004127 generic-all
 
-com/sun/jdi/JdbMethodExitTest.sh                                8031555 generic-all
+com/sun/jdi/JdbMethodExitTest.sh                                6902121 generic-all
 
 com/sun/jdi/RepStep.java                                        8043571 generic-all
 
-com/sun/jdi/RedefinePop.sh                                      8058616 generic-all
-
-com/sun/jdi/CatchPatternTest.sh                                 8068645 generic-all
-
 com/sun/jdi/GetLocalVariables4Test.sh                           8067354 windows-all
 
 com/sun/jdi/sde/SourceDebugExtensionTest.java                   8158066 windows-all
@@ -374,8 +367,6 @@
 
 sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java              8160376 macosx-all
 
-sun/tools/jstatd/TestJstatdExternalRegistry.java                8046285 generic-all
-
 sun/tools/jps/TestJpsJar.java                                   8160923 generic-all
 
 sun/tools/jps/TestJpsJarRelative.java                           6456333 generic-all
--- a/jdk/test/java/io/CharArrayReader/OverflowInRead.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/java/io/CharArrayReader/OverflowInRead.java	Mon Aug 15 08:15:02 2016 -0700
@@ -24,7 +24,7 @@
 /* @test
  * @bug 8163518
  * @summary Integer overflow when reading in large buffer
- * @requires (os.simpleArch == "x64" & os.maxMemory > 8g)
+ * @requires (sun.arch.data.model == "64" & os.maxMemory > 8g)
  * @run main/othervm -Xmx8g OverflowInRead
  */
 
--- a/jdk/test/java/io/StringBufferInputStream/OverflowInRead.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/java/io/StringBufferInputStream/OverflowInRead.java	Mon Aug 15 08:15:02 2016 -0700
@@ -24,7 +24,7 @@
 /* @test
  * @bug 8163518
  * @summary Integer overflow when reading in large buffer
- * @requires (os.simpleArch == "x64" & os.maxMemory > 4g)
+ * @requires (sun.arch.data.model == "64" & os.maxMemory > 4g)
  * @run main/othervm -Xmx4g OverflowInRead
  */
 
--- a/jdk/test/java/net/ProxySelector/B8035158.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/java/net/ProxySelector/B8035158.java	Mon Aug 15 08:15:02 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -22,7 +22,7 @@
  */
 /*
  * @test
- * @bug 8035158
+ * @bug 8035158 8145732
  * @run main/othervm B8035158
  */
 
@@ -94,6 +94,8 @@
                 false));
         t.add(new TestCase("google.com|google.ie", "http://google.ie",
                 false));
+        t.add(new TestCase("google.com|google.com|google.ie",
+                "http://google.ie", false));
 
         t.add(new TestCase("google.com|bing.com|yahoo.com",
                 "http://127.0.0.1", false));
--- a/jdk/test/javax/smartcardio/TestCardPermission.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/javax/smartcardio/TestCardPermission.java	Mon Aug 15 08:15:02 2016 -0700
@@ -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
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 6293767
+ * @bug 6293767 6469513
  * @summary Test for the CardPermission class
  * @author Andreas Sterbenz
  * @compile --add-modules=java.smartcardio TestCardPermission.java
@@ -49,15 +49,14 @@
         test("Reset,coNnect", "connect,reset");
         test("exclusive,*,connect", "*");
         test("connect,reset,exclusive,transmitControl,getBasicChannel,openLogicalChannel", "*");
+        test(null, null);
 
-        invalid(null);
         invalid("");
         invalid("foo");
         invalid("connect, reset");
         invalid("connect,,reset");
         invalid("connect,");
         invalid(",connect");
-        invalid("");
     }
 
     private static void invalid(String s) throws Exception {
@@ -77,7 +76,7 @@
         CardPermission p = new CardPermission("*", actions);
         System.out.println(p);
         String a = p.getActions();
-        if (canon.equals(a) == false) {
+        if (canon != null && canon.equals(a) == false) {
             throw new Exception("Canonical actions mismatch: " + canon + " != " + a);
         }
     }
--- a/jdk/test/sun/security/mscapi/AccessKeyStore.java	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/sun/security/mscapi/AccessKeyStore.java	Mon Aug 15 08:15:02 2016 -0700
@@ -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
@@ -22,7 +22,12 @@
  */
 
 /**
- * @see AccessKeyStore.sh
+ * @test
+ * @bug 6324295 6931562 8154113
+ * @modules jdk.crypto.mscapi
+ * @run main/othervm/java.security.policy==access.policy AccessKeyStore pass
+ * @run main/othervm/java.security.policy==noaccess.policy AccessKeyStore fail
+ * @summary Confirm that right permissions are granted to access keystores.
  */
 
 import java.security.Provider;
@@ -36,13 +41,16 @@
 
     public static void main(String[] args) throws Exception {
 
-        // Check that a security manager has been installed
+        // Check for security manager and required arg(s)
         if (System.getSecurityManager() == null) {
-            throw new Exception("A security manager has not been installed");
+            throw new Exception("Missing security manager");
         }
+        if (args.length <= 0) {
+            throw new Exception("Missing expected test status");
+        }
+        boolean shouldPass = args[0].equalsIgnoreCase("pass");
 
         Provider p = Security.getProvider("SunMSCAPI");
-
         System.out.println("SunMSCAPI provider classname is " +
             p.getClass().getName());
 
@@ -56,18 +64,14 @@
          *     SecurityPermission("authProvider.SunMSCAPI")
          */
         try {
-
             keyStore.load(null, null);
-
-            if (args.length > 0 && "-deny".equals(args[0])) {
+            if (!shouldPass) {
                 throw new Exception(
                     "Expected KeyStore.load to throw a SecurityException");
             }
-
         } catch (SecurityException se) {
-
-            if (args.length > 0 && "-deny".equals(args[0])) {
-                System.out.println("Caught the expected exception: " + se);
+            if (!shouldPass) {
+                System.out.println("Expected exception thrown: " + se);
                 return;
             } else {
                 throw se;
--- a/jdk/test/sun/security/mscapi/AccessKeyStore.sh	Fri Aug 12 14:35:56 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2005, 2015, 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 6324295 6931562
-# @requires os.family == "windows"
-# @run shell AccessKeyStore.sh
-# @summary Confirm that permission must be granted to access keystores.
-
-OS=`uname -s`
-case "$OS" in
-    Windows* | CYGWIN* )
-
-    # 'uname -m' does not give us enough information -
-    #  should rely on $PROCESSOR_IDENTIFIER (as is done in Defs-windows.gmk),
-    #  but JTREG does not pass this env variable when executing a shell script.
-    #
-    #  execute test program - rely on it to exit if platform unsupported
-
-	${TESTJAVA}/bin/javac -d . ${TESTSRC}\\AccessKeyStore.java
-
-	echo "Using access.policy..."
-	${TESTJAVA}/bin/java ${TESTVMOPTS} \
-	    -Djava.security.manager \
-	    -Djava.security.policy==${TESTSRC}\\access.policy \
-	    AccessKeyStore
-
-	echo "Using noaccess.policy..."
-	${TESTJAVA}/bin/java ${TESTVMOPTS} \
-	    -Djava.security.manager \
-	    -Djava.security.policy==${TESTSRC}\\noaccess.policy \
-	    AccessKeyStore -deny
-
-	exit
-	;;
-
-    * )
-        echo "This test is not intended for '$OS' - passing test"
-        exit 0
-        ;;
-esac
-
--- a/jdk/test/sun/security/mscapi/access.policy	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/sun/security/mscapi/access.policy	Mon Aug 15 08:15:02 2016 -0700
@@ -1,19 +1,4 @@
 grant {
-    // These permissions are required for the test to start
-    permission java.lang.RuntimePermission 
-			"accessClassInPackage.sun.*";
-
-    permission java.lang.RuntimePermission "loadLibrary.*";
-
-    permission java.util.PropertyPermission "os.arch", "read";
-
-    permission java.util.PropertyPermission 
-			"sun.security.mscapi.keyStoreCompatibilityMode", "read";
-
-    permission java.io.FilePermission "<<ALL FILES>>", "read";
-
-    permission java.security.SecurityPermission "putProviderProperty.SunMSCAPI";
-
     // This permission is required for the test to run to completion
     permission java.security.SecurityPermission "authProvider.SunMSCAPI";
 };
--- a/jdk/test/sun/security/mscapi/noaccess.policy	Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/sun/security/mscapi/noaccess.policy	Mon Aug 15 08:15:02 2016 -0700
@@ -1,19 +1,4 @@
 grant {
-    // These permissions are required for the test to start
-    permission java.lang.RuntimePermission 
-			"accessClassInPackage.sun.*";
-
-    permission java.lang.RuntimePermission "loadLibrary.*";
-
-    permission java.util.PropertyPermission "os.arch", "read";
-
-    permission java.util.PropertyPermission 
-			"sun.security.mscapi.keyStoreCompatibilityMode", "read";
-
-    permission java.io.FilePermission "<<ALL FILES>>", "read";
-
-    permission java.security.SecurityPermission "putProviderProperty.SunMSCAPI";
-
     // This permission is required for the test to run to completion
     //permission java.security.SecurityPermission "authProvider.SunMSCAPI";
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/CustomizedCipherSuites.java	Mon Aug 15 08:15:02 2016 -0700
@@ -0,0 +1,270 @@
+/*
+ * 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.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8162362
+ * @summary Cannot enable previously default enabled cipher suites
+ * @run main/othervm
+ *      CustomizedCipherSuites Default true
+ *      TLS_RSA_WITH_AES_128_CBC_SHA
+ *      SSL_RSA_WITH_DES_CBC_SHA
+ * @run main/othervm
+ *      -Djdk.tls.client.cipherSuites="unknown"
+ *      CustomizedCipherSuites Default true
+ *      TLS_RSA_WITH_AES_128_CBC_SHA
+ *      SSL_RSA_WITH_DES_CBC_SHA
+ * @run main/othervm
+ *      -Djdk.tls.client.cipherSuites=""
+ *      CustomizedCipherSuites Default true
+ *      TLS_RSA_WITH_AES_128_CBC_SHA
+ *      SSL_RSA_WITH_DES_CBC_SHA
+ * @run main/othervm
+ *      -Djdk.tls.client.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA"
+ *      CustomizedCipherSuites Default true
+ *      SSL_RSA_WITH_DES_CBC_SHA
+ *      TLS_RSA_WITH_AES_128_CBC_SHA
+ * @run main/othervm
+ *      -Djdk.tls.server.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA"
+ *      CustomizedCipherSuites Default false
+ *      SSL_RSA_WITH_DES_CBC_SHA
+ *      TLS_RSA_WITH_AES_128_CBC_SHA
+ * @run main/othervm
+ *      -Djdk.tls.client.cipherSuites="TLS_RSA_WITH_AES_128_CBC_SHA,unknown,SSL_RSA_WITH_DES_CBC_SHA"
+ *      CustomizedCipherSuites Default true
+ *      SSL_RSA_WITH_DES_CBC_SHA
+ *      ""
+ * @run main/othervm
+ *      -Djdk.tls.server.cipherSuites="TLS_RSA_WITH_AES_128_CBC_SHA,unknown,SSL_RSA_WITH_DES_CBC_SHA"
+ *      CustomizedCipherSuites Default false
+ *      TLS_RSA_WITH_AES_128_CBC_SHA
+ *      ""
+ * @run main/othervm
+ *      -Djdk.tls.server.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA"
+ *      CustomizedCipherSuites Default true
+ *      TLS_RSA_WITH_AES_128_CBC_SHA
+ *      SSL_RSA_WITH_DES_CBC_SHA
+ * @run main/othervm
+ *      -Djdk.tls.client.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA"
+ *      CustomizedCipherSuites Default false
+ *      TLS_RSA_WITH_AES_128_CBC_SHA
+ *      SSL_RSA_WITH_DES_CBC_SHA
+ */
+
+import javax.net.ssl.*;
+
+/**
+ * Test the customized default cipher suites.
+ *
+ * This test is based on the behavior that SSL_RSA_WITH_DES_CBC_SHA is
+ * disabled by default, and TLS_RSA_WITH_AES_128_CBC_SHA is enabled by
+ * default in JDK.  If the behavior is changed in the future, please
+ * update the test cases above accordingly.
+ */
+public class CustomizedCipherSuites {
+
+    private static String contextProtocol;
+    private static boolean isClientMode;
+
+    private static String enabledCipherSuite;
+    private static String disabledCipherSuite;
+
+    public static void main(String[] args) throws Exception {
+
+        contextProtocol = trimQuotes(args[0]);
+        isClientMode = Boolean.parseBoolean(args[1]);
+        enabledCipherSuite = trimQuotes(args[2]);
+        disabledCipherSuite = trimQuotes(args[3]);
+
+        //
+        // Create instance of SSLContext with the specified protocol.
+        //
+        SSLContext context = SSLContext.getInstance(contextProtocol);
+
+        // Default SSLContext is initialized automatically.
+        if (!contextProtocol.equals("Default")) {
+            // Use default TK, KM and random.
+            context.init((KeyManager[])null, (TrustManager[])null, null);
+        }
+
+        // SSLContext default parameters is client mode in JDK.
+        if (isClientMode) {
+            //
+            // Check default parameters of the specified SSLContext protocol
+            //
+            SSLParameters parameters = context.getDefaultSSLParameters();
+            System.out.println("Checking SSLContext default parameters ...");
+            checkEnabledCiphers(parameters.getCipherSuites());
+        }
+
+        //
+        // Check supported parameters of the specified SSLContext protocol
+        //
+        SSLParameters parameters = context.getSupportedSSLParameters();
+        System.out.println("Checking SSLContext suppport parameters ...");
+        checkSupportedCiphers(parameters.getCipherSuites());
+
+
+        //
+        // Check the default cipher suites of SSLEngine.
+        //
+        SSLEngine engine = context.createSSLEngine();
+        engine.setUseClientMode(isClientMode);
+
+        System.out.println("Checking SSLEngine default cipher suites ...");
+        checkEnabledCiphers(engine.getEnabledCipherSuites());
+
+        //
+        // Check the supported cipher suites of SSLEngine.
+        //
+        System.out.println("Checking SSLEngine supported cipher suites ...");
+        checkSupportedCiphers(engine.getSupportedCipherSuites());
+
+        if (isClientMode) {
+            SSLSocketFactory factory = context.getSocketFactory();
+            // Use an unconnected socket.
+            try (SSLSocket socket = (SSLSocket)factory.createSocket()) {
+                //
+                // Check the default cipher suites of SSLSocket.
+                //
+                System.out.println(
+                        "Checking SSLSocket default cipher suites ...");
+                checkEnabledCiphers(socket.getEnabledCipherSuites());
+
+                //
+                // Check the supported cipher suites of SSLSocket.
+                //
+                System.out.println(
+                        "Checking SSLSocket supported cipher suites ...");
+                checkSupportedCiphers(socket.getSupportedCipherSuites());
+            }
+        } else {
+            SSLServerSocketFactory factory = context.getServerSocketFactory();
+            // Use an unbound server socket.
+            try (SSLServerSocket socket =
+                    (SSLServerSocket)factory.createServerSocket()) {
+                //
+                // Check the default cipher suites of SSLServerSocket.
+                //
+                System.out.println(
+                        "Checking SSLServerSocket default cipher suites ...");
+                checkEnabledCiphers(socket.getEnabledCipherSuites());
+
+                //
+                // Check the supported cipher suites of SSLServerSocket.
+                //
+                System.out.println(
+                        "Checking SSLServerSocket supported cipher suites ...");
+                checkSupportedCiphers(socket.getSupportedCipherSuites());
+            }
+        }
+
+        System.out.println("\t... Success");
+    }
+
+    private static void checkEnabledCiphers(
+            String[] ciphers) throws Exception {
+
+        if (ciphers.length == 0) {
+            throw new Exception("No default cipher suites");
+        }
+
+        boolean isMatch = false;
+        if (enabledCipherSuite.isEmpty()) {
+            // Don't check if not specify the expected cipher suite.
+            isMatch = true;
+        }
+
+        boolean isBroken = false;
+        for (String cipher : ciphers) {
+            System.out.println("\tdefault cipher suite " + cipher);
+            if (!enabledCipherSuite.isEmpty() &&
+                        cipher.equals(enabledCipherSuite)) {
+                isMatch = true;
+            }
+
+            if (!disabledCipherSuite.isEmpty() &&
+                        cipher.equals(disabledCipherSuite)) {
+                isBroken = true;
+            }
+        }
+
+        if (!isMatch) {
+            throw new Exception(
+                "Cipher suite " + enabledCipherSuite + " should be enabled");
+        }
+
+        if (isBroken) {
+            throw new Exception(
+                "Cipher suite " + disabledCipherSuite + " should be disabled");
+        }
+    }
+
+    private static void checkSupportedCiphers(
+            String[] ciphers) throws Exception {
+
+        if (ciphers.length == 0) {
+            throw new Exception("No supported cipher suites");
+        }
+
+        boolean hasEnabledCipherSuite = enabledCipherSuite.isEmpty();
+        boolean hasDisabledCipherSuite = disabledCipherSuite.isEmpty();
+        for (String cipher : ciphers) {
+            System.out.println("\tsupported cipher suite " + cipher);
+            if (!enabledCipherSuite.isEmpty() &&
+                        cipher.equals(enabledCipherSuite)) {
+                hasEnabledCipherSuite = true;
+            }
+
+            if (!disabledCipherSuite.isEmpty() &&
+                        cipher.equals(disabledCipherSuite)) {
+                hasDisabledCipherSuite = true;
+            }
+        }
+
+        if (!hasEnabledCipherSuite) {
+            throw new Exception(
+                "Cipher suite " + enabledCipherSuite + " should be supported");
+        }
+
+        if (!hasDisabledCipherSuite) {
+            throw new Exception(
+                "Cipher suite " + disabledCipherSuite + " should be supported");
+        }
+    }
+
+    private static String trimQuotes(String candidate) {
+        if (candidate != null && candidate.length() != 0) {
+            // Remove double quote marks from beginning/end of the string.
+            if (candidate.length() > 1 && candidate.charAt(0) == '"' &&
+                    candidate.charAt(candidate.length() - 1) == '"') {
+                return candidate.substring(1, candidate.length() - 1);
+            }
+        }
+
+        return candidate;
+    }
+}