Merge
authorjwilhelm
Tue, 22 Jan 2019 19:56:19 +0100
changeset 53430 ccfd4e614bb8
parent 53423 1ae823617395 (current diff)
parent 53429 1b292ae4eb50 (diff)
child 53431 5abf1da9e9ad
Merge
src/hotspot/share/jvmci/jvmciEnv.cpp
src/hotspot/share/jvmci/jvmciEnv.hpp
src/hotspot/share/opto/compile.hpp
src/java.base/share/conf/security/java.security
test/hotspot/jtreg/ProblemList-graal.txt
test/jdk/ProblemList.txt
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, 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
@@ -63,9 +63,30 @@
 {
   // Get Jvmti capabilities under lock to get consistent values.
   MutexLocker mu(JvmtiThreadState_lock);
-  _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();
-  _jvmti_can_access_local_variables     = JvmtiExport::can_access_local_variables();
-  _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions();
+  _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;
+  _jvmti_can_access_local_variables     = JvmtiExport::can_access_local_variables() ? 1 : 0;
+  _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
+  _jvmti_can_pop_frame                  = JvmtiExport::can_pop_frame() ? 1 : 0;
+}
+
+bool JVMCIEnv::jvmti_state_changed() const {
+  if (!jvmti_can_access_local_variables() &&
+      JvmtiExport::can_access_local_variables()) {
+    return true;
+  }
+  if (!jvmti_can_hotswap_or_post_breakpoint() &&
+      JvmtiExport::can_hotswap_or_post_breakpoint()) {
+    return true;
+  }
+  if (!jvmti_can_post_on_exceptions() &&
+      JvmtiExport::can_post_on_exceptions()) {
+    return true;
+  }
+  if (!jvmti_can_pop_frame() &&
+      JvmtiExport::can_pop_frame()) {
+    return true;
+  }
+  return false;
 }
 
 // ------------------------------------------------------------------
@@ -413,11 +434,9 @@
 JVMCIEnv::CodeInstallResult JVMCIEnv::validate_compile_task_dependencies(Dependencies* dependencies, Handle compiled_code,
                                                                          JVMCIEnv* env, char** failure_detail) {
   // If JVMTI capabilities were enabled during compile, the compilation is invalidated.
-  if (env != NULL) {
-    if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) {
-      *failure_detail = (char*) "Hotswapping or breakpointing was enabled during compilation";
-      return JVMCIEnv::dependencies_failed;
-    }
+  if (env != NULL && env->jvmti_state_changed()) {
+    *failure_detail = (char*) "Jvmti state change during compilation invalidated dependencies";
+    return JVMCIEnv::dependencies_failed;
   }
 
   // Dependencies must be checked when the system dictionary changes
--- a/src/hotspot/share/jvmci/jvmciEnv.hpp	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/hotspot/share/jvmci/jvmciEnv.hpp	Tue Jan 22 19:56:19 2019 +0100
@@ -105,10 +105,13 @@
   // Specifies if _failure_reason is on the C heap.
   bool             _failure_reason_on_C_heap;
 
-  // Cache JVMTI state
-  bool  _jvmti_can_hotswap_or_post_breakpoint;
-  bool  _jvmti_can_access_local_variables;
-  bool  _jvmti_can_post_on_exceptions;
+  // Cache JVMTI state. Defined as bytes so that reading them from Java
+  // via Unsafe is well defined (the C++ type for bool is implementation
+  // defined and may not be the same as a Java boolean).
+  jbyte  _jvmti_can_hotswap_or_post_breakpoint;
+  jbyte  _jvmti_can_access_local_variables;
+  jbyte  _jvmti_can_post_on_exceptions;
+  jbyte  _jvmti_can_pop_frame;
 
   // Implementation methods for loading and constant pool access.
   static Klass* get_klass_by_name_impl(Klass* accessing_klass,
@@ -147,6 +150,12 @@
 public:
   CompileTask* task() { return _task; }
 
+  bool  jvmti_state_changed() const;
+  bool  jvmti_can_hotswap_or_post_breakpoint() const { return  _jvmti_can_hotswap_or_post_breakpoint != 0; }
+  bool  jvmti_can_access_local_variables() const     { return  _jvmti_can_access_local_variables != 0; }
+  bool  jvmti_can_post_on_exceptions() const         { return  _jvmti_can_post_on_exceptions != 0; }
+  bool  jvmti_can_pop_frame() const                  { return  _jvmti_can_pop_frame != 0; }
+
   const char* failure_reason() { return _failure_reason; }
   bool failure_reason_on_C_heap() { return _failure_reason_on_C_heap; }
   bool retryable() { return _retryable; }
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -182,13 +182,17 @@
   nonstatic_field(JavaThread,                  _pending_failed_speculation,                   long)                                  \
   nonstatic_field(JavaThread,                  _pending_transfer_to_interpreter,              bool)                                  \
   nonstatic_field(JavaThread,                  _jvmci_counters,                               jlong*)                                \
+  nonstatic_field(JavaThread,                  _should_post_on_exceptions_flag,               int)                                   \
   nonstatic_field(JavaThread,                  _reserved_stack_activation,                    address)                               \
                                                                                                                                      \
   static_field(java_lang_Class,                _klass_offset,                                 int)                                   \
   static_field(java_lang_Class,                _array_klass_offset,                           int)                                   \
                                                                                                                                      \
   nonstatic_field(JVMCIEnv,                    _task,                                         CompileTask*)                          \
-  nonstatic_field(JVMCIEnv,                    _jvmti_can_hotswap_or_post_breakpoint,         bool)                                  \
+  nonstatic_field(JVMCIEnv,                    _jvmti_can_hotswap_or_post_breakpoint,         jbyte)                                 \
+  nonstatic_field(JVMCIEnv,                    _jvmti_can_access_local_variables,             jbyte)                                 \
+  nonstatic_field(JVMCIEnv,                    _jvmti_can_post_on_exceptions,                 jbyte)                                 \
+  nonstatic_field(JVMCIEnv,                    _jvmti_can_pop_frame,                          jbyte)                                 \
                                                                                                                                      \
   nonstatic_field(InvocationCounter,           _counter,                                      unsigned int)                          \
                                                                                                                                      \
--- a/src/hotspot/share/opto/compile.cpp	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/hotspot/share/opto/compile.cpp	Tue Jan 22 19:56:19 2019 +0100
@@ -2188,13 +2188,16 @@
 // They were inserted during parsing (see add_safepoint()) to make
 // infinite loops without calls or exceptions visible to root, i.e.,
 // useful.
-void Compile::remove_root_to_sfpts_edges() {
+void Compile::remove_root_to_sfpts_edges(PhaseIterGVN& igvn) {
   Node *r = root();
   if (r != NULL) {
     for (uint i = r->req(); i < r->len(); ++i) {
       Node *n = r->in(i);
       if (n != NULL && n->is_SafePoint()) {
         r->rm_prec(i);
+        if (n->outcnt() == 0) {
+          igvn.remove_dead_node(n);
+        }
         --i;
       }
     }
@@ -2263,7 +2266,7 @@
 
   // Now that all inlining is over, cut edge from root to loop
   // safepoints
-  remove_root_to_sfpts_edges();
+  remove_root_to_sfpts_edges(igvn);
 
   // Remove the speculative part of types and clean up the graph from
   // the extra CastPP nodes whose only purpose is to carry them. Do
--- a/src/hotspot/share/opto/compile.hpp	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/hotspot/share/opto/compile.hpp	Tue Jan 22 19:56:19 2019 +0100
@@ -1088,7 +1088,7 @@
   void inline_string_calls(bool parse_time);
   void inline_boxing_calls(PhaseIterGVN& igvn);
   bool optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode);
-  void remove_root_to_sfpts_edges();
+  void remove_root_to_sfpts_edges(PhaseIterGVN& igvn);
 
   // Matching, CFG layout, allocation, code generation
   PhaseCFG*         cfg()                       { return _cfg; }
--- a/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -39,17 +39,19 @@
 enum CADistrustPolicy {
     /**
      * Distrust TLS Server certificates anchored by a Symantec root CA and
-     * issued after April 16, 2019. If enabled, this policy is currently
-     * enforced by the PKIX and SunX509 TrustManager implementations of the
-     * SunJSSE provider implementation.
+     * issued after April 16, 2019 (with exceptions for a couple of subordinate
+     * CAs, see the jdk.security.caDistrustPolicies definition in the
+     * java.security file for more details). If enabled, this policy is
+     * currently enforced by the PKIX and SunX509 TrustManager implementations
+     * of the SunJSSE provider implementation.
      */
     SYMANTEC_TLS {
-        void checkDistrust(String variant, X509Certificate anchor,
-                           X509Certificate ee) throws ValidatorException {
+        void checkDistrust(String variant, X509Certificate[] chain)
+                           throws ValidatorException {
             if (!variant.equals(Validator.VAR_TLS_SERVER)) {
                 return;
             }
-            SymantecTLSPolicy.checkDistrust(anchor, ee);
+            SymantecTLSPolicy.checkDistrust(chain);
         }
     };
 
@@ -57,13 +59,13 @@
      * Checks if the end-entity certificate is distrusted.
      *
      * @param variant the type of certificate being checked
-     * @param anchor the trust anchor certificate
-     * @param ee the end-entity certificate to check
+     * @param chain the end-entity's certificate chain. The end entity cert
+     *              is at index 0, the trust anchor at index n-1.
      * @throws ValidatorException if the end-entity certificate is distrusted
      */
     abstract void checkDistrust(String variant,
-                                X509Certificate anchor,
-                                X509Certificate ee) throws ValidatorException;
+                                X509Certificate[] chain)
+                                throws ValidatorException;
 
     // The policies set in the jdk.security.caDistrustPolicies property.
     static final EnumSet<CADistrustPolicy> POLICIES = parseProperty();
--- a/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -132,27 +132,26 @@
         return new EndEntityChecker(type, variant);
     }
 
-    void check(X509Certificate cert, Object parameter,
-            boolean checkUnresolvedCritExts, X509Certificate anchor)
-            throws CertificateException {
+    void check(X509Certificate[] chain, Object parameter,
+            boolean checkUnresolvedCritExts) throws CertificateException {
 
         if (variant.equals(Validator.VAR_GENERIC)) {
             return; // no checks
         }
 
-        Set<String> exts = getCriticalExtensions(cert);
+        Set<String> exts = getCriticalExtensions(chain[0]);
         if (variant.equals(Validator.VAR_TLS_SERVER)) {
-            checkTLSServer(cert, (String)parameter, exts);
+            checkTLSServer(chain[0], (String)parameter, exts);
         } else if (variant.equals(Validator.VAR_TLS_CLIENT)) {
-            checkTLSClient(cert, exts);
+            checkTLSClient(chain[0], exts);
         } else if (variant.equals(Validator.VAR_CODE_SIGNING)) {
-            checkCodeSigning(cert, exts);
+            checkCodeSigning(chain[0], exts);
         } else if (variant.equals(Validator.VAR_JCE_SIGNING)) {
-            checkCodeSigning(cert, exts);
+            checkCodeSigning(chain[0], exts);
         } else if (variant.equals(Validator.VAR_PLUGIN_CODE_SIGNING)) {
-            checkCodeSigning(cert, exts);
+            checkCodeSigning(chain[0], exts);
         } else if (variant.equals(Validator.VAR_TSA_SERVER)) {
-            checkTSAServer(cert, exts);
+            checkTSAServer(chain[0], exts);
         } else {
             throw new CertificateException("Unknown variant: " + variant);
         }
@@ -165,7 +164,7 @@
         // check if certificate should be distrusted according to policies
         // set in the jdk.security.caDistrustPolicies security property
         for (CADistrustPolicy policy : CADistrustPolicy.POLICIES) {
-            policy.checkDistrust(variant, anchor, cert);
+            policy.checkDistrust(variant, chain);
         }
     }
 
--- a/src/java.base/share/classes/sun/security/validator/SymantecTLSPolicy.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/java.base/share/classes/sun/security/validator/SymantecTLSPolicy.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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,6 +29,7 @@
 import java.time.Month;
 import java.time.ZoneOffset;
 import java.util.Date;
+import java.util.Map;
 import java.util.Set;
 
 import sun.security.x509.X509CertImpl;
@@ -119,6 +120,24 @@
         "2399561127A57125DE8CEFEA610DDF2FA078B5C8067F4E828290BFB860E84B3C"
     );
 
+    private static final LocalDate DECEMBER_31_2019 =
+        LocalDate.of(2019, Month.DECEMBER, 31);
+    // SHA-256 certificate fingerprints of subCAs with later distrust dates
+    private static final Map<String, LocalDate> EXEMPT_SUBCAS = Map.of(
+        // Subject DN: C=US, O=Apple Inc., OU=Certification Authority,
+        //             CN=Apple IST CA 2 - G1
+        // Issuer DN: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
+        "AC2B922ECFD5E01711772FEA8ED372DE9D1E2245FCE3F57A9CDBEC77296A424B",
+        DECEMBER_31_2019,
+        // Subject DN: C=US, O=Apple Inc., OU=Certification Authority,
+        //             CN=Apple IST CA 8 - G1
+        // Issuer DN: CN=GeoTrust Primary Certification Authority - G2,
+        //            OU=(c) 2007 GeoTrust Inc. - For authorized use only,
+        //            O=GeoTrust Inc., C=US
+        "A4FE7C7F15155F3F0AEF7AAA83CF6E06DEB97CA3F909DF920AC1490882D488ED",
+        DECEMBER_31_2019
+    );
+
     // Any TLS Server certificate that is anchored by one of the Symantec
     // roots above and is issued after this date will be distrusted.
     private static final LocalDate APRIL_16_2019 =
@@ -128,28 +147,47 @@
      * This method assumes the eeCert is a TLS Server Cert and chains back to
      * the anchor.
      *
-     * @param anchor the trust anchor certificate
-     * @param eeCert the certificate to check
+     * @param chain the end-entity's certificate chain. The end entity cert
+     *              is at index 0, the trust anchor at index n-1.
      * @throws ValidatorException if the certificate is distrusted
      */
-    static void checkDistrust(X509Certificate anchor,
-                              X509Certificate eeCert)
+    static void checkDistrust(X509Certificate[] chain)
                               throws ValidatorException {
-        String fp = (anchor instanceof X509CertImpl)
-                    ? ((X509CertImpl)anchor).getFingerprint("SHA-256")
-                    : X509CertImpl.getFingerprint("SHA-256", anchor);
-        if (FINGERPRINTS.contains(fp)) {
-            // reject if certificate is issued after April 16, 2019
-            Date notBefore = eeCert.getNotBefore();
+        X509Certificate anchor = chain[chain.length-1];
+        if (FINGERPRINTS.contains(fingerprint(anchor))) {
+            Date notBefore = chain[0].getNotBefore();
             LocalDate ldNotBefore = LocalDate.ofInstant(notBefore.toInstant(),
                                                         ZoneOffset.UTC);
-            if (ldNotBefore.isAfter(APRIL_16_2019)) {
-                throw new ValidatorException
-                    ("TLS Server certificate issued after " + APRIL_16_2019 +
-                     " and anchored by a distrusted legacy Symantec root CA: "
-                     + anchor.getSubjectX500Principal(),
-                     ValidatorException.T_UNTRUSTED_CERT, anchor);
+            // check if chain goes through one of the subCAs
+            if (chain.length > 2) {
+                X509Certificate subCA = chain[chain.length-2];
+                LocalDate distrustDate = EXEMPT_SUBCAS.get(fingerprint(subCA));
+                if (distrustDate != null) {
+                    // reject if certificate is issued after specified date
+                    checkNotBefore(ldNotBefore, distrustDate, anchor);
+                    return; // success
+                }
             }
+            // reject if certificate is issued after April 16, 2019
+            checkNotBefore(ldNotBefore, APRIL_16_2019, anchor);
+        }
+    }
+
+    private static String fingerprint(X509Certificate cert) {
+        return (cert instanceof X509CertImpl)
+               ? ((X509CertImpl)cert).getFingerprint("SHA-256")
+               : X509CertImpl.getFingerprint("SHA-256", cert);
+    }
+
+    private static void checkNotBefore(LocalDate notBeforeDate,
+            LocalDate distrustDate, X509Certificate anchor)
+            throws ValidatorException {
+        if (notBeforeDate.isAfter(distrustDate)) {
+            throw new ValidatorException
+                ("TLS Server certificate issued after " + distrustDate +
+                 " and anchored by a distrusted legacy Symantec root CA: "
+                 + anchor.getSubjectX500Principal(),
+                 ValidatorException.T_UNTRUSTED_CERT, anchor);
         }
     }
 
--- a/src/java.base/share/classes/sun/security/validator/Validator.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/java.base/share/classes/sun/security/validator/Validator.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -274,9 +274,8 @@
             // redundant.
             boolean checkUnresolvedCritExts =
                     (type == TYPE_PKIX) ? false : true;
-            endEntityChecker.check(chain[0], parameter,
-                                   checkUnresolvedCritExts,
-                                   chain[chain.length-1]);
+            endEntityChecker.check(chain, parameter,
+                                   checkUnresolvedCritExts);
         }
 
         return chain;
--- a/src/java.base/share/conf/security/java.security	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/java.base/share/conf/security/java.security	Tue Jan 22 19:56:19 2019 +0100
@@ -1167,8 +1167,15 @@
 # of which represents a policy for determining if a CA should be distrusted.
 # The supported values are:
 #
-# SYMANTEC_TLS : Distrust TLS Server certificates anchored by
-#                a Symantec root CA and issued after April 16, 2019.
+#   SYMANTEC_TLS : Distrust TLS Server certificates anchored by a Symantec
+#   root CA and issued after April 16, 2019 unless issued by one of the
+#   following subordinate CAs which have a later distrust date:
+#     1. Apple IST CA 2 - G1, SHA-256 fingerprint:
+#        AC2B922ECFD5E01711772FEA8ED372DE9D1E2245FCE3F57A9CDBEC77296A424B
+#        Distrust after December 31, 2019.
+#     2. Apple IST CA 8 - G1, SHA-256 fingerprint:
+#        A4FE7C7F15155F3F0AEF7AAA83CF6E06DEB97CA3F909DF920AC1490882D488ED
+#        Distrust after December 31, 2019.
 #
 # Leading and trailing whitespace surrounding each value are ignored.
 # Unknown values are ignored. If the property is commented out or set to the
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -309,8 +309,11 @@
     public final int jvmAccWrittenFlags = getConstant("JVM_ACC_WRITTEN_FLAGS", Integer.class);
     public final int jvmAccSynthetic = getConstant("JVM_ACC_SYNTHETIC", Integer.class);
 
+    public final int jvmciCompileStateCanPostOnExceptionsOffset = getFieldOffset("JVMCIEnv::_jvmti_can_post_on_exceptions", Integer.class, "jbyte", Integer.MIN_VALUE);
+
     public final int threadTlabOffset = getFieldOffset("Thread::_tlab", Integer.class, "ThreadLocalAllocBuffer");
     public final int javaThreadAnchorOffset = getFieldOffset("JavaThread::_anchor", Integer.class, "JavaFrameAnchor");
+    public final int javaThreadShouldPostOnExceptionsFlagOffset = getFieldOffset("JavaThread::_should_post_on_exceptions_flag", Integer.class, "int", Integer.MIN_VALUE);
     public final int threadObjectOffset = getFieldOffset("JavaThread::_threadObj", Integer.class, "oop");
     public final int osThreadOffset = getFieldOffset("JavaThread::_osthread", Integer.class, "OSThread*");
     public final int threadIsMethodHandleReturnOffset = getFieldOffset("JavaThread::_is_method_handle_return", Integer.class, "int");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -124,7 +124,7 @@
         Plugins plugins = new Plugins(invocationPlugins);
         NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes);
         HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes);
-        HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin);
+        HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin, config, wordTypes);
 
         plugins.appendTypePlugin(nodePlugin);
         plugins.appendNodePlugin(nodePlugin);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -24,21 +24,41 @@
 
 package org.graalvm.compiler.hotspot.meta;
 
+import static jdk.vm.ci.meta.DeoptimizationAction.None;
+import static jdk.vm.ci.meta.DeoptimizationReason.TransferToInterpreter;
 import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
 
+import org.graalvm.compiler.core.common.CompilationIdentifier;
+import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.StampPair;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotCompilationIdentifier;
+import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
+import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
 import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.FixedGuardNode;
+import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.LogicNode;
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderTool;
 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.TypePlugin;
+import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
 import org.graalvm.compiler.nodes.util.ConstantFoldUtil;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordOperationPlugin;
+import jdk.internal.vm.compiler.word.LocationIdentity;
 
+import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
@@ -47,23 +67,30 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
+import java.lang.reflect.Field;
+import sun.misc.Unsafe;
+
 /**
- * This plugin handles the HotSpot-specific customizations of bytecode parsing:
- * <p>
- * {@link Word}-type rewriting for {@link GraphBuilderContext#parsingIntrinsic intrinsic} functions
- * (snippets and method substitutions), by forwarding to the {@link WordOperationPlugin}. Note that
- * we forward the {@link NodePlugin} and {@link TypePlugin} methods, but not the
+ * This plugin does HotSpot-specific customization of bytecode parsing:
+ * <ul>
+ * <li>{@link Word}-type rewriting for {@link GraphBuilderContext#parsingIntrinsic intrinsic}
+ * functions (snippets and method substitutions), by forwarding to the {@link WordOperationPlugin}.
+ * Note that we forward the {@link NodePlugin} and {@link TypePlugin} methods, but not the
  * {@link InlineInvokePlugin} methods implemented by {@link WordOperationPlugin}. The latter is not
  * necessary because HotSpot only uses the {@link Word} type in methods that are force-inlined,
- * i.e., there are never non-inlined invokes that involve the {@link Word} type.
- * <p>
- * Constant folding of field loads.
+ * i.e., there are never non-inlined invokes that involve the {@link Word} type.</li>
+ * <li>Constant folding of field loads.</li>
+ * </ul>
  */
 public final class HotSpotNodePlugin implements NodePlugin, TypePlugin {
     protected final WordOperationPlugin wordOperationPlugin;
+    private final GraalHotSpotVMConfig config;
+    private final HotSpotWordTypes wordTypes;
 
-    public HotSpotNodePlugin(WordOperationPlugin wordOperationPlugin) {
+    public HotSpotNodePlugin(WordOperationPlugin wordOperationPlugin, GraalHotSpotVMConfig config, HotSpotWordTypes wordTypes) {
         this.wordOperationPlugin = wordOperationPlugin;
+        this.config = config;
+        this.wordTypes = wordTypes;
     }
 
     @Override
@@ -180,4 +207,58 @@
         }
         return false;
     }
+
+    @Override
+    public FixedWithNextNode instrumentExceptionDispatch(StructuredGraph graph, FixedWithNextNode afterExceptionLoaded) {
+        CompilationIdentifier id = graph.compilationId();
+        if (id instanceof HotSpotCompilationIdentifier) {
+            HotSpotCompilationRequest request = ((HotSpotCompilationIdentifier) id).getRequest();
+            if (request != null) {
+                long compileState = request.getJvmciEnv();
+                if (compileState != 0 &&
+                                config.jvmciCompileStateCanPostOnExceptionsOffset != Integer.MIN_VALUE &&
+                                config.javaThreadShouldPostOnExceptionsFlagOffset != Integer.MIN_VALUE) {
+                    long canPostOnExceptionsOffset = compileState + config.jvmciCompileStateCanPostOnExceptionsOffset;
+                    boolean canPostOnExceptions = UNSAFE.getByte(canPostOnExceptionsOffset) != 0;
+                    if (canPostOnExceptions) {
+                        // If the exception capability is set, then generate code
+                        // to check the JavaThread.should_post_on_exceptions flag to see
+                        // if we actually need to report exception events for the current
+                        // thread. If not, take the fast path otherwise deoptimize.
+                        CurrentJavaThreadNode thread = graph.unique(new CurrentJavaThreadNode(wordTypes.getWordKind()));
+                        ValueNode offset = graph.unique(ConstantNode.forLong(config.javaThreadShouldPostOnExceptionsFlagOffset));
+                        AddressNode address = graph.unique(new OffsetAddressNode(thread, offset));
+                        ReadNode shouldPostException = graph.add(new ReadNode(address, JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION, StampFactory.intValue(), BarrierType.NONE));
+                        afterExceptionLoaded.setNext(shouldPostException);
+                        ValueNode zero = graph.unique(ConstantNode.forInt(0));
+                        LogicNode cond = graph.unique(new IntegerEqualsNode(shouldPostException, zero));
+                        FixedGuardNode check = graph.add(new FixedGuardNode(cond, TransferToInterpreter, None, false));
+                        shouldPostException.setNext(check);
+                        return check;
+                    }
+                }
+            }
+        }
+        return afterExceptionLoaded;
+    }
+
+    private static final LocationIdentity JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION = NamedLocationIdentity.mutable("JavaThread::_should_post_on_exceptions_flag");
+
+    private static final Unsafe UNSAFE = initUnsafe();
+
+    private static Unsafe initUnsafe() {
+        try {
+            // Fast path when we are trusted.
+            return Unsafe.getUnsafe();
+        } catch (SecurityException se) {
+            // Slow path when we are not trusted.
+            try {
+                Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+                theUnsafe.setAccessible(true);
+                return (Unsafe) theUnsafe.get(Unsafe.class);
+            } catch (Exception e) {
+                throw new RuntimeException("exception while trying to get Unsafe", e);
+            }
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, 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
@@ -1106,7 +1106,11 @@
         deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
+    /**
+     * @return the entry point to exception dispatch
+     */
     private AbstractBeginNode handleException(ValueNode exceptionObject, int bci, boolean deoptimizeOnly) {
+        FixedWithNextNode currentLastInstr = lastInstr;
         assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
         debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
 
@@ -1126,18 +1130,25 @@
             dispatchState.setRethrowException(true);
         }
         this.controlFlowSplit = true;
-        FixedWithNextNode finishedDispatch = finishInstruction(dispatchBegin, dispatchState);
+        FixedWithNextNode afterExceptionLoaded = finishInstruction(dispatchBegin, dispatchState);
 
         if (deoptimizeOnly) {
             DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
-            dispatchBegin.setNext(BeginNode.begin(deoptimizeNode));
+            afterExceptionLoaded.setNext(BeginNode.begin(deoptimizeNode));
         } else {
-            createHandleExceptionTarget(finishedDispatch, bci, dispatchState);
-        }
+            createHandleExceptionTarget(afterExceptionLoaded, bci, dispatchState);
+        }
+        assert currentLastInstr == lastInstr;
         return dispatchBegin;
     }
 
-    protected void createHandleExceptionTarget(FixedWithNextNode finishedDispatch, int bci, FrameStateBuilder dispatchState) {
+    protected void createHandleExceptionTarget(FixedWithNextNode afterExceptionLoaded, int bci, FrameStateBuilder dispatchState) {
+        FixedWithNextNode afterInstrumentation = afterExceptionLoaded;
+        for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
+            afterInstrumentation = plugin.instrumentExceptionDispatch(graph, afterInstrumentation);
+            assert afterInstrumentation.next() == null : "exception dispatch instrumentation will be linked to dispatch block";
+        }
+
         BciBlock dispatchBlock = currentBlock.exceptionDispatchBlock();
         /*
          * The exception dispatch block is always for the last bytecode of a block, so if we are not
@@ -1149,7 +1160,7 @@
         }
 
         FixedNode target = createTarget(dispatchBlock, dispatchState);
-        finishedDispatch.setNext(target);
+        afterInstrumentation.setNext(target);
     }
 
     protected ValueNode genLoadIndexed(ValueNode array, ValueNode index, GuardingNode boundsCheck, JavaKind kind) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -24,6 +24,9 @@
 
 package org.graalvm.compiler.nodes.graphbuilderconf;
 
+import org.graalvm.compiler.graph.Node.ValueNumberable;
+import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 
@@ -210,6 +213,23 @@
     }
 
     /**
+     * Allows this plugin to add nodes after the exception object has been loaded in the dispatch
+     * sequence. Note that a {@link StructuredGraph} is provided to this call instead of a
+     * {@link GraphBuilderContext} so that the caller has a guarantee that its current control flow
+     * insertion point is not changed by this call. This means nodes must be added to the graph with
+     * the appropriate method (e.g., {@link StructuredGraph#unique} for {@link ValueNumberable}
+     * nodes) and fixed nodes must be manually {@linkplain FixedWithNextNode#setNext added} as
+     * successors of {@code afterExceptionLoaded}.
+     *
+     * @param graph the graph being parsed
+     * @param afterExceptionLoaded the last fixed node after loading the exception
+     * @return the last fixed node after instrumentation
+     */
+    default FixedWithNextNode instrumentExceptionDispatch(StructuredGraph graph, FixedWithNextNode afterExceptionLoaded) {
+        return afterExceptionLoaded;
+    }
+
+    /**
      * If the plugin {@link GraphBuilderContext#push pushes} a value with a different
      * {@link JavaKind} than specified by the bytecode, it must override this method and return
      * {@code true}. This disables assertion checking for value kinds.
--- a/test/hotspot/jtreg/ProblemList-graal.txt	Tue Jan 22 03:32:47 2019 -0800
+++ b/test/hotspot/jtreg/ProblemList-graal.txt	Tue Jan 22 19:56:19 2019 +0100
@@ -165,5 +165,3 @@
 org.graalvm.compiler.hotspot.test.ReservedStackAccessTest        8213567   windows-all
 
 org.graalvm.compiler.replacements.test.StringCompressInflateTest 8213556
-
-org.graalvm.compiler.debug.test.TimerKeyTest                     8213598
--- a/test/jdk/ProblemList.txt	Tue Jan 22 03:32:47 2019 -0800
+++ b/test/jdk/ProblemList.txt	Tue Jan 22 19:56:19 2019 +0100
@@ -559,9 +559,7 @@
 java/net/MulticastSocket/NoLoopbackPackets.java                 7122846 macosx-all
 java/net/MulticastSocket/SetLoopbackMode.java                   7122846 macosx-all
 
-java/net/MulticastSocket/Test.java                              7145658,8207404 macosx-all,aix-all
-java/net/MulticastSocket/JoinLeave.java                         8207404 aix-all
-java/net/MulticastSocket/SetGetNetworkInterfaceTest.java        8207404 aix-all
+java/net/MulticastSocket/Test.java                              7145658 macosx-all
 
 java/net/DatagramSocket/SendDatagramToBadAddress.java           7143960 macosx-all
 
--- a/test/jdk/java/net/MulticastSocket/JoinLeave.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/test/jdk/java/net/MulticastSocket/JoinLeave.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -21,7 +21,15 @@
  * questions.
  */
 
-/*
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
+
+import jdk.test.lib.NetworkConfiguration;
+
+/**
  * @test
  * @bug 4091811 4148753 4102731
  * @summary Test java.net.MulticastSocket joinGroup and leaveGroup
@@ -29,18 +37,11 @@
  * @build jdk.test.lib.NetworkConfiguration
  *        jdk.test.lib.Platform
  * @run main JoinLeave
+ * @run main/othervm -Djava.net.preferIPv4Stack=true JoinLeave
  */
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.net.InetAddress;
-import java.net.MulticastSocket;
-import java.net.NetworkInterface;
-import jdk.test.lib.NetworkConfiguration;
-
 public class JoinLeave {
 
-    public static void main(String args[]) throws IOException  {
+    public static void main(String args[]) throws IOException {
         InetAddress ip4Group = InetAddress.getByName("224.80.80.80");
         InetAddress ip6Group = InetAddress.getByName("ff02::a");
 
@@ -49,8 +50,7 @@
         nc.ip6MulticastInterfaces().forEach(nic -> joinLeave(ip6Group, nic));
     }
 
-    static void joinLeave(InetAddress group, NetworkInterface nif)
-    {
+    static void joinLeave(InetAddress group, NetworkInterface nif) {
         System.out.println("Joining:" + group + " on " + nif);
         try (MulticastSocket soc = new MulticastSocket()) {
             soc.setNetworkInterface(nif);
--- a/test/jdk/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/test/jdk/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -21,105 +21,50 @@
  * questions.
  */
 
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
 
-/*
+import jdk.test.lib.NetworkConfiguration;
+
+/**
  * @test
  * @bug 6458027
  * @summary Disabling IPv6 on a specific network interface causes problems.
- *
- */
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.MulticastSocket;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Arrays;
-import java.util.Enumeration;
-
-
-public class SetGetNetworkInterfaceTest  {
+ * @library /test/lib
+ * @build jdk.test.lib.NetworkConfiguration
+ *        jdk.test.lib.Platform
+ * @run main SetGetNetworkInterfaceTest
+ * @run main/othervm -Djava.net.preferIPv4Stack=true SetGetNetworkInterfaceTest
+*/
+public class SetGetNetworkInterfaceTest {
 
     public static void main(String[] args) throws Exception {
-
-        boolean passed = true;
-        try {
-            MulticastSocket ms = new MulticastSocket();
-            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface
-                    .getNetworkInterfaces();
-            while (networkInterfaces.hasMoreElements()) {
-                NetworkInterface netIf = networkInterfaces.nextElement();
-                if (isNetworkInterfaceTestable(netIf)) {
-                    printNetIfDetails(netIf);
-                    ms.setNetworkInterface(netIf);
-                    NetworkInterface msNetIf = ms.getNetworkInterface();
-                    if (netIf.equals(msNetIf)) {
-                        System.out.println(" OK");
-                    } else {
-                        System.out.println("FAILED!!!");
-                        printNetIfDetails(msNetIf);
-                        passed = false;
-                    }
-                    System.out.println("------------------");
-                }
-            }
+        NetworkConfiguration nc = NetworkConfiguration.probe();
+        try (MulticastSocket ms = new MulticastSocket()) {
+            nc.multicastInterfaces(true).forEach(nif -> setGetNetworkInterface(ms, nif));
         } catch (IOException e) {
             e.printStackTrace();
-            passed = false;
         }
-        if (!passed) {
-            throw new RuntimeException("Test Fail");
-        }
-        System.out.println("Test passed ");
+        System.out.println("Test passed.");
     }
 
-    private static boolean isNetworkInterfaceTestable(NetworkInterface netIf) throws Exception {
-        System.out.println("checking netif == " + netIf.getName());
-        return  (netIf.isUp() && netIf.supportsMulticast() && isIpAddrAvailable(netIf));
-    }
-
-    private static boolean isIpAddrAvailable (NetworkInterface netIf) {
-        boolean ipAddrAvailable = false;
-        byte[] nullIpAddr = {'0', '0', '0', '0'};
-        byte[] testIpAddr = null;
-
-        Enumeration<InetAddress> ipAddresses = netIf.getInetAddresses();
-        while (ipAddresses.hasMoreElements()) {
-            InetAddress testAddr = ipAddresses.nextElement();
-            testIpAddr = testAddr.getAddress();
-            if ((testIpAddr != null) && (!Arrays.equals(testIpAddr, nullIpAddr))) {
-                ipAddrAvailable = true;
-                break;
+    static void setGetNetworkInterface(MulticastSocket ms, NetworkInterface nif) {
+        try {
+            System.out.println(NetworkConfiguration.interfaceInformation(nif));
+            ms.setNetworkInterface(nif);
+            NetworkInterface msNetIf = ms.getNetworkInterface();
+            if (nif.equals(msNetIf)) {
+                System.out.println(" OK");
             } else {
-                System.out.println("ignore netif " + netIf.getName());
+                System.out.println("FAILED!!!");
+                System.out.println(NetworkConfiguration.interfaceInformation(msNetIf));
+                throw new RuntimeException("Test Fail");
             }
+            System.out.println("------------------");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
         }
-        return ipAddrAvailable;
-    }
-
-    private static void printNetIfDetails(NetworkInterface ni)
-            throws SocketException {
-        System.out.println("Name " + ni.getName() + " index " + ni.getIndex());
-        Enumeration<InetAddress> en = ni.getInetAddresses();
-        while (en.hasMoreElements()) {
-            System.out.println(" InetAdress: " + en.nextElement());
-        }
-        System.out.println("HardwareAddress: " + createMacAddrString(ni));
-        System.out.println("loopback: " + ni.isLoopback() + "; pointToPoint: "
-                + ni.isPointToPoint() + "; virtual: " + ni.isVirtual()
-                + "; MTU: " + ni.getMTU());
-    }
-
-    private static String createMacAddrString(NetworkInterface netIf)
-            throws SocketException {
-        byte[] macAddr = netIf.getHardwareAddress();
-        StringBuilder sb = new StringBuilder();
-        if (macAddr != null) {
-            for (int i = 0; i < macAddr.length; i++) {
-                sb.append(String.format("%02X%s", macAddr[i],
-                        (i < macAddr.length - 1) ? "-" : ""));
-            }
-        }
-        return sb.toString();
     }
 }
--- a/test/jdk/java/net/MulticastSocket/Test.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/test/jdk/java/net/MulticastSocket/Test.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -21,25 +21,31 @@
  * questions.
  */
 
-/*
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.SocketTimeoutException;
+
+import jdk.test.lib.NetworkConfiguration;
+
+/**
  * @test
  * @bug 4488458
  * @summary IPv4 and IPv6 multicasting broken on Linux
+ * @library /test/lib
+ * @build jdk.test.lib.NetworkConfiguration
+ *        jdk.test.lib.Platform
+ * @run main Test
+ * @run main/othervm -Djava.net.preferIPv4Stack=true Test
  */
-import java.net.*;
-import java.io.IOException;
-import java.util.Enumeration;
-
 public class Test {
 
     static int count = 0;
     static int failures = 0;
 
-    static boolean isSolaris = System.getProperty("os.name")
-        .toLowerCase()
-        .startsWith("sunos");
-
-    void doTest(String address) throws Exception {
+    void doTest(String address) throws IOException {
         boolean failed = false;
 
         InetAddress ia = InetAddress.getByName(address);
@@ -65,7 +71,7 @@
 
                 /* packets should be received */
 
-                for (int j=0; j<2; j++) {
+                for (int j = 0; j < 2; j++) {
                     p.setAddress(ia);
                     p.setPort(port);
 
@@ -127,67 +133,26 @@
         }
     }
 
-    static boolean isValidIpv6Address(InetAddress addr) {
-        if (! (addr instanceof Inet6Address))
-            return false;
-        if (!isSolaris)
-            return true;
-        return !(addr.isAnyLocalAddress() || addr.isLoopbackAddress());
-    }
+    void allTests() throws IOException {
+        NetworkConfiguration nc = NetworkConfiguration.probe();
 
-    void allTests() throws Exception {
-
-        /*
-         * Assume machine has IPv4 address
-         */
+        // unconditionally test IPv4 address
         doTest("224.80.80.80");
 
-        /*
-         * Check if IPv6 is enabled and the scope of the addresses
-         */
-        boolean has_ipv6 = false;
-        boolean has_siteaddress = false;
-        boolean has_linklocaladdress = false;
-        boolean has_globaladdress = false;
-
-        Enumeration nifs = NetworkInterface.getNetworkInterfaces();
-        while (nifs.hasMoreElements()) {
-            NetworkInterface ni = (NetworkInterface)nifs.nextElement();
-            Enumeration addrs = ni.getInetAddresses();
-
-            while (addrs.hasMoreElements()) {
-                InetAddress ia = (InetAddress)addrs.nextElement();
-
-                if (isValidIpv6Address(ia)) {
-                    has_ipv6 = true;
-                    if (ia.isLinkLocalAddress()) has_linklocaladdress = true;
-                    if (ia.isSiteLocalAddress()) has_siteaddress = true;
-
-                    if (!ia.isLinkLocalAddress() &&
-                        !ia.isSiteLocalAddress() &&
-                        !ia.isLoopbackAddress()) {
-                        has_globaladdress = true;
-                    }
-                }
-            }
-        }
-
-        /*
-         * If IPv6 is enabled perform multicast tests with various scopes
-         */
-        if (has_ipv6) {
+        // If IPv6 is enabled perform multicast tests with various scopes
+        if (nc.hasTestableIPv6Address()) {
             doTest("ff01::a");
         }
 
-        if (has_linklocaladdress) {
+        if (nc.hasLinkLocalAddress()) {
             doTest("ff02::a");
         }
 
-        if (has_siteaddress) {
+        if (nc.hasSiteLocalAddress()) {
             doTest("ff05::a");
         }
 
-        if (has_globaladdress) {
+        if (nc.has_globaladdress()) {
             doTest("ff0e::a");
         }
     }
@@ -198,7 +163,7 @@
         if (args.length == 0) {
             t.allTests();
         } else {
-            for (int i=0; i<args.length; i++) {
+            for (int i = 0; i < args.length; i++) {
                 t.doTest(args[i]);
             }
         }
--- a/test/jdk/java/nio/channels/DatagramChannel/UseDGWithIPv6.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/test/jdk/java/nio/channels/DatagramChannel/UseDGWithIPv6.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, 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
@@ -24,6 +24,8 @@
 /* @test
  * @bug 6435300
  * @summary Check using IPv6 address does not crash the VM
+ * @run main/othervm UseDGWithIPv6
+ * @run main/othervm -Djava.net.preferIPv4Stack=true UseDGWithIPv6
  */
 
 import java.io.IOException;
@@ -31,6 +33,7 @@
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.DatagramChannel;
+import java.nio.channels.UnsupportedAddressTypeException;
 
 public class UseDGWithIPv6 {
     static String[] targets = {
@@ -57,6 +60,8 @@
             try {
                 int n = dgChannel.send(data, sa);
                 System.out.println("DG_Sent " + n + " bytes");
+            } catch (UnsupportedAddressTypeException e) {
+                System.out.println("Ignoring unsupported address type");
             } catch (IOException e) {
                 //This regression test is to check vm crash only, so ioe is OK.
                 e.printStackTrace();
--- a/test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/Distrust.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/Distrust.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -35,13 +35,15 @@
 
 /**
  * @test
- * @bug 8207258
+ * @bug 8207258 8216280
  * @summary Check that TLS Server certificates chaining back to distrusted
  *          Symantec roots are invalid
  * @library /test/lib
  * @modules java.base/sun.security.validator
- * @run main/othervm Distrust true
- * @run main/othervm Distrust false
+ * @run main/othervm Distrust after policyOn invalid
+ * @run main/othervm Distrust after policyOff valid
+ * @run main/othervm Distrust before policyOn valid
+ * @run main/othervm Distrust before policyOff valid
  */
 
 public class Distrust {
@@ -57,35 +59,67 @@
         "thawteprimaryrootcag3", "verisignclass3g3ca", "verisignclass3g4ca",
         "verisignclass3g5ca", "verisignuniversalrootca" };
 
+    // Each of the subCAs with a delayed distrust date have a test certificate
+    // chain stored in a file named "<subCA>-chain.pem".
+    private static String[] subCAsToTest = new String[] {
+        "appleistca2g1", "appleistca8g1" };
+
     // A date that is after the restrictions take affect
     private static final Date APRIL_17_2019 =
         Date.from(LocalDate.of(2019, 4, 17)
                            .atStartOfDay(ZoneOffset.UTC)
                            .toInstant());
 
+    // A date that is a second before the restrictions take affect
+    private static final Date BEFORE_APRIL_17_2019 =
+        Date.from(LocalDate.of(2019, 4, 17)
+                           .atStartOfDay(ZoneOffset.UTC)
+                           .minusSeconds(1)
+                           .toInstant());
+
+    // A date that is after the subCA restrictions take affect
+    private static final Date JANUARY_1_2020 =
+        Date.from(LocalDate.of(2020, 1, 1)
+                           .atStartOfDay(ZoneOffset.UTC)
+                           .toInstant());
+
+    // A date that is a second before the subCA restrictions take affect
+    private static final Date BEFORE_JANUARY_1_2020 =
+        Date.from(LocalDate.of(2020, 1, 1)
+                           .atStartOfDay(ZoneOffset.UTC)
+                           .minusSeconds(1)
+                           .toInstant());
+
     public static void main(String[] args) throws Exception {
 
         cf = CertificateFactory.getInstance("X.509");
-        boolean distrust = args[0].equals("true");
-        if (!distrust) {
-            // disable policy
+
+        boolean before = args[0].equals("before");
+        boolean policyOn = args[1].equals("policyOn");
+        boolean isValid = args[2].equals("valid");
+
+        if (!policyOn) {
+            // disable policy (default is on)
             Security.setProperty("jdk.security.caDistrustPolicies", "");
         }
 
+        Date notBefore = before ? BEFORE_APRIL_17_2019 : APRIL_17_2019;
+
         X509TrustManager pkixTM = getTMF("PKIX", null);
         X509TrustManager sunX509TM = getTMF("SunX509", null);
         for (String test : rootsToTest) {
             System.err.println("Testing " + test);
             X509Certificate[] chain = loadCertificateChain(test);
 
-            testTM(sunX509TM, chain, !distrust);
-            testTM(pkixTM, chain, !distrust);
+            testTM(sunX509TM, chain, notBefore, isValid);
+            testTM(pkixTM, chain, notBefore, isValid);
         }
 
         // test chain if params are passed to TrustManager
         System.err.println("Testing verisignuniversalrootca with params");
         testTM(getTMF("PKIX", getParams()),
-               loadCertificateChain("verisignuniversalrootca"), !distrust);
+               loadCertificateChain("verisignuniversalrootca"),
+               notBefore, isValid);
 
         // test code-signing chain (should be valid as restrictions don't apply)
         System.err.println("Testing verisignclass3g5ca code-signing chain");
@@ -95,6 +129,16 @@
         // set validation date so this will still pass when cert expires
         v.setValidationDate(new Date(1544197375493l));
         v.validate(loadCertificateChain("verisignclass3g5ca-codesigning"));
+
+        // test chains issued through subCAs
+        notBefore = before ? BEFORE_JANUARY_1_2020 : JANUARY_1_2020;
+        for (String test : subCAsToTest) {
+            System.err.println("Testing " + test);
+            X509Certificate[] chain = loadCertificateChain(test);
+
+            testTM(sunX509TM, chain, notBefore, isValid);
+            testTM(pkixTM, chain, notBefore, isValid);
+        }
     }
 
     private static X509TrustManager getTMF(String type,
@@ -122,12 +166,13 @@
     }
 
     private static void testTM(X509TrustManager xtm, X509Certificate[] chain,
-                               boolean valid) throws Exception {
+                               Date notBefore, boolean valid) throws Exception {
         // Check if TLS Server certificate (the first element of the chain)
-        // is issued after April 16, 2019 (should be rejected unless distrust
-        // property is false). To do this, we need to fake the notBefore date
-        // since none of the test certs are issued after then.
-        chain[0] = new DistrustedTLSServerCert(chain[0], APRIL_17_2019);
+        // is issued after the specified notBefore date (should be rejected
+        // unless distrust property is false). To do this, we need to
+        // fake the notBefore date since none of the test certs are issued
+        // after then.
+        chain[0] = new DistrustedTLSServerCert(chain[0], notBefore);
 
         try {
             xtm.checkServerTrusted(chain, "ECDHE_RSA");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca2g1-chain.pem	Tue Jan 22 19:56:19 2019 +0100
@@ -0,0 +1,80 @@
+-----BEGIN CERTIFICATE-----
+MIIGGzCCBQOgAwIBAgIITJltLCqcD0gwDQYJKoZIhvcNAQELBQAwYjEcMBoGA1UE
+AxMTQXBwbGUgSVNUIENBIDIgLSBHMTEgMB4GA1UECxMXQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkxEzARBgNVBAoTCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE5
+MDEwODIxMTcxNFoXDTIwMDgwODIxMjcwMFowgaoxSjBIBgNVBAMMQWFjdGl2ZS5n
+ZW90cnVzdC1nbG9iYWwtY2EudGVzdC1wYWdlcy5jZXJ0aWZpY2F0ZW1hbmFnZXIu
+YXBwbGUuY29tMSUwIwYDVQQLDBxtYW5hZ2VtZW50OmlkbXMuZ3JvdXAuODY0ODU5
+MRMwEQYDVQQKDApBcHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYD
+VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCjFUrVHTEX
+0aVU6x9LiGa6oVr9blaCsMFrLicPQguc43Vs/pN+g4jzRXsTSMe9XefezBQb6tzZ
+SMRXVB4kWMr4K1BVgQDkXeyoh4KrXRkdEF9ZIJPNxwTmmYUOc5M6NOYwkLelYz+t
+7n1iNIGylbjwU4qwauElk2alFVqYTEPDLzwvqVDb9jMAJ8MPSDjfUlXW0XD9oXZM
+hC+8LU9JBgJ3YBdzRHa4WnrudUbWjspqaNfAYpVIX0cfCJKnMsKqaSKjS4pIRtWm
+L6NlCTCoIMyOh+wmbWPPX24H2D3+ump5FA35fRYbVznmosl5n1AK34S9tD4XZ7lO
+WZKfaFi1liMCAwEAAaOCAoowggKGMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU
+2HqURHyQcJAWnt0XnAFEA4bWKikwfgYIKwYBBQUHAQEEcjBwMDQGCCsGAQUFBzAC
+hihodHRwOi8vY2VydHMuYXBwbGUuY29tL2FwcGxlaXN0Y2EyZzEuZGVyMDgGCCsG
+AQUFBzABhixodHRwOi8vb2NzcC5hcHBsZS5jb20vb2NzcDAzLWFwcGxlaXN0Y2Ey
+ZzEwMTBMBgNVHREERTBDgkFhY3RpdmUuZ2VvdHJ1c3QtZ2xvYmFsLWNhLnRlc3Qt
+cGFnZXMuY2VydGlmaWNhdGVtYW5hZ2VyLmFwcGxlLmNvbTCB/wYDVR0gBIH3MIH0
+MIHxBgoqhkiG92NkBQsEMIHiMIGkBggrBgEFBQcCAjCBlwyBlFJlbGlhbmNlIG9u
+IHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5j
+ZSBvZiBhbnkgYXBwbGljYWJsZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2Ug
+YW5kL29yIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wOQYIKwYB
+BQUHAgEWLWh0dHA6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5
+L3JwYTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwNwYDVR0fBDAwLjAs
+oCqgKIYmaHR0cDovL2NybC5hcHBsZS5jb20vYXBwbGVpc3RjYTJnMS5jcmwwHQYD
+VR0OBBYEFP0qkmFJhArI0MsfW0V+/wY9x4GSMA4GA1UdDwEB/wQEAwIFoDANBgkq
+hkiG9w0BAQsFAAOCAQEATjT8M0bIq+mFc8k5cd4KDjCMBjYl/l3/8zKlWYGP+nl1
+KRogXcGRa3LcfpdJcqgMrx8e9Xohduvl8MBzwv671rYkppzZdsmZdLVorAdbL5GL
+suhTjAS5yL3NBWNMRpeOgFsVr7YtPDEvo3CFsnzjg7THe0S6Y35oYukJtUzGUvSY
+kC3ApBTdjj0vAeow+dbt+AHKnQiEnon4ToSFmtnkru08Uxe7uyHCQ2sLUg0EPYc9
+t9I8lviaHfK/mQoCzlme2O/H5Rher8dXCv8hVT1NKbsi28EpgpqcTLS+hn/Edc/q
+4dPDoO1Ozs+ixRzFeMpA+JrnAyARb6qbSrAPBgtIbQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEQDCCAyigAwIBAgIDAjp0MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTQwNjE2MTU0MjAyWhcNMjIwNTIwMTU0MjAyWjBiMRwwGgYDVQQD
+ExNBcHBsZSBJU1QgQ0EgMiAtIEcxMSAwHgYDVQQLExdDZXJ0aWZpY2F0aW9uIEF1
+dGhvcml0eTETMBEGA1UEChMKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQk6EdR0MgFrILa+vD1bTox5jN896/
+6E3p4zaAB/xFG2p8RYauVtOkCX9hDWtdflJrfbTIOcT0Zzr3g84Zb4YvfkV+Rxxn
+UsqVBV3iNlGFwNRngDVvFd0+/R3S/Y80UNjsdiq+49Pa5P3I6ygClhGXF2Ec6cRZ
+O0LcMtEJHdqm0UOG/16yvIzPZtsBiwKulEjzOI/96jKoCOyGl1GUJD5JSZZT6Hmh
+QIHpBbuTlVH84/18EUv3ngizFUkVB/nRN6CbSzL2tcTcatH8Cu324MUpoKiLcf4N
+krz+VHAYCm3H7Qz7yS0Gw4yF/MuGXNY2jhKLCX/7GRo41fCUMHoPpozzAgMBAAGj
+ggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1luMrMTjAdBgNVHQ4E
+FgQU2HqURHyQcJAWnt0XnAFEA4bWKikwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV
+HQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2cuc3ltY2IuY29t
+L2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYS
+aHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARFMEMwQQYKYIZIAYb4RQEHNjAzMDEG
+CCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvY3Bz
+MA0GCSqGSIb3DQEBCwUAA4IBAQAWR3NvhaJi4ecqdruJlUIml7xKrKxwUzo/MYM9
+PByrmuKxXRx2GqA8DHJXvtOeUODImdZY1wLqzg0pVHzN9cLGkClVo28UqAtCDTqY
+bQZ4nvBqox0CCqIopI3CgUY+bWfa3j/+hQ5CKhLetbf7uBunlux3n+zUU5V6/wf0
+8goUwFFSsdaOUAsamVy8C8m97e34XsFW201+I6QRoSzUGwWa5BtS9nw4mQVLunKN
+QolgBGYq9P1o12v3mUEo1mwkq+YlUy7Igpnioo8jvjCDsSeL+mh/AUnoxphrEC6Y
+XorXykuxx8lYmtA225aV7LaB5PLNbxt5h0wQPInkTfpU3Kqm
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
+R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
+9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
+fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
+iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
+1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
+MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
+ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
+uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
+Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
+tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
+PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
+hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
+5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
+-----END CERTIFICATE-----
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca8g1-chain.pem	Tue Jan 22 19:56:19 2019 +0100
@@ -0,0 +1,64 @@
+-----BEGIN CERTIFICATE-----
+MIIElDCCBDqgAwIBAgIIWax3IY1ByGIwCgYIKoZIzj0EAwIwYjEcMBoGA1UEAwwT
+QXBwbGUgSVNUIENBIDggLSBHMTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE5MDEw
+ODIxMTAyNFoXDTIwMDgwODIxMjAwMFowga0xTTBLBgNVBAMMRGFjdGl2ZS5nZW90
+cnVzdC1nbG9iYWwtY2EtZzIudGVzdC1wYWdlcy5jZXJ0aWZpY2F0ZW1hbmFnZXIu
+YXBwbGUuY29tMSUwIwYDVQQLDBxtYW5hZ2VtZW50OmlkbXMuZ3JvdXAuODY0ODU5
+MRMwEQYDVQQKDApBcHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYD
+VQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABN4oxNLGzmOIfgFRxDaU
+SaOYTQVZCc7a7MXlK1L4/KgN22stgSkrg47aOWviMuzb9Q9hDA/Tn19o9Zr8G5ON
+pYijggKMMIICiDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFMPEpFgFY9eDBrqW
+jdyyjzL2u7dBMH4GCCsGAQUFBwEBBHIwcDA0BggrBgEFBQcwAoYoaHR0cDovL2Nl
+cnRzLmFwcGxlLmNvbS9hcHBsZWlzdGNhOGcxLmRlcjA4BggrBgEFBQcwAYYsaHR0
+cDovL29jc3AuYXBwbGUuY29tL29jc3AwMy1hcHBsZWlzdGNhOGcxMDEwTwYDVR0R
+BEgwRoJEYWN0aXZlLmdlb3RydXN0LWdsb2JhbC1jYS1nMi50ZXN0LXBhZ2VzLmNl
+cnRpZmljYXRlbWFuYWdlci5hcHBsZS5jb20wgf4GA1UdIASB9jCB8zCB8AYKKoZI
+hvdjZAULBDCB4TCBpAYIKwYBBQUHAgIwgZcMgZRSZWxpYW5jZSBvbiB0aGlzIGNl
+cnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgYW55
+IGFwcGxpY2FibGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlIGFuZC9vciBj
+ZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMDgGCCsGAQUFBwICMCwM
+Kmh0dHA6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5LzAdBgNV
+HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwNwYDVR0fBDAwLjAsoCqgKIYmaHR0
+cDovL2NybC5hcHBsZS5jb20vYXBwbGVpc3RjYThnMS5jcmwwHQYDVR0OBBYEFCQy
+hU8U00tcIz6L0MCT6EGVho0EMA4GA1UdDwEB/wQEAwIDiDAKBggqhkjOPQQDAgNI
+ADBFAiAl5nGHi2u8V0aJSp4o1i3TlK7ao8WvxwBuHKfuKibSLAIhAN8PZqhESS9u
+V7Dr6qzs88yn/1z6oeqPwDsntFpUFtWG
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAtugAwIBAgIQE1Iuv8HdXOEe8nZAdR/n3zAKBggqhkjOPQQDAzCBmDEL
+MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
+KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
+MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEcyMB4XDTE2MDYwOTAwMDAwMFoXDTMxMDYwODIzNTk1OVowYjEcMBoGA1UE
+AwwTQXBwbGUgSVNUIENBIDggLSBHMTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAELVSOaLAQE+/0LdvYCbJD6J1lmW40uNSXyY7J
+1qgiNzLIcWDusPHyxWT2ukdf/OYHeDIt9sqAIMn9cPhykyGIRaOCATowggE2MBIG
+A1UdEwEB/wQIMAYBAf8CAQAwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2cuc3lt
+Y2IuY29tL0dlb1RydXN0UENBLUcyLmNybDAOBgNVHQ8BAf8EBAMCAQYwLgYIKwYB
+BQUHAQEEIjAgMB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wSQYDVR0g
+BEIwQDA+BgZngQwBAgIwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2VvdHJ1
+c3QuY29tL3Jlc291cmNlcy9jcHMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
+BwMCMB0GA1UdDgQWBBTDxKRYBWPXgwa6lo3cso8y9ru3QTAfBgNVHSMEGDAWgBQV
+XzVXUVX7JbKtA2n8AaP6vhFV1TAKBggqhkjOPQQDAwNnADBkAjBH2jMNybjCk3Ts
+OidXxJX9YDPMd5S3KDCv8vyTdJGhtoly7fQJRNv5rnVz+6YGfsMCMEp6wyheL7NK
+mqavsduix2R+j1B3wRjelzJYgXzgM3nwhQKKlJWxpF7IGHuva1taxg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
+MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
+KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
+MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
+BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
+NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
+BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
+MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
+So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
+tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
+CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
+qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
+rD6ogRLQy7rQkgu2npaqBA+K
+-----END CERTIFICATE-----
--- a/test/lib/jdk/test/lib/NetworkConfiguration.java	Tue Jan 22 03:32:47 2019 -0800
+++ b/test/lib/jdk/test/lib/NetworkConfiguration.java	Tue Jan 22 19:56:19 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,9 @@
 
 package jdk.test.lib;
 
+import java.io.IOException;
 import java.io.PrintStream;
 import java.io.UncheckedIOException;
-import java.io.IOException;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -35,9 +35,9 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+
 import static java.net.NetworkInterface.getNetworkInterfaces;
 import static java.util.Collections.list;
 
@@ -49,12 +49,140 @@
 
     private Map<NetworkInterface,List<Inet4Address>> ip4Interfaces;
     private Map<NetworkInterface,List<Inet6Address>> ip6Interfaces;
+    private final boolean isIPv6Available;
+    private boolean has_testableipv6address = false;
+    private boolean has_sitelocaladdress = false;
+    private boolean has_linklocaladdress = false;
+    private boolean has_globaladdress = false;
 
     private NetworkConfiguration(
             Map<NetworkInterface,List<Inet4Address>> ip4Interfaces,
             Map<NetworkInterface,List<Inet6Address>> ip6Interfaces) {
         this.ip4Interfaces = ip4Interfaces;
         this.ip6Interfaces = ip6Interfaces;
+
+        // initialize properties that can be queried
+        isIPv6Available = !ip6Interfaces().collect(Collectors.toList()).isEmpty();
+        ip6Interfaces().forEach(nif -> {
+            ip6Addresses(nif)
+                // On Solaris or AIX, a configuration with only local or loopback
+                // addresses does not fully enable IPv6 operations.
+                // E.g. IPv6 multicasting does not work.
+                // So, don't set has_testableipv6address if we only find these.
+                .filter(addr -> Platform.isSolaris() || Platform.isAix() ?
+                    !(addr.isAnyLocalAddress() || addr.isLoopbackAddress()) : true)
+                .forEach(ia -> {
+                    has_testableipv6address = true;
+                    if (ia.isLinkLocalAddress()) has_linklocaladdress = true;
+                    if (ia.isSiteLocalAddress()) has_sitelocaladdress = true;
+
+                    if (!ia.isLinkLocalAddress() &&
+                        !ia.isSiteLocalAddress() &&
+                        !ia.isLoopbackAddress()) {
+                        has_globaladdress = true;
+                    }
+                });
+        });
+    }
+
+    private static boolean isNotExcludedInterface(NetworkInterface nif) {
+        if (Platform.isOSX() && nif.getName().contains("awdl")) {
+            return false;
+        }
+        if (Platform.isWindows()) {
+            String dName = nif.getDisplayName();
+            if (dName != null && dName.contains("Teredo")) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean isNotLoopback(NetworkInterface nif) {
+        try {
+            return !nif.isLoopback();
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    private boolean hasIp4Addresses(NetworkInterface nif) {
+        return ip4Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress());
+    }
+
+    private boolean hasIp6Addresses(NetworkInterface nif) {
+        return ip6Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress());
+    }
+
+    private boolean supportsIp4Multicast(NetworkInterface nif) {
+        try {
+            if (!nif.supportsMulticast()) {
+                return false;
+            }
+
+            // On AIX there is a bug:
+            // When IPv6 is enabled on the system, the JDK opens sockets as AF_INET6.
+            // If there's an interface configured with IPv4 addresses only, it should
+            // be able to become the network interface for a multicast socket (that
+            // could be in both, IPv4 or IPv6 space). But both possible setsockopt
+            // calls for either IPV6_MULTICAST_IF or IP_MULTICAST_IF return
+            // EADDRNOTAVAIL. So we must skip such interfaces here.
+            if (Platform.isAix() && isIPv6Available() && !hasIp6Addresses(nif)) {
+                return false;
+            }
+
+            return hasIp4Addresses(nif);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    private boolean supportsIp6Multicast(NetworkInterface nif) {
+        try {
+            if (!nif.supportsMulticast()) {
+                return false;
+            }
+
+            return hasIp6Addresses(nif);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    /**
+     * Returns whether IPv6 is available at all.
+     * This should resemble the result of native ipv6_available() in net_util.c
+     */
+    public boolean isIPv6Available() {
+        return isIPv6Available;
+    }
+
+    /**
+     * Does any (usable) IPv6 address exist in the network configuration?
+     */
+    public boolean hasTestableIPv6Address() {
+        return has_testableipv6address;
+    }
+
+    /**
+     * Does any site local address exist?
+     */
+    public boolean hasSiteLocalAddress() {
+        return has_sitelocaladdress;
+    }
+
+    /**
+     * Does any link local address exist?
+     */
+    public boolean hasLinkLocalAddress() {
+        return has_linklocaladdress;
+    }
+
+    /**
+     * Does any global IPv6 address exist?
+     */
+    public boolean has_globaladdress() {
+        return has_globaladdress;
     }
 
     /**
@@ -72,7 +200,7 @@
         return ip4Interfaces.keySet()
                             .stream()
                             .filter(NetworkConfiguration::isNotExcludedInterface)
-                            .filter(hasIp4Addresses);
+                            .filter(this::hasIp4Addresses);
     }
 
     /**
@@ -82,64 +210,57 @@
         return ip6Interfaces.keySet()
                             .stream()
                             .filter(NetworkConfiguration::isNotExcludedInterface)
-                            .filter(hasIp6Addresses);
+                            .filter(this::hasIp6Addresses);
     }
 
-    private static boolean isNotExcludedInterface(NetworkInterface nif) {
-        if (Platform.isOSX() && nif.getName().contains("awdl")) {
-            return false;
-        }
-        String dName = nif.getDisplayName();
-        if (Platform.isWindows() && dName != null && dName.contains("Teredo")) {
-            return false;
-        }
-        return true;
+    /**
+     * Returns a stream of interfaces suitable for functional tests.
+     */
+    public Stream<NetworkInterface> multicastInterfaces(boolean includeLoopback) {
+        return Stream
+            .concat(ip4MulticastInterfaces(includeLoopback),
+                    ip6MulticastInterfaces(includeLoopback))
+            .distinct();
     }
 
-    private final Predicate<NetworkInterface> hasIp4Addresses = nif ->
-            ip4Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress());
-
-    private final Predicate<NetworkInterface> hasIp6Addresses = nif ->
-            ip6Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress());
-
+    /**
+     * Returns a stream of interfaces suitable for IPv4 multicast tests.
+     *
+     * The loopback interface will not be included.
+     */
+    public Stream<NetworkInterface> ip4MulticastInterfaces() {
+        return ip4MulticastInterfaces(false);
+    }
 
     /**
      * Returns a stream of interfaces suitable for IPv4 multicast tests.
      */
-    public Stream<NetworkInterface> ip4MulticastInterfaces() {
-        return ip4Interfaces().filter(supportsIp4Multicast);
+    public Stream<NetworkInterface> ip4MulticastInterfaces(boolean includeLoopback) {
+        return (includeLoopback) ?
+            ip4Interfaces().filter(this::supportsIp4Multicast) :
+            ip4Interfaces().filter(this::supportsIp4Multicast)
+                .filter(NetworkConfiguration::isNotLoopback);
+    }
+
+    /**
+     * Returns a stream of interfaces suitable for IPv6 multicast tests.
+     *
+     * The loopback interface will not be included.
+     */
+    public Stream<NetworkInterface> ip6MulticastInterfaces() {
+        return ip6MulticastInterfaces(false);
     }
 
     /**
      * Returns a stream of interfaces suitable for IPv6 multicast tests.
      */
-    public Stream<NetworkInterface> ip6MulticastInterfaces() {
-        return ip6Interfaces().filter(supportsIp6Multicast);
+    public Stream<NetworkInterface> ip6MulticastInterfaces(boolean includeLoopback) {
+        return (includeLoopback) ?
+            ip6Interfaces().filter(this::supportsIp6Multicast) :
+            ip6Interfaces().filter(this::supportsIp6Multicast)
+                .filter(NetworkConfiguration::isNotLoopback);
     }
 
-    private final Predicate<NetworkInterface> supportsIp4Multicast = nif -> {
-        try {
-            if (!nif.supportsMulticast() || nif.isLoopback()) {
-                return false;
-            }
-            return hasIp4Addresses.test(nif);
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    };
-
-    private final Predicate<NetworkInterface> supportsIp6Multicast = nif -> {
-        try {
-            if (!nif.supportsMulticast() || nif.isLoopback()) {
-                return false;
-            }
-
-            return hasIp6Addresses.test(nif);
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    };
-
     /**
      * Returns all addresses on all "functional" interfaces.
      */
@@ -176,6 +297,12 @@
         return ip6Interfaces.get(nif).stream();
     }
 
+    @Override
+    public String toString() {
+        return interfaces().map(NetworkConfiguration::interfaceInformation)
+                           .collect(Collectors.joining());
+    }
+
     /**
      * Return a NetworkConfiguration instance.
      */
@@ -205,12 +332,6 @@
         return new NetworkConfiguration(ip4Interfaces, ip6Interfaces);
     }
 
-    @Override
-    public String toString() {
-        return interfaces().map(NetworkConfiguration::interfaceInformation)
-                           .collect(Collectors.joining());
-    }
-
     /** Returns detailed information for the given interface. */
     public static String interfaceInformation(NetworkInterface nif) {
         StringBuilder sb = new StringBuilder();