Merge
authorddehaven
Wed, 24 Feb 2016 08:58:31 -0800
changeset 36460 44903b87cbf5
parent 36459 a34194491737 (current diff)
parent 36127 2f5428e9e415 (diff)
child 36461 a66465d5a442
Merge
jdk/src/java.base/share/native/libjava/Bits.c
--- a/jdk/make/lib/CoreLibraries.gmk	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/make/lib/CoreLibraries.gmk	Wed Feb 24 08:58:31 2016 -0800
@@ -137,12 +137,6 @@
   endif
 endif
 
-ifeq ($(OPENJDK_TARGET_OS), linux)
-  ifeq ($(OPENJDK_TARGET_CPU), x86_64)
-    BUILD_LIBJAVA_Bits.c_CFLAGS := $(C_O_FLAG_NORM)
-  endif
-endif
-
 $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
     LIBRARY := java, \
     OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
@@ -225,7 +219,7 @@
         $(call SET_SHARED_LIBRARY_ORIGIN), \
     LDFLAGS_windows := -export:ZIP_Open -export:ZIP_Close -export:ZIP_FindEntry \
         -export:ZIP_ReadEntry -export:ZIP_GetNextEntry \
-        -export:ZIP_InflateFully, \
+        -export:ZIP_InflateFully -export:ZIP_CRC32, \
     LIBS_unix := -ljvm -ljava $(LIBZ), \
     LIBS_solaris := -lc, \
     LIBS_windows := jvm.lib $(WIN_JAVA_LIB), \
--- a/jdk/make/mapfiles/libjava/mapfile-vers	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/make/mapfiles/libjava/mapfile-vers	Wed Feb 24 08:58:31 2016 -0800
@@ -229,12 +229,6 @@
 		Java_java_lang_Throwable_fillInStackTrace;
                 Java_java_lang_Throwable_getStackTraceDepth;
                 Java_java_lang_Throwable_getStackTraceElement;
-                Java_java_nio_Bits_copyFromShortArray;
-                Java_java_nio_Bits_copyToShortArray;
-                Java_java_nio_Bits_copyFromIntArray;
-                Java_java_nio_Bits_copyToIntArray;
-                Java_java_nio_Bits_copyFromLongArray;
-                Java_java_nio_Bits_copyToLongArray;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2;
--- a/jdk/make/mapfiles/libnet/mapfile-vers	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/make/mapfiles/libnet/mapfile-vers	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -87,6 +87,9 @@
 		Java_java_net_PlainSocketImpl_socketConnect;
 		Java_java_net_PlainDatagramSocketImpl_getTimeToLive;
 		Java_java_net_PlainDatagramSocketImpl_setTimeToLive;
+                Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0;
+                Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0;
+                Java_jdk_net_Sockets_isReusePortAvailable0;
 		Java_sun_net_PortConfig_getUpper0;
 		Java_sun_net_PortConfig_getLower0;
 		Java_sun_net_dns_ResolverConfigurationImpl_localDomain0;
@@ -112,6 +115,7 @@
 		NET_EnableFastTcpLoopback;
 		NET_ThrowNew;
                 ipv6_available;
+                reuseport_available;
                 initInetAddressIDs;
 
 	local:
--- a/jdk/make/mapfiles/libnio/mapfile-linux	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/make/mapfiles/libnio/mapfile-linux	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -109,6 +109,7 @@
 		Java_sun_nio_ch_Net_setIntOption0;
                 Java_sun_nio_ch_Net_initIDs;
 		Java_sun_nio_ch_Net_isIPv6Available0;
+                Java_sun_nio_ch_Net_isReusePortAvailable0;
 		Java_sun_nio_ch_Net_joinOrDrop4;
 		Java_sun_nio_ch_Net_blockOrUnblock4;
 		Java_sun_nio_ch_Net_joinOrDrop6;
--- a/jdk/make/mapfiles/libnio/mapfile-macosx	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/make/mapfiles/libnio/mapfile-macosx	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -102,6 +102,7 @@
 		Java_sun_nio_ch_Net_setIntOption0;
                 Java_sun_nio_ch_Net_initIDs;
 		Java_sun_nio_ch_Net_isIPv6Available0;
+                Java_sun_nio_ch_Net_isReusePortAvailable0;
 		Java_sun_nio_ch_Net_joinOrDrop4;
 		Java_sun_nio_ch_Net_blockOrUnblock4;
 		Java_sun_nio_ch_Net_joinOrDrop6;
--- a/jdk/make/mapfiles/libnio/mapfile-solaris	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/make/mapfiles/libnio/mapfile-solaris	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -97,6 +97,7 @@
 		Java_sun_nio_ch_Net_setIntOption0;
                 Java_sun_nio_ch_Net_initIDs;
 		Java_sun_nio_ch_Net_isIPv6Available0;
+                Java_sun_nio_ch_Net_isReusePortAvailable0;
 		Java_sun_nio_ch_Net_joinOrDrop4;
 		Java_sun_nio_ch_Net_blockOrUnblock4;
 		Java_sun_nio_ch_Net_joinOrDrop6;
--- a/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java	Wed Feb 24 08:58:31 2016 -0800
@@ -248,10 +248,7 @@
             dir.mkdirs();
         }
         String className =
-            (CLDRConverter.isBaseModule ? "CLDRBaseLocaleDataMetaInfo" :
-                "CLDRLocaleDataMetaInfo_" +
-                CLDRConverter.DESTINATION_DIR.substring(CLDRConverter.DESTINATION_DIR.lastIndexOf('/')+1)
-                    .replaceAll("\\.", "_"));
+            (CLDRConverter.isBaseModule ? "CLDRBaseLocaleDataMetaInfo" : "CLDRLocaleDataMetaInfo");
         File file = new File(dir, className + ".java");
         if (!file.exists()) {
             file.createNewFile();
--- a/jdk/make/src/native/genconstants/ch/genSocketOptionRegistry.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/make/src/native/genconstants/ch/genSocketOptionRegistry.c	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,21 @@
 #include <netinet/tcp.h>
 #endif
 
+/* Defines SO_REUSEPORT */
+#if !defined(SO_REUSEPORT)
+#ifdef _WIN32
+#define SO_REUSEPORT 0
+#elif __linux__
+#define SO_REUSEPORT 15
+#elif __solaris__
+#define SO_REUSEPORT 0x100e
+#elif defined(AIX) || defined(MACOSX)
+#define SO_REUSEPORT 0x0200
+#else
+#define SO_REUSEPORT 0
+#endif
+#endif
+
 /**
  * Generates sun.nio.ch.SocketOptionRegistry, a class that maps Java-level
  * socket options to the platform specific level and option.
@@ -102,6 +117,7 @@
     emit_unspec("StandardSocketOptions.SO_SNDBUF",    SOL_SOCKET, SO_SNDBUF);
     emit_unspec("StandardSocketOptions.SO_RCVBUF",    SOL_SOCKET, SO_RCVBUF);
     emit_unspec("StandardSocketOptions.SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR);
+    emit_unspec("StandardSocketOptions.SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT);
     emit_unspec("StandardSocketOptions.TCP_NODELAY",  IPPROTO_TCP, TCP_NODELAY);
 
     emit_inet("StandardSocketOptions.IP_TOS",            IPPROTO_IP,     IP_TOS);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -778,8 +778,21 @@
             return (asTypeCache = wrapper);
         }
 
+        // Customize target if counting happens for too long.
+        private int invocations = CUSTOMIZE_THRESHOLD;
+        private void maybeCustomizeTarget() {
+            int c = invocations;
+            if (c >= 0) {
+                if (c == 1) {
+                    target.customize();
+                }
+                invocations = c - 1;
+            }
+        }
+
         boolean countDown() {
             int c = count;
+            maybeCustomizeTarget();
             if (c <= 1) {
                 // Try to limit number of updates. MethodHandle.updateForm() doesn't guarantee LF update visibility.
                 if (isCounting) {
--- a/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,9 @@
 import java.io.IOException;
 import java.security.AccessController;
 import sun.net.ResourceManager;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
 
 /**
  * Abstract datagram and multicast socket implementation base class.
@@ -70,6 +73,45 @@
             });
     }
 
+    private static volatile boolean checkedReusePort;
+    private static volatile boolean isReusePortAvailable;
+
+    /**
+     * Tells whether SO_REUSEPORT is supported.
+     */
+    static boolean isReusePortAvailable() {
+        if (!checkedReusePort) {
+            isReusePortAvailable = isReusePortAvailable0();
+            checkedReusePort = true;
+        }
+        return isReusePortAvailable;
+    }
+
+    private static volatile Set<SocketOption<?>> socketOptions;
+
+    /**
+     * Returns a set of SocketOptions supported by this impl
+     * and by this impl's socket (Socket or ServerSocket)
+     *
+     * @return a Set of SocketOptions
+     */
+    @Override
+    protected Set<SocketOption<?>> supportedOptions() {
+        Set<SocketOption<?>> options = socketOptions;
+        if (options == null) {
+            if (isReusePortAvailable()) {
+                options = new HashSet<>();
+                options.addAll(super.supportedOptions());
+                options.add(StandardSocketOptions.SO_REUSEPORT);
+                options = Collections.unmodifiableSet(options);
+            } else {
+                options = super.supportedOptions();
+            }
+            socketOptions = options;
+        }
+        return options;
+    }
+
     /**
      * Creates a datagram socket
      */
@@ -303,6 +345,14 @@
              if (o == null || !(o instanceof Boolean))
                  throw new SocketException("bad argument for IP_MULTICAST_LOOP");
              break;
+         case SO_REUSEPORT:
+             if (o == null || !(o instanceof Boolean)) {
+                 throw new SocketException("bad argument for SO_REUSEPORT");
+             }
+             if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+                 throw new UnsupportedOperationException("unsupported option");
+             }
+             break;
          default:
              throw new SocketException("invalid option: " + optID);
          }
@@ -343,6 +393,13 @@
                 result = socketGetOption(optID);
                 break;
 
+            case SO_REUSEPORT:
+                if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+                    throw new UnsupportedOperationException("unsupported option");
+                }
+                result = socketGetOption(optID);
+                break;
+
             default:
                 throw new SocketException("invalid option: " + optID);
         }
@@ -364,4 +421,5 @@
     }
 
     abstract int dataAvailable();
+    private static native boolean isReusePortAvailable0();
 }
--- a/jdk/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2013, 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
@@ -33,6 +33,9 @@
 import sun.net.ConnectionResetException;
 import sun.net.NetHooks;
 import sun.net.ResourceManager;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
 
 /**
  * Default Socket Implementation. This implementation does
@@ -87,6 +90,45 @@
             });
     }
 
+    private static volatile boolean checkedReusePort;
+    private static volatile boolean isReusePortAvailable;
+
+    /**
+     * Tells whether SO_REUSEPORT is supported.
+     */
+    static boolean isReusePortAvailable() {
+        if (!checkedReusePort) {
+            isReusePortAvailable = isReusePortAvailable0();
+            checkedReusePort = true;
+        }
+        return isReusePortAvailable;
+    }
+
+    private static volatile Set<SocketOption<?>> socketOptions;
+
+   /**
+    * Returns a set of SocketOptions supported by this impl
+    * and by this impl's socket (Socket or ServerSocket)
+    *
+    * @return a Set of SocketOptions
+    */
+    @Override
+    protected Set<SocketOption<?>> supportedOptions() {
+        Set<SocketOption<?>> options = socketOptions;
+        if (options == null) {
+            if (isReusePortAvailable()) {
+                options = new HashSet<>();
+                options.addAll(super.supportedOptions());
+                options.add(StandardSocketOptions.SO_REUSEPORT);
+                options = Collections.unmodifiableSet(options);
+            } else {
+                options = super.supportedOptions();
+            }
+            socketOptions = options;
+        }
+        return options;
+    }
+
     /**
      * Creates a socket with a boolean that specifies whether this
      * is a stream socket (true) or an unconnected UDP socket (false).
@@ -269,6 +311,13 @@
                 throw new SocketException("bad parameter for SO_REUSEADDR");
             on = ((Boolean)val).booleanValue();
             break;
+        case SO_REUSEPORT:
+            if (val == null || !(val instanceof Boolean))
+                throw new SocketException("bad parameter for SO_REUSEPORT");
+            if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT))
+                throw new UnsupportedOperationException("unsupported option");
+            on = ((Boolean)val).booleanValue();
+            break;
         default:
             throw new SocketException("unrecognized TCP option: " + opt);
         }
@@ -326,6 +375,12 @@
         case SO_KEEPALIVE:
             ret = socketGetOption(opt, null);
             return Boolean.valueOf(ret != -1);
+        case SO_REUSEPORT:
+            if (!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+                throw new UnsupportedOperationException("unsupported option");
+            }
+            ret = socketGetOption(opt, null);
+            return Boolean.valueOf(ret != -1);
         // should never get here
         default:
             return null;
@@ -723,4 +778,6 @@
 
     public static final int SHUT_RD = 0;
     public static final int SHUT_WR = 1;
+
+    private static native boolean isReusePortAvailable0();
 }
--- a/jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -287,6 +287,9 @@
             setOption(SocketOptions.SO_RCVBUF, value);
         } else if (name == StandardSocketOptions.SO_REUSEADDR) {
             setOption(SocketOptions.SO_REUSEADDR, value);
+        } else if (name == StandardSocketOptions.SO_REUSEPORT &&
+            supportedOptions().contains(name)) {
+            setOption(SocketOptions.SO_REUSEPORT, value);
         } else if (name == StandardSocketOptions.IP_TOS) {
             setOption(SocketOptions.IP_TOS, value);
         } else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
@@ -329,6 +332,9 @@
             return (T) getOption(SocketOptions.SO_RCVBUF);
         } else if (name == StandardSocketOptions.SO_REUSEADDR) {
             return (T) getOption(SocketOptions.SO_REUSEADDR);
+        } else if (name == StandardSocketOptions.SO_REUSEPORT &&
+            supportedOptions().contains(name)) {
+            return (T) getOption(SocketOptions.SO_REUSEPORT);
         } else if (name == StandardSocketOptions.IP_TOS) {
             return (T) getOption(SocketOptions.IP_TOS);
         } else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
--- a/jdk/src/java.base/share/classes/java/net/MulticastSocket.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/MulticastSocket.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,11 @@
      * <p>
      * When the socket is created the
      * {@link DatagramSocket#setReuseAddress(boolean)} method is
-     * called to enable the SO_REUSEADDR socket option.
+     * called to enable the SO_REUSEADDR socket option. When
+     * {@link StandardSocketOptions#SO_REUSEPORT SO_REUSEPORT} is
+     * supported then
+     * {@link DatagramSocketImpl#setOption(SocketOption, Object)}
+     * is called to enable the socket option.
      *
      * @exception IOException if an I/O exception occurs
      * while creating the MulticastSocket
@@ -106,6 +110,7 @@
      *             {@code checkListen} method doesn't allow the operation.
      * @see SecurityManager#checkListen
      * @see java.net.DatagramSocket#setReuseAddress(boolean)
+     * @see java.net.DatagramSocketImpl#setOption(SocketOption, Object)
      */
     public MulticastSocket() throws IOException {
         this(new InetSocketAddress(0));
@@ -167,6 +172,11 @@
         // Enable SO_REUSEADDR before binding
         setReuseAddress(true);
 
+        // Enable SO_REUSEPORT if supported before binding
+        if (supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+            this.setOption(StandardSocketOptions.SO_REUSEPORT, true);
+        }
+
         if (bindaddr != null) {
             try {
                 bind(bindaddr);
--- a/jdk/src/java.base/share/classes/java/net/SocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/SocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -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
@@ -386,6 +386,9 @@
             setOption(SocketOptions.SO_RCVBUF, value);
         } else if (name == StandardSocketOptions.SO_REUSEADDR) {
             setOption(SocketOptions.SO_REUSEADDR, value);
+        } else if (name == StandardSocketOptions.SO_REUSEPORT &&
+            supportedOptions().contains(name)) {
+            setOption(SocketOptions.SO_REUSEPORT, value);
         } else if (name == StandardSocketOptions.SO_LINGER &&
                 (getSocket() != null)) {
             setOption(SocketOptions.SO_LINGER, value);
@@ -426,6 +429,9 @@
             return (T)getOption(SocketOptions.SO_RCVBUF);
         } else if (name == StandardSocketOptions.SO_REUSEADDR) {
             return (T)getOption(SocketOptions.SO_REUSEADDR);
+        } else if (name == StandardSocketOptions.SO_REUSEPORT &&
+            supportedOptions().contains(name)) {
+            return (T)getOption(SocketOptions.SO_REUSEPORT);
         } else if (name == StandardSocketOptions.SO_LINGER &&
                 (getSocket() != null)) {
             return (T)getOption(SocketOptions.SO_LINGER);
--- a/jdk/src/java.base/share/classes/java/net/SocketOptions.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/SocketOptions.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -170,6 +170,17 @@
 
     @Native public static final int SO_REUSEADDR = 0x04;
 
+    /** Sets SO_REUSEPORT for a socket. This option enables and disables
+     *  the ability to have multiple sockets listen to the same address
+     *  and port.
+     * <P>
+     * Valid for: SocketImpl, DatagramSocketImpl
+     *
+     * @since 9
+     * @see StandardSocketOptions#SO_REUSEPORT
+     */
+    @Native public static final int SO_REUSEPORT = 0x0E;
+
     /**
      * Sets SO_BROADCAST for a socket. This option enables and disables
      * the ability of the process to send broadcast messages. It is supported
--- a/jdk/src/java.base/share/classes/java/net/StandardSocketOptions.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/StandardSocketOptions.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -187,6 +187,29 @@
         new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
 
     /**
+     * Re-use port.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. The exact semantics of this
+     * socket option are socket type and system dependent.
+     *
+     * <p> In the case of stream-oriented sockets, this socket option usually allows
+     * multiple listening sockets to be bound to both same address
+     * and same port.
+     *
+     * <p> For datagram-oriented sockets the socket option usually allows
+     * multiple UDP sockets to be bound to the same address and port.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Changing the value of this socket option
+     * after the socket is bound has no effect.
+     *
+     * @since 9
+     */
+    public static final SocketOption<Boolean> SO_REUSEPORT =
+        new StdSocketOption<Boolean>("SO_REUSEPORT", Boolean.class);
+
+    /**
      * Linger on close if data is present.
      *
      * <p> The value of this socket option is an {@code Integer} that controls
--- a/jdk/src/java.base/share/classes/java/nio/Bits.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/nio/Bits.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -807,31 +807,131 @@
         }
     }
 
-    static void copyFromCharArray(Object src, long srcPos, long dstAddr,
-                                  long length)
-    {
-        copyFromShortArray(src, srcPos, dstAddr, length);
+    /**
+     * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory
+     *
+     * @param src
+     *        the source array, must be a 16-bit primitive array type
+     * @param srcPos
+     *        byte offset within source array of the first element to read
+     * @param dstAddr
+     *        destination address
+     * @param length
+     *        number of bytes to copy
+     */
+    static void copyFromCharArray(Object src, long srcPos, long dstAddr, long length) {
+        unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2);
     }
 
-    static void copyToCharArray(long srcAddr, Object dst, long dstPos,
-                                long length)
-    {
-        copyToShortArray(srcAddr, dst, dstPos, length);
+    /**
+     * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array
+     *
+     * @param srcAddr
+     *        source address
+     * @param dst
+     *        destination array, must be a 16-bit primitive array type
+     * @param dstPos
+     *        byte offset within the destination array of the first element to write
+     * @param length
+     *        number of bytes to copy
+     */
+    static void copyToCharArray(long srcAddr, Object dst, long dstPos, long length) {
+        unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2);
+    }
+
+    /**
+     * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory
+     *
+     * @param src
+     *        the source array, must be a 16-bit primitive array type
+     * @param srcPos
+     *        byte offset within source array of the first element to read
+     * @param dstAddr
+     *        destination address
+     * @param length
+     *        number of bytes to copy
+     */
+    static void copyFromShortArray(Object src, long srcPos, long dstAddr, long length) {
+        unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2);
+    }
+
+    /**
+     * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array
+     *
+     * @param srcAddr
+     *        source address
+     * @param dst
+     *        destination array, must be a 16-bit primitive array type
+     * @param dstPos
+     *        byte offset within the destination array of the first element to write
+     * @param length
+     *        number of bytes to copy
+     */
+    static void copyToShortArray(long srcAddr, Object dst, long dstPos, long length) {
+        unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2);
     }
 
-    static native void copyFromShortArray(Object src, long srcPos, long dstAddr,
-                                          long length);
-    static native void copyToShortArray(long srcAddr, Object dst, long dstPos,
-                                        long length);
+    /**
+     * Copy and unconditionally byte swap 32 bit elements from a heap array to off-heap memory
+     *
+     * @param src
+     *        the source array, must be a 32-bit primitive array type
+     * @param srcPos
+     *        byte offset within source array of the first element to read
+     * @param dstAddr
+     *        destination address
+     * @param length
+     *        number of bytes to copy
+     */
+    static void copyFromIntArray(Object src, long srcPos, long dstAddr, long length) {
+        unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 4);
+    }
+
+    /**
+     * Copy and unconditionally byte swap 32 bit elements from off-heap memory to a heap array
+     *
+     * @param srcAddr
+     *        source address
+     * @param dst
+     *        destination array, must be a 32-bit primitive array type
+     * @param dstPos
+     *        byte offset within the destination array of the first element to write
+     * @param length
+     *        number of bytes to copy
+     */
+    static void copyToIntArray(long srcAddr, Object dst, long dstPos, long length) {
+        unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 4);
+    }
 
-    static native void copyFromIntArray(Object src, long srcPos, long dstAddr,
-                                        long length);
-    static native void copyToIntArray(long srcAddr, Object dst, long dstPos,
-                                      long length);
+    /**
+     * Copy and unconditionally byte swap 64 bit elements from a heap array to off-heap memory
+     *
+     * @param src
+     *        the source array, must be a 64-bit primitive array type
+     * @param srcPos
+     *        byte offset within source array of the first element to read
+     * @param dstAddr
+     *        destination address
+     * @param length
+     *        number of bytes to copy
+     */
+    static void copyFromLongArray(Object src, long srcPos, long dstAddr, long length) {
+        unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 8);
+    }
 
-    static native void copyFromLongArray(Object src, long srcPos, long dstAddr,
-                                         long length);
-    static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
-                                       long length);
-
+    /**
+     * Copy and unconditionally byte swap 64 bit elements from off-heap memory to a heap array
+     *
+     * @param srcAddr
+     *        source address
+     * @param dst
+     *        destination array, must be a 64-bit primitive array type
+     * @param dstPos
+     *        byte offset within the destination array of the first element to write
+     * @param length
+     *        number of bytes to copy
+     */
+    static void copyToLongArray(long srcAddr, Object dst, long dstPos, long length) {
+        unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 8);
+    }
 }
--- a/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/javax/crypto/JceSecurity.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, 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
@@ -64,8 +64,7 @@
     private static final Map<Provider, Object> verifyingProviders =
             new IdentityHashMap<>();
 
-    // Set the default value. May be changed in the static initializer.
-    private static boolean isRestricted = true;
+    private static final boolean isRestricted;
 
     /*
      * Don't let anyone instantiate this.
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/Signal.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Signal.java	Wed Feb 24 08:58:31 2016 -0800
@@ -279,6 +279,11 @@
         public void handle(Signal sig) {
             throw new UnsupportedOperationException("invoking native signal handle not supported");
         }
+
+        public String toString() {
+            return this == SIG_DFL ? "SIG_DFL" :
+                    (this == SIG_IGN ? "SIG_IGN" : super.toString());
+        }
     }
 
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -458,6 +458,78 @@
         copyMemory(null, srcAddress, null, destAddress, bytes);
     }
 
+    private boolean isPrimitiveArray(Class<?> c) {
+        Class<?> componentType = c.getComponentType();
+        return componentType != null && componentType.isPrimitive();
+    }
+
+    private native void copySwapMemory0(Object srcBase, long srcOffset,
+                                        Object destBase, long destOffset,
+                                        long bytes, long elemSize);
+
+    /**
+     * Copies all elements from one block of memory to another block,
+     * *unconditionally* byte swapping the elements on the fly.
+     *
+     * <p>This method determines each block's base address by means of two parameters,
+     * and so it provides (in effect) a <em>double-register</em> addressing mode,
+     * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
+     * the offset supplies an absolute base address.
+     *
+     * @since 9
+     */
+    public void copySwapMemory(Object srcBase, long srcOffset,
+                               Object destBase, long destOffset,
+                               long bytes, long elemSize) {
+        if (bytes < 0) {
+            throw new IllegalArgumentException();
+        }
+        if (elemSize != 2 && elemSize != 4 && elemSize != 8) {
+            throw new IllegalArgumentException();
+        }
+        if (bytes % elemSize != 0) {
+            throw new IllegalArgumentException();
+        }
+        if ((srcBase == null && srcOffset == 0) ||
+            (destBase == null && destOffset == 0)) {
+            throw new NullPointerException();
+        }
+
+        // Must be off-heap, or primitive heap arrays
+        if (srcBase != null && (srcOffset < 0 || !isPrimitiveArray(srcBase.getClass()))) {
+            throw new IllegalArgumentException();
+        }
+        if (destBase != null && (destOffset < 0 || !isPrimitiveArray(destBase.getClass()))) {
+            throw new IllegalArgumentException();
+        }
+
+        // Sanity check size and offsets on 32-bit platforms. Most
+        // significant 32 bits must be zero.
+        if (ADDRESS_SIZE == 4 &&
+            (bytes >>> 32 != 0 || srcOffset >>> 32 != 0 || destOffset >>> 32 != 0)) {
+            throw new IllegalArgumentException();
+        }
+
+        if (bytes == 0) {
+            return;
+        }
+
+        copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize);
+    }
+
+   /**
+     * Copies all elements from one block of memory to another block, byte swapping the
+     * elements on the fly.
+     *
+     * This provides a <em>single-register</em> addressing mode, as
+     * discussed in {@link #getInt(Object,long)}.
+     *
+     * Equivalent to {@code copySwapMemory(null, srcAddress, null, destAddress, bytes, elemSize)}.
+     */
+    public void copySwapMemory(long srcAddress, long destAddress, long bytes, long elemSize) {
+        copySwapMemory(null, srcAddress, null, destAddress, bytes, elemSize);
+    }
+
     /**
      * Disposes of a block of native memory, as obtained from {@link
      * #allocateMemory} or {@link #reallocateMemory}.  The address passed to
@@ -1159,7 +1231,12 @@
     /** @see #getLongUnaligned(Object, long) */
     @HotSpotIntrinsicCandidate
     public final char getCharUnaligned(Object o, long offset) {
-        return (char)getShortUnaligned(o, offset);
+        if ((offset & 1) == 0) {
+            return getChar(o, offset);
+        } else {
+            return (char)makeShort(getByte(o, offset),
+                                   getByte(o, offset + 1));
+        }
     }
 
     /** @see #getLongUnaligned(Object, long, boolean) */
--- a/jdk/src/java.base/share/classes/jdk/net/Sockets.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/jdk/net/Sockets.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -251,9 +251,23 @@
         }
     }
 
+    private static volatile boolean checkedReusePort;
+    private static volatile boolean isReusePortAvailable;
+
+    /**
+     * Tells whether SO_REUSEPORT is supported.
+     */
+    static boolean isReusePortAvailable() {
+        if (!checkedReusePort) {
+            isReusePortAvailable = isReusePortAvailable0();
+            checkedReusePort = true;
+        }
+        return isReusePortAvailable;
+    }
+
     private static void initOptionSets() {
         boolean flowsupported = ExtendedOptionsImpl.flowSupported();
-
+        boolean reuseportsupported = isReusePortAvailable();
         // Socket
 
         Set<SocketOption<?>> set = new HashSet<>();
@@ -261,6 +275,9 @@
         set.add(StandardSocketOptions.SO_SNDBUF);
         set.add(StandardSocketOptions.SO_RCVBUF);
         set.add(StandardSocketOptions.SO_REUSEADDR);
+        if (reuseportsupported) {
+            set.add(StandardSocketOptions.SO_REUSEPORT);
+        }
         set.add(StandardSocketOptions.SO_LINGER);
         set.add(StandardSocketOptions.IP_TOS);
         set.add(StandardSocketOptions.TCP_NODELAY);
@@ -275,6 +292,9 @@
         set = new HashSet<>();
         set.add(StandardSocketOptions.SO_RCVBUF);
         set.add(StandardSocketOptions.SO_REUSEADDR);
+        if (reuseportsupported) {
+            set.add(StandardSocketOptions.SO_REUSEPORT);
+        }
         set.add(StandardSocketOptions.IP_TOS);
         set = Collections.unmodifiableSet(set);
         options.put(ServerSocket.class, set);
@@ -285,6 +305,9 @@
         set.add(StandardSocketOptions.SO_SNDBUF);
         set.add(StandardSocketOptions.SO_RCVBUF);
         set.add(StandardSocketOptions.SO_REUSEADDR);
+        if (reuseportsupported) {
+            set.add(StandardSocketOptions.SO_REUSEPORT);
+        }
         set.add(StandardSocketOptions.IP_TOS);
         if (flowsupported) {
             set.add(ExtendedSocketOptions.SO_FLOW_SLA);
@@ -298,6 +321,9 @@
         set.add(StandardSocketOptions.SO_SNDBUF);
         set.add(StandardSocketOptions.SO_RCVBUF);
         set.add(StandardSocketOptions.SO_REUSEADDR);
+        if (reuseportsupported) {
+            set.add(StandardSocketOptions.SO_REUSEPORT);
+        }
         set.add(StandardSocketOptions.IP_TOS);
         set.add(StandardSocketOptions.IP_MULTICAST_IF);
         set.add(StandardSocketOptions.IP_MULTICAST_TTL);
@@ -308,4 +334,6 @@
         set = Collections.unmodifiableSet(set);
         options.put(MulticastSocket.class, set);
     }
+
+    private static native boolean isReusePortAvailable0();
 }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -231,6 +231,9 @@
             HashSet<SocketOption<?>> set = new HashSet<>(2);
             set.add(StandardSocketOptions.SO_RCVBUF);
             set.add(StandardSocketOptions.SO_REUSEADDR);
+            if (Net.isReusePortAvailable()) {
+                set.add(StandardSocketOptions.SO_REUSEPORT);
+            }
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -508,6 +508,9 @@
             set.add(StandardSocketOptions.SO_RCVBUF);
             set.add(StandardSocketOptions.SO_KEEPALIVE);
             set.add(StandardSocketOptions.SO_REUSEADDR);
+            if (Net.isReusePortAvailable()) {
+                set.add(StandardSocketOptions.SO_REUSEPORT);
+            }
             set.add(StandardSocketOptions.TCP_NODELAY);
             if (ExtendedOptionsImpl.flowSupported()) {
                 set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -298,6 +298,9 @@
             set.add(StandardSocketOptions.SO_SNDBUF);
             set.add(StandardSocketOptions.SO_RCVBUF);
             set.add(StandardSocketOptions.SO_REUSEADDR);
+            if (Net.isReusePortAvailable()) {
+                set.add(StandardSocketOptions.SO_REUSEPORT);
+            }
             set.add(StandardSocketOptions.SO_BROADCAST);
             set.add(StandardSocketOptions.IP_TOS);
             set.add(StandardSocketOptions.IP_MULTICAST_IF);
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,8 @@
 
     private static volatile boolean checkedIPv6;
     private static volatile boolean isIPv6Available;
+    private static volatile boolean checkedReusePort;
+    private static volatile boolean isReusePortAvailable;
 
     /**
      * Tells whether dual-IPv4/IPv6 sockets should be used.
@@ -69,6 +71,17 @@
     }
 
     /**
+     * Tells whether SO_REUSEPORT is supported.
+     */
+    static boolean isReusePortAvailable() {
+        if (!checkedReusePort) {
+            isReusePortAvailable = isReusePortAvailable0();
+            checkedReusePort = true;
+        }
+        return isReusePortAvailable;
+    }
+
+    /**
      * Returns true if exclusive binding is on
      */
     static boolean useExclusiveBind() {
@@ -389,6 +402,8 @@
 
     private static native boolean isIPv6Available0();
 
+    private static native boolean isReusePortAvailable0();
+
     /*
      * Returns 1 for Windows and -1 for Solaris/Linux/Mac OS
      */
--- a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,6 @@
 import java.util.*;
 import sun.net.NetHooks;
 
-
 /**
  * An implementation of ServerSocketChannels
  */
@@ -185,6 +184,9 @@
             HashSet<SocketOption<?>> set = new HashSet<>(2);
             set.add(StandardSocketOptions.SO_RCVBUF);
             set.add(StandardSocketOptions.SO_REUSEADDR);
+            if (Net.isReusePortAvailable()) {
+                set.add(StandardSocketOptions.SO_REUSEPORT);
+            }
             set.add(StandardSocketOptions.IP_TOS);
             return Collections.unmodifiableSet(set);
         }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -234,6 +234,9 @@
             set.add(StandardSocketOptions.SO_RCVBUF);
             set.add(StandardSocketOptions.SO_KEEPALIVE);
             set.add(StandardSocketOptions.SO_REUSEADDR);
+            if (Net.isReusePortAvailable()) {
+                set.add(StandardSocketOptions.SO_REUSEPORT);
+            }
             set.add(StandardSocketOptions.SO_LINGER);
             set.add(StandardSocketOptions.TCP_NODELAY);
             // additional options required by socket adaptor
--- a/jdk/src/java.base/share/native/libjava/Bits.c	Wed Feb 24 14:36:53 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jlong.h"
-#include <string.h>
-
-#define MBYTE 1048576
-
-#define GETCRITICAL_OR_RETURN(bytes, env, obj) { \
-    bytes = (*env)->GetPrimitiveArrayCritical(env, obj, NULL); \
-    if (bytes == NULL)  { \
-        if ((*env)->ExceptionOccurred(env) == NULL) \
-            JNU_ThrowInternalError(env, "Unable to get array"); \
-        return; \
-    } \
-}
-
-#define RELEASECRITICAL(bytes, env, obj, mode) { \
-    (*env)->ReleasePrimitiveArrayCritical(env, obj, bytes, mode); \
-}
-
-#define SWAPSHORT(x) ((jshort)(((x) << 8) | (((x) >> 8) & 0xff)))
-#define SWAPINT(x)   ((jint)((SWAPSHORT((jshort)(x)) << 16) | \
-                            (SWAPSHORT((jshort)((x) >> 16)) & 0xffff)))
-#define SWAPLONG(x)  ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \
-                              ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff)))
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jclass clazz, jobject src,
-                                      jlong srcPos, jlong dstAddr, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jshort *srcShort, *dstShort, *endShort;
-    jshort tmpShort;
-
-    dstShort = (jshort *)jlong_to_ptr(dstAddr);
-
-    while (length > 0) {
-        size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
-
-        GETCRITICAL_OR_RETURN(bytes, env, src);
-
-        srcShort = (jshort *)(bytes + srcPos);
-        endShort = srcShort + (size / sizeof(jshort));
-        while (srcShort < endShort) {
-          tmpShort = *srcShort++;
-          *dstShort++ = SWAPSHORT(tmpShort);
-        }
-
-        RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
-        length -= size;
-        srcPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jclass clazz, jlong srcAddr,
-                                    jobject dst, jlong dstPos, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jshort *srcShort, *dstShort, *endShort;
-    jshort tmpShort;
-
-    srcShort = (jshort *)jlong_to_ptr(srcAddr);
-
-    while (length > 0) {
-        size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
-
-        GETCRITICAL_OR_RETURN(bytes, env, dst);
-
-        dstShort = (jshort *)(bytes + dstPos);
-        endShort = srcShort + (size / sizeof(jshort));
-        while (srcShort < endShort) {
-            tmpShort = *srcShort++;
-            *dstShort++ = SWAPSHORT(tmpShort);
-        }
-
-        RELEASECRITICAL(bytes, env, dst, 0);
-
-        length -= size;
-        dstPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jclass clazz, jobject src,
-                                    jlong srcPos, jlong dstAddr, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jint *srcInt, *dstInt, *endInt;
-    jint tmpInt;
-
-    dstInt = (jint *)jlong_to_ptr(dstAddr);
-
-    while (length > 0) {
-        size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
-
-        GETCRITICAL_OR_RETURN(bytes, env, src);
-
-        srcInt = (jint *)(bytes + srcPos);
-        endInt = srcInt + (size / sizeof(jint));
-        while (srcInt < endInt) {
-            tmpInt = *srcInt++;
-            *dstInt++ = SWAPINT(tmpInt);
-        }
-
-        RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
-        length -= size;
-        srcPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jclass clazz, jlong srcAddr,
-                                  jobject dst, jlong dstPos, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jint *srcInt, *dstInt, *endInt;
-    jint tmpInt;
-
-    srcInt = (jint *)jlong_to_ptr(srcAddr);
-
-    while (length > 0) {
-        size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
-
-        GETCRITICAL_OR_RETURN(bytes, env, dst);
-
-        dstInt = (jint *)(bytes + dstPos);
-        endInt = srcInt + (size / sizeof(jint));
-        while (srcInt < endInt) {
-            tmpInt = *srcInt++;
-            *dstInt++ = SWAPINT(tmpInt);
-        }
-
-        RELEASECRITICAL(bytes, env, dst, 0);
-
-        length -= size;
-        dstPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jclass clazz, jobject src,
-                                     jlong srcPos, jlong dstAddr, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jlong *srcLong, *dstLong, *endLong;
-    jlong tmpLong;
-
-    dstLong = (jlong *)jlong_to_ptr(dstAddr);
-
-    while (length > 0) {
-        size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
-
-        GETCRITICAL_OR_RETURN(bytes, env, src);
-
-        srcLong = (jlong *)(bytes + srcPos);
-        endLong = srcLong + (size / sizeof(jlong));
-        while (srcLong < endLong) {
-            tmpLong = *srcLong++;
-            *dstLong++ = SWAPLONG(tmpLong);
-        }
-
-        RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
-        length -= size;
-        srcPos += size;
-    }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jclass clazz, jlong srcAddr,
-                                   jobject dst, jlong dstPos, jlong length)
-{
-    jbyte *bytes;
-    size_t size;
-    jlong *srcLong, *dstLong, *endLong;
-    jlong tmpLong;
-
-    srcLong = (jlong *)jlong_to_ptr(srcAddr);
-
-    while (length > 0) {
-        size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
-
-        GETCRITICAL_OR_RETURN(bytes, env, dst);
-
-        dstLong = (jlong *)(bytes + dstPos);
-        endLong = srcLong + (size / sizeof(jlong));
-        while (srcLong < endLong) {
-            tmpLong = *srcLong++;
-            *dstLong++ = SWAPLONG(tmpLong);
-        }
-
-        RELEASECRITICAL(bytes, env, dst, 0);
-
-        length -= size;
-        dstPos += size;
-    }
-}
--- a/jdk/src/java.base/share/native/libnet/net_util.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/native/libnet/net_util.c	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,14 +29,21 @@
 #include "net_util.h"
 
 int IPv6_supported() ;
+int reuseport_supported() ;
 
 static int IPv6_available;
+static int REUSEPORT_available;
 
 JNIEXPORT jint JNICALL ipv6_available()
 {
     return IPv6_available ;
 }
 
+JNIEXPORT jint JNICALL reuseport_available()
+{
+    return REUSEPORT_available;
+}
+
 JNIEXPORT jint JNICALL
 DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
@@ -45,7 +52,6 @@
     jmethodID mid;
     jstring s;
     jint preferIPv4Stack;
-
     if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
         return JNI_EVERSION; /* JNI version not supported */
     }
@@ -64,6 +70,9 @@
        supporting socket APIs are available
     */
     IPv6_available = IPv6_supported() & (!preferIPv4Stack);
+
+    /* check if SO_REUSEPORT is supported on this platform */
+    REUSEPORT_available = reuseport_supported();
     platformInit();
     parseExclusiveBindProperty(env);
 
--- a/jdk/src/java.base/share/native/libnet/net_util.h	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/native/libnet/net_util.h	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, 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
@@ -131,6 +131,8 @@
 
 JNIEXPORT jint JNICALL ipv6_available() ;
 
+JNIEXPORT jint JNICALL reuseport_available() ;
+
 void
 NET_AllocSockaddr(struct sockaddr **him, int *len);
 
--- a/jdk/src/java.base/share/native/libzip/CRC32.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/share/native/libzip/CRC32.c	Wed Feb 24 08:58:31 2016 -0800
@@ -54,7 +54,7 @@
     return crc;
 }
 
-JNIEXPORT jint JNICALL
+jint JNICALL
 ZIP_CRC32(jint crc, const jbyte *buf, jint len)
 {
     return crc32(crc, (Bytef*)buf, len);
--- a/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -45,7 +45,15 @@
 
     protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
         if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
-            super.setOption(name, value);
+            if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
+                super.setOption(name, value);
+            } else {
+               if (supportedOptions().contains(name)) {
+                   super.setOption(name, value);
+               } else {
+                   throw new UnsupportedOperationException("unsupported option");
+               }
+            }
         } else {
             if (!flowSupported()) {
                 throw new UnsupportedOperationException("unsupported option");
@@ -62,7 +70,15 @@
     @SuppressWarnings("unchecked")
     protected <T> T getOption(SocketOption<T> name) throws IOException {
         if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
-            return super.getOption(name);
+            if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
+                return super.getOption(name);
+            } else {
+                if (supportedOptions().contains(name)) {
+                    return super.getOption(name);
+                } else {
+                    throw new UnsupportedOperationException("unsupported option");
+                }
+            }
         }
         if (!flowSupported()) {
             throw new UnsupportedOperationException("unsupported option");
@@ -87,6 +103,9 @@
     }
 
     protected void socketSetOption(int opt, Object val) throws SocketException {
+        if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+            throw new UnsupportedOperationException("unsupported option");
+        }
         try {
             socketSetOption0(opt, val);
         } catch (SocketException se) {
--- a/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -59,7 +59,15 @@
 
     protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
         if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
-            super.setOption(name, value);
+            if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
+                super.setOption(name, value);
+            } else {
+                if (supportedOptions().contains(name)) {
+                    super.setOption(name, value);
+                } else {
+                    throw new UnsupportedOperationException("unsupported option");
+                }
+            }
         } else {
             if (getSocket() == null || !flowSupported()) {
                 throw new UnsupportedOperationException("unsupported option");
@@ -76,7 +84,15 @@
     @SuppressWarnings("unchecked")
     protected <T> T getOption(SocketOption<T> name) throws IOException {
         if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
-            return super.getOption(name);
+            if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
+                return super.getOption(name);
+            } else {
+                if (supportedOptions().contains(name)) {
+                    return super.getOption(name);
+                } else {
+                    throw new UnsupportedOperationException("unsupported option");
+                }
+            }
         }
         if (getSocket() == null || !flowSupported()) {
             throw new UnsupportedOperationException("unsupported option");
@@ -101,6 +117,9 @@
     }
 
     protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
+        if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+            throw new UnsupportedOperationException("unsupported option");
+        }
         try {
             socketSetOption0(opt, b, val);
         } catch (SocketException se) {
--- a/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1392,6 +1392,7 @@
             }
 
         case java_net_SocketOptions_SO_REUSEADDR:
+        case java_net_SocketOptions_SO_REUSEPORT:
         case java_net_SocketOptions_SO_BROADCAST:
             {
                 jclass cls;
@@ -1769,6 +1770,9 @@
         case java_net_SocketOptions_SO_REUSEADDR:
             return createBoolean(env, optval.i);
 
+        case java_net_SocketOptions_SO_REUSEPORT:
+            return createBoolean(env, optval.i);
+
         case java_net_SocketOptions_SO_SNDBUF:
         case java_net_SocketOptions_SO_RCVBUF:
         case java_net_SocketOptions_IP_TOS:
--- a/jdk/src/java.base/unix/native/libnet/SdpSupport.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/unix/native/libnet/SdpSupport.c	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -108,6 +108,11 @@
         len = sizeof(arg);
         if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, &len) == 0)
             setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, len);
+#ifdef SO_REUSEPORT
+        len = sizeof(arg);
+        if (getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char*)&arg, &len) == 0)
+            setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char*)&arg, len);
+#endif
         len = sizeof(arg);
         if (getsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, &len) == 0)
             setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char*)&arg, len);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/unix/native/libnet/SocketImpl.c	Wed Feb 24 08:58:31 2016 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+#include <string.h>
+
+#include "net_util.h"
+
+JNIEXPORT jboolean JNICALL
+Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
+{
+    return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
+{
+    return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
+{
+    return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
+}
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, 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
@@ -439,6 +439,25 @@
 }
 #endif /* DONT_ENABLE_IPV6 */
 
+jint reuseport_supported()
+{
+    /* Do a simple dummy call, and try to figure out from that */
+    int one = 1;
+    int rv, s;
+    s = socket(PF_INET, SOCK_STREAM, 0);
+    if (s < 0) {
+        return JNI_FALSE;
+    }
+    rv = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void *)&one, sizeof(one));
+    if (rv != 0) {
+        rv = JNI_FALSE;
+    } else {
+        rv = JNI_TRUE;
+    }
+    close(s);
+    return rv;
+}
+
 void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
                                                const char* hostname,
                                                int gai_error)
@@ -1014,6 +1033,7 @@
         { java_net_SocketOptions_SO_RCVBUF,             SOL_SOCKET,     SO_RCVBUF },
         { java_net_SocketOptions_SO_KEEPALIVE,          SOL_SOCKET,     SO_KEEPALIVE },
         { java_net_SocketOptions_SO_REUSEADDR,          SOL_SOCKET,     SO_REUSEADDR },
+        { java_net_SocketOptions_SO_REUSEPORT,          SOL_SOCKET,     SO_REUSEPORT },
         { java_net_SocketOptions_SO_BROADCAST,          SOL_SOCKET,     SO_BROADCAST },
         { java_net_SocketOptions_IP_TOS,                IPPROTO_IP,     IP_TOS },
         { java_net_SocketOptions_IP_MULTICAST_IF,       IPPROTO_IP,     IP_MULTICAST_IF },
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.h	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.h	Wed Feb 24 08:58:31 2016 -0800
@@ -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
@@ -60,6 +60,19 @@
 #define NET_WAIT_WRITE   0x02
 #define NET_WAIT_CONNECT 0x04
 
+/* Defines SO_REUSEPORT */
+#ifndef SO_REUSEPORT
+#ifdef __linux__
+#define SO_REUSEPORT 15
+#elif __solaris__
+#define SO_REUSEPORT 0x100e
+#elif defined(AIX) || defined(MACOSX)
+#define SO_REUSEPORT 0x0200
+#else
+#define SO_REUSEPORT 0
+#endif
+#endif
+
 jint NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout);
 
 /************************************************************************
--- a/jdk/src/java.base/unix/native/libnio/ch/Net.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/unix/native/libnio/ch/Net.c	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -161,6 +161,12 @@
     return (ipv6_available()) ? JNI_TRUE : JNI_FALSE;
 }
 
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_ch_Net_isReusePortAvailable0(JNIEnv* env, jclass c1)
+{
+    return (reuseport_available()) ? JNI_TRUE : JNI_FALSE;
+}
+
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
     return -1;
--- a/jdk/src/java.base/unix/native/libnio/ch/nio_util.h	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/unix/native/libnio/ch/nio_util.h	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,18 @@
   } while((_result == -1) && (errno == EINTR)); \
 } while(0)
 
+/* Defines SO_REUSEPORT */
+#ifndef SO_REUSEPORT
+#ifdef __linux__
+#define SO_REUSEPORT 15
+#elif __solaris__
+#define SO_REUSEPORT 0x100e
+#elif defined(AIX) || defined(MACOSX)
+#define SO_REUSEPORT 0x0200
+#else
+#define SO_REUSEPORT 0
+#endif
+#endif
 
 /* NIO utility procedures */
 
--- a/jdk/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -167,6 +167,11 @@
 
         int optionValue = 0;
 
+        // SO_REUSEPORT is not supported on Windows.
+        if (opt == SO_REUSEPORT) {
+            throw new UnsupportedOperationException("unsupported option");
+        }
+
         switch(opt) {
             case IP_TOS :
             case SO_RCVBUF :
@@ -200,6 +205,9 @@
         }
         if (opt == SO_REUSEADDR && reuseAddressEmulated)
             return isReuseAddress;
+        // SO_REUSEPORT is not supported on Windows.
+        if (opt == SO_REUSEPORT)
+            throw new UnsupportedOperationException("unsupported option");
 
         int value = socketGetIntOption(nativefd, opt);
         Object returnValue = null;
--- a/jdk/src/java.base/windows/classes/java/net/DualStackPlainSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/windows/classes/java/net/DualStackPlainSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -181,6 +181,10 @@
         if (opt == SO_TIMEOUT) {  // timeout implemented through select.
             return;
         }
+        // SO_REUSEPORT is not supported on Windows.
+        if (opt == SO_REUSEPORT) {
+            throw new UnsupportedOperationException("unsupported option");
+        }
 
         int optionValue = 0;
 
@@ -224,6 +228,10 @@
             localAddress(nativefd, (InetAddressContainer)iaContainerObj);
             return 0;  // return value doesn't matter.
         }
+        // SO_REUSEPORT is not supported on Windows.
+        if (opt == SO_REUSEPORT) {
+            throw new UnsupportedOperationException("unsupported option");
+        }
 
         // SO_REUSEADDR emulated when using exclusive bind
         if (opt == SO_REUSEADDR && exclusiveBind)
--- a/jdk/src/java.base/windows/classes/java/net/PlainSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/windows/classes/java/net/PlainSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -173,10 +173,18 @@
     }
 
     public void setOption(int opt, Object val) throws SocketException {
+        if (opt == SocketOptions.SO_REUSEPORT) {
+            // SO_REUSEPORT is not supported on Windows.
+            throw new UnsupportedOperationException("unsupported option");
+        }
         impl.setOption(opt, val);
     }
 
     public Object getOption(int opt) throws SocketException {
+        if (opt == SocketOptions.SO_REUSEPORT) {
+            // SO_REUSEPORT is not supported on Windows.
+            throw new UnsupportedOperationException("unsupported option");
+        }
         return impl.getOption(opt);
     }
 
@@ -332,14 +340,27 @@
 
     void socketSetOption(int cmd, boolean on, Object value)
         throws SocketException {
+        if (cmd == SocketOptions.SO_REUSEPORT) {
+            // SO_REUSEPORT is not supported on Windows.
+            throw new UnsupportedOperationException("unsupported option");
+        }
         impl.socketSetOption(cmd, on, value);
     }
 
     int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
+        if (opt == SocketOptions.SO_REUSEPORT) {
+            // SO_REUSEPORT is not supported on Windows.
+            throw new UnsupportedOperationException("unsupported option");
+        }
         return impl.socketGetOption(opt, iaContainerObj);
     }
 
     void socketSendUrgentData(int data) throws IOException {
         impl.socketSendUrgentData(data);
     }
+
+    static boolean isReusePortAvailable() {
+        // SO_REUSEPORT is not supported on Windows.
+        return false;
+    }
 }
--- a/jdk/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -130,6 +130,9 @@
             return socketLocalAddress(family);
         } else if (optID == SO_REUSEADDR && reuseAddressEmulated) {
             return isReuseAddress;
+        } else if (optID == SO_REUSEPORT) {
+            // SO_REUSEPORT is not supported on Windows.
+            throw new UnsupportedOperationException("unsupported option");
         } else {
             return super.getOption(optID);
         }
@@ -142,6 +145,9 @@
             // socket already bound, emulate
             reuseAddressEmulated = true;
             isReuseAddress = (Boolean)val;
+        } else if (opt == SO_REUSEPORT) {
+            // SO_REUSEPORT is not supported on Windows.
+            throw new UnsupportedOperationException("unsupported option");
         } else {
             socketNativeSetOption(opt, val);
         }
--- a/jdk/src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -128,6 +128,9 @@
         } else if (opt == SO_REUSEADDR && exclusiveBind) {
             // SO_REUSEADDR emulated when using exclusive bind
             return isReuseAddress;
+        } else if (opt == SO_REUSEPORT) {
+            // SO_REUSEPORT is not supported on Windows.
+            throw new UnsupportedOperationException("unsupported option");
         } else
             return super.getOption(opt);
     }
@@ -144,6 +147,10 @@
         // SO_REUSEADDR emulated when using exclusive bind
         if (opt == SO_REUSEADDR && exclusiveBind)
             isReuseAddress = on;
+        else if (opt == SO_REUSEPORT) {
+            // SO_REUSEPORT is not supported on Windows.
+            throw new UnsupportedOperationException("unsupported option");
+        }
         else
             socketNativeSetOption(opt, on, value);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/windows/native/libnet/SocketImpl.c	Wed Feb 24 08:58:31 2016 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+
+JNIEXPORT jboolean JNICALL
+Java_java_net_AbstractPlainSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
+{
+    // SO_REUSEPORT is not supported on Windows
+    return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_net_AbstractPlainDatagramSocketImpl_isReusePortAvailable0(JNIEnv* env, jclass c1)
+{
+    // SO_REUSEPORT is not supported on Windows
+    return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_jdk_net_Sockets_isReusePortAvailable0(JNIEnv* env, jclass c1)
+{
+    // SO_REUSEPORT is not supported on Windows
+    return JNI_FALSE;
+}
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.c	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, 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
@@ -242,6 +242,11 @@
     return JNI_TRUE;
 }
 
+jint reuseport_supported()
+{
+    /* SO_REUSEPORT is not supported onn Windows */
+    return JNI_FALSE;
+}
 /*
  * Return the default TOS value
  */
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.h	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.h	Wed Feb 24 08:58:31 2016 -0800
@@ -54,6 +54,9 @@
 
 #else
 
+/*SO_REUSEPORT is not supported on Windows, define it to 0*/
+#define SO_REUSEPORT 0
+
 /* Retain this code a little longer to support building in
  * old environments.  _MSC_VER is defined as:
  *     1200 for MSVC++ 6.0
@@ -353,3 +356,4 @@
 
 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
 (JNIEnv *env, jclass cls, jstring name, jint index);
+
--- a/jdk/src/java.base/windows/native/libnio/ch/Net.c	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/java.base/windows/native/libnio/ch/Net.c	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -93,6 +93,13 @@
     return ipv6_available() ? JNI_TRUE : JNI_FALSE;
 }
 
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_ch_Net_isReusePortAvailable0(JNIEnv* env, jclass c1)
+{
+    // SO_REUSEPORT is not supported on Windows
+    return JNI_FALSE;
+}
+
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_Net_isExclusiveBindAvailable(JNIEnv *env, jclass clazz) {
     return 1;
--- a/jdk/src/jdk.localedata/share/classes/META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/src/jdk.localedata/share/classes/META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo	Wed Feb 24 08:58:31 2016 -0800
@@ -1,2 +1,2 @@
 sun.util.resources.provider.NonBaseLocaleDataMetaInfo
-sun.util.resources.cldr.provider.CLDRLocaleDataMetaInfo_jdk_localedata
+sun.util.resources.cldr.provider.CLDRLocaleDataMetaInfo
--- a/jdk/test/java/net/SocketOption/OptionsTest.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/test/java/net/SocketOption/OptionsTest.java	Wed Feb 24 08:58:31 2016 -0800
@@ -54,6 +54,7 @@
         Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
+        Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
         Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(80)),
         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
     };
@@ -61,6 +62,7 @@
     static Test[] serverSocketTests = new Test[] {
         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
+        Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
     };
 
@@ -68,6 +70,7 @@
         Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
         Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
         Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
+        Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
         Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100))
     };
 
@@ -97,15 +100,19 @@
             Socket c = new Socket("127.0.0.1", srv.getLocalPort());
             Socket s = srv.accept();
         ) {
+            Set<SocketOption<?>> options = c.supportedOptions();
+            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
             for (int i=0; i<socketTests.length; i++) {
                 Test test = socketTests[i];
-                c.setOption((SocketOption)test.option, test.testValue);
-                Object getval = c.getOption((SocketOption)test.option);
-                Object legacyget = legacyGetOption(Socket.class, c,test.option);
-                if (!getval.equals(legacyget)) {
-                    Formatter f = new Formatter();
-                    f.format("S Err %d: %s/%s", i, getval, legacyget);
-                    throw new RuntimeException(f.toString());
+                if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
+                    c.setOption((SocketOption)test.option, test.testValue);
+                    Object getval = c.getOption((SocketOption)test.option);
+                    Object legacyget = legacyGetOption(Socket.class, c,test.option);
+                    if (!getval.equals(legacyget)) {
+                        Formatter f = new Formatter();
+                        f.format("S Err %d: %s/%s", i, getval, legacyget);
+                        throw new RuntimeException(f.toString());
+                    }
                 }
             }
         }
@@ -115,15 +122,19 @@
         try (
             DatagramSocket c = new DatagramSocket(0);
         ) {
+            Set<SocketOption<?>> options = c.supportedOptions();
+            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
             for (int i=0; i<dgSocketTests.length; i++) {
                 Test test = dgSocketTests[i];
-                c.setOption((SocketOption)test.option, test.testValue);
-                Object getval = c.getOption((SocketOption)test.option);
-                Object legacyget = legacyGetOption(DatagramSocket.class, c,test.option);
-                if (!getval.equals(legacyget)) {
-                    Formatter f = new Formatter();
-                    f.format("DG Err %d: %s/%s", i, getval, legacyget);
-                    throw new RuntimeException(f.toString());
+                if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
+                    c.setOption((SocketOption)test.option, test.testValue);
+                    Object getval = c.getOption((SocketOption)test.option);
+                    Object legacyget = legacyGetOption(DatagramSocket.class, c,test.option);
+                    if (!getval.equals(legacyget)) {
+                        Formatter f = new Formatter();
+                        f.format("DG Err %d: %s/%s", i, getval, legacyget);
+                        throw new RuntimeException(f.toString());
+                    }
                 }
             }
         }
@@ -151,17 +162,21 @@
         try (
             ServerSocket c = new ServerSocket(0);
         ) {
+            Set<SocketOption<?>> options = c.supportedOptions();
+            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
             for (int i=0; i<serverSocketTests.length; i++) {
                 Test test = serverSocketTests[i];
-                c.setOption((SocketOption)test.option, test.testValue);
-                Object getval = c.getOption((SocketOption)test.option);
-                Object legacyget = legacyGetOption(
-                    ServerSocket.class, c, test.option
-                );
-                if (!getval.equals(legacyget)) {
-                    Formatter f = new Formatter();
-                    f.format("SS Err %d: %s/%s", i, getval, legacyget);
-                    throw new RuntimeException(f.toString());
+                if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
+                    c.setOption((SocketOption)test.option, test.testValue);
+                    Object getval = c.getOption((SocketOption)test.option);
+                    Object legacyget = legacyGetOption(
+                        ServerSocket.class, c, test.option
+                    );
+                    if (!getval.equals(legacyget)) {
+                        Formatter f = new Formatter();
+                        f.format("SS Err %d: %s/%s", i, getval, legacyget);
+                        throw new RuntimeException(f.toString());
+                    }
                 }
             }
         }
@@ -174,6 +189,8 @@
     {
         if (type.equals(Socket.class)) {
             Socket socket = (Socket)s;
+            Set<SocketOption<?>> options = socket.supportedOptions();
+            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
 
             if (option.equals(StandardSocketOptions.SO_KEEPALIVE)) {
                 return Boolean.valueOf(socket.getKeepAlive());
@@ -183,6 +200,8 @@
                 return Integer.valueOf(socket.getReceiveBufferSize());
             } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
                 return Boolean.valueOf(socket.getReuseAddress());
+            } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
+                return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
             } else if (option.equals(StandardSocketOptions.SO_LINGER)) {
                 return Integer.valueOf(socket.getSoLinger());
             } else if (option.equals(StandardSocketOptions.IP_TOS)) {
@@ -194,10 +213,15 @@
             }
         } else if  (type.equals(ServerSocket.class)) {
             ServerSocket socket = (ServerSocket)s;
+            Set<SocketOption<?>> options = socket.supportedOptions();
+            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
+
             if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
                 return Integer.valueOf(socket.getReceiveBufferSize());
             } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
                 return Boolean.valueOf(socket.getReuseAddress());
+            } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
+                return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
             } else if (option.equals(StandardSocketOptions.IP_TOS)) {
                 return Integer.valueOf(jdk.net.Sockets.getOption(
                     socket, StandardSocketOptions.IP_TOS));
@@ -206,6 +230,8 @@
             }
         } else if  (type.equals(DatagramSocket.class)) {
             DatagramSocket socket = (DatagramSocket)s;
+            Set<SocketOption<?>> options = socket.supportedOptions();
+            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
 
             if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
                 return Integer.valueOf(socket.getSendBufferSize());
@@ -213,6 +239,8 @@
                 return Integer.valueOf(socket.getReceiveBufferSize());
             } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
                 return Boolean.valueOf(socket.getReuseAddress());
+            } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
+                return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
             } else if (option.equals(StandardSocketOptions.IP_TOS)) {
                 return Integer.valueOf(socket.getTrafficClass());
             } else {
@@ -221,6 +249,8 @@
 
         } else if  (type.equals(MulticastSocket.class)) {
             MulticastSocket socket = (MulticastSocket)s;
+            Set<SocketOption<?>> options = socket.supportedOptions();
+            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
 
             if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
                 return Integer.valueOf(socket.getSendBufferSize());
@@ -228,6 +258,8 @@
                 return Integer.valueOf(socket.getReceiveBufferSize());
             } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
                 return Boolean.valueOf(socket.getReuseAddress());
+            } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
+                return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
             } else if (option.equals(StandardSocketOptions.IP_TOS)) {
                 return Integer.valueOf(socket.getTrafficClass());
             } else if (option.equals(StandardSocketOptions.IP_MULTICAST_IF)) {
--- a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -141,8 +141,11 @@
         try {
             // check supported options
             Set<SocketOption<?>> options = ch.supportedOptions();
+            boolean reuseport = options.contains(SO_REUSEPORT);
             if (!options.contains(SO_REUSEADDR))
                 throw new RuntimeException("SO_REUSEADDR should be supported");
+            if (!options.contains(SO_REUSEPORT) && reuseport)
+                throw new RuntimeException("SO_REUSEPORT should be supported");
             if (!options.contains(SO_RCVBUF))
                 throw new RuntimeException("SO_RCVBUF should be supported");
 
@@ -156,6 +159,13 @@
             checkOption(ch, SO_REUSEADDR, true);
             ch.setOption(SO_REUSEADDR, false);
             checkOption(ch, SO_REUSEADDR, false);
+
+            if (reuseport) {
+                ch.setOption(SO_REUSEPORT, true);
+                checkOption(ch, SO_REUSEPORT, true);
+                ch.setOption(SO_REUSEPORT, false);
+                checkOption(ch, SO_REUSEPORT, false);
+            }
         } finally {
             ch.close();
         }
--- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 import java.util.concurrent.atomic.*;
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.Set;
 
 public class Basic {
     static final Random rand = new Random();
@@ -165,6 +166,15 @@
             // read others (can't check as actual value is implementation dependent)
             ch.getOption(SO_RCVBUF);
             ch.getOption(SO_SNDBUF);
+
+            Set<SocketOption<?>> options = ch.supportedOptions();
+            boolean reuseport = options.contains(SO_REUSEPORT);
+            if (reuseport) {
+                if (ch.getOption(SO_REUSEPORT))
+                    throw new RuntimeException("Default of SO_REUSEPORT should be 'false'");
+                if (!ch.setOption(SO_REUSEPORT, true).getOption(SO_REUSEPORT))
+                    throw new RuntimeException("SO_REUSEPORT did not change");
+            }
         }
     }
 
--- a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,9 +50,17 @@
 
         // check supported options
         Set<SocketOption<?>> options = dc.supportedOptions();
-        List<? extends SocketOption<?>> expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
-            SO_REUSEADDR, SO_BROADCAST, IP_TOS, IP_MULTICAST_IF, IP_MULTICAST_TTL,
-            IP_MULTICAST_LOOP);
+        boolean reuseport = options.contains(SO_REUSEPORT);
+        List<? extends SocketOption<?>> expected;
+        if (reuseport) {
+           expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
+                      SO_REUSEADDR, SO_REUSEPORT, SO_BROADCAST, IP_TOS, IP_MULTICAST_IF,
+                      IP_MULTICAST_TTL, IP_MULTICAST_LOOP);
+        } else {
+           expected = Arrays.asList(SO_SNDBUF, SO_RCVBUF,
+                      SO_REUSEADDR, SO_BROADCAST, IP_TOS, IP_MULTICAST_IF, IP_MULTICAST_TTL,
+                      IP_MULTICAST_LOOP);
+        }
         for (SocketOption opt: expected) {
             if (!options.contains(opt))
                 throw new RuntimeException(opt.name() + " should be supported");
@@ -83,7 +91,12 @@
         checkOption(dc, SO_REUSEADDR, true);
         dc.setOption(SO_REUSEADDR, false);
         checkOption(dc, SO_REUSEADDR, false);
-
+        if (reuseport) {
+            dc.setOption(SO_REUSEPORT, true);
+            checkOption(dc, SO_REUSEPORT, true);
+            dc.setOption(SO_REUSEPORT, false);
+            checkOption(dc, SO_REUSEPORT, false);
+        }
         // bind socket
         dc.bind(new InetSocketAddress(0));
 
--- a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Wed Feb 24 08:58:31 2016 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -49,8 +49,11 @@
 
         // check supported options
         Set<SocketOption<?>> options = ssc.supportedOptions();
+        boolean reuseport = options.contains(SO_REUSEPORT);
         if (!options.contains(SO_REUSEADDR))
             throw new RuntimeException("SO_REUSEADDR should be supported");
+        if (!options.contains(SO_REUSEPORT) && reuseport)
+            throw new RuntimeException("SO_REUSEPORT should be supported");
         if (!options.contains(SO_RCVBUF))
             throw new RuntimeException("SO_RCVBUF should be supported");
 
@@ -64,6 +67,12 @@
         checkOption(ssc, SO_REUSEADDR, true);
         ssc.setOption(SO_REUSEADDR, false);
         checkOption(ssc, SO_REUSEADDR, false);
+        if (reuseport) {
+            ssc.setOption(SO_REUSEPORT, true);
+            checkOption(ssc, SO_REUSEPORT, true);
+            ssc.setOption(SO_REUSEPORT, false);
+            checkOption(ssc, SO_REUSEPORT, false);
+        }
 
         // NullPointerException
         try {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/JceSecurity/FinalRestricted.java	Wed Feb 24 08:58:31 2016 -0800
@@ -0,0 +1,45 @@
+/*
+ * 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 8149417
+ * @summary Use final restricted flag
+ */
+
+import java.security.*;
+import java.lang.reflect.*;
+
+public class FinalRestricted {
+
+    public static void main(String[] args) throws Exception {
+
+        int modifiers = Class.forName("javax.crypto.JceSecurity")
+                    .getDeclaredField("isRestricted").getModifiers();
+        if (!(Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers) &&
+                Modifier.isPrivate(modifiers))) {
+            throw new Exception("JceSecurity.isRestricted is not " +
+                                "a private static final field!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/misc/Unsafe/CopySwap.java	Wed Feb 24 08:58:31 2016 -0800
@@ -0,0 +1,711 @@
+/*
+ * 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 jdk.internal.misc.Unsafe;
+import java.lang.reflect.Field;
+
+/*
+ * @test
+ * @summary Test Unsafe.copySwapMemory
+ * @modules java.base/jdk.internal.misc
+ */
+public class CopySwap {
+    private static final boolean DEBUG = Boolean.getBoolean("CopySwap.DEBUG");
+
+    public static final long KB = 1024;
+    public static final long MB = KB * 1024;
+    public static final long GB = MB * 1024;
+
+    private static final Unsafe UNSAFE;
+    private static final int SMALL_COPY_SIZE = 32;
+    private static final int BASE_ALIGNMENT = 16;
+
+    static {
+        try {
+            Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
+            f.setAccessible(true);
+            UNSAFE = (jdk.internal.misc.Unsafe) f.get(null);
+        } catch (Exception e) {
+            throw new RuntimeException("Unable to get Unsafe instance.", e);
+        }
+    }
+
+    private static long alignDown(long value, long alignment) {
+        return value & ~(alignment - 1);
+    }
+
+    private static long alignUp(long value, long alignment) {
+        return (value + alignment - 1) & ~(alignment - 1);
+    }
+
+    private static boolean isAligned(long value, long alignment) {
+        return value == alignDown(value, alignment);
+    }
+
+    private CopySwap() {
+    }
+
+    /**
+     * Generate verification data for a given offset
+     *
+     * The verification data is used to verify that the correct bytes
+     * have indeed been copied and byte swapped.
+     *
+     * The data is generated based on the offset (in bytes) into the
+     * source buffer. For a native buffer the offset is relative to
+     * the base pointer. For a heap array it is relative to the
+     * address of the first array element.
+     *
+     * This method will return the result of doing an elementSize byte
+     * read starting at offset (in bytes).
+     *
+     * @param offset offset into buffer
+     * @param elemSize size (in bytes) of the element
+     *
+     * @return the verification data, only the least significant
+     * elemSize*8 bits are set, zero extended
+     */
+    private long getVerificationDataForOffset(long offset, long elemSize) {
+        byte[] bytes = new byte[(int)elemSize];
+
+        for (long i = 0; i < elemSize; i++) {
+            bytes[(int)i] = (byte)(offset + i);
+        }
+
+        long o = UNSAFE.arrayBaseOffset(byte[].class);
+
+        switch ((int)elemSize) {
+        case 1: return Byte.toUnsignedLong(UNSAFE.getByte(bytes, o));
+        case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(bytes, o));
+        case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(bytes, o));
+        case 8: return UNSAFE.getLongUnaligned(bytes, o);
+        default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
+        }
+    }
+
+    /**
+     * Verify byte swapped data
+     *
+     * @param ptr the data to verify
+     * @param srcOffset the srcOffset (in bytes) from which the copy started,
+     *        used as key to regenerate the verification data
+     * @param dstOffset the offset (in bytes) in the array at which to start
+     *        the verification, relative to the first element in the array
+     * @param size size (in bytes) of data to to verify
+     * @param elemSize size (in bytes) of the individual array elements
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void verifySwappedData(GenericPointer ptr, long srcOffset, long dstOffset, long size, long elemSize) {
+        for (long offset = 0; offset < size; offset += elemSize) {
+            long expectedUnswapped = getVerificationDataForOffset(srcOffset + offset, elemSize);
+            long expected = byteSwap(expectedUnswapped, elemSize);
+
+            long actual = getArrayElem(ptr, dstOffset + offset, elemSize);
+
+            if (expected != actual) {
+                throw new RuntimeException("srcOffset: 0x" + Long.toHexString(srcOffset) +
+                                           " dstOffset: 0x" + Long.toHexString(dstOffset) +
+                                           " size: 0x" + Long.toHexString(size) +
+                                           " offset: 0x" + Long.toHexString(offset) +
+                                           " expectedUnswapped: 0x" + Long.toHexString(expectedUnswapped) +
+                                           " expected: 0x" + Long.toHexString(expected) +
+                                           " != actual: 0x" + Long.toHexString(actual));
+            }
+        }
+    }
+
+    /**
+     * Initialize an array with verification friendly data
+     *
+     * @param ptr pointer to the data to initialize
+     * @param size size (in bytes) of the data
+     * @param elemSize size (in bytes) of the individual elements
+     */
+    private void initVerificationData(GenericPointer ptr, long size, long elemSize) {
+        for (long offset = 0; offset < size; offset++) {
+            byte data = (byte)getVerificationDataForOffset(offset, 1);
+
+            if (ptr.isOnHeap()) {
+                UNSAFE.putByte(ptr.getObject(), ptr.getOffset() + offset, data);
+            } else {
+                UNSAFE.putByte(ptr.getOffset() + offset, data);
+            }
+        }
+    }
+
+    /**
+     * Allocate a primitive array
+     *
+     * @param size size (in bytes) of all the array elements (elemSize * length)
+     * @param elemSize the size of the array elements
+     *
+     * @return a newly allocated primitive array
+     */
+    Object allocArray(long size, long elemSize) {
+        int length = (int)(size / elemSize);
+
+        switch ((int)elemSize) {
+        case 2: return new short[length];
+        case 4: return new int[length];
+        case 8: return new long[length];
+        default:
+            throw new IllegalArgumentException("Invalid element size: " + elemSize);
+        }
+    }
+
+    /**
+     * Get the value of a primitive array entry
+     *
+     * @param ptr pointer to the data
+     * @param offset offset (in bytes) of the array element, relative to the first element in the array
+     *
+     * @return the array element, as an unsigned long
+     */
+    private long getArrayElem(GenericPointer ptr, long offset, long elemSize) {
+        if (ptr.isOnHeap()) {
+            Object o = ptr.getObject();
+            int index = (int)(offset / elemSize);
+
+            if (o instanceof short[]) {
+                short[] arr = (short[])o;
+                return Short.toUnsignedLong(arr[index]);
+            } else if (o instanceof int[]) {
+                int[] arr = (int[])o;
+                return Integer.toUnsignedLong(arr[index]);
+            } else if (o instanceof long[]) {
+                long[] arr = (long[])o;
+                return arr[index];
+            } else {
+                throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
+            }
+        } else {
+            long addr = ptr.getOffset() + offset;
+
+            switch ((int)elemSize) {
+            case 1: return Byte.toUnsignedLong(UNSAFE.getByte(addr));
+            case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(null, addr));
+            case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(null, addr));
+            case 8: return UNSAFE.getLongUnaligned(null, addr);
+            default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
+            }
+        }
+    }
+
+    private void putValue(long addr, long elemSize, long value) {
+        switch ((int)elemSize) {
+        case 1: UNSAFE.putByte(addr, (byte)value); break;
+        case 2: UNSAFE.putShortUnaligned(null, addr, (short)value); break;
+        case 4: UNSAFE.putIntUnaligned(null, addr, (int)value); break;
+        case 8: UNSAFE.putLongUnaligned(null, addr, value); break;
+        default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
+        }
+    }
+
+    /**
+     * Get the size of the elements for an array
+     *
+     * @param o a primitive heap array
+     *
+     * @return the size (in bytes) of the individual array elements
+     */
+    private long getArrayElemSize(Object o) {
+        if (o instanceof short[]) {
+            return 2;
+        } else if (o instanceof int[]) {
+            return 4;
+        } else if (o instanceof long[]) {
+            return 8;
+        } else {
+            throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
+        }
+    }
+
+    /**
+     * Byte swap a value
+     *
+     * @param value the value to swap, only the bytes*8 least significant bits are used
+     * @param size size (in bytes) of the value
+     *
+     * @return the byte swapped value in the bytes*8 least significant bits
+     */
+    private long byteSwap(long value, long size) {
+        switch ((int)size) {
+        case 2: return Short.toUnsignedLong(Short.reverseBytes((short)value));
+        case 4: return Integer.toUnsignedLong(Integer.reverseBytes((int)value));
+        case 8: return Long.reverseBytes(value);
+        default: throw new IllegalArgumentException("Invalid element size: " + size);
+        }
+    }
+
+    /**
+     * Verify data in a heap array which has *not* been byte swapped
+     *
+     * @param ptr the data to verify
+     * @param startOffset the offset (in bytes) at which to start the verification
+     * @param size size (in bytes) of the data to verify
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void verifyUnswappedData(GenericPointer ptr, long startOffset, long size) {
+        for (long elemOffset = startOffset; elemOffset < startOffset + size; elemOffset++) {
+            byte expected = (byte)getVerificationDataForOffset(elemOffset, 1);
+
+            byte actual;
+            if (ptr.isOnHeap()) {
+                actual = UNSAFE.getByte(ptr.getObject(), ptr.getOffset() + elemOffset);
+            } else {
+                actual = UNSAFE.getByte(ptr.getOffset() + elemOffset);
+            }
+
+            if (expected != actual) {
+                throw new RuntimeException("startOffset: 0x" + Long.toHexString(startOffset) +
+                                           " size: 0x" + Long.toHexString(size) +
+                                           " elemOffset: 0x" + Long.toHexString(elemOffset) +
+                                           " expected: 0x" + Long.toHexString(expected) +
+                                           " != actual: 0x" + Long.toHexString(actual));
+            }
+        }
+    }
+
+
+    /**
+     * Copy and byte swap data from the source to the destination
+     *
+     * This method will pre-populate the whole source and destination
+     * buffers with verification friendly data. It will then use
+     * copySwapMemory to fill part of the destination buffer with
+     * swapped data from the source. Some space (padding) will be
+     * left before and after the data in the destination buffer, which
+     * should not be touched/overwritten by the copy call.
+     *
+     * Note: Both source and destination buffers will be overwritten!
+     *
+     * @param src source buffer to copy from
+     * @param srcOffset the offset (in bytes) in the source buffer, relative to
+     *        the first array element, at which to start reading data
+     * @param dst destination buffer to copy to
+     * @param dstOffset the offset (in bytes) in the destination
+     *        buffer, relative to the first array element, at which to
+     *        start writing data
+     * @param bufSize the size (in bytes) of the src and dst arrays
+     * @param copyBytes the size (in bytes) of the copy to perform,
+     *        must be a multiple of elemSize
+     * @param elemSize the size (in bytes) of the elements to byte swap
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void testCopySwap(GenericPointer src, long srcOffset,
+                              GenericPointer dst, long dstOffset,
+                              long bufSize, long copyBytes, long elemSize) {
+        if (!isAligned(copyBytes, elemSize)) {
+            throw new IllegalArgumentException(
+                "copyBytes (" + copyBytes + ") must be a multiple of elemSize (" + elemSize + ")");
+        }
+        if (src.isOnHeap() && !isAligned(srcOffset, elemSize)) {
+            throw new IllegalArgumentException(
+                "srcOffset (" + srcOffset + ") must be a multiple of elemSize (" + elemSize + ")");
+        }
+        if (dst.isOnHeap() && !isAligned(dstOffset, elemSize)) {
+            throw new IllegalArgumentException(
+                "dstOffset (" + dstOffset + ") must be a multiple of elemSize (" + elemSize + ")");
+        }
+        if (srcOffset + copyBytes > bufSize) {
+            throw new IllegalArgumentException(
+                "srcOffset (" + srcOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
+        }
+        if (dstOffset + copyBytes > bufSize) {
+            throw new IllegalArgumentException(
+                "dstOffset (" + dstOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
+        }
+
+        // Initialize the whole source buffer with a verification friendly pattern (no 0x00 bytes)
+        initVerificationData(src, bufSize, elemSize);
+        if (!src.equals(dst)) {
+            initVerificationData(dst, bufSize, elemSize);
+        }
+
+        if (DEBUG) {
+            System.out.println("===before===");
+            for (int offset = 0; offset < bufSize; offset += elemSize) {
+                long srcValue = getArrayElem(src, offset, elemSize);
+                long dstValue = getArrayElem(dst, offset, elemSize);
+
+                System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
+                                 " src=0x" + Long.toHexString(srcValue) +
+                                 " dst=0x" + Long.toHexString(dstValue));
+            }
+        }
+
+        // Copy & swap data into the middle of the destination buffer
+        UNSAFE.copySwapMemory(src.getObject(),
+                              src.getOffset() + srcOffset,
+                              dst.getObject(),
+                              dst.getOffset() + dstOffset,
+                              copyBytes,
+                              elemSize);
+
+        if (DEBUG) {
+            System.out.println("===after===");
+            for (int offset = 0; offset < bufSize; offset += elemSize) {
+                long srcValue = getArrayElem(src, offset, elemSize);
+                long dstValue = getArrayElem(dst, offset, elemSize);
+
+                System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
+                                 " src=0x" + Long.toHexString(srcValue) +
+                                 " dst=0x" + Long.toHexString(dstValue));
+            }
+        }
+
+        // Verify the the front padding is unchanged
+        verifyUnswappedData(dst, 0, dstOffset);
+
+        // Verify swapped data
+        verifySwappedData(dst, srcOffset, dstOffset, copyBytes, elemSize);
+
+        // Verify that the back back padding is unchanged
+        long frontAndDataBytes = dstOffset + copyBytes;
+        long trailingBytes = bufSize - frontAndDataBytes;
+        verifyUnswappedData(dst, frontAndDataBytes, trailingBytes);
+    }
+
+    /**
+     * Test various configurations copy-swapping from one buffer to the other
+     *
+     * @param src the source buffer to copy from
+     * @param dst the destination buffer to copy to
+     * @param size size (in bytes) of the buffers
+     * @param elemSize size (in bytes) of the individual elements
+     *
+     * @throws RuntimeException if an error is found
+     */
+    public void testBufferPair(GenericPointer src, GenericPointer dst, long size, long elemSize) {
+        // offset in source from which to start reading data
+        for (long srcOffset = 0; srcOffset < size; srcOffset += (src.isOnHeap() ? elemSize : 1)) {
+
+            // offset in destination at which to start writing data
+            for (int dstOffset = 0; dstOffset < size; dstOffset += (dst.isOnHeap() ? elemSize : 1)) {
+
+                // number of bytes to copy
+                long maxCopyBytes = Math.min(size - srcOffset, size - dstOffset);
+                for (long copyBytes = 0; copyBytes < maxCopyBytes; copyBytes += elemSize) {
+                    try {
+                        testCopySwap(src, srcOffset, dst, dstOffset, size, copyBytes, elemSize);
+                    } catch (RuntimeException e) {
+                        // Wrap the exception in another exception to catch the relevant configuration data
+                        throw new RuntimeException("testBufferPair: " +
+                                                   "src=" + src +
+                                                   " dst=" + dst +
+                                                   " elemSize=0x" + Long.toHexString(elemSize) +
+                                                   " copyBytes=0x" + Long.toHexString(copyBytes) +
+                                                   " srcOffset=0x" + Long.toHexString(srcOffset) +
+                                                   " dstOffset=0x" + Long.toHexString(dstOffset),
+                                                   e);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Test copying between various permutations of buffers
+     *
+     * @param buffers buffers to permute (src x dst)
+     * @param size size (in bytes) of buffers
+     * @param elemSize size (in bytes) of individual elements
+     *
+     * @throws RuntimeException if an error is found
+     */
+    public void testPermuteBuffers(GenericPointer[] buffers, long size, long elemSize) {
+        for (int srcIndex = 0; srcIndex < buffers.length; srcIndex++) {
+            for (int dstIndex = 0; dstIndex < buffers.length; dstIndex++) {
+                testBufferPair(buffers[srcIndex], buffers[dstIndex], size, elemSize);
+            }
+        }
+    }
+
+    /**
+     * Test copying of a specific element size
+     *
+     * @param size size (in bytes) of buffers to allocate
+     * @param elemSize size (in bytes) of individual elements
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void testElemSize(long size, long elemSize) {
+        long buf1Raw = 0;
+        long buf2Raw = 0;
+
+        try {
+            buf1Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
+            long buf1 = alignUp(buf1Raw, BASE_ALIGNMENT);
+
+            buf2Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
+            long buf2 = alignUp(buf2Raw, BASE_ALIGNMENT);
+
+            GenericPointer[] buffers = {
+                new GenericPointer(buf1),
+                new GenericPointer(buf2),
+                new GenericPointer(allocArray(size, elemSize)),
+                new GenericPointer(allocArray(size, elemSize))
+            };
+
+            testPermuteBuffers(buffers, size, elemSize);
+        } finally {
+            if (buf1Raw != 0) {
+                UNSAFE.freeMemory(buf1Raw);
+            }
+            if (buf2Raw != 0) {
+                UNSAFE.freeMemory(buf2Raw);
+            }
+        }
+    }
+
+    /**
+     * Verify that small copy swaps work
+     */
+    private void testSmallCopy() {
+        int smallBufSize = SMALL_COPY_SIZE;
+
+        // Test various element types and heap/native combinations
+        for (long elemSize = 2; elemSize <= 8; elemSize <<= 1) {
+            testElemSize(smallBufSize, elemSize);
+        }
+    }
+
+
+    /**
+     * Verify that large copy swaps work
+     */
+    private void testLargeCopy() {
+        long size = 2 * GB + 8;
+        long bufRaw = 0;
+
+        // Check that a large native copy succeeds
+        try {
+            try {
+                bufRaw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
+            } catch (OutOfMemoryError e) {
+                // Accept failure, skip test
+                return;
+            }
+
+            long buf = alignUp(bufRaw, BASE_ALIGNMENT);
+
+            UNSAFE.copySwapMemory(null, buf, null, buf, size, 8);
+        } catch (Exception e) {
+            throw new RuntimeException("copySwapMemory of large buffer failed");
+        } finally {
+            if (bufRaw != 0) {
+                UNSAFE.freeMemory(bufRaw);
+            }
+        }
+    }
+
+    /**
+     * Run positive tests
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void testPositive() {
+        testSmallCopy();
+        testLargeCopy();
+    }
+
+    /**
+     * Run negative tests, testing corner cases and the various exceptions
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void testNegative() {
+        long bufRaw = 0;
+
+        try {
+            bufRaw = UNSAFE.allocateMemory(1024);
+            long buf = alignUp(bufRaw, BASE_ALIGNMENT);
+            short[] arr = new short[16];
+
+            // Check various illegal element sizes
+            for (int elemSize = 2; elemSize <= 8; elemSize <<= 1) {
+                long[] illegalSizes = { -1, 1, elemSize - 1, elemSize + 1, elemSize * 2 - 1 };
+                for (long size : illegalSizes) {
+                    try {
+                        // Check that illegal elemSize throws an IAE
+                        UNSAFE.copySwapMemory(null, buf, null, buf, size, elemSize);
+                        throw new RuntimeException("copySwapMemory failed to throw IAE for size=" + size + " elemSize=" + elemSize);
+                    } catch (IllegalArgumentException e) {
+                        // good
+                    }
+                }
+            }
+
+            try {
+                // Check that negative srcOffset throws an IAE
+                UNSAFE.copySwapMemory(arr, -1, arr, UNSAFE.arrayBaseOffset(arr.getClass()), 16, 2);
+                throw new RuntimeException("copySwapMemory failed to throw IAE for srcOffset=-1");
+            } catch (IllegalArgumentException e) {
+                // good
+            }
+
+            try {
+                // Check that negative dstOffset throws an IAE
+                UNSAFE.copySwapMemory(arr, UNSAFE.arrayBaseOffset(arr.getClass()), arr, -1, 16, 2);
+                throw new RuntimeException("copySwapMemory failed to throw IAE for destOffset=-1");
+            } catch (IllegalArgumentException e) {
+                // good
+            }
+
+            long illegalElemSizes[] = { 0, 1, 3, 5, 6, 7, 9, 10, -1 };
+            for (long elemSize : illegalElemSizes) {
+                try {
+                    // Check that elemSize 1 throws an IAE
+                    UNSAFE.copySwapMemory(null, buf, null, buf, 16, elemSize);
+                    throw new RuntimeException("copySwapMemory failed to throw NPE");
+                } catch (IllegalArgumentException e) {
+                    // good
+                }
+            }
+
+            try {
+                // Check that a NULL source throws NPE
+                UNSAFE.copySwapMemory(null, 0, null, buf, 16, 2);
+                throw new RuntimeException("copySwapMemory failed to throw NPE");
+            } catch (NullPointerException e) {
+                // good
+            }
+
+            try {
+                // Check that a NULL destination throws NPE
+                UNSAFE.copySwapMemory(null, buf, null, 0, 16, 2);
+                throw new RuntimeException("copySwapMemory failed to throw NPE");
+            } catch (NullPointerException e) {
+                // good
+            }
+
+            try {
+                // Check that a reference array destination throws IAE
+                UNSAFE.copySwapMemory(null, buf, new Object[16], UNSAFE.arrayBaseOffset(Object[].class), 16, 8);
+                throw new RuntimeException("copySwapMemory failed to throw NPE");
+            } catch (IllegalArgumentException e) {
+                // good
+            }
+
+            // Check that invalid source & dest pointers throw IAEs (only relevant on 32-bit platforms)
+            if (UNSAFE.addressSize() == 4) {
+                long invalidPtr = (long)1 << 35; // Pick a random bit in upper 32 bits
+
+                try {
+                    // Check that an invalid (not 32-bit clean) source pointer throws IAE
+                    UNSAFE.copySwapMemory(null, invalidPtr, null, buf, 16, 2);
+                    throw new RuntimeException("copySwapMemory failed to throw IAE for srcOffset 0x" +
+                                               Long.toHexString(invalidPtr));
+                } catch (IllegalArgumentException e) {
+                    // good
+                }
+
+                try {
+                    // Check that an invalid (not 32-bit clean) source pointer throws IAE
+                    UNSAFE.copySwapMemory(null, buf, null, invalidPtr, 16, 2);
+                    throw new RuntimeException("copySwapMemory failed to throw IAE for destOffset 0x" +
+                                               Long.toHexString(invalidPtr));
+                } catch (IllegalArgumentException e) {
+                    // good
+                }
+            }
+        } finally {
+            if (bufRaw != 0) {
+                UNSAFE.freeMemory(bufRaw);
+            }
+        }
+    }
+
+    /**
+     * Run all tests
+     *
+     * @throws RuntimeException if an error is found
+     */
+    private void test() {
+        testPositive();
+        testNegative();
+    }
+
+    public static void main(String[] args) {
+        CopySwap cs = new CopySwap();
+        cs.test();
+    }
+
+    /**
+     * Helper class to represent a "pointer" - either a heap array or
+     * a pointer to a native buffer.
+     *
+     * In the case of a native pointer, the Object is null and the offset is
+     * the absolute address of the native buffer.
+     *
+     * In the case of a heap object, the Object is a primitive array, and
+     * the offset will be set to the base offset to the first element, meaning
+     * the object and the offset together form a double-register pointer.
+     */
+    static class GenericPointer {
+        private final Object o;
+        private final long offset;
+
+        private GenericPointer(Object o, long offset) {
+            this.o = o;
+            this.offset = offset;
+        }
+
+        public String toString() {
+            return "GenericPointer(o={" + o + "}, offset=0x" + Long.toHexString(offset) + ")";
+        }
+
+        public boolean equals(Object other) {
+            if (!(other instanceof GenericPointer)) {
+                return false;
+            }
+
+            GenericPointer otherp = (GenericPointer)other;
+
+            return o == otherp.o && offset == otherp.offset;
+        }
+
+        GenericPointer(Object o) {
+            this(o, UNSAFE.arrayBaseOffset(o.getClass()));
+        }
+
+        GenericPointer(long offset) {
+            this(null, offset);
+        }
+
+        public boolean isOnHeap() {
+            return o != null;
+        }
+
+        public Object getObject() {
+            return o;
+        }
+
+        public long getOffset() {
+            return offset;
+        }
+    }
+}
--- a/jdk/test/sun/misc/SunMiscSignalTest.java	Wed Feb 24 14:36:53 2016 +0300
+++ b/jdk/test/sun/misc/SunMiscSignalTest.java	Wed Feb 24 08:58:31 2016 -0800
@@ -180,6 +180,12 @@
         return newArray;
     }
 
+    // Return true if the signal is one of the shutdown signals known to the VM
+    private static boolean isShutdownSignal(Signal signal) {
+        String name = signal.getName();
+        return name.equals("INT") || name.equals("HUP") || name.equals("TERM");
+    }
+
     /**
      * Quick verification of supported signals using sun.misc.Signal.
      *
@@ -201,14 +207,24 @@
             Assert.assertEquals(signal.toString(), "SIG" + name, "toString() mismatch, ");
 
             try {
-                SignalHandler old = Signal.handle(signal, h);
+                orig = Signal.handle(signal, h);
+                printf("oldHandler: %s%n", orig);
                 Assert.assertEquals(CanRegister.YES, register, "Unexpected handle succeeded " + name);
                 try {
                     Signal.raise(signal);
                     Assert.assertEquals(CanRaise.YES, raise, "Unexpected raise success for " + name);
                     Invoked inv = h.semaphore().tryAcquire(Utils.adjustTimeout(100L),
                             TimeUnit.MILLISECONDS) ? Invoked.YES : Invoked.NO;
-                    Assert.assertEquals(inv, invoked, "handler not invoked;");
+                    if (!isShutdownSignal(signal)) {
+                        // Normal case
+                        Assert.assertEquals(inv, invoked, "handler not invoked;");
+                    } else {
+                        if (orig == SignalHandler.SIG_IGN) {
+                            Assert.assertEquals(inv, Invoked.NO, "handler should not be invoked");
+                        } else {
+                            Assert.assertEquals(inv, invoked, "handler not invoked;");
+                        }
+                    }
                 } catch (IllegalArgumentException uoe3) {
                     Assert.assertNotEquals(CanRaise.YES, raise, "raise failed for " + name +
                             ": " + uoe3.getMessage());
@@ -270,14 +286,22 @@
     }
 
     // Test expected exception when raising a signal when no handler defined
-    @Test(expectedExceptions = IllegalArgumentException.class)
+    @Test
     static void testRaiseNoConsumer() {
         Signal signal = new Signal("INT");
         SignalHandler orig = null;
         try {
-            Signal.handle(signal, SignalHandler.SIG_DFL);
+            orig = Signal.handle(signal, SignalHandler.SIG_DFL);
+            printf("oldHandler: %s%n", orig);
+            if (orig == SignalHandler.SIG_IGN) {
+                // SIG_IGN for TERM means it cannot be handled
+                return;
+            }
             Signal.raise(signal);
-        }  finally {
+            Assert.fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            printf("IAE message: %s%n", iae.getMessage());
+        } finally {
             // Restore original signal handler
             if (orig != null && signal != null) {
                 Signal.handle(signal, orig);
@@ -296,7 +320,13 @@
         }
         Handler handler = new Handler();
         Signal signal = new Signal("INT");
-        Signal.handle(signal, handler);
+        SignalHandler orig = Signal.handle(signal, handler);
+        printf("oldHandler: %s%n", orig);
+        if (orig == SignalHandler.SIG_IGN) {
+            // SIG_IGN for INT means it cannot be handled
+            return;
+        }
+
         Signal.raise(signal);
         boolean handled = handler.semaphore()
                 .tryAcquire(Utils.adjustTimeout(100L), TimeUnit.MILLISECONDS);
@@ -332,6 +362,10 @@
         Handler h1 = new Handler();
         Handler h2 = new Handler();
         SignalHandler orig = Signal.handle(signal, h1);
+        if (orig == SignalHandler.SIG_IGN) {
+            // SIG_IGN for TERM means it cannot be handled
+            return;
+        }
 
         try {
             SignalHandler prev = Signal.handle(signal, h2);