changeset 13401:073ad89cfa90 nestmates

8186074: [Nestmates] Initial push for nestmates support Summary: Add initial Hotspot support for nestmates Reviewed-by: acorn
author mcimadamore
date Thu, 10 Aug 2017 15:01:17 +0100
parents 23d7878acfb7
children 002f847a0202
files make/symbols/symbols-unix src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/classFileParser.hpp src/share/vm/classfile/stackMapFrame.hpp src/share/vm/classfile/verificationType.cpp src/share/vm/classfile/verificationType.hpp src/share/vm/classfile/verifier.cpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/interpreter/linkResolver.cpp src/share/vm/logging/logTag.hpp src/share/vm/memory/heapInspection.hpp src/share/vm/oops/constantPool.cpp src/share/vm/oops/instanceKlass.cpp src/share/vm/oops/instanceKlass.hpp src/share/vm/prims/jvm.cpp src/share/vm/prims/jvm.h src/share/vm/runtime/reflection.cpp test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java test/compiler/jvmci/events/JvmciShutdownEventTest.java test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java test/runtime/Nestmates/classFileParsing/BadNestMembersEntry.jcod test/runtime/Nestmates/classFileParsing/BadNestMembersLength.jcod test/runtime/Nestmates/classFileParsing/BadNestTop.jcod test/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestMember.jcod test/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestTop.jcod test/runtime/Nestmates/classFileParsing/DuplicateNestMemberEntry.jcod test/runtime/Nestmates/classFileParsing/TestFinalMethodOverride.java test/runtime/Nestmates/classFileParsing/TestNestmateAttributes.java test/runtime/Nestmates/classFileParsing/TwoMemberOfNest.jcod test/runtime/Nestmates/classFileParsing/TwoNestMembers.jcod test/runtime/Nestmates/membership/ArrayNestTop.jcod test/runtime/Nestmates/membership/MissingNestTop.jcod test/runtime/Nestmates/membership/NestTop.jcod test/runtime/Nestmates/membership/NestTop_NestMember.jcod test/runtime/Nestmates/membership/NotAMember.jcod test/runtime/Nestmates/membership/NotAMember2.jcod test/runtime/Nestmates/membership/TestNestmateMembership.java test/runtime/Nestmates/privateConstructors/TestInvokeSpecial.java test/runtime/Nestmates/privateConstructors/TestMethodHandles.java test/runtime/Nestmates/privateConstructors/TestReflection.java test/runtime/Nestmates/privateFields/TestMethodHandles.java test/runtime/Nestmates/privateFields/TestPrivateField.java test/runtime/Nestmates/privateFields/TestReflection.java test/runtime/Nestmates/privateMethods/ExternalSub.jcod test/runtime/Nestmates/privateMethods/ExternalSuper.jcod test/runtime/Nestmates/privateMethods/MissingMethod.jcod test/runtime/Nestmates/privateMethods/MissingMethodWithSuper.jcod test/runtime/Nestmates/privateMethods/MissingNestTop.jcod test/runtime/Nestmates/privateMethods/TestInvokeSpecial.java test/runtime/Nestmates/privateMethods/TestInvokeSpecialErrors.java test/runtime/Nestmates/privateMethods/TestInvokeSpecialHierarchy.java test/runtime/Nestmates/privateMethods/TestMethodHandles.java test/runtime/Nestmates/privateMethods/TestReflection.java test/runtime/Nestmates/privateStaticFields/TestMethodHandles.java test/runtime/Nestmates/privateStaticFields/TestPrivateStaticField.java test/runtime/Nestmates/privateStaticFields/TestReflection.java test/runtime/Nestmates/privateStaticMethods/TestInvokeStatic.java test/runtime/Nestmates/privateStaticMethods/TestMethodHandles.java test/runtime/Nestmates/privateStaticMethods/TestReflection.java
diffstat 62 files changed, 5813 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/make/symbols/symbols-unix	Thu Aug 10 04:49:27 2017 -0700
+++ b/make/symbols/symbols-unix	Thu Aug 10 15:01:17 2017 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
 #
 
 JVM_ActiveProcessorCount
+JVM_AreNestMates
 JVM_ArrayCopy
 JVM_AssertionStatusDirectives
 JVM_CallStackWalk
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Aug 10 15:01:17 2017 +0100
@@ -114,6 +114,9 @@
   if (_bad_constant_seen == 0) _bad_constant_seen = bad_constant;
 }
 
+// FIX ME: update this
+#define JAVA_10_VERSION                    53
+
 void ClassFileParser::parse_constant_pool_entries(const ClassFileStream* const stream,
                                                   ConstantPool* cp,
                                                   const int length,
@@ -3079,7 +3082,6 @@
   _inner_classes = inner_classes;
 
   int index = 0;
-  const int cp_size = _cp->length();
   cfs->guarantee_more(8 * length, CHECK_0);  // 4-tuples of u2
   for (int n = 0; n < length; n++) {
     // Inner class index
@@ -3153,6 +3155,47 @@
   return length;
 }
 
+u2 ClassFileParser::parse_classfile_nest_members_attribute(const ClassFileStream* const cfs,
+                                                           const u1* const nest_members_attribute_start,
+                                                           TRAPS) {
+  const u1* const current_mark = cfs->current();
+  u2 length = 0;
+  if (nest_members_attribute_start != NULL) {
+    cfs->set_current(nest_members_attribute_start);
+    cfs->guarantee_more(2, CHECK_0);  // length
+    length = cfs->get_u2_fast();
+  }
+  const int size = length;
+  Array<u2>* const nest_members = MetadataFactory::new_array<u2>(_loader_data, size, CHECK_0);
+  _nest_members = nest_members;
+
+  int index = 0;
+  cfs->guarantee_more(2 * length, CHECK_0);
+  for (int n = 0; n < length; n++) {
+    const u2 class_info_index = cfs->get_u2_fast();
+    check_property(
+      valid_klass_reference_at(class_info_index),
+      "Nest member class_info_index %u has bad constant type in class file %s",
+      class_info_index, CHECK_0);
+    nest_members->at_put(index++, class_info_index);
+  }
+  if (_need_verify) {
+    for (int i = 0; i < length; i++) {
+      for (int j = i + 1; j < length; j++) {
+        guarantee_property((nest_members->at(i) != nest_members->at(j)),
+                           "Duplicate entry in NestMembers in class file %s",
+                           CHECK_0);
+      }
+    }
+  }
+  assert(index == size, "wrong size");
+
+  // Restore buffer's current position.
+  cfs->set_current(current_mark);
+
+  return length;
+}
+
 void ClassFileParser::parse_classfile_synthetic_attribute(TRAPS) {
   set_class_synthetic_flag(true);
 }
@@ -3260,10 +3303,14 @@
 
   // Set inner classes attribute to default sentinel
   _inner_classes = Universe::the_empty_short_array();
+  // Set nest members attribute to default sentinel
+  _nest_members = Universe::the_empty_short_array();
   cfs->guarantee_more(2, CHECK);  // attributes_count
   u2 attributes_count = cfs->get_u2_fast();
   bool parsed_sourcefile_attribute = false;
   bool parsed_innerclasses_attribute = false;
+  bool parsed_nest_members_attribute = false;
+  bool parsed_member_of_nest_attribute = false;
   bool parsed_enclosingmethod_attribute = false;
   bool parsed_bootstrap_methods_attribute = false;
   const u1* runtime_visible_annotations = NULL;
@@ -3281,6 +3328,9 @@
   u4  inner_classes_attribute_length = 0;
   u2  enclosing_method_class_index = 0;
   u2  enclosing_method_method_index = 0;
+  const u1* nest_members_attribute_start = NULL;
+  u4  nest_members_attribute_length = 0;
+
   // Iterate over attributes
   while (attributes_count--) {
     cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
@@ -3320,6 +3370,35 @@
       inner_classes_attribute_start = cfs->current();
       inner_classes_attribute_length = attribute_length;
       cfs->skip_u1(inner_classes_attribute_length, CHECK);
+    } else if (tag == vmSymbols::tag_nest_members()) {
+      // Check for NestMembers tag
+      if (parsed_nest_members_attribute) {
+        classfile_parse_error("Multiple NestMembers attributes in class file %s", CHECK);
+      } else {
+        parsed_nest_members_attribute = true;
+      }
+      if (parsed_member_of_nest_attribute) {
+        classfile_parse_error("Conflicting MemberOfNest and NestMembers attributes in class file %s", CHECK);
+      }
+      nest_members_attribute_start = cfs->current();
+      nest_members_attribute_length = attribute_length;
+      cfs->skip_u1(nest_members_attribute_length, CHECK);
+    } else if (tag == vmSymbols::tag_member_of_nest()) {
+      if (parsed_member_of_nest_attribute) {
+        classfile_parse_error("Multiple MemberOfNest attributes in class file %s", CHECK);
+      } else {
+        parsed_member_of_nest_attribute = true;
+      }
+      if (parsed_nest_members_attribute) {
+        classfile_parse_error("Conflicting NestMembers and MemberOfNest attributes in class file %s", CHECK);
+      }
+      cfs->guarantee_more(2, CHECK);
+      u2 class_info_index = cfs->get_u2_fast();
+      check_property(
+        valid_klass_reference_at(class_info_index),
+        "Nest top class_info_index %u has bad constant type in class file %s",
+        class_info_index, CHECK);
+      _nest_top = class_info_index;
     } else if (tag == vmSymbols::tag_synthetic()) {
       // Check for Synthetic tag
       // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
@@ -3457,13 +3536,25 @@
                             enclosing_method_class_index,
                             enclosing_method_method_index,
                             CHECK);
-    if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
+    if (parsed_innerclasses_attribute && _need_verify && _major_version >= JAVA_1_5_VERSION) {
       guarantee_property(
         inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
         "Wrong InnerClasses attribute length in class file %s", CHECK);
     }
   }
 
+  if (parsed_nest_members_attribute) {
+    const u2 num_of_classes = parse_classfile_nest_members_attribute(
+                            cfs,
+                            nest_members_attribute_start,
+                            CHECK);
+    if (_need_verify && _major_version >= JAVA_10_VERSION) {
+      guarantee_property(
+        nest_members_attribute_length == sizeof(num_of_classes) + sizeof(u2) * num_of_classes,
+        "Wrong NestMembers attribute length in class file %s", CHECK);
+    }
+  }
+
   if (_max_bootstrap_specifier_index >= 0) {
     guarantee_property(parsed_bootstrap_methods_attribute,
                        "Missing BootstrapMethods attribute in class file %s", CHECK);
@@ -3526,6 +3617,8 @@
   this_klass->set_fields(_fields, java_fields_count);
   this_klass->set_methods(_methods);
   this_klass->set_inner_classes(_inner_classes);
+  this_klass->set_nest_members(_nest_members);
+  this_klass->set_nest_top_index(_nest_top);
   this_klass->set_local_interfaces(_local_interfaces);
   this_klass->set_transitive_interfaces(_transitive_interfaces);
   this_klass->set_annotations(_combined_annotations);
@@ -4533,7 +4626,8 @@
           }
 
           if (super_m->is_final() && !super_m->is_static() &&
-              // matching method in super is final, and not static
+              !super_m->access_flags().is_private() &&
+              // matching method in super is final, and not static or private
               (Reflection::verify_field_access(this_klass,
                                                super_m->method_holder(),
                                                super_m->method_holder(),
@@ -5338,6 +5432,7 @@
   assert(NULL == _fields, "invariant");
   assert(NULL == _methods, "invariant");
   assert(NULL == _inner_classes, "invariant");
+  assert(NULL == _nest_members, "invariant");
   assert(NULL == _local_interfaces, "invariant");
   assert(NULL == _transitive_interfaces, "invariant");
   assert(NULL == _combined_annotations, "invariant");
@@ -5599,6 +5694,8 @@
   _fields(NULL),
   _methods(NULL),
   _inner_classes(NULL),
+  _nest_members(NULL),
+  _nest_top(0),
   _local_interfaces(NULL),
   _transitive_interfaces(NULL),
   _combined_annotations(NULL),
@@ -5703,6 +5800,7 @@
   _fields = NULL;
   _methods = NULL;
   _inner_classes = NULL;
+  _nest_members = NULL;
   _local_interfaces = NULL;
   _transitive_interfaces = NULL;
   _combined_annotations = NULL;
@@ -5729,6 +5827,10 @@
     MetadataFactory::free_array<u2>(_loader_data, _inner_classes);
   }
 
+  if (_nest_members != NULL && _nest_members != Universe::the_empty_short_array()) {
+    MetadataFactory::free_array<u2>(_loader_data, _nest_members);
+  }
+
   // Free interfaces
   InstanceKlass::deallocate_interfaces(_loader_data, _super_klass,
                                        _local_interfaces, _transitive_interfaces);
--- a/src/share/vm/classfile/classFileParser.hpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/classfile/classFileParser.hpp	Thu Aug 10 15:01:17 2017 +0100
@@ -97,6 +97,8 @@
   Array<u2>* _fields;
   Array<Method*>* _methods;
   Array<u2>* _inner_classes;
+  Array<u2>* _nest_members;
+  u2 _nest_top;
   Array<Klass*>* _local_interfaces;
   Array<Klass*>* _transitive_interfaces;
   Annotations* _combined_annotations;
@@ -290,6 +292,10 @@
                                                u2 enclosing_method_method_index,
                                                TRAPS);
 
+  u2 parse_classfile_nest_members_attribute(const ClassFileStream* const cfs,
+                                            const u1* const nest_members_attribute_start,
+                                            TRAPS);
+
   void parse_classfile_attributes(const ClassFileStream* const cfs,
                                   ConstantPool* cp,
                                   ClassAnnotationCollector* parsed_annotations,
--- a/src/share/vm/classfile/stackMapFrame.hpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/classfile/stackMapFrame.hpp	Thu Aug 10 15:01:17 2017 +0100
@@ -215,6 +215,17 @@
     _stack[_stack_size++] = type2;
   }
 
+  // Return the top type on stack without popping.
+  inline VerificationType peek_stack(TRAPS) {
+    if (_stack_size <= 0) {
+      verifier()->verify_error(
+          ErrorContext::stack_underflow(_offset, this),
+          "Operand stack underflow");
+      return VerificationType::bogus_type();
+    }
+    return _stack[_stack_size - 1];
+  }
+
   // Pop and return the top type on stack without verifying.
   inline VerificationType pop_stack(TRAPS) {
     if (_stack_size <= 0) {
--- a/src/share/vm/classfile/verificationType.cpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/classfile/verificationType.cpp	Thu Aug 10 15:01:17 2017 +0100
@@ -141,6 +141,31 @@
   }
 }
 
+bool VerificationType::is_nestmate_of(InstanceKlass* cur, TRAPS) const {
+  // cur is the current class being verified
+  // 'this' represents the target class for the bytecode e.g. invokespecial
+  if (is_object()) {
+    // target class may not have been loaded so we have to be prepared to do 
+    // that here and allow for possible exceptions
+    Klass* target = 
+        SystemDictionary::resolve_or_fail(name(),
+                                          Handle(THREAD, cur->class_loader()),
+                                          Handle(THREAD, cur->protection_domain()),
+                                          true,
+                                          CHECK_false);
+    if (log_is_enabled(Info, class, resolve)) {
+      Verifier::trace_class_resolution(target, cur);
+    }
+    assert(target->is_instance_klass(), "is_object() but not instance class??");
+    //ResourceMark rm(THREAD);
+    //    tty->print_cr(" Verification: checking %s->%s", cur->name()->as_C_string(), target->name()->as_C_string());
+    bool res = cur->has_nestmate_access_to(InstanceKlass::cast(target), THREAD);
+    //tty->print_cr(" - result: %s", res ? "true" : "false");
+    return res;
+  } 
+  return false;
+}
+
 void VerificationType::print_on(outputStream* st) const {
   switch (_u._data) {
     case Bogus:            st->print("top"); break;
--- a/src/share/vm/classfile/verificationType.hpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/classfile/verificationType.hpp	Thu Aug 10 15:01:17 2017 +0100
@@ -327,6 +327,10 @@
     return index;
   }
 
+  // checks if the class represented by 'this' is a nestmate of the
+  // cur class being verified
+  bool is_nestmate_of(InstanceKlass* cur, TRAPS) const;
+
   void print_on(outputStream* st) const;
 
  private:
--- a/src/share/vm/classfile/verifier.cpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/classfile/verifier.cpp	Thu Aug 10 15:01:17 2017 +0100
@@ -2776,6 +2776,10 @@
     }
   }
 
+  // need to track if invokespecial is related to a nestmate access
+  bool nestmate_access = false;
+  bool nestmates_checked = false;
+
   if (method_name->byte_at(0) == '<') {
     // Make sure <init> can only be invoked by invokespecial
     if (opcode != Bytecodes::_invokespecial ||
@@ -2784,40 +2788,71 @@
           "Illegal call to internal method");
       return;
     }
-  } else if (opcode == Bytecodes::_invokespecial
-             && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type)
-             && !ref_class_type.equals(VerificationType::reference_type(
-                  current_class()->super()->name()))) {
-    bool subtype = false;
-    bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
+  } else if (opcode == Bytecodes::_invokespecial) {
+    bool same_or_direct_interface = is_same_or_direct_interface(current_class(), current_type(), ref_class_type);
+    bool is_super_class = ref_class_type.equals(VerificationType::reference_type(current_class()->super()->name()));
+
+    // We can pass these initial set of verification checks when dealing with nestmates that are
+    // in the same type hierarchy, only to fail later when we finally apply the 4.9.2 check that
+    // the objectref on the operand stack is assignable to the current class. So we need to perform
+    // that check early and if it would fail then do a nestmate check. Then below we skip the
+    // operand check when we pop the stack. Unfortunately in the failing case we perform the check
+    // a second time to trigger the failure. This also means that we are forced to do the nestmate
+    // access check early, instead of using it is a last resort when all other checks have failed.
+
+    // If we don't skip anonymous classes here things break very badly
     if (!current_class()->is_anonymous()) {
-      subtype = ref_class_type.is_assignable_from(
-                 current_type(), this, false, CHECK_VERIFY(this));
-    } else {
-      VerificationType host_klass_type =
-                        VerificationType::reference_type(current_class()->host_klass()->name());
-      subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this));
-
-      // If invokespecial of IMR, need to recheck for same or
-      // direct interface relative to the host class
-      have_imr_indirect = (have_imr_indirect &&
-                           !is_same_or_direct_interface(
-                             current_class()->host_klass(),
-                             host_klass_type, ref_class_type));
-    }
-    if (!subtype) {
-      verify_error(ErrorContext::bad_code(bci),
-          "Bad invokespecial instruction: "
-          "current class isn't assignable to reference class.");
-       return;
-    } else if (have_imr_indirect) {
-      verify_error(ErrorContext::bad_code(bci),
-          "Bad invokespecial instruction: "
-          "interface method reference is in an indirect superinterface.");
-      return;
+      VerificationType top = current_frame->peek_stack(CHECK_VERIFY(this));
+      bool is_assignable = current_type().is_assignable_from(top, this, false, CHECK_VERIFY(this));
+      if (!is_assignable) {
+        nestmate_access = ref_class_type.is_nestmate_of(current_class(), CHECK_VERIFY(this));
+        nestmates_checked = true;
+      }
     }
 
+    if (!same_or_direct_interface && !is_super_class) {
+      bool subtype = false;
+      bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
+      if (!current_class()->is_anonymous()) {
+        subtype = ref_class_type.is_assignable_from(current_type(), this, false, CHECK_VERIFY(this));
+      } else {
+        VerificationType host_klass_type =
+            VerificationType::reference_type(current_class()->host_klass()->name());
+        subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this));
+
+        // If invokespecial of IMR, need to recheck for same or
+        // direct interface relative to the host class
+        have_imr_indirect = (have_imr_indirect &&
+                             !is_same_or_direct_interface(current_class()->host_klass(),
+                                                          host_klass_type, ref_class_type));
+      }
+      
+      if ((!subtype  || have_imr_indirect) && !nestmates_checked) {
+        // invokespecial may still be legitimate if current class and reference class
+        // are nestmates. But in that case we also have to check that the method being
+        // invoked is defined in the reference class. However that is deferred to runtime
+        // as we don't have the information available here.
+        nestmate_access = ref_class_type.is_nestmate_of(current_class(), CHECK_VERIFY(this));
+        nestmates_checked = true;
+      }
+
+      // report any definite verification failures
+      if (!nestmate_access) {
+        if (!subtype) {
+          verify_error(ErrorContext::bad_code(bci),
+                       "Bad invokespecial instruction: "
+                       "current class isn't assignable to reference class.");
+          return;
+        } else if (have_imr_indirect) {
+          verify_error(ErrorContext::bad_code(bci),
+                       "Bad invokespecial instruction: "
+                       "interface method reference is in an indirect superinterface.");
+          return;
+        }
+      }
+    }
   }
+
   // Match method descriptor with operand stack
   for (int i = nargs - 1; i >= 0; i--) {  // Run backwards
     current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this));
@@ -2831,9 +2866,13 @@
         CHECK_VERIFY(this));
       if (was_recursively_verified()) return;
     } else {   // other methods
-      // Ensures that target class is assignable to method class.
+      // Ensures that target class is assignable to current class (4.9.2),
+      // unless performing a nestmate access
       if (opcode == Bytecodes::_invokespecial) {
-        if (!current_class()->is_anonymous()) {
+        if (nestmate_access) {
+          VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this));
+        }
+        else if (!current_class()->is_anonymous()) {
           current_frame->pop_stack(current_type(), CHECK_VERIFY(this));
         } else {
           // anonymous class invokespecial calls: check if the
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Aug 10 15:01:17 2017 +0100
@@ -141,6 +141,8 @@
   /* class file format tags */                                                                    \
   template(tag_source_file,                           "SourceFile")                               \
   template(tag_inner_classes,                         "InnerClasses")                             \
+  template(tag_nest_members,                          "NestMembers")                              \
+  template(tag_member_of_nest,                        "MemberOfNest")                             \
   template(tag_constant_value,                        "ConstantValue")                            \
   template(tag_code,                                  "Code")                                     \
   template(tag_exceptions,                            "Exceptions")                               \
--- a/src/share/vm/interpreter/linkResolver.cpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/interpreter/linkResolver.cpp	Thu Aug 10 15:01:17 2017 +0100
@@ -730,9 +730,33 @@
     }
   }
 
+#if 0
+  // Experiment: disallow invokevirtual of private methods
+  if (code == Bytecodes::_invokevirtual && !resolved_method.is_null() && resolved_method->is_private()) {
+    ResourceMark rm(THREAD);
+    char buf[200];
+
+    KlassHandle current_klass = link_info.current_klass();
+    jio_snprintf(buf, sizeof(buf), "private method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
+                 Method::name_and_sig_as_C_string(resolved_klass,
+                                                  resolved_method->name(),
+                                                  resolved_method->signature()),
+                                                  (current_klass == NULL ? "<NULL>" : current_klass->internal_name()));
+     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+  }
+#endif
+
   // 5. method lookup failed
   if (resolved_method.is_null()) {
     ResourceMark rm(THREAD);
+    if (UseNewCode) {
+      static int count = 0;
+      tty->print_cr("Missing method: %s", Method::name_and_sig_as_C_string(resolved_klass,
+                                                                           link_info.name(),
+                                                                           link_info.signature()));
+      if (count++ > 0)
+        guarantee(false, "Boom");
+    }
     THROW_MSG_CAUSE_(vmSymbols::java_lang_NoSuchMethodError(),
                     Method::name_and_sig_as_C_string(resolved_klass,
                                                      link_info.name(),
@@ -1087,7 +1111,7 @@
 
   // Invokespecial is called for multiple special reasons:
   // <init>
-  // local private method invocation, for classes and interfaces
+  // local, or nestmate, private method invocation, for classes and interfaces
   // superclass.method, which can also resolve to a default method
   // and the selected method is recalculated relative to the direct superclass
   // superinterface.method, which explicitly does not check shadowing
@@ -1115,7 +1139,28 @@
     return NULL;
   }
 
-  // check if invokespecial's interface method reference is in an indirect superinterface
+  // For private method invocation we should only find the method in the resolved class.
+  // If that is not the case then we have a found a supertype method that we have nestmate
+  // access to.
+  // FIXME: the "ignoring xxx" part is for debugging only
+  if (resolved_method->is_private() &&
+      resolved_method->method_holder() != resolved_klass) {
+    ResourceMark rm(THREAD);
+    assert(InstanceKlass::cast(link_info.current_klass())->has_nestmate_access_to(InstanceKlass::cast(resolved_klass), THREAD), "was only expecting nestmates here!");
+    Exceptions::fthrow(
+      THREAD_AND_LOCATION,
+      vmSymbols::java_lang_NoSuchMethodError(),
+      "%s: method %s%s not found (ignoring %s)",
+      resolved_klass->external_name(),
+      resolved_method->name()->as_C_string(),
+      resolved_method->signature()->as_C_string(),
+      resolved_method->method_holder()->external_name()
+    );
+    return NULL;
+  }
+
+  // check that invokespecial's interface method reference is in a direct superinterface,
+  // unless we are dealing with nestmates.
   Klass* current_klass = link_info.current_klass();
   if (current_klass != NULL && resolved_klass->is_interface()) {
     InstanceKlass* ck = InstanceKlass::cast(current_klass);
@@ -1127,14 +1172,16 @@
                         SystemDictionary::reflect_MagicAccessorImpl_klass());
 
     if (!is_reflect &&
-        !klass_to_check->is_same_or_direct_interface(resolved_klass)) {
+        !klass_to_check->is_same_or_direct_interface(resolved_klass) &&
+        (ck == klass_to_check && // don't check nestmate access for anonymous classes
+         !klass_to_check->has_nestmate_access_to(InstanceKlass::cast(resolved_klass), THREAD))) {
       ResourceMark rm(THREAD);
       char buf[200];
       jio_snprintf(buf, sizeof(buf),
-                   "Interface method reference: %s, is in an indirect superinterface of %s",
+                   "Interface method reference: %s, is not in a direct superinterface of %s",
                    Method::name_and_sig_as_C_string(resolved_klass,
-                                                    resolved_method->name(),
-                                                    resolved_method->signature()),
+                                                                           resolved_method->name(),
+                                                                           resolved_method->signature()),
                    current_klass->external_name());
       THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
     }
@@ -1176,17 +1223,20 @@
 
   if (check_access &&
       // check if the method is not <init>
-      resolved_method->name() != vmSymbols::object_initializer_name()) {
-
-  // check if this is an old-style super call and do a new lookup if so
-        // a) check if ACC_SUPER flag is set for the current class
+      resolved_method->name() != vmSymbols::object_initializer_name()
+      ) {
+    // check if this is an old-style super call and do a new lookup if so
+    // a) check if ACC_SUPER flag is set for the current class
     if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
         // b) check if the class of the resolved_klass is a superclass
         // (not supertype in order to exclude interface classes) of the current class.
         // This check is not performed for super.invoke for interface methods
         // in super interfaces.
         current_klass->is_subclass_of(resolved_klass) &&
-        current_klass != resolved_klass) {
+        current_klass != resolved_klass &&
+        // c) check the method is not private - we don't re-resolve private methods
+        !resolved_method->is_private()
+        ) {
       // Lookup super method
       Klass* super_klass = current_klass->super();
       sel_method = lookup_instance_method_in_klasses(super_klass,
@@ -1203,16 +1253,20 @@
     }
 
     // Check that the class of objectref (the receiver) is the current class or interface,
-    // or a subtype of the current class or interface (the sender), otherwise invokespecial
-    // throws IllegalAccessError.
+    // or a subtype of the current class or interface (the sender), or else they are 
+    // nestmates, otherwise invokespecial throws IllegalAccessError.
     // The verifier checks that the sender is a subtype of the class in the I/MR operand.
     // The verifier also checks that the receiver is a subtype of the sender, if the sender is
     // a class.  If the sender is an interface, the check has to be performed at runtime.
-    InstanceKlass* sender = InstanceKlass::cast(current_klass);
-    sender = sender->is_anonymous() ? sender->host_klass() : sender;
+    InstanceKlass* cur_ik = InstanceKlass::cast(current_klass);
+    InstanceKlass* sender = cur_ik->is_anonymous() ? cur_ik->host_klass() : cur_ik;
     if (sender->is_interface() && recv.not_null()) {
       Klass* receiver_klass = recv->klass();
-      if (!receiver_klass->is_subtype_of(sender)) {
+      if (!receiver_klass->is_subtype_of(sender) &&
+          (cur_ik == sender && // don't check nestmate access for anonymous classes
+           // Note: we check the resolved class here, not the receiver class - the latter
+           // may be a subtype of the resolved class defined outside the nest.
+           !sender->has_nestmate_access_to(InstanceKlass::cast(resolved_klass), THREAD))) {
         ResourceMark rm(THREAD);
         char buf[500];
         jio_snprintf(buf, sizeof(buf),
--- a/src/share/vm/logging/logTag.hpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/logging/logTag.hpp	Thu Aug 10 15:01:17 2017 +0100
@@ -93,6 +93,7 @@
   LOG_TAG(module) \
   LOG_TAG(monitorinflation) \
   LOG_TAG(monitormismatch) \
+  LOG_TAG(nestmates) \
   LOG_TAG(nmethod) \
   LOG_TAG(normalize) \
   LOG_TAG(objecttagging) \
--- a/src/share/vm/memory/heapInspection.hpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/memory/heapInspection.hpp	Thu Aug 10 15:01:17 2017 +0100
@@ -86,6 +86,8 @@
         "Number of bytes used by the InstanceKlass::fields() array") \
     f(inner_classes_bytes, IK_inner_classes, \
         "Number of bytes used by the InstanceKlass::inner_classes() array") \
+    f(nest_members_bytes, IK_nest_members, \
+        "Number of bytes used by the InstanceKlass::nest_members() array") \
     f(signers_bytes, IK_signers, \
         "Number of bytes used by the InstanceKlass::singers() array") \
     f(class_annotations_bytes, class_annotations, \
--- a/src/share/vm/oops/constantPool.cpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/oops/constantPool.cpp	Thu Aug 10 15:01:17 2017 +0100
@@ -255,6 +255,44 @@
   // class redefinition. Since shared ConstantPools cannot be deallocated anyway,
   // we always set _on_stack to true to avoid having to change _flags during runtime.
   _flags |= (_on_stack | _is_shared);
+
+  // Some CONSTANT_Class entries may be resolved at dump time due to nestmate validation.
+  // These need to be undone so that class resolution at run time will not be affected.
+  for (int index = 1; index < length(); index++) { // Index 0 is unused
+    assert(!tag_at(index).is_unresolved_klass_in_error(),
+           "This must not happen during dump time");
+    if (tag_at(index).is_klass()) {
+      /* Old code
+      CPSlot entry = slot_at(index);
+      Klass* k = entry.get_klass();
+      unresolved_klass_at_put(index, k->name());
+      if (log_is_enabled(Trace, cds, resolve)){
+        ResourceMark rm;
+        log_trace(cds, resolve)("CP %p : unresolved class (%3d) %s", this, index,k->name()->as_klass_external_name());
+      }
+      */
+      CPKlassSlot kslot = klass_slot_at(index);
+      int resolved_klass_index = kslot.resolved_klass_index();
+      int name_index = kslot.name_index();
+      assert(tag_at(name_index).is_symbol(), "sanity");
+
+      if (1) { // temp debug code
+        Klass* klass = resolved_klasses()->at(resolved_klass_index);
+        tty->print_cr("undo resolution %d %s: %p", index, symbol_at(name_index)->as_C_string(), klass);
+      }
+
+      Klass** adr = resolved_klasses()->adr_at(resolved_klass_index);
+      OrderAccess::release_store_ptr((Klass* volatile *)adr, NULL);
+      // DAVID: what should this comment say?
+      // (copied from ConstantPool::klass_at_impl)
+      // The interpreter assumes when the tag is stored, the klass is resolved
+      // and the Klass* stored in _resolved_klasses is non-NULL, so we need
+      // hardware store ordering here.
+      release_tag_at_put(index, JVM_CONSTANT_UnresolvedClass);
+
+      assert(klass_name_at(index) == symbol_at(name_index), "sanity");
+    }
+  }
 }
 
 int ConstantPool::cp_to_object_index(int cp_index) {
--- a/src/share/vm/oops/instanceKlass.cpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/oops/instanceKlass.cpp	Thu Aug 10 15:01:17 2017 +0100
@@ -144,6 +144,166 @@
   return false;
 }
 
+// called to verify that k is a member of this nest
+bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const {
+  if (_nest_members == NULL || _nest_members == Universe::the_empty_short_array()) {
+    if (log_is_enabled(Trace, class, nestmates)) {
+      ResourceMark rm(THREAD);
+      log_trace(class, nestmates)("Checking nest membership of %s in non-nest-top class %s",
+                                  k->name()->as_C_string(), this->name()->as_C_string());
+    }
+    return false;
+  }
+
+  if (log_is_enabled(Trace, class, nestmates)) {
+    ResourceMark rm(THREAD);
+    log_trace(class, nestmates)("Checking nest membership of %s in %s",
+                                k->name()->as_C_string(), this->name()->as_C_string());
+  }
+
+  // Check names first and if they match then check actual klass. This avoids
+  // resolving anything unnecessarily.
+  for (int i = 0; i < _nest_members->length(); i++) {
+    int cp_index = _nest_members->at(i);
+    Symbol* name = _constants->klass_name_at(cp_index);
+    if (name == k->name()) {
+      log_trace(class, nestmates)("- Found it at nest_members[%d] => cp[%d]", i, cp_index);
+
+      // names match so check actual klass - this may trigger class loading if
+      // it doesn't match (but that should be impossible)
+      Klass* k2 = _constants->klass_at(cp_index, CHECK_false);
+      if (k2 == k) {
+        log_trace(class, nestmates)("- klass is nestmate member");
+        return true;
+      }
+      else {
+        // same name but different klass!
+        log_trace(class, nestmates)(" - klass comparison failed!");
+      }
+    }
+  }
+  log_trace(class, nestmates)("- klass is NOT nestmate member!");
+  return false;
+}
+
+// Return nest top class, resolving and saving it if needed
+InstanceKlass* InstanceKlass::nest_top(TRAPS) {
+  InstanceKlass* ret_nest_top = _nest_top;
+  if (ret_nest_top == NULL) {
+    // need to resolve and save our nest top class. This could be attempted
+    // concurrently but as the result is idempotent and we don't use the class
+    // then we do not need any synchronization beyond what is implicitly used
+    // during class loading.
+    if (_nest_top_index != 0) { // we have a real nest_top
+      if (log_is_enabled(Trace, class, nestmates)) {
+        ResourceMark rm(THREAD);
+        log_trace(class, nestmates)("Resolving nest top of %s using cp entry for %s",
+                                    this->name()->as_C_string(),
+                                    _constants->klass_name_at(_nest_top_index)->as_C_string());
+      }
+      
+      Klass* k = _constants->klass_at(_nest_top_index, CHECK_NULL);
+      
+      if (log_is_enabled(Trace, class, nestmates)) {
+        ResourceMark rm(THREAD);
+        log_trace(class, nestmates)("Resolved nest top of %s to %s",
+                                    this->name()->as_C_string(), k->name()->as_C_string());
+      }
+      if (!k->is_instance_klass()) {
+        ResourceMark rm(THREAD);
+        Exceptions::fthrow(
+                           THREAD_AND_LOCATION,
+                           vmSymbols::java_lang_IncompatibleClassChangeError(),
+                           "class %s has non-instance class %s as nest-top",
+                           this->external_name(),
+                           k->external_name()
+                           );
+        return NULL;
+      }
+      ret_nest_top = InstanceKlass::cast(k);
+    }
+    else {
+      if (log_is_enabled(Trace, class, nestmates)) {
+        ResourceMark rm(THREAD);
+        log_trace(class, nestmates)("Class %s is not part of a nest: setting nest top to self",
+                                    this->name()->as_C_string());
+      }
+      
+      ret_nest_top = const_cast<InstanceKlass*>(this);
+    }
+  }
+  return ret_nest_top;
+}
+ 
+// check if 'this' and k are nestmates (same nest_top), or k is our nest_top,
+// or we are k's nest_top - all of which is covered by comparing the two
+// resolved_nest_tops
+bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
+
+  // nest-top should have been resolved and validated before any access checks occur
+
+  if (_nest_top == NULL) {
+    ResourceMark rm(THREAD);
+    log_trace(class, nestmates)("Nest-top of %s not resolved when checking access to %s",
+                                this->name()->as_C_string(), 
+                                k->name()->as_C_string());
+  }
+  assert(_nest_top != NULL, "_nest_top should be resolved before access checks occur!");
+
+  InstanceKlass* cur_top = nest_top(CHECK_false);
+
+  // k may not be linked yet so it's nest-top may need to be loaded
+  // if it is not in our nest
+  Klass* k_nest_top = k->nest_top(CHECK_false);
+
+  bool access = (cur_top == k_nest_top);
+
+  if (log_is_enabled(Trace, class, nestmates)) {
+    ResourceMark rm(THREAD);
+    log_trace(class, nestmates)("Class %s does %shave nestmate accesss to %s",
+                                this->name()->as_C_string(), 
+                                access ? "" : "NOT ",
+                                k->name()->as_C_string());
+  }
+
+  return access;
+}
+
+// Resolves nest-top, if needed, and verifies we are actually a member of its nest
+void InstanceKlass::validate_nest_top(TRAPS) {
+  InstanceKlass* nest_top_k = nest_top(CHECK);
+  if (nest_top_k != this) { // real nest-top to check
+    bool is_member = nest_top_k->has_nest_member(this, CHECK);
+    if (!is_member) {
+      // this_k and nest_top disagree about nest membership
+      ResourceMark rm(THREAD);
+      Exceptions::fthrow(
+        THREAD_AND_LOCATION,
+        vmSymbols::java_lang_IncompatibleClassChangeError(),
+        "Type %s is not a nest member of %s",
+        this->external_name(),
+        nest_top_k->external_name()
+      );
+      return;
+    }
+
+    if (!is_same_class_package(nest_top_k)) {
+      ResourceMark rm(THREAD);
+      Exceptions::fthrow(
+        THREAD_AND_LOCATION,
+        vmSymbols::java_lang_IncompatibleClassChangeError(),
+        "Class %s is in a different package to its nest top class %s",
+        this->external_name(),
+        nest_top_k->external_name()
+      );
+      return;
+    }
+  }
+  // save resolved nest-top value
+  _nest_top = nest_top_k;
+}
+
+
 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) {
   const int size = InstanceKlass::size(parser.vtable_size(),
                                        parser.itable_size(),
@@ -223,7 +383,10 @@
   _static_field_size(parser.static_field_size()),
   _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())),
   _itable_len(parser.itable_size()),
-  _reference_type(parser.reference_type()) {
+  _reference_type(parser.reference_type()), 
+  _nest_members(NULL),
+  _nest_top_index(0),
+  _nest_top(NULL) {
     set_vtable_length(parser.vtable_size());
     set_kind(kind);
     set_access_flags(parser.access_flags());
@@ -364,6 +527,13 @@
   }
   set_inner_classes(NULL);
 
+  if (nest_members() != NULL &&
+      nest_members() != Universe::the_empty_short_array() &&
+      !nest_members()->is_shared()) {
+    MetadataFactory::free_array<jushort>(loader_data, nest_members());
+  }
+  set_nest_members(NULL);
+
   // We should deallocate the Annotations instance if it's not in shared spaces.
   if (annotations() != NULL && !annotations()->is_shared()) {
     MetadataFactory::free_metadata(loader_data, annotations());
@@ -572,6 +742,8 @@
     return true;
   }
 
+  validate_nest_top(CHECK_false);
+
   // trace only the link time for this klass that includes
   // the verification time
   PerfClassTraceTime vmtimer(ClassLoader::perf_class_link_time(),
@@ -648,7 +820,6 @@
   return true;
 }
 
-
 // Rewrite the byte codes of all of the methods of a class.
 // The rewriter must be called exactly once. Rewriting must happen after
 // verification but before the first method of the class is executed.
@@ -2024,6 +2195,9 @@
     Method* m = methods()->at(i);
     m->remove_unshareable_info();
   }
+
+  // clear _nest_top to ensure re-load at runtime
+  _nest_top = NULL;
 }
 
 static void restore_unshareable_in_class(Klass* k, TRAPS) {
@@ -2876,6 +3050,7 @@
     st->cr();
   }
   st->print(BULLET"inner classes:     "); inner_classes()->print_value_on(st);     st->cr();
+  st->print(BULLET"nest members:     "); nest_members()->print_value_on(st);     st->cr();
   st->print(BULLET"java mirror:       "); java_mirror()->print_value_on(st);       st->cr();
   st->print(BULLET"vtable length      %d  (start addr: " INTPTR_FORMAT ")", vtable_length(), p2i(start_of_vtable())); st->cr();
   if (vtable_length() > 0 && (Verbose || WizardMode))  print_vtable(start_of_vtable(), vtable_length(), st);
@@ -3118,6 +3293,7 @@
   n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
   n += (sz->_fields_bytes                = sz->count_array(fields()));
   n += (sz->_inner_classes_bytes         = sz->count_array(inner_classes()));
+  n += (sz->_nest_members_bytes          = sz->count_array(nest_members()));
   sz->_ro_bytes += n;
 
   const ConstantPool* cp = constants();
--- a/src/share/vm/oops/instanceKlass.hpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/oops/instanceKlass.hpp	Thu Aug 10 15:01:17 2017 +0100
@@ -163,6 +163,18 @@
   // number_of_inner_classes * 4 + enclosing_method_attribute_size.
   Array<jushort>* _inner_classes;
 
+  // The NestMembers attribute. An array of shorts, where each is a
+  // class info index for the class that is a nest member
+  Array<jushort>* _nest_members;
+
+  // The MemberOfNest attribute. The class info index for the class
+  // that is the nest-top of this class
+  jushort _nest_top_index;
+
+  // Resolved nest-top klass: either true nest-top or self if we are not nested.
+  // By always being set it makes nest-member access checks simpler.
+  InstanceKlass* _nest_top;
+
   // the source debug extension for this klass, NULL if not specified.
   // Specified as UTF-8 string without terminating zero byte in the classfile,
   // it is stored in the instanceklass as a NULL-terminated UTF-8 string
@@ -430,6 +442,27 @@
   Array<u2>* inner_classes() const       { return _inner_classes; }
   void set_inner_classes(Array<u2>* f)   { _inner_classes = f; }
 
+  // nest members
+  Array<u2>* nest_members() const     { return _nest_members; }
+  void set_nest_members(Array<u2>* m) { _nest_members = m; }
+
+  // nest-top index
+  jushort nest_top_index() const { return _nest_top_index; }
+  void set_nest_top_index(u2 i)  { _nest_top_index = i; }
+
+  // Returns nest-top class, resolving it if needed
+  // Returns NULL if an exception occurs during loading.
+  InstanceKlass* nest_top(TRAPS);
+  InstanceKlass* raw_nest_top() { return _nest_top; } // debugging
+
+  // Resolves nest-top, if needed, and verifies we are actually a member of its nest
+  void validate_nest_top(TRAPS);
+
+  // Called to verify that k is a member of this nest - does not look at k's nest-top
+  bool has_nest_member(InstanceKlass* k, TRAPS) const;
+  // Check if this klass is a nestmate of k
+  bool has_nestmate_access_to(InstanceKlass* k, TRAPS);
+
   enum InnerClassAttributeOffset {
     // From http://mirror.eng/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc10.html#18814
     inner_class_inner_class_info_offset = 0,
--- a/src/share/vm/prims/jvm.cpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/prims/jvm.cpp	Thu Aug 10 15:01:17 2017 +0100
@@ -1902,6 +1902,18 @@
 }
 JVM_END
 
+JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member))
+{
+  JVMWrapper("JVM_AreNestMates");
+  Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
+  assert(c->is_instance_klass(), "must be");
+  InstanceKlass* ck = InstanceKlass::cast(c);
+  Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member));
+  assert(m->is_instance_klass(), "must be");
+  InstanceKlass* mk = InstanceKlass::cast(m);
+  return ck->has_nestmate_access_to(mk, THREAD);
+}
+JVM_END
 
 // Constant pool access //////////////////////////////////////////////////////////
 
--- a/src/share/vm/prims/jvm.h	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/prims/jvm.h	Thu Aug 10 15:01:17 2017 +0100
@@ -551,6 +551,10 @@
 JNIEXPORT jint JNICALL
 JVM_GetClassAccessFlags(JNIEnv *env, jclass cls);
 
+/* Nestmate access - since JDK 10 */
+JNIEXPORT jboolean JNICALL
+JVM_AreNestMates(JNIEnv *env, jclass current, jclass member);
+
 /*
  * Constant pool access; currently used to implement reflective access to annotations (JDK 1.5)
  */
--- a/src/share/vm/runtime/reflection.cpp	Thu Aug 10 04:49:27 2017 -0700
+++ b/src/share/vm/runtime/reflection.cpp	Thu Aug 10 15:01:17 2017 +0100
@@ -701,18 +701,32 @@
     }
   }
 
+  // package access
   if (!access.is_private() && is_same_class_package(current_class, field_class)) {
     return true;
   }
 
+  // private access between different classes needs a nestmate check, but
+  // not for anonymous classes - so check host_class
+  if (access.is_private() && host_class == current_class) {
+    if (current_class->is_instance_klass() && field_class->is_instance_klass() ) {
+      InstanceKlass* cur_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(current_class));
+      InstanceKlass* field_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(field_class));
+      if (cur_ik->has_nestmate_access_to(field_ik, Thread::current())) {
+        guarantee(resolved_class->is_subclass_of(field_class), "must be!");
+        return true;
+      }
+    }
+  }
+
   // Allow all accesses from jdk/internal/reflect/MagicAccessorImpl subclasses to
   // succeed trivially.
   if (current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
     return true;
   }
 
-  return can_relax_access_check_for(
-    current_class, field_class, classloader_only);
+  // Check for special relaxations
+  return can_relax_access_check_for(current_class, field_class, classloader_only);
 }
 
 bool Reflection::is_same_class_package(const Klass* class1, const Klass* class2) {
--- a/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java	Thu Aug 10 04:49:27 2017 -0700
+++ b/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java	Thu Aug 10 15:01:17 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@
  * @run driver jdk.test.lib.FileInstaller ./JvmciNotifyBootstrapFinishedEventTest.config
  *     ./META-INF/services/jdk.vm.ci.services.JVMCIServiceLocator
  * @run driver ClassFileInstaller
+ *      compiler.jvmci.common.JVMCIHelpers
  *      compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilationRequestResult
--- a/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java	Thu Aug 10 04:49:27 2017 -0700
+++ b/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java	Thu Aug 10 15:01:17 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
  * @run driver jdk.test.lib.FileInstaller ./JvmciNotifyInstallEventTest.config
  *     ./META-INF/services/jdk.vm.ci.services.JVMCIServiceLocator
  * @run driver ClassFileInstaller
+ *      compiler.jvmci.common.JVMCIHelpers
  *      compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilationRequestResult
--- a/test/compiler/jvmci/events/JvmciShutdownEventTest.java	Thu Aug 10 04:49:27 2017 -0700
+++ b/test/compiler/jvmci/events/JvmciShutdownEventTest.java	Thu Aug 10 15:01:17 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -38,6 +38,7 @@
  * @run driver jdk.test.lib.FileInstaller ./JvmciShutdownEventTest.config
  *     ./META-INF/services/jdk.vm.ci.services.JVMCIServiceLocator
  * @run driver ClassFileInstaller
+ *      compiler.jvmci.common.JVMCIHelpers
  *      compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilationRequestResult
--- a/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java	Thu Aug 10 04:49:27 2017 -0700
+++ b/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java	Thu Aug 10 15:01:17 2017 +0100
@@ -39,6 +39,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
 
 public class ResolvedJavaTypeResolveConcreteMethodTest {
     public final MetaAccessProvider metaAccess;
@@ -117,8 +118,9 @@
         ResolvedJavaType c = getType(C.class);
         ResolvedJavaMethod priv = getMethod(a, "priv");
 
-        assertNull(a.resolveConcreteMethod(priv, c));
-        assertNull(b.resolveConcreteMethod(priv, c));
+        // nestmates have access to private methods
+        assertNotNull(a.resolveConcreteMethod(priv, c));
+        assertNotNull(b.resolveConcreteMethod(priv, c));
     }
 
     @Test
--- a/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java	Thu Aug 10 04:49:27 2017 -0700
+++ b/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java	Thu Aug 10 15:01:17 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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,6 +39,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
 
 public class ResolvedJavaTypeResolveMethodTest {
     public final MetaAccessProvider metaAccess;
@@ -117,8 +118,9 @@
         ResolvedJavaType c = getType(C.class);
         ResolvedJavaMethod priv = getMethod(a, "priv");
 
-        assertNull(a.resolveMethod(priv, c));
-        assertNull(b.resolveMethod(priv, c));
+        // nestmates have access to private methods
+        assertNotNull(a.resolveMethod(priv, c));
+        assertNotNull(b.resolveMethod(priv, c));
     }
 
     @Test
--- a/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Thu Aug 10 04:49:27 2017 -0700
+++ b/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Thu Aug 10 15:01:17 2017 +0100
@@ -29,7 +29,7 @@
  *          java.management
  *          jdk.attach/sun.tools.attach
  *          jdk.internal.jvmstat/sun.jvmstat.monitor
- * @run main/othervm/timeout=900 TestOptionsWithRanges
+ * @run main/othervm/timeout=9000 TestOptionsWithRanges
  */
 
 import java.util.ArrayList;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/BadNestMembersEntry.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Source: NestmateAttributeHolder.java
+
+public class NestmateAttributeHolder {
+    public static class TwoMemberOfNest {
+    }
+}
+*/
+
+// NestMembers attribute refers to non-class entry
+
+class BadNestMembersEntry {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #16; // #3    
+    class #17; // #4    
+    Utf8 "TwoMemberOfNest"; // #5    
+    Utf8 "InnerClasses"; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "SourceFile"; // #11    
+    Utf8 "BadNestMembersEntry.java"; // #12    
+    Utf8 "NestMembers"; // #13    
+    NameAndType #7 #8; // #14    
+    Utf8 "BadNestMembersEntry"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "BadNestMembersEntry$TwoMemberOfNest"; // #17    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  1;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#11) { // SourceFile
+      #12;
+    } // end SourceFile
+    ;
+    Attr(#13) { // NestMembers
+      0x00010009;  // not a class index
+      } // end NestMembers
+    ;
+    Attr(#6) { // InnerClasses
+      [] { // InnerClasses
+        #4 #2 #5 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class BadNestMembersEntry
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/BadNestMembersLength.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Source: NestmateAttributeHolder.java
+
+public class NestmateAttributeHolder {
+    public static class TwoMemberOfNest {
+    }
+}
+*/
+
+// NestMembers attribute has wrong count for number of nestmates
+
+class BadNestMembersLength {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #16; // #3    
+    class #17; // #4    
+    Utf8 "TwoMemberOfNest"; // #5    
+    Utf8 "InnerClasses"; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "SourceFile"; // #11    
+    Utf8 "BadNestMembersLength.java"; // #12    
+    Utf8 "NestMembers"; // #13    
+    NameAndType #7 #8; // #14    
+    Utf8 "BadNestMembersLength"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "BadNestMembersLength$TwoMemberOfNest"; // #17    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  1;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#11) { // SourceFile
+      #12;
+    } // end SourceFile
+    ;
+    Attr(#13) { // NestMembers
+      0x00000004;   // bad length
+    } // end NestMembers
+    ;
+    Attr(#6) { // InnerClasses
+      [] { // InnerClasses
+        #4 #2 #5 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class BadNestMembersLength
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/BadNestTop.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Source: NestmateAttributeHolder.java
+
+public class NestmateAttributeHolder {
+    public static class TwoMemberOfNest {
+    }
+}
+*/
+
+// MemberOfNest attribute does not refer to a class
+
+class NestmateAttributeHolder$BadNestTop {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #12; // #1    
+    class #13; // #2    
+    class #16; // #3    
+    Utf8 "<init>"; // #4    
+    Utf8 "()V"; // #5    
+    Utf8 "Code"; // #6    
+    Utf8 "LineNumberTable"; // #7    
+    Utf8 "SourceFile"; // #8    
+    Utf8 "NestmateAttributeHolder.java"; // #9    
+    Utf8 "MemberOfNest"; // #10    
+    class #17; // #11    
+    NameAndType #4 #5; // #12    
+    Utf8 "NestmateAttributeHolder$BadNestTop"; // #13    
+    Utf8 "BadNestTop"; // #14    
+    Utf8 "InnerClasses"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "NestmateAttributeHolder"; // #17    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #4; // name_cpx
+      #5; // sig_cpx
+      [] { // Attributes
+        Attr(#6) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#7) { // LineNumberTable
+              [] { // LineNumberTable
+                0  2;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#8) { // SourceFile
+      #9;
+    } // end SourceFile
+    ;
+    Attr(#10) { // MemberOfNest
+      0x000A;  // not a class index
+    } // end MemberOfNest
+    ;
+    Attr(#15) { // InnerClasses
+      [] { // InnerClasses
+        #2 #11 #14 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class NestmateAttributeHolder$BadNestTop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestMember.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Source: NestmateAttributeHolder.java
+
+public class NestmateAttributeHolder {
+    public static class TwoMemberOfNest {
+    }
+}
+*/
+
+class NestmateAttributeHolder$ConflictingAttributesInNestMember {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #12; // #1    
+    class #13; // #2    
+    class #16; // #3    
+    Utf8 "<init>"; // #4    
+    Utf8 "()V"; // #5    
+    Utf8 "Code"; // #6    
+    Utf8 "LineNumberTable"; // #7    
+    Utf8 "SourceFile"; // #8    
+    Utf8 "NestmateAttributeHolder.java"; // #9    
+    Utf8 "MemberOfNest"; // #10    
+    class #17; // #11    
+    NameAndType #4 #5; // #12    
+    Utf8 "NestmateAttributeHolder$ConflictingAttributesInNestMember"; // #13    
+    Utf8 "ConflictingAttributesInNestMember"; // #14    
+    Utf8 "InnerClasses"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "NestmateAttributeHolder"; // #17    
+    Utf8 "NestMembers"; // #18    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #4; // name_cpx
+      #5; // sig_cpx
+      [] { // Attributes
+        Attr(#6) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#7) { // LineNumberTable
+              [] { // LineNumberTable
+                0  2;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#8) { // SourceFile
+      #9;
+    } // end SourceFile
+    ;
+    Attr(#10) { // MemberOfNest
+      0x000B;
+    } // end MemberOfNest
+    ;
+    // conflict: can't have nest members when you are a member of a nest
+    Attr(#18) { // NestMembers
+      0x00010004;
+    } // end NestMembers
+    ;
+    Attr(#15) { // InnerClasses
+      [] { // InnerClasses
+        #2 #11 #14 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class NestmateAttributeHolder$ConflictingAttributesInNestMember
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestTop.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Source: NestmateAttributeHolder.java
+
+public class NestmateAttributeHolder {
+    public static class TwoMemberOfNest {
+    }
+}
+*/
+
+// Add MemberOfNest attribute to nest top class - conflicting attributes
+
+class ConflictingAttributesInNestTop {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #16; // #3    
+    class #17; // #4    
+    Utf8 "TwoMemberOfNest"; // #5    
+    Utf8 "InnerClasses"; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "SourceFile"; // #11    
+    Utf8 "ConflictingAttributesInNestTop.java"; // #12    
+    Utf8 "NestMembers"; // #13    
+    NameAndType #7 #8; // #14    
+    Utf8 "ConflictingAttributesInNestTop"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "ConflictingAttributesInNestTop$TwoMemberOfNest"; // #17    
+    Utf8 "MemberOfNest"; // #18
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  1;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#11) { // SourceFile
+      #12;
+    } // end SourceFile
+    ;
+    Attr(#13) { // NestMembers
+      0x00010004;
+    } // end NestMembers
+    ;
+    // conflict - can't be a member of a nest and have nest members
+    Attr(#18) { // MemberOfNest
+      0x0003; // #3 is Object
+    } // end MemberOfNest
+    ;
+    Attr(#6) { // InnerClasses
+      [] { // InnerClasses
+        #4 #2 #5 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class ConflictingAttributesInNestTop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/DuplicateNestMemberEntry.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Source: NestmateAttributeHolder.java
+
+public class NestmateAttributeHolder {
+    public static class TwoMemberOfNest {
+    }
+}
+*/
+
+// NestMembers attribute has two entries for the same class
+
+class DuplicateNestMemberEntry {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #16; // #3    
+    class #17; // #4    
+    Utf8 "TwoMemberOfNest"; // #5    
+    Utf8 "InnerClasses"; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "SourceFile"; // #11    
+    Utf8 "DuplicateNestMemberEntry.java"; // #12    
+    Utf8 "NestMembers"; // #13    
+    NameAndType #7 #8; // #14    
+    Utf8 "DuplicateNestMemberEntry"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "DuplicateNestMemberEntry$TwoMemberOfNest"; // #17    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  1;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#11) { // SourceFile
+      #12;
+    } // end SourceFile
+    ;
+    Attr(#13) { // NestMembers
+      0x000200040004; // duplicate entry
+    } // end NestMembers
+    ;
+    Attr(#6) { // InnerClasses
+      [] { // InnerClasses
+        #4 #2 #5 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class DuplicateNestMemberEntry
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/TestFinalMethodOverride.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test nestmate checks are no longer used when check_final_method_override is executed during parsing
+ * @run main TestFinalMethodOverride
+ */
+
+public class TestFinalMethodOverride {
+
+  public static class Super {
+    private final void theMethod() {}
+  }
+
+  public static class Inner extends Super {
+    // define our own theMethod
+    public void theMethod() {}
+  }
+
+  public static void main(String[] args) {
+    Inner i = new Inner();
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/TestNestmateAttributes.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test incorrect use of Nestmate related attributes
+ * @compile TwoMemberOfNest.jcod
+ *          TwoNestMembers.jcod
+ *          ConflictingAttributesInNestTop.jcod
+ *          ConflictingAttributesInNestMember.jcod
+ *          BadNestMembersLength.jcod
+ *          BadNestMembersEntry.jcod
+ *          DuplicateNestMemberEntry.jcod
+ *          BadNestTop.jcod
+ * @run main TestNestmateAttributes
+ */
+
+public class TestNestmateAttributes {
+    public static void main(String args[]) throws Throwable {
+        String[] badClasses = new String[] {
+            "NestmateAttributeHolder$TwoMemberOfNest",
+            "NestmateAttributeHolder",
+            "ConflictingAttributesInNestTop",
+            "NestmateAttributeHolder$ConflictingAttributesInNestMember",
+            "BadNestMembersLength",
+            "BadNestMembersEntry",
+            "DuplicateNestMemberEntry",
+            "NestmateAttributeHolder$BadNestTop",
+        };
+
+        String[] messages = new String[] {
+            "Multiple MemberOfNest attributes in class file",
+            "Multiple NestMembers attributes in class file",
+            "Conflicting NestMembers and MemberOfNest attributes",
+            "Conflicting MemberOfNest and NestMembers attributes",
+            "Wrong NestMembers attribute length", 
+            "Nest member class_info_index 9 has bad constant type",
+            "Duplicate entry in NestMembers ",
+            "Nest top class_info_index 10 has bad constant type",
+        };
+        
+        for (int i = 0; i < badClasses.length; i++ ) {
+            try {
+                Class c = Class.forName(badClasses[i]);
+                throw new Error("Missing ClassFormatError: " + messages[i]);
+            }
+            catch (ClassFormatError expected) {
+                if (!expected.getMessage().contains(messages[i]))
+                   throw new Error("Wrong ClassFormatError message: \"" +
+                                   expected.getMessage() + "\" does not contain \"" +
+                                   messages[i] + "\"");
+                System.out.println("OK - got expected exception: " + expected);
+            }
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/TwoMemberOfNest.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Source: NestmateAttributeHolder.java
+
+public class NestmateAttributeHolder {
+    public static class TwoMemberOfNest {
+    }
+}
+*/
+
+// Add second MemberOfNest attribute - should fail parsing
+class NestmateAttributeHolder$TwoMemberOfNest {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #12; // #1    
+    class #13; // #2    
+    class #16; // #3    
+    Utf8 "<init>"; // #4    
+    Utf8 "()V"; // #5    
+    Utf8 "Code"; // #6    
+    Utf8 "LineNumberTable"; // #7    
+    Utf8 "SourceFile"; // #8    
+    Utf8 "NestmateAttributeHolder.java"; // #9    
+    Utf8 "MemberOfNest"; // #10    
+    class #17; // #11    
+    NameAndType #4 #5; // #12    
+    Utf8 "NestmateAttributeHolder$TwoMemberOfNest"; // #13    
+    Utf8 "TwoMemberOfNest"; // #14    
+    Utf8 "InnerClasses"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "NestmateAttributeHolder"; // #17    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #4; // name_cpx
+      #5; // sig_cpx
+      [] { // Attributes
+        Attr(#6) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#7) { // LineNumberTable
+              [] { // LineNumberTable
+                0  2;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#8) { // SourceFile
+      #9;
+    } // end SourceFile
+    ;
+    Attr(#10) { // MemberOfNest
+      0x000B;
+    } // end MemberOfNest
+    ;
+    Attr(#10) { // MemberOfNest
+      0x000B;
+    } // end MemberOfNest
+    ;
+    Attr(#15) { // InnerClasses
+      [] { // InnerClasses
+        #2 #11 #14 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class NestmateAttributeHolder$TwoMemberOfNest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/classFileParsing/TwoNestMembers.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Source: NestmateAttributeHolder.java
+
+public class NestmateAttributeHolder {
+    public static class TwoMemberOfNest {
+    }
+}
+*/
+
+// Add second NestMembers attribute - should fail parsing
+
+class NestmateAttributeHolder {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #16; // #3    
+    class #17; // #4    
+    Utf8 "TwoMemberOfNest"; // #5    
+    Utf8 "InnerClasses"; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "SourceFile"; // #11    
+    Utf8 "NestmateAttributeHolder.java"; // #12    
+    Utf8 "NestMembers"; // #13    
+    NameAndType #7 #8; // #14    
+    Utf8 "NestmateAttributeHolder"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "NestmateAttributeHolder$TwoMemberOfNest"; // #17    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  1;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#11) { // SourceFile
+      #12;
+    } // end SourceFile
+    ;
+    Attr(#13) { // NestMembers
+      0x00010004;
+    } // end NestMembers
+    ;
+    Attr(#13) { // NestMembers
+      0x00010004;
+    } // end NestMembers
+    ;
+    Attr(#6) { // InnerClasses
+      [] { // InnerClasses
+        #4 #2 #5 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class NestmateAttributeHolder
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/membership/ArrayNestTop.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Generated from:
+
+public class TestNestMaterMembership {
+  public static class Nested {}
+}
+*/
+
+// Class ArrayNestTop claims to be in the nest of Object[] (not an instance class)
+
+class ArrayNestTop {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #18; // #3    
+    Utf8 "obj"; // #4    
+    Utf8 "[Ljava/lang/Object;"; // #5    
+    Utf8 "<init>"; // #6    
+    Utf8 "()V"; // #7    
+    Utf8 "Code"; // #8    
+    Utf8 "LineNumberTable"; // #9    
+    Utf8 "SourceFile"; // #10    
+    Utf8 "TestNestmateMembership.java"; // #11    
+    Utf8 "MemberOfNest"; // #12    
+    class #19; // #13    
+    NameAndType #6 #7; // #14    
+    Utf8 "ArrayNestTop"; // #15    
+    Utf8 "Nested"; // #16    
+    Utf8 "InnerClasses"; // #17    
+    Utf8 "java/lang/Object"; // #18    
+    Utf8 "TestNestmateMembership"; // #19    
+    class #5; // #20 Object[] class
+  } // Constant Pool
+
+  0x0020; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+    { // Member
+      0x0000; // access
+      #4; // name_cpx
+      #5; // sig_cpx
+      [] { // Attributes
+      } // Attributes
+    } // Member
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #6; // name_cpx
+      #7; // sig_cpx
+      [] { // Attributes
+        Attr(#8) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#9) { // LineNumberTable
+              [] { // LineNumberTable
+                0  37;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#10) { // SourceFile
+      #11;
+    } // end SourceFile
+    ;
+    Attr(#12) { // MemberOfNest
+      0x0014;  // refers to Object[] class
+    } // end MemberOfNest
+    ;
+    Attr(#17) { // InnerClasses
+      [] { // InnerClasses
+        #2 #13 #16 8;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class ArrayNestTop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/membership/MissingNestTop.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Generated from:
+
+public class TestNestMaterMembership {
+  public static class Nested {}
+}
+*/
+
+// Class MissingNestTop claims to be in the nest of the non-existent NoSuchClass
+
+class MissingNestTop {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #18; // #3    
+    Utf8 "obj"; // #4    
+    Utf8 "[Ljava/lang/Object;"; // #5    
+    Utf8 "<init>"; // #6    
+    Utf8 "()V"; // #7    
+    Utf8 "Code"; // #8    
+    Utf8 "LineNumberTable"; // #9    
+    Utf8 "SourceFile"; // #10    
+    Utf8 "TestNestmateMembership.java"; // #11    
+    Utf8 "MemberOfNest"; // #12    
+    class #19; // #13    
+    NameAndType #6 #7; // #14    
+    Utf8 "MissingNestTop"; // #15    
+    Utf8 "Nested"; // #16    
+    Utf8 "InnerClasses"; // #17    
+    Utf8 "java/lang/Object"; // #18    
+    Utf8 "NoSuchClass"; // #19    
+  } // Constant Pool
+
+  0x0020; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+    { // Member
+      0x0000; // access
+      #4; // name_cpx
+      #5; // sig_cpx
+      [] { // Attributes
+      } // Attributes
+    } // Member
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #6; // name_cpx
+      #7; // sig_cpx
+      [] { // Attributes
+        Attr(#8) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#9) { // LineNumberTable
+              [] { // LineNumberTable
+                0  37;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#10) { // SourceFile
+      #11;
+    } // end SourceFile
+    ;
+    Attr(#12) { // MemberOfNest
+      0x000D;
+    } // end MemberOfNest
+    ;
+    Attr(#17) { // InnerClasses
+      [] { // InnerClasses
+        #2 #13 #16 8;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class MissingNestTop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/membership/NestTop.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Generated from:
+
+public class NestTop {
+  public static class NestMember {}
+}
+*/
+
+// Class P1.NestTop claims to have a nest member NestTop$NestMember (different package)
+
+class P1/NestTop {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #16; // #3    
+    class #17; // #4    
+    Utf8 "NestMember"; // #5    
+    Utf8 "InnerClasses"; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "SourceFile"; // #11    
+    Utf8 "NestTop.java"; // #12    
+    Utf8 "NestMembers"; // #13    
+    NameAndType #7 #8; // #14    
+    Utf8 "P1/NestTop"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "NestTop$NestMember"; // #17    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  3;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#11) { // SourceFile
+      #12;
+    } // end SourceFile
+    ;
+    Attr(#13) { // NestMembers
+      0x00010004;
+    } // end NestMembers
+    ;
+    Attr(#6) { // InnerClasses
+      [] { // InnerClasses
+        #4 #2 #5 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class P1/NestTop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/membership/NestTop_NestMember.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Generated from:
+
+public class NestTop {
+  public static class NestMember {}
+}
+*/
+
+// Class NestTop$NestMember claims to be in the nest of P1.NestTop (different package)
+
+class NestTop$NestMember {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #12; // #1    
+    class #13; // #2    
+    class #16; // #3    
+    Utf8 "<init>"; // #4    
+    Utf8 "()V"; // #5    
+    Utf8 "Code"; // #6    
+    Utf8 "LineNumberTable"; // #7    
+    Utf8 "SourceFile"; // #8    
+    Utf8 "NestTop.java"; // #9    
+    Utf8 "MemberOfNest"; // #10    
+    class #17; // #11    
+    NameAndType #4 #5; // #12    
+    Utf8 "NestTop$NestMember"; // #13    
+    Utf8 "NestMember"; // #14    
+    Utf8 "InnerClasses"; // #15    
+    Utf8 "java/lang/Object"; // #16    
+    Utf8 "P1/NestTop"; // #17    
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0001; // access
+      #4; // name_cpx
+      #5; // sig_cpx
+      [] { // Attributes
+        Attr(#6) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#7) { // LineNumberTable
+              [] { // LineNumberTable
+                0  4;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#8) { // SourceFile
+      #9;
+    } // end SourceFile
+    ;
+    Attr(#10) { // MemberOfNest
+      0x000B;
+    } // end MemberOfNest
+    ;
+    Attr(#15) { // InnerClasses
+      [] { // InnerClasses
+        #2 #11 #14 9;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class NestTop$NestMember
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/membership/NotAMember.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Generated from:
+
+public class TestNestMaterMembership {
+  public static class Nested {}
+}
+*/
+
+// Class NotAMember claims to be in the nest of Object (which has no nest)
+
+class NotAMember {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #18; // #3    
+    Utf8 "obj"; // #4    
+    Utf8 "[Ljava/lang/Object;"; // #5    
+    Utf8 "<init>"; // #6    
+    Utf8 "()V"; // #7    
+    Utf8 "Code"; // #8    
+    Utf8 "LineNumberTable"; // #9    
+    Utf8 "SourceFile"; // #10    
+    Utf8 "TestNestmateMembership.java"; // #11    
+    Utf8 "MemberOfNest"; // #12    
+    class #19; // #13    
+    NameAndType #6 #7; // #14    
+    Utf8 "NotAMember"; // #15    
+    Utf8 "Nested"; // #16    
+    Utf8 "InnerClasses"; // #17    
+    Utf8 "java/lang/Object"; // #18    
+    Utf8 "TestNestmateMembership"; // #19    
+  } // Constant Pool
+
+  0x0020; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+    { // Member
+      0x0000; // access
+      #4; // name_cpx
+      #5; // sig_cpx
+      [] { // Attributes
+      } // Attributes
+    } // Member
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #6; // name_cpx
+      #7; // sig_cpx
+      [] { // Attributes
+        Attr(#8) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#9) { // LineNumberTable
+              [] { // LineNumberTable
+                0  37;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#10) { // SourceFile
+      #11;
+    } // end SourceFile
+    ;
+    Attr(#12) { // MemberOfNest
+      0x0003;  // refers to Object class
+    } // end MemberOfNest
+    ;
+    Attr(#17) { // InnerClasses
+      [] { // InnerClasses
+        #2 #13 #16 8;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class NotAMember
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/membership/NotAMember2.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/* Generated from:
+
+public class TestNestMaterMembership {
+  public static class Nested {}
+}
+*/
+
+// Class NotAMember2 claims to be in the nest of TestNestmateMembership but isn't
+
+class NotAMember2 {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #3 #14; // #1    
+    class #15; // #2    
+    class #18; // #3    
+    Utf8 "obj"; // #4    
+    Utf8 "[Ljava/lang/Object;"; // #5    
+    Utf8 "<init>"; // #6    
+    Utf8 "()V"; // #7    
+    Utf8 "Code"; // #8    
+    Utf8 "LineNumberTable"; // #9    
+    Utf8 "SourceFile"; // #10    
+    Utf8 "TestNestmateMembership.java"; // #11    
+    Utf8 "MemberOfNest"; // #12    
+    class #19; // #13    
+    NameAndType #6 #7; // #14    
+    Utf8 "NotAMember2"; // #15    
+    Utf8 "Nested"; // #16    
+    Utf8 "InnerClasses"; // #17    
+    Utf8 "java/lang/Object"; // #18    
+    Utf8 "TestNestmateMembership"; // #19    
+  } // Constant Pool
+
+  0x0020; // access
+  #2;// this_cpx
+  #3;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+    { // Member
+      0x0000; // access
+      #4; // name_cpx
+      #5; // sig_cpx
+      [] { // Attributes
+      } // Attributes
+    } // Member
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #6; // name_cpx
+      #7; // sig_cpx
+      [] { // Attributes
+        Attr(#8) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#9) { // LineNumberTable
+              [] { // LineNumberTable
+                0  37;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#10) { // SourceFile
+      #11;
+    } // end SourceFile
+    ;
+    Attr(#12) { // MemberOfNest
+      0x000D;  // refers to TestNestmateMembership
+    } // end MemberOfNest
+    ;
+    Attr(#17) { // InnerClasses
+      [] { // InnerClasses
+        #2 #13 #16 8;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class NotAMember2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/membership/TestNestmateMembership.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test the various rules for nest members and nest-tops
+ * @compile TestNestmateMembership.java
+ *          MissingNestTop.jcod
+ *          ArrayNestTop.jcod
+ *          NotAMember.jcod
+ *          NotAMember2.jcod
+ *          NestTop.jcod
+ *          NestTop_NestMember.jcod
+ * @run main/othervm -Xlog:class+nestmates=off TestNestmateMembership
+ */
+
+// We test all the "illegal" relationships between a nest member and its nest-top
+// except for the case where the name of the nest-member matches the name listed
+// in the nest-top, but resolves to a different class. There doesn't seem to 
+// be a way to construct that scenario.
+
+public class TestNestmateMembership {
+
+  static class Nested { // basic template for the jcod files
+    Object[] obj;
+  }
+
+  public static void main(String[] args) throws Throwable {
+    // Class's nest top does not exist
+    String msg = "NoSuchClass";
+    try {
+      Class<?> c = Class.forName("MissingNestTop");
+      throw new Error("Missing NoClassDefFoundError: " + msg);
+    }
+    catch (NoClassDefFoundError expected) {
+      if (!expected.getMessage().contains(msg))
+        throw new Error("Wrong NoClassDefFoundError: \"" +
+                        expected.getMessage() + "\" does not contain \"" +
+                        msg + "\"");
+      System.out.println("OK - got expected exception: " + expected);
+    }
+
+    String[] badClasses = new String[] {
+      "ArrayNestTop",  // Listed  nest-top is not an instance class
+      "NotAMember",    // Listed nest-top has no nest
+      "NotAMember2",   // Listed nest-top doesn't list this class as member
+      "NestTop$NestMember", // nest-top and nest member are in different packages
+                            // - note both classes have to list the incorrect package
+    };
+    
+    String[] messages = new String[] {
+      "ArrayNestTop has non-instance class [Ljava.lang.Object; as nest-top",
+      "NotAMember is not a nest member of java.lang.Object",
+      "NotAMember2 is not a nest member of TestNestmateMembership",
+      "NestTop$NestMember is in a different package to its nest top class",
+    };
+
+    for (int i = 0; i < badClasses.length; i++ ) {
+      try {
+        Class<?> c = Class.forName(badClasses[i]);
+        throw new Error("Missing IncompatibleClassChangeError:" + messages[i]);
+      }
+      catch (IncompatibleClassChangeError expected) {
+        if (!expected.getMessage().contains(messages[i]))
+          throw new Error("Wrong IncompatibleClassChangeError: \"" +
+                          expected.getMessage() + "\" does not contain \"" +
+                          messages[i] + "\"");
+        System.out.println("OK - got expected exception: " + expected);
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateConstructors/TestInvokeSpecial.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private constructors between nestmates and nest-top
+ *          using different flavours of named nested types that will
+ *          generate invokespecial for the calls
+ * @compile -XDdisablePrivateAccessors TestInvokeSpecial.java
+ * @run main TestInvokeSpecial
+ */
+
+public class TestInvokeSpecial {
+
+    // All constructors are private to ensure nestmate access checks apply
+
+    // All doConstruct methods are public so they don't involve invoke_special
+
+    private TestInvokeSpecial() {}
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        default void doConstruct(TestInvokeSpecial o) {
+            Object obj = new TestInvokeSpecial();
+        }
+        default void doConstruct(InnerNested o) {
+            Object obj = new TestInvokeSpecial().new InnerNested();
+        }
+        default void doConstruct(StaticNested o) {
+            Object obj = new StaticNested();
+        }
+        default void doConstruct(StaticIface o) {
+            Object obj = new StaticIface() {};
+        }
+    }
+
+    static class StaticNested {
+
+        private StaticNested() {}
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        public void doConstruct(TestInvokeSpecial o) {
+            Object obj = new TestInvokeSpecial();
+        }
+        public void doConstruct(InnerNested o) {
+            Object obj = new TestInvokeSpecial().new InnerNested();
+        }
+        public void doConstruct(StaticNested o) {
+            Object obj = new StaticNested();
+        }
+        public void doConstruct(StaticIface o) {
+            Object obj = new StaticIface() {};
+        }
+    }
+
+    class InnerNested {
+
+        private InnerNested() {}
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        public void doConstruct(TestInvokeSpecial o) {
+            Object obj = new TestInvokeSpecial();
+        }
+        public void doConstruct(InnerNested o) {
+            Object obj = new TestInvokeSpecial().new InnerNested();
+        }
+        public void doConstruct(StaticNested o) {
+            Object obj = new StaticNested();
+        }
+        public void doConstruct(StaticIface o) {
+            Object obj = new StaticIface() {};
+        }
+    }
+
+    public static void main(String[] args) {
+        // These initial constructions test nest-top access
+        TestInvokeSpecial o = new TestInvokeSpecial();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        s.doConstruct(o);
+        s.doConstruct(i);
+        s.doConstruct(s);
+        s.doConstruct(intf);
+
+        i.doConstruct(o);
+        i.doConstruct(i);
+        i.doConstruct(s);
+        i.doConstruct(intf);
+
+        intf.doConstruct(o);
+        intf.doConstruct(i);
+        intf.doConstruct(s);
+        intf.doConstruct(intf);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateConstructors/TestMethodHandles.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private constructors between nestmates and nest-top
+ *          using different flavours of named nested types using method handles
+ * @compile -XDdisablePrivateAccessors TestMethodHandles.java
+ * @run main TestMethodHandles
+ */
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class TestMethodHandles {
+
+  static final MethodType NOARG_T = MethodType.methodType(void.class);
+  static final MethodType INNER_T = MethodType.methodType(void.class, TestMethodHandles.class);
+
+    // All constructors are private to ensure nestmate access checks apply
+
+    // All doConstruct methods are public so they don't involve invoke_special
+
+    private TestMethodHandles() {}
+
+    // The various nestmates
+
+    // Note: No constructor on interfaces so no StaticIface variants
+
+    static interface StaticIface {
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        default void doConstruct(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(TestMethodHandles.class, NOARG_T);
+            TestMethodHandles obj = (TestMethodHandles) mh.invoke();
+            obj = (TestMethodHandles) mh.invokeExact();
+        }
+        default void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(InnerNested.class, INNER_T);
+            InnerNested obj = (InnerNested) mh.invoke(outer);
+            obj = (InnerNested) mh.invokeExact(outer);
+        }
+        default void doConstruct(StaticNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(StaticNested.class, NOARG_T);
+            StaticNested obj = (StaticNested) mh.invoke();
+            obj = (StaticNested) mh.invokeExact();
+        }
+    }
+
+    static class StaticNested {
+
+        private StaticNested() {}
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        public void doConstruct(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(TestMethodHandles.class, NOARG_T);
+            TestMethodHandles obj = (TestMethodHandles) mh.invoke();
+            obj = (TestMethodHandles) mh.invokeExact();
+        }
+        public  void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(InnerNested.class, INNER_T);
+            InnerNested obj = (InnerNested) mh.invoke(outer);
+            obj = (InnerNested) mh.invokeExact(outer);
+        }
+        public void doConstruct(StaticNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(StaticNested.class, NOARG_T);
+            StaticNested obj = (StaticNested) mh.invoke();
+            obj = (StaticNested) mh.invokeExact();
+        }
+    }
+
+    class InnerNested {
+
+        private InnerNested() {}
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        public void doConstruct(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(TestMethodHandles.class, NOARG_T);
+            TestMethodHandles obj = (TestMethodHandles) mh.invoke();
+            obj = (TestMethodHandles) mh.invokeExact();
+        }
+        public  void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(InnerNested.class, INNER_T);
+            InnerNested obj = (InnerNested) mh.invoke(outer);
+            obj = (InnerNested) mh.invokeExact(outer);
+        }
+        public void doConstruct(StaticNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findConstructor(StaticNested.class, NOARG_T);
+            StaticNested obj = (StaticNested) mh.invoke();
+            obj = (StaticNested) mh.invokeExact();
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        // These initial constructions test nest-top access
+        MethodHandle mh = 
+          lookup().findConstructor(TestMethodHandles.class, NOARG_T);
+        TestMethodHandles o = (TestMethodHandles) mh.invoke();
+        o = (TestMethodHandles) mh.invokeExact();
+
+        mh = lookup().findConstructor(StaticNested.class, NOARG_T);
+        StaticNested s = (StaticNested) mh.invoke();
+        s = (StaticNested) mh.invokeExact();
+
+        mh = lookup().findConstructor(InnerNested.class, INNER_T);
+        InnerNested i = (InnerNested) mh.invoke(o);
+        i = (InnerNested) mh.invokeExact(o);
+
+        StaticIface intf = new StaticIface() {};
+
+        s.doConstruct(o);
+        s.doConstruct(o, i);
+        s.doConstruct(s);
+
+        i.doConstruct(o);
+        i.doConstruct(o, i);
+        i.doConstruct(s);
+
+        intf.doConstruct(o);
+        intf.doConstruct(o, i);
+        intf.doConstruct(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateConstructors/TestReflection.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private constructors between nestmates and nest-top
+ *          using different flavours of named nested types using core reflection
+ * @run main TestReflection
+ */
+
+public class TestReflection {
+
+    // All constructors are private to ensure nestmate access checks apply
+
+    // All doConstruct methods are public so they don't involve invoke_special
+
+    private TestReflection() {}
+
+    // The various nestmates
+
+    // Note: No constructor on interfaces so no StaticIface variants
+
+    static interface StaticIface {
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        default void doConstruct(TestReflection o) throws Throwable {
+          Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]);
+        }
+        default void doConstruct(TestReflection tr, InnerNested o) throws Throwable {
+          Object obj = InnerNested.class.getDeclaredConstructor(new Class<?>[] {TestReflection.class}).newInstance(new Object[] { tr });
+        }
+        default void doConstruct(StaticNested o) throws Throwable {
+          Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]);
+        }
+    }
+
+    static class StaticNested {
+
+        private StaticNested() {}
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        public void doConstruct(TestReflection o) throws Throwable {
+          Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]);
+        }
+        public  void doConstruct(TestReflection tr, InnerNested o) throws Throwable {
+          Object obj = InnerNested.class.getDeclaredConstructor(new Class<?>[] {TestReflection.class}).newInstance(new Object[] { tr });
+        }
+        public void doConstruct(StaticNested o) throws Throwable {
+          Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]);
+        }
+    }
+
+    class InnerNested {
+
+        private InnerNested() {}
+
+        // Methods that will access private constructors of nestmates.
+        // The arg is a dummy for overloading purposes
+
+        public void doConstruct(TestReflection o) throws Throwable {
+          Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]);
+        }
+        public  void doConstruct(TestReflection tr, InnerNested o) throws Throwable {
+          Object obj = InnerNested.class.getDeclaredConstructor(new Class<?>[] {TestReflection.class}).newInstance(new Object[] { tr });
+        }
+        public void doConstruct(StaticNested o) throws Throwable {
+          Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]);
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        // These initial constructions test nest-top access
+        TestReflection o = TestReflection.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]);
+        StaticNested s = StaticNested.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]);
+        InnerNested i = InnerNested.class.getDeclaredConstructor(new Class<?>[] {TestReflection.class}).newInstance(new Object[] { o });
+
+        StaticIface intf = new StaticIface() {};
+
+        s.doConstruct(o);
+        s.doConstruct(o, i);
+        s.doConstruct(s);
+
+        i.doConstruct(o);
+        i.doConstruct(o, i);
+        i.doConstruct(s);
+
+        intf.doConstruct(o);
+        intf.doConstruct(o, i);
+        intf.doConstruct(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateFields/TestMethodHandles.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private fields between nestmates and nest-top
+ *          using different flavours of named nested types using method handles
+ * @compile -XDdisablePrivateAccessors TestMethodHandles.java
+ * @run main TestMethodHandles
+ */
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+
+public class TestMethodHandles {
+
+    // Private field of nest-top for nestmates to access
+    private int priv_field;
+
+    // public constructor so we aren't relying on private access
+    public TestMethodHandles() {}
+
+    // Methods that will access private fields of nestmates
+
+    // NOTE: No StaticIface variants as interfaces can't have instance fields
+
+    void access_priv(TestMethodHandles o) throws Throwable {
+        MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+        this.priv_field = (int) mh.invoke(o);
+        this.priv_field = (int) mh.invokeExact(o);
+        checkBadInvokeG(mh, new StaticNested()); // wrong nestmate
+        checkBadInvokeG(mh, mh); // completely wrong type
+
+        mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+        mh.invoke(o, 2);
+        mh.invokeExact(o, 3);
+        checkBadInvokeS(mh, new StaticNested()); // wrong nestmate
+        checkBadInvokeS(mh, mh); // completely wrong type
+    }
+    void access_priv(InnerNested o) throws Throwable {
+        MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+        this.priv_field = (int) mh.invoke(o);
+        this.priv_field = (int) mh.invokeExact(o);
+        checkBadInvokeG(mh, this); // wrong nestmate
+        checkBadInvokeG(mh, mh); // completely wrong type
+
+        mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+        mh.invoke(o, 2);
+        mh.invokeExact(o, 3);
+        checkBadInvokeS(mh, this); // wrong nestmate
+        checkBadInvokeS(mh, mh); // completely wrong type
+    }
+    void access_priv(StaticNested o) throws Throwable {
+        MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+        this.priv_field = (int) mh.invoke(o);
+        this.priv_field = (int) mh.invokeExact(o);
+        checkBadInvokeG(mh, this); // wrong nestmate
+        checkBadInvokeG(mh, mh); // completely wrong type
+
+        mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+        mh.invoke(o, 2);
+        mh.invokeExact(o, 3);
+        checkBadInvokeS(mh, this); // wrong nestmate
+        checkBadInvokeS(mh, mh); // completely wrong type
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        // Methods that will access private fields of nestmates
+
+        default void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            int priv_field = (int) mh.invoke(o);
+            priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, this); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, this); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+        default void access_priv(InnerNested o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            int priv_field = (int) mh.invoke(o);
+            priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, this); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, this); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+        default void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            int priv_field = (int) mh.invoke(o);
+            priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, this); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, this); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+    }
+
+    static class StaticNested {
+
+        private int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private fields of nestmates
+
+        void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            this.priv_field = (int) mh.invoke(o);
+            this.priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, this); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, this); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+        void access_priv(InnerNested o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            this.priv_field = (int) mh.invoke(o);
+            this.priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, this); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, this); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            this.priv_field = (int) mh.invoke(o);
+            this.priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, new TestMethodHandles()); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, new TestMethodHandles()); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+    }
+
+    class InnerNested {
+
+        private int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            this.priv_field = (int) mh.invoke(o);
+            this.priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, this); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, this); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+        void access_priv(InnerNested o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            this.priv_field = (int) mh.invoke(o);
+            this.priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, new StaticNested()); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, new StaticNested()); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class);
+            this.priv_field = (int) mh.invoke(o);
+            this.priv_field = (int) mh.invokeExact(o);
+            checkBadInvokeG(mh, this); // wrong nestmate
+            checkBadInvokeG(mh, mh); // completely wrong type
+
+            mh = lookup().findSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(o, 2);
+            mh.invokeExact(o, 3);
+            checkBadInvokeS(mh, this); // wrong nestmate
+            checkBadInvokeS(mh, mh); // completely wrong type
+        }
+    }
+
+    static void checkBadInvokeG(MethodHandle mh, Object o) throws Throwable {
+        try {
+            int x = (int) mh.invoke(o);
+            throw new Error("Invoke on MethodHandle " + mh + " with receiver "
+                            + o + "should have failed with ClassCastException!");
+        }
+        catch (ClassCastException expected) {
+            System.out.println("invoke got expected exception: " + expected);
+        }
+    }
+
+    static void checkBadInvokeS(MethodHandle mh, Object o) throws Throwable {
+        try {
+            mh.invoke(o, 42);
+            throw new Error("Invoke on MethodHandle " + mh + " with receiver "
+                            + o + "should have failed with ClassCastException!");
+         }
+         catch (ClassCastException expected) {
+             System.out.println("invoke got expected exception: " + expected);
+         }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        TestMethodHandles o = new TestMethodHandles();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestMethodHandles());
+        o.access_priv(i);
+        o.access_priv(s);
+
+        s.access_priv(o);
+        s.access_priv(i);
+        s.access_priv(new StaticNested());
+
+        i.access_priv(o);
+        i.access_priv(o.new InnerNested());
+        i.access_priv(s);
+
+        intf.access_priv(o);
+        intf.access_priv(i);
+        intf.access_priv(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateFields/TestPrivateField.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private fields between nestmates and nest-top
+ *          using different flavours of named nested types
+ * @compile -XDdisablePrivateAccessors TestPrivateField.java
+ * @run main TestPrivateField
+ */
+
+public class TestPrivateField {
+
+    // Private field of nest-top for nestmates to access
+    private int priv_field;
+
+    // public constructor so we aren't relying on private access
+    public TestPrivateField() {}
+
+    // Methods that will access private fields of nestmates
+
+    // NOTE: No StaticIface variants as interfaces can't have instance fields
+
+    void access_priv(TestPrivateField o) {
+        this.priv_field = o.priv_field++;
+    }
+    void access_priv(InnerNested o) {
+        this.priv_field = o.priv_field++;
+    }
+    void access_priv(StaticNested o) {
+        this.priv_field = o.priv_field++;
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        // Methods that will access private fields of nestmates
+
+        default void access_priv(TestPrivateField o) {
+            int priv_field = o.priv_field++;
+        }
+        default void access_priv(InnerNested o) {
+            int priv_field = o.priv_field++;
+        }
+        default void access_priv(StaticNested o) {
+            int priv_field = o.priv_field++;
+        }
+    }
+
+    static class StaticNested {
+
+        private int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private fields of nestmates
+
+        void access_priv(TestPrivateField o) {
+            this.priv_field = o.priv_field++;
+        }
+        void access_priv(InnerNested o) {
+            this.priv_field = o.priv_field++;
+        }
+        void access_priv(StaticNested o) {
+            this.priv_field = o.priv_field++;
+        }
+    }
+
+    class InnerNested {
+
+        private int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestPrivateField o) {
+            this.priv_field = o.priv_field++;
+        }
+        void access_priv(InnerNested o) {
+            this.priv_field = o.priv_field++;
+        }
+        void access_priv(StaticNested o) {
+            this.priv_field = o.priv_field++;
+        }
+    }
+
+    public static void main(String[] args) {
+        TestPrivateField o = new TestPrivateField();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestPrivateField());
+        o.access_priv(i);
+        o.access_priv(s);
+
+        s.access_priv(o);
+        s.access_priv(i);
+        s.access_priv(new StaticNested());
+
+        i.access_priv(o);
+        i.access_priv(o.new InnerNested());
+        i.access_priv(s);
+
+        intf.access_priv(o);
+        intf.access_priv(i);
+        intf.access_priv(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateFields/TestReflection.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private fields between nestmates and nest-top
+ *          using different flavours of named nested types using core reflection
+ * @compile -XDdisablePrivateAccessors TestReflection.java
+ * @run main TestReflection
+ */
+
+import java.lang.reflect.Field;
+
+public class TestReflection {
+
+    // Private field of nest-top for nestmates to access
+    private int priv_field;
+
+    // public constructor so we aren't relying on private access
+    public TestReflection() {}
+
+    // Methods that will access private fields of nestmates
+
+    // NOTE: No StaticIface variants as interfaces can't have instance fields
+
+    void access_priv(TestReflection o) throws Throwable {
+        Field f = o.getClass().getDeclaredField("priv_field");
+        this.priv_field = f.getInt(o);
+        f.setInt(o, 2);
+    }
+    void access_priv(InnerNested o) throws Throwable {
+        Field f = o.getClass().getDeclaredField("priv_field");
+        this.priv_field = f.getInt(o);
+        f.setInt(o, 2);
+    }
+    void access_priv(StaticNested o) throws Throwable {
+        Field f = o.getClass().getDeclaredField("priv_field");
+        this.priv_field = f.getInt(o);
+        f.setInt(o, 2);
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        // Methods that will access private fields of nestmates
+
+        default void access_priv(TestReflection o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            int priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+        default void access_priv(InnerNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            int priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+        default void access_priv(StaticNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            int priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+    }
+
+    static class StaticNested {
+
+        private int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private fields of nestmates
+
+        void access_priv(TestReflection o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            this.priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+        void access_priv(InnerNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            this.priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            this.priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+    }
+
+    class InnerNested {
+
+        private int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestReflection o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            this.priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+        void access_priv(InnerNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            this.priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            this.priv_field = f.getInt(o);
+            f.setInt(o, 2);
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        TestReflection o = new TestReflection();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestReflection());
+        o.access_priv(i);
+        o.access_priv(s);
+
+        s.access_priv(o);
+        s.access_priv(i);
+        s.access_priv(new StaticNested());
+
+        i.access_priv(o);
+        i.access_priv(o.new InnerNested());
+        i.access_priv(s);
+
+        intf.access_priv(o);
+        intf.access_priv(i);
+        intf.access_priv(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/ExternalSub.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// Generated from the source in TestInvokeSpecialHierarchy.java
+// with priv_invoke access modifier changed to private
+
+class ExternalSub {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #4 #16; // #1    
+    class #17; // #2    
+    String #18; // #3    
+    class #20; // #4    
+    Utf8 "ID"; // #5    
+    Utf8 "Ljava/lang/String;"; // #6    
+    Utf8 "ConstantValue"; // #7    
+    Utf8 "<init>"; // #8    
+    Utf8 "()V"; // #9    
+    Utf8 "Code"; // #10    
+    Utf8 "LineNumberTable"; // #11    
+    Utf8 "priv_invoke"; // #12    
+    Utf8 "()Ljava/lang/String;"; // #13    
+    Utf8 "SourceFile"; // #14    
+    Utf8 "TestInvokeSpecialHierarchy.java"; // #15    
+    NameAndType #8 #9; // #16    
+    Utf8 "ExternalSub"; // #17    
+    Utf8 "ExternalSub::priv_invoke"; // #18    
+    class #23; // #19    
+    Utf8 "TestInvokeSpecialHierarchy$NestedC"; // #20    
+    Utf8 "NestedC"; // #21    
+    Utf8 "InnerClasses"; // #22    
+    Utf8 "TestInvokeSpecialHierarchy"; // #23    
+  } // Constant Pool
+
+  0x0020; // access
+  #2;// this_cpx
+  #4;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+    { // Member
+      0x0018; // access
+      #5; // name_cpx
+      #6; // sig_cpx
+      [] { // Attributes
+        Attr(#7) { // ConstantValue
+          #3;
+        } // end ConstantValue
+      } // Attributes
+    } // Member
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #8; // name_cpx
+      #9; // sig_cpx
+      [] { // Attributes
+        Attr(#10) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#11) { // LineNumberTable
+              [] { // LineNumberTable
+                0  129;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member
+      0x0002; // access - private
+      #12; // name_cpx
+      #13; // sig_cpx
+      [] { // Attributes
+        Attr(#10) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x1203B0;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#11) { // LineNumberTable
+              [] { // LineNumberTable
+                0  132;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#14) { // SourceFile
+      #15;
+    } // end SourceFile
+    ;
+    Attr(#22) { // InnerClasses
+      [] { // InnerClasses
+        #4 #19 #21 8;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class ExternalSub
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/ExternalSuper.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// Generated from the source in TestInvokeSpecialHierarchy.java
+// with priv_invoke access modifier changed to private
+
+class ExternalSuper {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #4 #16; // #1    
+    class #17; // #2    
+    String #18; // #3    
+    class #19; // #4    
+    Utf8 "ID"; // #5    
+    Utf8 "Ljava/lang/String;"; // #6    
+    Utf8 "ConstantValue"; // #7    
+    Utf8 "<init>"; // #8    
+    Utf8 "()V"; // #9    
+    Utf8 "Code"; // #10    
+    Utf8 "LineNumberTable"; // #11    
+    Utf8 "priv_invoke_s"; // #12    
+    Utf8 "()Ljava/lang/String;"; // #13    
+    Utf8 "SourceFile"; // #14    
+    Utf8 "TestInvokeSpecialHierarchy.java"; // #15    
+    NameAndType #8 #9; // #16    
+    Utf8 "ExternalSuper"; // #17    
+    Utf8 "ExternalSuper::priv_invoke_s"; // #18    
+    Utf8 "java/lang/Object"; // #19    
+  } // Constant Pool
+
+  0x0020; // access
+  #2;// this_cpx
+  #4;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+    { // Member
+      0x0018; // access
+      #5; // name_cpx
+      #6; // sig_cpx
+      [] { // Attributes
+        Attr(#7) { // ConstantValue
+          #3;
+        } // end ConstantValue
+      } // Attributes
+    } // Member
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #8; // name_cpx
+      #9; // sig_cpx
+      [] { // Attributes
+        Attr(#10) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#11) { // LineNumberTable
+              [] { // LineNumberTable
+                0  119;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member
+      0x0002; // access - private
+      #12; // name_cpx
+      #13; // sig_cpx
+      [] { // Attributes
+        Attr(#10) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x1203B0;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#11) { // LineNumberTable
+              [] { // LineNumberTable
+                0  124;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#14) { // SourceFile
+      #15;
+    } // end SourceFile
+  } // Attributes
+} // end class ExternalSuper
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/MissingMethod.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// Generated from the source in TestInvokeSpecialErrors.java
+// with priv_invoke renamed to not_priv_invoke so it isn't found
+
+class TestInvokeSpecialErrors$MissingMethod {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #6 #16; // #1    
+    Field #17 #18; // #2    
+    String #19; // #3    
+    Method #20 #21; // #4    
+    class #22; // #5    
+    class #25; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "not_priv_invoke"; // #11 - renamed    
+    Utf8 "SourceFile"; // #12    
+    Utf8 "TestInvokeSpecialErrors.java"; // #13    
+    Utf8 "MemberOfNest"; // #14    
+    class #26; // #15    
+    NameAndType #7 #8; // #16    
+    class #27; // #17    
+    NameAndType #28 #29; // #18    
+    Utf8 "MissingMethod::priv_invoke"; // #19    
+    class #30; // #20    
+    NameAndType #31 #32; // #21    
+    Utf8 "TestInvokeSpecialErrors$MissingMethod"; // #22    
+    Utf8 "MissingMethod"; // #23    
+    Utf8 "InnerClasses"; // #24    
+    Utf8 "java/lang/Object"; // #25    
+    Utf8 "TestInvokeSpecialErrors"; // #26    
+    Utf8 "java/lang/System"; // #27    
+    Utf8 "out"; // #28    
+    Utf8 "Ljava/io/PrintStream;"; // #29    
+    Utf8 "java/io/PrintStream"; // #30    
+    Utf8 "println"; // #31    
+    Utf8 "(Ljava/lang/String;)V"; // #32    
+  } // Constant Pool
+
+  0x0020; // access
+  #5;// this_cpx
+  #6;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  35;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member
+      0x0002; // access
+      #11; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          2; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0xB200021203B60004;
+            0xB1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  38;
+                8  39;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#12) { // SourceFile
+      #13;
+    } // end SourceFile
+    ;
+    Attr(#14) { // MemberOfNest
+      0x000F;
+    } // end MemberOfNest
+    ;
+    Attr(#24) { // InnerClasses
+      [] { // InnerClasses
+        #5 #15 #23 8;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class TestInvokeSpecialErrors$MissingMethod
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/MissingMethodWithSuper.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// Generated from the source in TestInvokeSpecialErrors.java
+// with priv_invoke renamed to not_priv_invoke so it isn't found
+
+class TestInvokeSpecialErrors$MissingMethodWithSuper {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #6 #16; // #1    
+    Field #17 #18; // #2    
+    String #19; // #3    
+    Method #20 #21; // #4    
+    class #22; // #5    
+    class #25; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "not_priv_invoke"; // #11 - rename    
+    Utf8 "SourceFile"; // #12    
+    Utf8 "TestInvokeSpecialErrors.java"; // #13    
+    Utf8 "MemberOfNest"; // #14    
+    class #27; // #15    
+    NameAndType #7 #8; // #16    
+    class #28; // #17    
+    NameAndType #29 #30; // #18    
+    Utf8 "MissingMethodWithSuper::priv_invoke"; // #19    
+    class #31; // #20    
+    NameAndType #32 #33; // #21    
+    Utf8 "TestInvokeSpecialErrors$MissingMethodWithSuper"; // #22    
+    Utf8 "MissingMethodWithSuper"; // #23    
+    Utf8 "InnerClasses"; // #24    
+    Utf8 "TestInvokeSpecialErrors$Nested"; // #25    
+    Utf8 "Nested"; // #26    
+    Utf8 "TestInvokeSpecialErrors"; // #27    
+    Utf8 "java/lang/System"; // #28    
+    Utf8 "out"; // #29    
+    Utf8 "Ljava/io/PrintStream;"; // #30    
+    Utf8 "java/io/PrintStream"; // #31    
+    Utf8 "println"; // #32    
+    Utf8 "(Ljava/lang/String;)V"; // #33    
+  } // Constant Pool
+
+  0x0020; // access
+  #5;// this_cpx
+  #6;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  49;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member
+      0x0002; // access
+      #11; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          2; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0xB200021203B60004;
+            0xB1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  52;
+                8  53;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#12) { // SourceFile
+      #13;
+    } // end SourceFile
+    ;
+    Attr(#14) { // MemberOfNest
+      0x000F;
+    } // end MemberOfNest
+    ;
+    Attr(#24) { // InnerClasses
+      [] { // InnerClasses
+        #5 #15 #23 8;
+        #6 #15 #26 8;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class TestInvokeSpecialErrors$MissingMethodWithSuper
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/MissingNestTop.jcod	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// Generated from the source in TestInvokeSpecialErrors.java
+// with MemberOfNest referring to non-existent class: NoSuchClass
+
+class TestInvokeSpecialErrors$MissingNestTop {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [] { // Constant Pool
+    ; // first element is empty
+    Method #6 #16; // #1    
+    Field #17 #18; // #2    
+    String #19; // #3    
+    Method #20 #21; // #4    
+    class #22; // #5    
+    class #25; // #6    
+    Utf8 "<init>"; // #7    
+    Utf8 "()V"; // #8    
+    Utf8 "Code"; // #9    
+    Utf8 "LineNumberTable"; // #10    
+    Utf8 "priv_invoke"; // #11    
+    Utf8 "SourceFile"; // #12    
+    Utf8 "TestInvokeSpecialErrors.java"; // #13    
+    Utf8 "MemberOfNest"; // #14    
+    class #26; // #15    
+    NameAndType #7 #8; // #16    
+    class #27; // #17    
+    NameAndType #28 #29; // #18    
+    Utf8 "MissingNestTop::priv_invoke"; // #19    
+    class #30; // #20    
+    NameAndType #31 #32; // #21    
+    Utf8 "TestInvokeSpecialErrors$MissingNestTop"; // #22    
+    Utf8 "MissingNestTop"; // #23    
+    Utf8 "InnerClasses"; // #24    
+    Utf8 "java/lang/Object"; // #25    
+    Utf8 "TestInvokeSpecialErrors"; // #26    
+    Utf8 "java/lang/System"; // #27    
+    Utf8 "out"; // #28    
+    Utf8 "Ljava/io/PrintStream;"; // #29    
+    Utf8 "java/io/PrintStream"; // #30    
+    Utf8 "println"; // #31    
+    Utf8 "(Ljava/lang/String;)V"; // #32    
+    Utf8 "NoSuchClass"; // #33 - added    
+    class #33; // #34 - added
+  } // Constant Pool
+
+  0x0020; // access
+  #5;// this_cpx
+  #6;// super_cpx
+
+  [] { // Interfaces
+  } // Interfaces
+
+  [] { // fields
+  } // fields
+
+  [] { // methods
+    { // Member
+      0x0000; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          1; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0x2AB70001B1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  57;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member
+      0x0002; // access
+      #11; // name_cpx
+      #8; // sig_cpx
+      [] { // Attributes
+        Attr(#9) { // Code
+          2; // max_stack
+          1; // max_locals
+          Bytes[]{
+            0xB200021203B60004;
+            0xB1;
+          };
+          [] { // Traps
+          } // end Traps
+          [] { // Attributes
+            Attr(#10) { // LineNumberTable
+              [] { // LineNumberTable
+                0  60;
+                8  61;
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [] { // Attributes
+    Attr(#12) { // SourceFile
+      #13;
+    } // end SourceFile
+    ;
+    Attr(#14) { // MemberOfNest
+      0x0022; // Modified: class #34 -> NoSuchClass
+    } // end MemberOfNest
+    ;
+    Attr(#24) { // InnerClasses
+      [] { // InnerClasses
+        #5 #15 #23 8;
+      }
+    } // end InnerClasses
+  } // Attributes
+} // end class TestInvokeSpecialErrors$MissingNestTop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/TestInvokeSpecial.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private methods between nestmates and nest-top
+ *          using different flavours of named nested types that will
+ *          generate invokespecial for the calls
+ * @compile -XDdisablePrivateAccessors TestInvokeSpecial.java
+ * @run main TestInvokeSpecial
+ */
+
+public class TestInvokeSpecial {
+
+    // Private method of nest-top for nestmates to access
+    private void priv_invoke() {
+        System.out.println("TestInvokeSpecial::priv_invoke");
+    }
+
+    // public constructor so we aren't relying on private access
+    public TestInvokeSpecial() {}
+
+    // Methods that will access private methods of nestmates
+
+    void access_priv(TestInvokeSpecial o) {
+        o.priv_invoke();
+    }
+    void access_priv(InnerNested o) {
+        o.priv_invoke();
+    }
+    void access_priv(StaticNested o) {
+        o.priv_invoke();
+    }
+    void access_priv(StaticIface o) {
+        o.priv_invoke();
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        private void priv_invoke() {
+            System.out.println("StaticIface::priv_invoke");
+        }
+
+        // Methods that will access private methods of nestmates
+
+        default void access_priv(TestInvokeSpecial o) {
+            o.priv_invoke();
+        }
+        default void access_priv(InnerNested o) {
+            o.priv_invoke();
+        }
+        default void access_priv(StaticNested o) {
+            o.priv_invoke();
+        }
+        default void access_priv(StaticIface o) {
+            o.priv_invoke();
+        }
+    }
+
+    static class StaticNested {
+
+        private void priv_invoke() {
+            System.out.println("StaticNested::priv_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private methods of nestmates
+
+        void access_priv(TestInvokeSpecial o) {
+            o.priv_invoke();
+        }
+        void access_priv(InnerNested o) {
+            o.priv_invoke();
+        }
+        void access_priv(StaticNested o) {
+            o.priv_invoke();
+        }
+        void access_priv(StaticIface o) {
+            o.priv_invoke();
+        }
+    }
+
+    class InnerNested {
+
+        private void priv_invoke() {
+            System.out.println("InnerNested::priv_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestInvokeSpecial o) {
+            o.priv_invoke();
+        }
+        void access_priv(InnerNested o) {
+            o.priv_invoke();
+        }
+        void access_priv(StaticNested o) {
+            o.priv_invoke();
+        }
+        void access_priv(StaticIface o) {
+            o.priv_invoke();
+        }
+    }
+
+    public static void main(String[] args) {
+        TestInvokeSpecial o = new TestInvokeSpecial();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestInvokeSpecial());
+        o.access_priv(i);
+        o.access_priv(s);
+        o.access_priv(intf);
+
+        s.access_priv(o);
+        s.access_priv(i);
+        s.access_priv(new StaticNested());
+        s.access_priv(intf);
+
+        i.access_priv(o);
+        i.access_priv(o.new InnerNested());
+        i.access_priv(s);
+        i.access_priv(intf);
+
+        intf.access_priv(o);
+        intf.access_priv(i);
+        intf.access_priv(s);
+        intf.access_priv(new StaticIface(){});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/TestInvokeSpecialErrors.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Setup invokespecial-based nestmate call to private methods
+ *          then use modified jcod classes to introduce errors. Test with
+ *          and without verification enabled 
+ * @compile -XDdisablePrivateAccessors TestInvokeSpecialErrors.java
+ * @compile MissingMethod.jcod
+ *          MissingMethodWithSuper.jcod
+ *          MissingNestTop.jcod
+ * @run main TestInvokeSpecialErrors true
+ * @run main/othervm -Xverify:none TestInvokeSpecialErrors false
+ */
+
+public class TestInvokeSpecialErrors {
+
+    static class Nested {
+        private void priv_invoke() {
+            System.out.println("Nested::priv_invoke");
+        }
+    }
+
+    static class MissingMethod {
+        // jcod version will rename this method to not_priv_invoke
+        private void priv_invoke() {
+            System.out.println("MissingMethod::priv_invoke");
+        }
+    }
+
+    static class MissingMethodWithSuper extends Nested {
+        // jcod version will rename this method to not_priv_invoke
+        private void priv_invoke() {
+            System.out.println("MissingMethodWithSuper::priv_invoke");
+        }
+    }
+
+    static class MissingNestTop {
+        // jcod version will change MemberOfNest to a non-existent class
+        private void priv_invoke() {
+            System.out.println("MissingNestTop::priv_invoke");
+        }
+    }
+    static class Helper {
+        // If these tests are directly in main() they trigger failures
+        // loading the main class much earlier than runtime.
+        static void doTest(boolean verifying) {
+            if (verifying)
+                throw new Error("Unexpected load of Helper class with verification enabled");
+            try {
+                MissingNestTop m = new MissingNestTop();
+                m.priv_invoke();
+                throw new Error("Unexpected success invoking MissingNestTop.priv_invoke");
+            }
+            catch (NoClassDefFoundError ncdfe) {
+                System.out.println("Got expected exception:" + ncdfe);
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        // some errors change depending on whether they are caught by the
+        // verifier first
+        boolean verifying = Boolean.parseBoolean(args[0]);
+        System.out.println("Verification is " + 
+                           (verifying ? "enabled" : "disabled"));
+
+        try {
+            MissingMethod m = new MissingMethod();
+            m.priv_invoke();
+            throw new Error("Unexpected success invoking MissingMethod.priv_invoke");
+        }
+        catch (NoSuchMethodError nsme) {
+            System.out.println("Got expected exception:" + nsme);
+        }
+
+        try {
+            MissingMethodWithSuper m = new MissingMethodWithSuper();
+            m.priv_invoke();
+            throw new Error("Unexpected success invoking MissingMethodWithSuper.priv_invoke");
+        }
+        catch (NoSuchMethodError nsme) {
+            System.out.println("Got expected exception:" + nsme);
+        }
+
+        // with verification enabled we can't even reference Helper
+        try {
+            Helper.doTest(verifying);
+        } 
+        catch (NoClassDefFoundError ncdfe) {
+            if (verifying)
+                System.out.println("Got expected exception:" + ncdfe);
+            else
+                throw new Error("Unexpected error loading Helper class with verification disabled");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/TestInvokeSpecialHierarchy.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private methods between nestmates where there
+ *          is an inheritance hierarchy and we use invokespecial to invoke
+ *          private methods that exist in specific classes in the hierarchy.
+ * @compile -XDdisablePrivateAccessors TestInvokeSpecialHierarchy.java
+ * @compile ExternalSuper.jcod ExternalSub.jcod
+ * @run main TestInvokeSpecialHierarchy
+ */
+
+public class TestInvokeSpecialHierarchy {
+
+    static class NestedA extends ExternalSuper {
+        static final String ID =  "NestedA::priv_invoke";
+        private String priv_invoke() {
+            return ID;
+        }
+        static void checkA(NestedA a) throws Throwable {
+            verifyEquals(a.priv_invoke(), NestedA.ID);
+        }
+    }
+
+    static class NestedB extends NestedA {
+        static final String ID =  "NestedB::priv_invoke";
+        private String priv_invoke() {
+            return ID;
+        }
+        static void checkA(NestedA a) throws Throwable {
+            verifyEquals(a.priv_invoke(), NestedA.ID);
+        }
+    }
+
+    static class NestedC extends NestedB {
+        static final String ID =  "NestedC::priv_invoke";
+        private String priv_invoke() {
+            return ID;
+        }
+        static void checkA(NestedA a) throws Throwable {
+            verifyEquals(a.priv_invoke(), NestedA.ID);
+        }
+    }
+
+    static void checkA(NestedA a) throws Throwable {
+        verifyEquals(a.priv_invoke(), NestedA.ID);
+    }
+
+    static void checkB(NestedB b) throws Throwable {
+        verifyEquals(b.priv_invoke(), NestedB.ID);
+    }
+
+    static void checkC(NestedC c) throws Throwable {
+        verifyEquals(c.priv_invoke(), NestedC.ID);
+    }
+
+
+    // Access to private members of classes outside the nest is
+    // not permitted. These tests should throw IllegalAccessError
+    // at runtime. To allow them to compile the classes below are
+    // defined with public members. We then replace those class files
+    // with jcod variants that make the member private again.
+
+    static void checkExternalSuper(ExternalSuper s) throws Throwable {
+        try {
+            String str = s.priv_invoke_s();
+            throw new Error("Unexpected access to ExternalSuper.priv_invoke_s");
+        }
+        catch (IllegalAccessError iae) {
+            System.out.println("Got expected exception accessing ExternalSuper.priv_invoke_s:" + iae);
+        }
+    }
+
+    static void checkExternalSub(ExternalSub s) throws Throwable {
+        try {
+            String str = s.priv_invoke();
+            throw new Error("Unexpected access to ExternalSub.priv_invoke");
+        }
+        catch (IllegalAccessError iae) {
+            System.out.println("Got expected exception accessing ExternalSub.priv_invoke:" + iae);
+        }
+    }
+
+    static void verifyEquals(String actual, String expected) {
+        if (!actual.equals(expected)) {
+            throw new Error("Expected " + expected + " but got " + actual);
+        }
+        System.out.println("Check passed for " + expected);
+    }
+
+    public static void main(String[] args) throws Throwable {
+        NestedA a = new NestedA();
+        NestedB b = new NestedB();
+        NestedC c = new NestedC();
+        ExternalSub sub = new ExternalSub();
+        ExternalSuper sup = new ExternalSuper();
+
+        checkExternalSuper(sup);
+        checkExternalSuper(a);
+        checkExternalSuper(b);
+        checkExternalSuper(c);
+        checkExternalSuper(sub);
+
+        checkA(a);
+        checkA(b);
+        checkA(c);
+        checkA(sub);
+
+        NestedA.checkA(a);
+        NestedA.checkA(b);
+        NestedA.checkA(c);
+        NestedA.checkA(sub);
+
+        NestedB.checkA(a);
+        NestedB.checkA(b);
+        NestedB.checkA(c);
+        NestedB.checkA(sub);
+
+        NestedC.checkA(a);
+        NestedC.checkA(b);
+        NestedC.checkA(c);
+        NestedC.checkA(sub);
+
+        checkB(b);
+        checkB(c);
+        checkB(sub);
+
+        checkC(c);
+        checkC(sub);
+
+        checkExternalSub(sub);
+    }
+}
+
+// Classes that are not part of the nest
+// Being non-public allows us to declare them in this file.
+// The priv_invoke* member is public to allow this file to compile, but
+// the jcod files change it back to private.
+
+class ExternalSuper {
+    static final String ID =  "ExternalSuper::priv_invoke_s";
+    // Can't call this priv_invoke as subclasses make it less accessible
+    // which is not allowed.
+    public String priv_invoke_s() {
+        return ID;
+    }
+}
+
+
+class ExternalSub extends TestInvokeSpecialHierarchy.NestedC {
+    static final String ID =  "ExternalSub::priv_invoke";
+    public String priv_invoke() {
+        return ID;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/TestMethodHandles.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private methods between nestmates and nest-top
+ *          using different flavours of named nested types using MethodHandles
+ * @compile -XDdisablePrivateAccessors TestMethodHandles.java
+ * @run main TestMethodHandles
+ */
+
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class TestMethodHandles {
+
+    static final MethodType M_T = MethodType.methodType(void.class);
+
+    // Private method of nest-top for nestmates to access
+    private void priv_invoke() {
+        System.out.println("TestMethodHandles::priv_invoke");
+    }
+
+    // public constructor so we aren't relying on private access
+    public TestMethodHandles() {}
+
+    // Methods that will access private methods of nestmates
+
+    void access_priv(TestMethodHandles o) throws Throwable {
+        MethodHandle mh = 
+          lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+        mh.invoke(o);
+        mh.invokeExact(o);
+        checkBadInvoke(mh, new StaticNested()); // wrong nestmate
+        checkBadInvoke(mh, mh); // completely wrong type
+    }
+    void access_priv(InnerNested o) throws Throwable {
+        MethodHandle mh = 
+          lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+        mh.invoke(o);
+        mh.invokeExact(o);
+        checkBadInvoke(mh, this); // wrong nestmate
+        checkBadInvoke(mh, mh); // completely wrong type
+    }
+    void access_priv(StaticNested o) throws Throwable {
+        MethodHandle mh = 
+          lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+        mh.invoke(o);
+        mh.invokeExact(o);
+        checkBadInvoke(mh, this); // wrong nestmate
+        checkBadInvoke(mh, mh); // completely wrong type
+    }
+    void access_priv(StaticIface o) throws Throwable {
+        MethodHandle mh = 
+          lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass());
+        mh.invoke(o);
+        mh.invokeExact(o);
+        checkBadInvoke(mh, this); // wrong nestmate
+        checkBadInvoke(mh, mh); // completely wrong type
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        private void priv_invoke() {
+            System.out.println("StaticIface::priv_invoke");
+        }
+
+        // Methods that will access private methods of nestmates
+
+        default void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class);
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        default void access_priv(InnerNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class);
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        default void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class);
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        default void access_priv(StaticIface o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, StaticIface.class);
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, new StaticNested()); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+    }
+
+    static class StaticNested {
+
+        private void priv_invoke() {
+            System.out.println("StaticNested::priv_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private methods of nestmates
+
+        void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        void access_priv(InnerNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, new TestMethodHandles()); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        void access_priv(StaticIface o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass());
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+    }
+
+    class InnerNested {
+
+        private void priv_invoke() {
+            System.out.println("InnerNested::priv_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        void access_priv(InnerNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, new StaticNested()); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass());
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+        void access_priv(StaticIface o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass());
+            mh.invoke(o);
+            mh.invokeExact(o);
+            checkBadInvoke(mh, this); // wrong nestmate
+            checkBadInvoke(mh, mh); // completely wrong type
+        }
+    }
+
+    static void checkBadInvoke(MethodHandle mh, Object o) throws Throwable {
+        try {
+            mh.invoke(o);
+            throw new Error("Invoke on MethodHandle " + mh + " with receiver "
+                            + o + "should have failed with ClassCastException!");
+         }
+         catch (ClassCastException expected) {
+             System.out.println("invoke got expected exception: " + expected);
+         }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        TestMethodHandles o = new TestMethodHandles();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestMethodHandles());
+        o.access_priv(i);
+        o.access_priv(s);
+        o.access_priv(intf);
+
+        s.access_priv(o);
+        s.access_priv(i);
+        s.access_priv(new StaticNested());
+        s.access_priv(intf);
+
+        i.access_priv(o);
+        i.access_priv(o.new InnerNested());
+        i.access_priv(s);
+        i.access_priv(intf);
+
+        intf.access_priv(o);
+        intf.access_priv(i);
+        intf.access_priv(s);
+        intf.access_priv(new StaticIface(){});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateMethods/TestReflection.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private methods between nestmates and nest-top
+ *          using different flavours of named nested types using core reflection
+ * @compile -XDdisablePrivateAccessors TestReflection.java
+ * @run main TestReflection
+ */
+
+public class TestReflection {
+
+    // Private method of nest-top for nestmates to access
+    private void priv_invoke() {
+        System.out.println("TestReflection::priv_invoke");
+    }
+
+    // public constructor so we aren't relying on private access
+    public TestReflection() {}
+
+    // Methods that will access private methods of nestmates
+
+    void access_priv(TestReflection o) throws Throwable {
+        o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+    }
+    void access_priv(InnerNested o) throws Throwable {
+        o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+    }
+    void access_priv(StaticNested o) throws Throwable {
+        o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+    }
+    void access_priv(StaticIface o) throws Throwable {
+        StaticIface.class.getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        private void priv_invoke() {
+            System.out.println("StaticIface::priv_invoke");
+        }
+
+        // Methods that will access private methods of nestmates
+
+        default void access_priv(TestReflection o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        default void access_priv(InnerNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        default void access_priv(StaticNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        default void access_priv(StaticIface o) throws Throwable {
+            StaticIface.class.getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+    }
+
+    static class StaticNested {
+
+        private void priv_invoke() {
+            System.out.println("StaticNested::priv_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private methods of nestmates
+
+        void access_priv(TestReflection o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        void access_priv(InnerNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        void access_priv(StaticIface o) throws Throwable {
+            StaticIface.class.getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+    }
+
+    class InnerNested {
+
+        private void priv_invoke() {
+            System.out.println("InnerNested::priv_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestReflection o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        void access_priv(InnerNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+        void access_priv(StaticIface o) throws Throwable {
+            StaticIface.class.getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]);
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        TestReflection o = new TestReflection();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestReflection());
+        o.access_priv(i);
+        o.access_priv(s);
+        o.access_priv(intf);
+
+        s.access_priv(o);
+        s.access_priv(i);
+        s.access_priv(new StaticNested());
+        s.access_priv(intf);
+
+        i.access_priv(o);
+        i.access_priv(o.new InnerNested());
+        i.access_priv(s);
+        i.access_priv(intf);
+
+        intf.access_priv(o);
+        intf.access_priv(i);
+        intf.access_priv(s);
+        intf.access_priv(new StaticIface(){});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateStaticFields/TestMethodHandles.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private static fields between nestmates and nest-top
+ *          using different flavours of named nested types using core reflection
+ * @compile -XDdisablePrivateAccessors TestMethodHandles.java
+ * @run main TestMethodHandles
+ */
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+
+import java.lang.reflect.Field;
+
+public class TestMethodHandles {
+
+    // private static field of nest-top for nestmates to access
+    private static int priv_field;
+
+    // public constructor so we aren't relying on private access
+    public TestMethodHandles() {}
+
+    // Methods that will access private static fields of nestmates
+
+    // NOTE: No InnerNested calls in this test because non-static nested types
+    // can't have static fields. Also no StaticIface calls as static interface
+    // fields must be public (and final)
+
+    void access_priv(TestMethodHandles o) throws Throwable {
+        MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class);
+        priv_field = (int) mh.invoke();
+        priv_field = (int) mh.invokeExact();
+        mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class);
+        mh.invoke(2);
+        mh.invokeExact(3);
+    }
+    void access_priv(StaticNested o) throws Throwable {
+        MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class);
+        priv_field = (int) mh.invoke();
+        priv_field = (int) mh.invokeExact();
+        mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class);
+        mh.invoke(2);
+        mh.invokeExact(3);
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        // Methods that will access private static fields of nestmates
+
+        default void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class);
+            int priv_field = (int) mh.invoke();
+            priv_field = (int) mh.invokeExact();
+            mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(2);
+            mh.invokeExact(3);
+        }
+        default void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class);
+            int priv_field = (int) mh.invoke();
+            priv_field = (int) mh.invokeExact();
+			mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(2);
+            mh.invokeExact(3);
+        }
+    }
+
+    static class StaticNested {
+
+        private static int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private static fields of nestmates
+
+        void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class);
+            priv_field = (int) mh.invoke();
+            priv_field = (int) mh.invokeExact();
+            mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(2);
+            mh.invokeExact(3);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class);
+            priv_field = (int) mh.invoke();
+            priv_field = (int) mh.invokeExact();
+            mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(2);
+            mh.invokeExact(3);
+        }
+    }
+
+    class InnerNested {
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class);
+            priv_field = (int) mh.invoke();
+            priv_field = (int) mh.invokeExact();
+            mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(2);
+            mh.invokeExact(3);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class);
+            priv_field = (int) mh.invoke();
+            priv_field = (int) mh.invokeExact();
+            mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class);
+            mh.invoke(2);
+            mh.invokeExact(3);
+        }
+    }
+
+	public static void main(String[] args) throws Throwable {
+        TestMethodHandles o = new TestMethodHandles();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestMethodHandles());
+        o.access_priv(s);
+
+        s.access_priv(o);
+        s.access_priv(new StaticNested());
+
+        i.access_priv(o);
+        i.access_priv(s);
+
+        intf.access_priv(o);
+        intf.access_priv(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateStaticFields/TestPrivateStaticField.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private static fields between nestmates and nest-top
+ *          using different flavours of named nested types
+ * @compile -XDdisablePrivateAccessors TestPrivateStaticField.java
+ * @run main TestPrivateStaticField
+ */
+
+public class TestPrivateStaticField {
+
+    // Private static field of nest-top for nestmates to access
+    private static int priv_field;
+
+    // public constructor so we aren't relying on private access
+    public TestPrivateStaticField() {}
+
+    // Methods that will access private static fields of nestmates
+    // We use the arguments for overloading purposes and use the fact
+    // you can access a static field through an object reference for
+    // convenience. 
+
+    // NOTE: No InnerNested calls in this test because non-static nested types
+    // can't have static fields. Also no StaticIface calls as static interface
+    // fields must be public (and final)
+
+    void access_priv(TestPrivateStaticField o) {
+        priv_field = o.priv_field++;
+    }
+    void access_priv(StaticNested o) {
+        priv_field = o.priv_field++;
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        // Methods that will access private static fields of nestmates
+
+        default void access_priv(TestPrivateStaticField o) {
+            int priv_field = o.priv_field++;
+        }
+        default void access_priv(StaticNested o) {
+            int priv_field = o.priv_field++;
+        }
+    }
+
+    static class StaticNested {
+
+        private static int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private static fields of nestmates
+
+        void access_priv(TestPrivateStaticField o) {
+            priv_field = o.priv_field++;
+        }
+        void access_priv(StaticNested o) {
+            priv_field = o.priv_field++;
+        }
+    }
+
+    class InnerNested {
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestPrivateStaticField o) {
+            int priv_field = o.priv_field++;
+        }
+        void access_priv(StaticNested o) {
+            int priv_field = o.priv_field++;
+        }
+    }
+
+    public static void main(String[] args) {
+        TestPrivateStaticField o = new TestPrivateStaticField();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestPrivateStaticField());
+        o.access_priv(s);
+
+        s.access_priv(o);
+        s.access_priv(new StaticNested());
+
+        i.access_priv(o);
+        i.access_priv(s);
+
+        intf.access_priv(o);
+        intf.access_priv(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateStaticFields/TestReflection.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private static fields between nestmates and nest-top
+ *          using different flavours of named nested types using core reflection
+ * @compile -XDdisablePrivateAccessors TestReflection.java
+ * @run main TestReflection
+ */
+
+import java.lang.reflect.Field;
+
+public class TestReflection {
+
+    // private static field of nest-top for nestmates to access
+    private static int priv_field;
+
+    // public constructor so we aren't relying on private access
+    public TestReflection() {}
+
+    // Methods that will access private static fields of nestmates
+
+    // NOTE: No InnerNested calls in this test because non-static nested types
+    // can't have static fields. Also no StaticIface calls as static interface
+    // fields must be public (and final)
+
+    void access_priv(TestReflection o) throws Throwable {
+        Field f = o.getClass().getDeclaredField("priv_field");
+        priv_field = f.getInt(null);
+        f.setInt(null, 2);
+    }
+    void access_priv(StaticNested o) throws Throwable {
+        Field f = o.getClass().getDeclaredField("priv_field");
+        priv_field = f.getInt(null);
+        f.setInt(null, 2);
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        // Methods that will access private static fields of nestmates
+
+        default void access_priv(TestReflection o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            int priv_field = f.getInt(null);
+            f.setInt(null, 2);
+        }
+        default void access_priv(StaticNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            int priv_field = f.getInt(null);
+            f.setInt(null, 2);
+        }
+    }
+
+    static class StaticNested {
+
+        private static int priv_field;
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private static fields of nestmates
+
+        void access_priv(TestReflection o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            priv_field = f.getInt(null);
+            f.setInt(null, 2);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            priv_field = f.getInt(null);
+            f.setInt(null, 2);
+        }
+    }
+
+    class InnerNested {
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestReflection o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            priv_field = f.getInt(null);
+            f.setInt(null, 2);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            Field f = o.getClass().getDeclaredField("priv_field");
+            priv_field = f.getInt(null);
+            f.setInt(null, 2);
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        TestReflection o = new TestReflection();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestReflection());
+        o.access_priv(s);
+
+        s.access_priv(o);
+        s.access_priv(new StaticNested());
+
+        i.access_priv(o);
+        i.access_priv(s);
+
+        intf.access_priv(o);
+        intf.access_priv(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateStaticMethods/TestInvokeStatic.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private static methods between nestmates and nest-top
+ *          using different flavours of named nested types
+ * @compile -XDdisablePrivateAccessors TestInvokeStatic.java
+ * @run main TestInvokeStatic
+ */
+
+public class TestInvokeStatic {
+
+    // Private static method of nest-top for nestmates to access
+    private static void priv_static_invoke() {
+        System.out.println("TestInvokeStatic::priv_static_invoke");
+    }
+
+    // public constructor so we aren't relying on private access
+    public TestInvokeStatic() {}
+
+    // Methods that will access private static methods of nestmates
+    // We use the arguments for overloading purposes and use the fact
+    // you can invoke a static method through an object reference for
+    // convenience. Except for static interface methods of course.
+
+    // NOTE: No InnerNested calls in this test because non-static nested types
+    // can't have static method
+
+    void access_priv(TestInvokeStatic o) {
+        o.priv_static_invoke();
+    }
+    void access_priv(StaticNested o) {
+        o.priv_static_invoke();
+    }
+    void access_priv(StaticIface o) {
+        StaticIface.priv_static_invoke();
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        private static void priv_static_invoke() {
+            System.out.println("StaticIface::priv_static_invoke");
+        }
+
+        // Methods that will access private static methods of nestmates
+
+        default void access_priv(TestInvokeStatic o) {
+            o.priv_static_invoke();
+        }
+        default void access_priv(StaticNested o) {
+            o.priv_static_invoke();
+        }
+        default void access_priv(StaticIface o) {
+            StaticIface.priv_static_invoke();
+        }
+    }
+
+    static class StaticNested {
+
+        private static void priv_static_invoke() {
+            System.out.println("StaticNested::priv_static_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private static methods of nestmates
+
+        void access_priv(TestInvokeStatic o) {
+            o.priv_static_invoke();
+        }
+        void access_priv(StaticNested o) {
+            o.priv_static_invoke();
+        }
+        void access_priv(StaticIface o) {
+            StaticIface.priv_static_invoke();
+        }
+    }
+
+    class InnerNested {
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestInvokeStatic o) {
+            o.priv_static_invoke();
+        }
+        void access_priv(StaticNested o) {
+            o.priv_static_invoke();
+        }
+        void access_priv(StaticIface o) {
+            StaticIface.priv_static_invoke();
+        }
+    }
+
+    public static void main(String[] args) {
+        TestInvokeStatic o = new TestInvokeStatic();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestInvokeStatic());
+        o.access_priv(s);
+        o.access_priv(intf);
+
+        s.access_priv(o);
+        s.access_priv(new StaticNested());
+        s.access_priv(intf);
+
+        i.access_priv(o);
+        i.access_priv(s);
+        i.access_priv(intf);
+
+        intf.access_priv(o);
+        intf.access_priv(s);
+        intf.access_priv(new StaticIface(){});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateStaticMethods/TestMethodHandles.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private static methods between nestmates and nest-top
+ *          using different flavours of named nested types using MethodHandles
+ * @compile -XDdisablePrivateAccessors TestMethodHandles.java
+ * @run main TestMethodHandles
+ */
+
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class TestMethodHandles {
+
+    static final MethodType INVOKE_T = MethodType.methodType(void.class);
+
+    // Private static method of nest-top for nestmates to access
+    private static void priv_static_invoke() {
+        System.out.println("TestMethodHandles::priv_static_invoke");
+    }
+
+    // public constructor so we aren't relying on private access
+    public TestMethodHandles() {}
+
+    // Methods that will access private static methods of nestmates
+
+    // NOTE: No InnerNested calls in this test because non-static nested types
+    // can't have static methods
+
+    void access_priv(TestMethodHandles o) throws Throwable {
+        MethodHandle mh = 
+          lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T);
+        mh.invoke();
+        mh.invokeExact();
+    }
+    void access_priv(StaticNested o) throws Throwable {
+        MethodHandle mh = 
+          lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T);
+        mh.invoke();
+        mh.invokeExact();
+    }
+    void access_priv(StaticIface o) throws Throwable {
+        MethodHandle mh = 
+          lookup().findStatic(StaticIface.class, "priv_static_invoke", INVOKE_T);
+        mh.invoke();
+        mh.invokeExact();
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        private static void priv_static_invoke() {
+            System.out.println("StaticIface::priv_static_invoke");
+        }
+
+        // Methods that will access private static methods of nestmates
+
+        default void access_priv(TestMethodHandles o) throws Throwable {
+          MethodHandle mh = 
+            lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T);
+          mh.invoke();
+          mh.invokeExact();
+        }
+        default void access_priv(StaticNested o) throws Throwable {
+          MethodHandle mh = 
+            lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T);
+          mh.invoke();
+          mh.invokeExact();
+        }
+        default void access_priv(StaticIface o) throws Throwable {
+          MethodHandle mh = 
+            lookup().findStatic(StaticIface.class, "priv_static_invoke", INVOKE_T);
+          mh.invoke();
+          mh.invokeExact();
+        }
+    }
+
+    static class StaticNested {
+
+        private static void priv_static_invoke() {
+            System.out.println("StaticNested::priv_static_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private static methods of nestmates
+
+        void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T);
+          mh.invoke();
+          mh.invokeExact();
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T);
+          mh.invoke();
+          mh.invokeExact();
+        }
+        void access_priv(StaticIface o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findStatic(StaticIface.class, "priv_static_invoke", INVOKE_T);
+          mh.invoke();
+          mh.invokeExact();
+        }
+    }
+
+    class InnerNested {
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestMethodHandles o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T);
+            mh.invoke();
+            mh.invokeExact();
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T);
+            mh.invoke();
+            mh.invokeExact();
+        }
+        void access_priv(StaticIface o) throws Throwable {
+            MethodHandle mh = 
+              lookup().findStatic(StaticIface.class, "priv_static_invoke", INVOKE_T);
+            mh.invoke();
+            mh.invokeExact();
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        TestMethodHandles o = new TestMethodHandles();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestMethodHandles());
+        o.access_priv(s);
+        o.access_priv(intf);
+
+        s.access_priv(o);
+        s.access_priv(new StaticNested());
+        s.access_priv(intf);
+
+        i.access_priv(o);
+        i.access_priv(s);
+        i.access_priv(intf);
+
+        intf.access_priv(o);
+        intf.access_priv(s);
+        intf.access_priv(new StaticIface(){});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Nestmates/privateStaticMethods/TestReflection.java	Thu Aug 10 15:01:17 2017 +0100
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017, 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 8046171
+ * @summary Test access to private static methods between nestmates and nest-top
+ *          using different flavours of named nested types using core reflection
+ * @compile -XDdisablePrivateAccessors TestReflection.java
+ * @run main TestReflection
+ */
+
+public class TestReflection {
+
+    // Private method of nest-top for nestmates to access
+    private static void priv_static_invoke() {
+        System.out.println("TestReflection::priv_static_invoke");
+    }
+
+    // public constructor so we aren't relying on private access
+    public TestReflection() {}
+
+    // Methods that will access private static methods of nestmates
+
+    // NOTE: No InnerNested calls in this test because non-static nested types
+    // can't have static methods
+
+    void access_priv(TestReflection o) throws Throwable {
+        o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+    }
+    void access_priv(StaticNested o) throws Throwable {
+        o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+    }
+    void access_priv(StaticIface o) throws Throwable {
+        StaticIface.class.getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+    }
+
+    // The various nestmates
+
+    static interface StaticIface {
+
+        private static void priv_static_invoke() {
+            System.out.println("StaticIface::priv_static_invoke");
+        }
+
+        // Methods that will access private static methods of nestmates
+
+        default void access_priv(TestReflection o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+        default void access_priv(StaticNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+        default void access_priv(StaticIface o) throws Throwable {
+            StaticIface.class.getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+    }
+
+    static class StaticNested {
+
+        private static void priv_static_invoke() {
+            System.out.println("StaticNested::priv_static_invoke");
+        }
+
+        // public constructor so we aren't relying on private access
+        public StaticNested() {}
+
+        // Methods that will access private static methods of nestmates
+
+        void access_priv(TestReflection o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+        void access_priv(StaticIface o) throws Throwable {
+            StaticIface.class.getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+    }
+
+    class InnerNested {
+
+        // public constructor so we aren't relying on private access
+        public InnerNested() {}
+
+        void access_priv(TestReflection o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+        void access_priv(StaticNested o) throws Throwable {
+            o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+        void access_priv(StaticIface o) throws Throwable {
+            StaticIface.class.getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]);
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        TestReflection o = new TestReflection();
+        StaticNested s = new StaticNested();
+        InnerNested i = o.new InnerNested();
+        StaticIface intf = new StaticIface() {};
+
+        o.access_priv(new TestReflection());
+        o.access_priv(s);
+        o.access_priv(intf);
+
+        s.access_priv(o);
+        s.access_priv(new StaticNested());
+        s.access_priv(intf);
+
+        i.access_priv(o);
+        i.access_priv(s);
+        i.access_priv(intf);
+
+        intf.access_priv(o);
+        intf.access_priv(s);
+        intf.access_priv(new StaticIface(){});
+    }
+}