changeset 56254:4be2cb65666f nestmates

[Nestmates] update hidden/nestmate/weak class prototype
author mchung
date Thu, 29 Aug 2019 19:32:19 -0700
parents faef7de0eba8
children d0a11d2498d2
files src/hotspot/share/oops/instanceKlass.cpp src/hotspot/share/oops/method.hpp src/hotspot/share/runtime/reflection.cpp src/java.base/share/classes/java/lang/Class.java src/java.base/share/classes/java/lang/StringConcatHelper.java src/java.base/share/classes/java/lang/System.java src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java src/java.base/share/classes/java/lang/invoke/MethodHandles.java src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java src/java.base/share/classes/java/lang/reflect/AccessibleObject.java src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java src/jdk.unsupported/share/classes/sun/misc/Unsafe.java test/hotspot/jtreg/compiler/cha/ObjectHashCode.java test/hotspot/jtreg/compiler/cha/ObjectToString.java test/hotspot/jtreg/compiler/cha/StrengthReduceInterfaceCall.java test/hotspot/jtreg/compiler/cha/ThreeLevelDefaultHierarchy.java test/hotspot/jtreg/compiler/cha/ThreeLevelDefaultHierarchy1.java test/hotspot/jtreg/compiler/cha/ThreeLevelHierarchyAbstractVsDefault.java test/hotspot/jtreg/compiler/cha/ThreeLevelHierarchyLinear.java test/hotspot/jtreg/compiler/cha/TwoLevelHierarchyLinear.java test/hotspot/jtreg/runtime/Nestmates/membership/TestDynamicNestmateMembership.java test/jdk/java/lang/StackWalker/VerifyStackTrace.java test/jdk/java/lang/invoke/defineClass/DefineClassTest.java test/jdk/java/lang/invoke/defineClass/DefineClassWithClassData.java test/jdk/java/lang/invoke/defineClass/DefineNonFindableClass.java test/jdk/java/lang/invoke/defineClass/nonFindable/NonFindable.java test/jdk/java/lang/invoke/defineClass/nonFindable/NonFindableField.java test/jdk/java/lang/invoke/defineClass/nonFindable/NonFindableMethod.java test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java test/jdk/java/lang/invoke/defineHiddenClass/DefineClassWithClassData.java test/jdk/java/lang/invoke/defineHiddenClass/DefineHiddenClassTest.java test/jdk/java/lang/invoke/defineHiddenClass/SelfRefField.java test/jdk/java/lang/invoke/defineHiddenClass/SelfRefMethod.java test/jdk/java/lang/invoke/defineHiddenClass/SelfReferenceDescriptor.java test/jdk/java/lang/invoke/defineHiddenClass/src/AbstractClass.java test/jdk/java/lang/invoke/defineHiddenClass/src/EnclosingClass.java test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenCantReflect.java test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenClass.java test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenClassThrow.java test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenInterface.java test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenSuper.java test/jdk/java/lang/invoke/defineHiddenClass/src/Lambda.java test/jdk/java/lang/invoke/defineHiddenClass/src/Outer.java test/langtools/jdk/javadoc/doclet/testSingletonLists/TestSingletonLists.java test/micro/org/openjdk/bench/java/lang/invoke/LookupDefineClass.java
diffstat 50 files changed, 2725 insertions(+), 1726 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/oops/instanceKlass.cpp	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Thu Aug 29 19:32:19 2019 -0700
@@ -2907,7 +2907,7 @@
       *inner_is_member = true;
     }
     if (NULL == outer_klass) {
-      // It may be unsafe anonymous; try for that.
+      // It may be a local or anonymous class; try for that.
       int encl_method_class_idx = enclosing_method_class_index();
       if (encl_method_class_idx != 0) {
         Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL);
--- a/src/hotspot/share/oops/method.hpp	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/hotspot/share/oops/method.hpp	Thu Aug 29 19:32:19 2019 -0700
@@ -888,8 +888,9 @@
     _flags = x ? (_flags | _dont_inline) : (_flags & ~_dont_inline);
   }
 
-  bool is_hidden() {
-    return (_flags & _hidden) != 0;
+  bool is_hidden() const {
+    // ## FIXME: should be set at class parsing time
+    return method_holder()->is_nonfindable() || (_flags & _hidden) != 0;
   }
   void set_hidden(bool x) {
     _flags = x ? (_flags | _hidden) : (_flags & ~_hidden);
--- a/src/hotspot/share/runtime/reflection.cpp	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/hotspot/share/runtime/reflection.cpp	Thu Aug 29 19:32:19 2019 -0700
@@ -707,7 +707,7 @@
 // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
 // throw an incompatible class change exception
 // If inner_is_member, require the inner to be a member of the outer.
-// If !inner_is_member, require the inner to be a nonfindable or unsafe anonymous (a non-member).
+// If !inner_is_member, require the inner to be a local or anonymous class (a non-member).
 // Caller is responsible for figuring out in advance which case must be true.
 void Reflection::check_for_inner_class(const InstanceKlass* outer, const InstanceKlass* inner,
                                        bool inner_is_member, TRAPS) {
--- a/src/java.base/share/classes/java/lang/Class.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/Class.java	Thu Aug 29 19:32:19 2019 -0700
@@ -63,7 +63,6 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.stream.Stream;
 import java.util.stream.Collectors;
 
 import jdk.internal.HotSpotIntrinsicCandidate;
@@ -129,10 +128,9 @@
  * enclosed within the top-level class declaration.
  *
  * <p> Some methods of class {@code Class} expose some characteristics of
- * a class defined via
- * {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty...)
- * Lookup::defineClass} API such as whether this class is a
- * {@linkplain #isHiddenClass() hidden class}.
+ * hidden classes that can be defined by calling
+ * {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOptions...)
+ * Lookup::defineHiddenClass}.
  *
  * <p> The following example uses a {@code Class} object to print the
  * class name of an object:
@@ -761,6 +759,9 @@
      * by
      * <cite>The Java&trade; Language Specification</cite>.
      *
+     * <p> If this class object represents a {@linkplain #isHiddenClass() hidden class},
+     * then the name is given by the JVM and it may not be a valid binary name.
+     *
      * <p> If this class object represents a primitive type or void, then the
      * name returned is a {@code String} equal to the Java language
      * keyword corresponding to the primitive type or void.
@@ -1655,7 +1656,8 @@
 
     /**
      * Returns {@code true} if and only if the underlying class
-     * is an anonymous class.
+     * is an anonymous class.  An anonymous class is not a
+     * {@linkplain #isHiddenClass() hidden class}.
      *
      * @return {@code true} if and only if this class is an anonymous class.
      * @since 1.5
@@ -3922,10 +3924,11 @@
      * {@code NestMembers} attribute (JVMS 4.7.29).
      * A {@code class} file of version 54.0 or lower does not use these
      * attributes.
-     * A class defined at runtime in a nest via
-     * {@link MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty[])}
-     * must not have the {@code NestHost} attribute and is not enumerated
-     * in the {@code NestMembers} attribute of the class file of the nest host.
+     * If this class was created by calling
+     * {@link MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOptions...)
+     * Lookup.defineHiddenClass}
+     * and added to the nest of the lookup object's lookup class, then
+     * this class has the same nest host as the lookup class.
      *
      * @return the nest host of this class or interface
      *
@@ -4018,16 +4021,12 @@
      * interface records itself as a member of that same nest. Any exceptions
      * that occur during this validation are rethrown by this method.
      *
-     * <p>This method does not return the
-     * {@linkplain MethodHandles.Lookup.ClassProperty#NESTMATE nest members}
-     * defined dynamically via
-     * {@link MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty...)}.
-     *
      * @apiNote
-     * Reflection API presents the static view of this class. The dynamic
-     * nestmates are not listed in the {@code NestMembers} attribute.
-     * We can revisit this in the future if there is a need to find
-     * all dynamically defined nest members.
+     * This method returns the nest members listed in the {@code NestMembers}
+     * attribute.  The returned array does not include nest members created
+     * by calling
+     * {@link MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOptions...)
+     * Lookup.defineHiddenClass}.
      *
      * @return an array of all classes and interfaces in the same nest as
      * this class
@@ -4045,7 +4044,7 @@
      *
      * @since 11
      * @see #getNestHost()
-     * @see MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty...)
+     * @see MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOptions...)
      */
     @CallerSensitive
     public Class<?>[] getNestMembers() {
@@ -4135,28 +4134,21 @@
     /**
      * Returns {@code true} if this class is a hidden class.
      *
-     * <p> A <em>hidden class</em> is a class to which no constant pool entry
-     * (or symbolic reference derived therefrom) can refer.
-     * Loading, linking, and initializing of a hidden class are controlled solely
-     * by invocations on the {@link MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty...)
-     * MethodHandles.Lookup} object.
-     *
-     * <p> A hidden class does not have a {@linkplain #getCanonicalName()
-     * canonical name}.
-     *
-     * <p> If this class is hidden then it cannot be found via its name
-     * including {@link Class#forName(String) Class.forName(this.getName())},
+     * <p> A <em>hidden class</em> is non-discoverable by class loaders
+     * by bytecode linkage.  It cannot be found by
+     * {@link Class#forName(String) Class.forName(this.getName())},
      * {@link ClassLoader#findLoadedClass},
      * and {@link MethodHandles.Lookup#findClass(String) MethodHandles.Lookup.findClass}.
      *
      * <p> If this class is an array class and its component class is hidden,
      * then this array class is also hidden.
      *
-     * @return {@code true} if this class is hidden; otherwise {@code false}.
+     * <p> An anonymous class is not a hidden class.
+     *
+     * @return {@code true} if this class is a hidden class; otherwise {@code false}.
      *
      * @since 14
-     * @see MethodHandles.Lookup.ClassProperty#HIDDEN
-     * @see MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty[])
+     * @see MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOptions...)
      */
     public boolean isHiddenClass() {
         return getName().indexOf('/') > -1;
--- a/src/java.base/share/classes/java/lang/StringConcatHelper.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/StringConcatHelper.java	Thu Aug 29 19:32:19 2019 -0700
@@ -28,6 +28,10 @@
 import jdk.internal.misc.Unsafe;
 import jdk.internal.vm.annotation.ForceInline;
 
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
 /**
  * Helper for string concatenation. These methods are mostly looked up with private lookups
  * from {@link java.lang.invoke.StringConcatFactory}, and used in {@link java.lang.invoke.MethodHandle}
@@ -466,4 +470,13 @@
         return String.COMPACT_STRINGS ? LATIN1 : UTF16;
     }
 
+    static MethodHandle lookupStatic(String name, MethodType methodType) {
+        try {
+            return MethodHandles.lookup().findStatic(StringConcatHelper.class, name, methodType);
+        } catch (NoSuchMethodException|IllegalAccessException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+
 }
--- a/src/java.base/share/classes/java/lang/System.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/System.java	Thu Aug 29 19:32:19 2019 -0700
@@ -35,6 +35,8 @@
 import java.io.PrintStream;
 import java.io.UnsupportedEncodingException;
 import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
 import java.lang.module.ModuleDescriptor;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Executable;
@@ -2282,6 +2284,11 @@
             public ProtectionDomain protectionDomain(Class<?> c) {
                 return c.protectionDomain();
             }
+
+            public MethodHandle stringConcatHelper(String name, MethodType methodType) {
+                return StringConcatHelper.lookupStatic(name, methodType);
+            }
+
         });
     }
 }
--- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Thu Aug 29 19:32:19 2019 -0700
@@ -25,7 +25,6 @@
 
 package java.lang.invoke;
 
-import jdk.internal.misc.Unsafe;
 import jdk.internal.org.objectweb.asm.*;
 import sun.invoke.util.BytecodeDescriptor;
 import sun.security.action.GetPropertyAction;
@@ -41,7 +40,7 @@
 import java.util.PropertyPermission;
 import java.util.Set;
 
-import static java.lang.invoke.MethodHandles.Lookup.*;
+import static java.lang.invoke.MethodHandles.Lookup.ClassOptions.NESTMATE;
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 /**
@@ -51,8 +50,6 @@
  * @see LambdaMetafactory
  */
 /* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
-    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
-
     private static final int CLASSFILE_VERSION = 52;
     private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
     private static final String JAVA_LANG_OBJECT = "java/lang/Object";
@@ -78,8 +75,6 @@
     private static final String DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION = "(Ljava/lang/String;)V";
     private static final String[] SER_HOSTILE_EXCEPTIONS = new String[] {NAME_NOT_SERIALIZABLE_EXCEPTION};
 
-    private static final String DESCR_HIDDEN = "Ljdk/internal/vm/annotation/Hidden;";
-
     private static final String[] EMPTY_STRING_ARRAY = new String[0];
 
     // Used to ensure that each spun class name is unique
@@ -158,7 +153,7 @@
         implMethodName = implInfo.getName();
         implMethodDesc = implInfo.getMethodType().toMethodDescriptorString();
         constructorType = invokedType.changeReturnType(Void.TYPE);
-        lambdaClassName = targetClass.getName().replace('.', '/') + "$$Lambda$" + counter.incrementAndGet();
+        lambdaClassName = lambdaClassName(targetClass);
         cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
         int parameterCount = invokedType.parameterCount();
         if (parameterCount > 0) {
@@ -173,6 +168,15 @@
         }
     }
 
+    private static String lambdaClassName(Class<?> targetClass) {
+        String name = targetClass.getName();
+        if (targetClass.isHiddenClass()) {
+            // use the original class name
+            name = name.replace('/', '_');
+        }
+        return name.replace('.', '/') + "$$Lambda$" + counter.incrementAndGet();
+    }
+
     /**
      * Build the CallSite. Generate a class file which implements the functional
      * interface, define the class, if there are no parameters create an instance
@@ -187,7 +191,7 @@
      */
     @Override
     CallSite buildCallSite() throws LambdaConversionException {
-        Lookup lookup = spinInnerClassAsLookup();
+        Lookup lookup = spinInnerClass();
         Class<?> innerClass = lookup.lookupClass();
         assert innerClass.isHiddenClass() : innerClass.toString();
         if (invokedType.parameterCount() == 0) {
@@ -241,7 +245,7 @@
      * @throws LambdaConversionException If properly formed functional interface
      * is not found
      */
-    private Lookup spinInnerClassAsLookup() throws LambdaConversionException {
+    private Lookup spinInnerClass() throws LambdaConversionException {
         String[] interfaces;
         String samIntf = samBase.getName().replace('.', '/');
         boolean accidentallySerializable = !isSerializable && Serializable.class.isAssignableFrom(samBase);
@@ -276,7 +280,6 @@
         // Forward the SAM method
         MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samMethodName,
                                           samMethodType.toMethodDescriptorString(), null, null);
-        mv.visitAnnotation(DESCR_HIDDEN, true);
         new ForwardingMethodGenerator(mv).generate(samMethodType);
 
         // Forward the bridges
@@ -284,7 +287,6 @@
             for (MethodType mt : additionalBridges) {
                 mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samMethodName,
                                     mt.toMethodDescriptorString(), null, null);
-                mv.visitAnnotation(DESCR_HIDDEN, true);
                 new ForwardingMethodGenerator(mv).generate(mt);
             }
         }
@@ -312,8 +314,12 @@
             // createDirectories may need it
             new PropertyPermission("user.dir", "read"));
         }
-        // this class is linked at the indy callsite.  No need to be weak class
-        return caller.defineClassAsLookupNoCheck(classBytes, HIDDEN_NESTMATE);
+        try {
+            // this class is linked at the indy callsite; so define a hidden nestmate
+            return caller.defineHiddenClassAsLookup(classBytes, true, NESTMATE);
+        } catch (IllegalAccessException e) {
+            throw new LambdaConversionException("Exception defining lambda proxy class", e);
+        }
     }
 
     /**
--- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Thu Aug 29 19:32:19 2019 -0700
@@ -308,19 +308,12 @@
     /**
      * Extract the MemberName of a newly-defined method.
      */
-    private MemberName loadMethod(byte[] classFile, List<Object> classData) {
-        Class<?> invokerClass = loadAndInitializeInvokerClass(classFile, classData);
+    private MemberName loadMethod(byte[] classFile) {
+        Class<?> invokerClass = LOOKUP.defineClassAsLookup(className(), classFile,
+                HIDDEN_CLASS|WEAK_CLASS|ACCESS_VM_ANNOTATIONS, true, classDataValues()).lookupClass();
         return resolveInvokerMember(invokerClass, invokerName, invokerType);
     }
 
-    /**
-     * Define a given class as anonymous class in the runtime system.
-     */
-    private static Class<?> loadAndInitializeInvokerClass(byte[] classBytes, List<Object> classData) {
-        return LOOKUP.defineClassAsLookupNoCheck(classBytes, WEAK_HIDDEN_NESTMATE, classData)
-                     .lookupClass();
-    }
-
     private static MemberName resolveInvokerMember(Class<?> invokerClass, String name, MethodType type) {
         MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic);
         try {
@@ -761,7 +754,7 @@
         if (pregenerated != null)  return pregenerated; // pre-generated bytecode
 
         InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType);
-        return g.loadMethod(g.generateCustomizedCodeBytes(), g.classDataValues());
+        return g.loadMethod(g.generateCustomizedCodeBytes());
     }
 
     /** Generates code to check that actual receiver and LambdaForm matches */
@@ -1816,7 +1809,7 @@
         MethodType type = mt;  // includes leading argument
         type = type.changeParameterType(0, MethodHandle.class);
         InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", name, type);
-        return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes(), g.classDataValues());
+        return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes());
     }
 
     private byte[] generateLambdaFormInterpreterEntryPointBytes() {
@@ -1876,7 +1869,7 @@
         MethodType invokerType = NamedFunction.INVOKER_METHOD_TYPE;
         String invokerName = "invoke_" + shortenSignature(basicTypeSignature(typeForm.erasedType()));
         InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("NFI", invokerName, invokerType);
-        return g.loadMethod(g.generateNamedFunctionInvokerImpl(typeForm), g.classDataValues());
+        return g.loadMethod(g.generateNamedFunctionInvokerImpl(typeForm));
     }
 
     private byte[] generateNamedFunctionInvokerImpl(MethodTypeForm typeForm) {
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Aug 29 19:32:19 2019 -0700
@@ -54,7 +54,7 @@
 import static java.lang.invoke.LambdaForm.*;
 import static java.lang.invoke.MethodHandleStatics.*;
 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-import static java.lang.invoke.MethodHandles.Lookup.WEAK_HIDDEN_NESTMATE;
+import static java.lang.invoke.MethodHandleNatives.Constants.HIDDEN_CLASS;
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 /**
@@ -1177,8 +1177,8 @@
                  *
                  * @CSM must be public and exported if called by any module.
                  */
-                String name = targetClass.getNestHost().getName() + "$$InjectedInvoker";
-                Lookup lookup = new Lookup(targetClass).defineClassAsLookupNoCheck(name, INJECTED_INVOKER_TEMPLATE, WEAK_HIDDEN_NESTMATE);
+                String name = targetClass.getName() + "$$InjectedInvoker";
+                Lookup lookup = new Lookup(targetClass).defineClassAsLookup(name, INJECTED_INVOKER_TEMPLATE, HIDDEN_CLASS, true, null);
                 Class<?> invokerClass = lookup.lookupClass();
                 assert checkInjectedInvoker(targetClass, invokerClass);
                 return lookup.findStatic(invokerClass, "invoke_V", INVOKER_MT);
@@ -1276,10 +1276,6 @@
                           "(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;",
                           null, null);
 
-            // Suppress invoker method in stack traces.
-            AnnotationVisitor av0 = mv.visitAnnotation(InvokerBytecodeGenerator.HIDDEN_SIG, true);
-            av0.visitEnd();
-
             mv.visitCode();
             mv.visitVarInsn(ALOAD, 0);
             mv.visitVarInsn(ALOAD, 1);
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Thu Aug 29 19:32:19 2019 -0700
@@ -142,7 +142,7 @@
             REF_LIMIT                  = 10;
 
         /**
-         * Flags for Lookup.ClassProperty
+         * Flags for Lookup.ClassOptions
          */
         static final int
             NESTMATE_CLASS            = 0x00000001,
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Aug 29 19:32:19 2019 -0700
@@ -29,6 +29,8 @@
 import jdk.internal.access.SharedSecrets;
 import jdk.internal.module.IllegalAccessLogger;
 import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.reflect.CallerSensitive;
 import jdk.internal.reflect.Reflection;
 import jdk.internal.vm.annotation.ForceInline;
@@ -58,7 +60,6 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import static java.lang.invoke.MethodHandles.Lookup.ClassProperty.*;
 import static java.lang.invoke.MethodHandleImpl.Intrinsic;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
@@ -550,8 +551,8 @@
      * and the Core Reflection API
      * (as found on {@link java.lang.Class Class}).
      * <p>
-     * If a security manager is present, member and class lookups are subject to
-     * additional checks.
+     * If a security manager is present, member and class lookups are
+     * subject to additional checks.
      * From one to three calls are made to the security manager.
      * Any of these calls can refuse access by throwing a
      * {@link java.lang.SecurityException SecurityException}.
@@ -595,6 +596,13 @@
      * Therefore, the above rules presuppose a member or class that is public,
      * or else that is being accessed from a lookup class that has
      * rights to access the member or class.
+     * <p>
+     * If a security manager is present and the current lookup object does not have
+     * <a href="MethodHandles.Lookup.html#privacc">private access</a>, then
+     * {@link #defineClass(byte[]) defineClass} and
+     * {@link #defineHiddenClass(byte[], boolean, ClassOptions...) defineHiddenClass}
+     * call {@link SecurityManager#checkPermission smgr.checkPermission}
+     * with {@code RuntimePermission("defineClass")} is called.
      *
      * <h2><a id="callsens"></a>Caller sensitive methods</h2>
      * A small number of Java methods have a special property called caller sensitivity.
@@ -822,8 +830,6 @@
          * @param requestedLookupClass the desired lookup class for the new lookup object
          * @return a lookup object which reports the desired lookup class, or the same object
          * if there is no change
-         * @throws IllegalArgumentException if {@code requestedLookupClass} is
-         * a primitive type or array class
          * @throws NullPointerException if the argument is null
          *
          * @revised 9
@@ -831,10 +837,6 @@
          */
         public Lookup in(Class<?> requestedLookupClass) {
             Objects.requireNonNull(requestedLookupClass);
-            if (requestedLookupClass.isPrimitive())
-                throw new IllegalArgumentException(requestedLookupClass + " is a primitive class");
-            if (requestedLookupClass.isArray())
-                throw new IllegalArgumentException(requestedLookupClass + " is an array class");
 
             if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
                 return new Lookup(requestedLookupClass, FULL_POWER_MODES);
@@ -910,16 +912,20 @@
          * {@linkplain java.security.ProtectionDomain protection domain} as this lookup's
          * {@linkplain #lookupClass() lookup class}.
          *
-         * This method is equivalent to calling {@link #defineClass(byte[], ClassProperty[])
-         * defineClass(bytes, new ClassProperty[0])}.
+         * <p> The {@linkplain #lookupModes() lookup modes} for this lookup must include
+         * {@link #PACKAGE PACKAGE} access as default (package) members will be
+         * accessible to the class. The {@code PACKAGE} lookup mode serves to authenticate
+         * that the lookup object was created by a caller in the runtime package (or derived
+         * from a lookup originally created by suitably privileged code to a target class in
+         * the runtime package). </p>
          *
-         * <p> The {@linkplain #lookupModes() lookup modes} for this lookup must
-         * have {@code PRIVATE} and {@code MODULE} access in order to add a new
-         * member in the module of this lookup class.
+         * <p> The {@code bytes} parameter is the class bytes of a valid class file (as defined
+         * by the <em>The Java Virtual Machine Specification</em>) with a class name in the
+         * same package as the lookup class. </p>
          *
-         * <p> The class bytes of a nestmate class must not contain
-         * the {@code NestHost} attribute nor the {@code NestMembers} attribute;
-         * otherwise {@code IllegalArgumentException} will be thrown.
+         * <p> This method does not run the class initializer. The class initializer may
+         * run at a later time, as detailed in section 12.4 of the <em>The Java Language
+         * Specification</em>. </p>
          *
          * <p> If there is a security manager, its {@code checkPermission} method is first called
          * to check {@code RuntimePermission("defineClass")}. </p>
@@ -928,7 +934,7 @@
          * @return the {@code Class} object for the class
          * @throws IllegalArgumentException the bytes are for a class in a different package
          * to the lookup class
-         * @throws IllegalAccessException   if this lookup does not have {@code PRIVATE} and {@code MODULE} access
+         * @throws IllegalAccessException if this lookup does not have {@code PACKAGE} access
          * @throws LinkageError if the class is malformed ({@code ClassFormatError}), cannot be
          * verified ({@code VerifyError}), is already defined, or another linkage error occurs
          * @throws SecurityException if denied by the security manager
@@ -940,271 +946,287 @@
          * @see ClassLoader#defineClass(String,byte[],int,int,ProtectionDomain)
          */
         public Class<?> defineClass(byte[] bytes) throws IllegalAccessException {
-            return defineClass(bytes, EMPTY_CLASS_PROPS);
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkPermission(new RuntimePermission("defineClass"));
+            if ((lookupModes() & PACKAGE) == 0)
+                throw new IllegalAccessException("Lookup does not have PACKAGE access");
+            assert (lookupModes() & (MODULE|PUBLIC)) != 0;
+
+            // parse class bytes to get class name (in internal form)
+            bytes = bytes.clone();
+            String name;
+            try {
+                ClassReader reader = new ClassReader(bytes);
+                name = reader.getClassName();
+            } catch (RuntimeException e) {
+                // ASM exceptions are poorly specified
+                ClassFormatError cfe = new ClassFormatError();
+                cfe.initCause(e);
+                throw cfe;
+            }
+
+            // get package and class name in binary form
+            String cn, pn;
+            int index = name.lastIndexOf('/');
+            if (index == -1) {
+                cn = name;
+                pn = "";
+            } else {
+                cn = name.replace('/', '.');
+                pn = cn.substring(0, index);
+            }
+            if (!pn.equals(lookupClass.getPackageName())) {
+                throw new IllegalArgumentException("Class not in same package as lookup class");
+            }
+
+            return defineClass(cn, bytes, 0, false, null);
         }
 
+        private void checkDefineClassPermission() {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm == null)  return;
+            if (allowedModes == TRUSTED)  return;
+
+            if (!hasPrivateAccess()) {
+                sm.checkPermission(new RuntimePermission("defineClass"));
+            }
+        }
+
         /**
-         * Defines a class to the same class loader and in the same runtime package
-         * and {@linkplain java.security.ProtectionDomain protection domain} as
-         * this lookup's {@linkplain #lookupClass() lookup class}.
-         * The {@code props} parameter specifies the properties of the class.
+         * Defines a hidden class to the same class loader and in the same runtime package
+         * and {@linkplain java.security.ProtectionDomain protection domain} as this
+         * lookup's {@linkplain #lookupClass() lookup class}.
+         * The {@code options} parameter specifies the class options.
          *
-         * <p> A class can be defined with the following properties:
+         * <p> The hidden class is initialized if the {@code initialize} parameter is
+         * {@code true}.
+         *
+         * <p>
+         * A {@link Class#isHiddenClass() <em>hidden</em>} class, i.e. a class cannot be
+         * symbolically referenced in other classes, with the following properties:
          * <ul>
-         * <li>A {@linkplain ClassProperty#NESTMATE <em>nestmate</em>} of the lookup class,
-         *     i.e. in the same {@linkplain Class#getNestHost nest}
-         *     of the lookup class.  The class will have access to the private members
-         *     of all classes and interfaces in the same nest.
-         *     </li>
-         * <li>A {@linkplain ClassProperty#HIDDEN <em>hidden</em>} class,
-         *     i.e. a class cannot be named in other classes.
-         *     A hidden class has the following properties:
-         *     <ul>
-         *     <li>Naming:
-         *     The name of this class is derived from the name of
-         *     the class in the class bytes so that the class name does not
-         *     collide with other classes defined to the same class loader.
-         *     <li>Class resolution:
+         * <li>Naming:
+         *     The name of this class is determined by the JVM and the class name
+         *     does not collide with other classes defined to the same class loader.
+         *     The name returned by {@link Class#getName()} must be unique
+         *     in the same package as this lookup class.
+         *     It may not be a valid binary name.
+         *     There is no two classes (whether ordinary or hidden) with the same
+         *     defining loader have the same name.
+         * <li>Class resolution:
          *     A hidden class is not registered with a globally defined name and
          *     hence cannot be found by its class loader.
          *     A hidden class cannot be named as a field type, a method parameter
          *     type and a method return type.
-         *     The name returned by {@link Class#getName()} is a unique name
-         *     in the same package as this lookup class and
-         *     is different from the name in the class bytes.
-         *     <li>Class retransformation:
+         * <li>Class retransformation:
          *     A hidden class is not {@linkplain java.lang.instrument.Instrumentation#isModifiableClass(Class)
          *     modifiable} by Java agents or tool agents using
          *     the <a href="{@docRoot}/../specs/jvmti.html">JVM Tool Interface</a>.
-         *     <li>Reflective access:
+         * <li>Reflective access:
          *     The {@linkplain java.lang.reflect.AccessibleObject#setAccessible(boolean)
          *     accessible} flag of its {@link Field}, {@link Method},
          *     {@link Constructor} reflected objects of a hidden class cannot be set
          *     to suppress access check.
-         *     </ul>
-         *     </li>
-         * <li>A {@linkplain ClassProperty#WEAK <em>weak</em>} class,
-         *     i.e. a class may be unloaded independently with
-         *     its defining class loader when it becomes
-         *     <a href="../ref/package.html#reachability">reachable</a>,
-         *     as if the defining class loader would only hold a
-         *     {@linkplain java.lang.ref.WeakReference weak reference} of
-         *     the class.
-         *     A weak class is hidden.  If the {@code WEAK} property is set,
-         *     then it implies that {@code HIDDEN} property is also set.</li>
          * </ul>
          *
+         * <p> If {@code options} has {@link ClassOptions#NESTMATE}, then this method adds
+         * the hidden class to join the nest of the lookup class.
+         * The hidden class has the same {@linkplain Class#getNestHost nest host}
+         * as the lookup class and therefore it can access to the private members
+         * of all classes and interfaces in the same nest.
+         *
+         * <p> If {@code options} has {@link ClassOptions#WEAK}, then the hidden class is
+         * weakly reachable from its defining class loader and may be unloaded while
+         * its defining class loader is strongly reachable.
+         *
          * <p> The {@linkplain #lookupModes() lookup modes} for this lookup must
          * have {@code PRIVATE} and {@code MODULE} access in order to add a new
          * member in the module of this lookup class.
          *
          * <p> The {@code bytes} parameter is the class bytes of a valid class file
          * (as defined by the <em>The Java Virtual Machine Specification</em>)
-         * with a class name in the same package as the lookup class.
-         *
-         * <p> The class bytes of a nestmate class must not contain
-         * the {@code NestHost} attribute nor the {@code NestMembers} attribute;
-         * otherwise {@code IllegalArgumentException} will be thrown.
-         *
-         * <p> If there is a security manager, its {@code checkPermission} method is first called
-         * to check {@code RuntimePermission("defineClass")}.
-         *
-         * <p> This method does not run the class initializer. The class initializer may
-         * run at a later time, as detailed in section 12.4 of the <em>The Java Language
-         * Specification</em>.
-         *
-         * @apiNote  An implementation of the Java Progamming Language may
-         * unload classes as specified in section 12.7 of the Java Language Specification.
-         * A class or interface may be unloaded if and only if
-         * its defining class loader may be reclaimed by the garbage collector.
-         * If the implementation supports class loading, a weak class
-         * may become weakly reachable while its defining class loader is
-         * strongly reachable.
+         * with a class name in the same package as the lookup class.  In addition,
+         * <ul>
+         * <li> It must be a top-level class.</li>
+         * <li> It cannot be abstract.</li>
+         * <li> It cannot be an interface.</li>
+         * <li> It cannot be an enclosing class.</li>
+         * <li> It cannot be a superclass.</li>
+         * <li> It cannot be in any static nest membership, i.e. the class bytes
+         *      must not contain the {@code NestHost}, {@code NestMembers}.</li>
+         * </ul>
+         * If any of the above checks is violated, {@code IllegalArgumentException}
+         * will be thrown.
          *
          * @param bytes the class bytes
-         * @param props {@linkplain ClassProperty class properties}
-         * @return the {@code Class} object for the class
+         * @param initialize if {@code true} the class will be initialized.
+         *                   See Section 12.4 of <em>The Java Language Specification</em>.
+         * @param options {@linkplain ClassOptions class options}
+         * @return the {@code Lookup} object on the hidden class
          *
          * @throws IllegalArgumentException the bytes are for a class in a different package
-         *                                  to the lookup class; or if {@code NESTMATE} class
-         *                                  property is specified and the bytes contain
-         *                                  {@code NestHost} or {@code NestMembers} attribute
+         *                                  to the lookup class; or the bytes contain
+         *                                  {@code NestHost}, {@code NestMembers}, {@code InnerClasses} or
+         *                                  {@code EnclosingMethod} attribute.
          * @throws IllegalAccessException   if this lookup does not have {@code PRIVATE} and {@code MODULE} access
          * @throws LinkageError             if the class is malformed ({@code ClassFormatError}), cannot be
          *                                  verified ({@code VerifyError}), is already defined,
          *                                  or another linkage error occurs
-         * @throws SecurityException        if denied by the security manager
+         * @throws SecurityException        if a security manager is present and it
+         *                                  <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
          * @throws NullPointerException     if {@code bytes} is {@code null}
          *
          * @since 14
          * @jls 12.7 Unloading of Classes and Interfaces
          */
-        public Class<?> defineClass(byte[] bytes, ClassProperty... props) throws IllegalAccessException {
+        public Class<?> defineHiddenClass(byte[] bytes, boolean initialize, ClassOptions... options)
+                throws IllegalAccessException
+        {
+            checkDefineClassPermission();
+
             Objects.requireNonNull(bytes);
-
-            // clone the properties before access
-            Set<ClassProperty> properties;
-            if (props == null || props.length == 0) {
-                properties = Set.of();
-            } else {
-                properties = Set.of(props);
-            }
             if ((lookupModes() & (PRIVATE|MODULE)) != (PRIVATE|MODULE)){
                 throw new IllegalAccessException(this + " does not have PRIVATE or MODULE access");
             }
 
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                sm.checkPermission(new RuntimePermission("defineClass"));
+            int flags = HIDDEN_CLASS;
+            if (options != null && options.length > 0) {
+                // clone options parameters
+                Set<ClassOptions> opts = Set.of(options);
+                for (ClassOptions cp : opts) {
+                    flags |= cp.flag;
+                }
             }
-
             bytes = bytes.clone();
-            return defineClass(className(bytes), bytes, classPropertiesToFlags(properties), null, false);
+            ClassFileChecker cfc = new ClassFileChecker(bytes).validate();
+            return defineClass(cfc.className(), bytes, flags, initialize, null);
         }
 
         /**
-         * Returns a {@code Lookup} on the class defined to the same class loader and
-         * in the same runtime package and
-         * {@linkplain java.security.ProtectionDomain protection domain} as this lookup's
-         * {@linkplain #lookupClass() lookup class} with its class initializer invoked.
+         * Defines a {@link Class#isHiddenClass() hidden} class to the same class loader
+         * and in the same runtime package and {@linkplain java.security.ProtectionDomain
+         * protection domain} as this lookup's {@linkplain #lookupClass() lookup class}.
          *
-         * <p> This method is equivalent to calling {@link #defineClass(byte[], ClassProperty...)
-         * defineClass(bytes, props)} to define the class and then calling
-         * its class initializer.  If the newly loaded class is a nestmate of this lookup class,
-         * this method returns a {@code Lookup} with {@link #PRIVATE} access; otherwise
-         * this method returns a {@code Lookup} with {@link #PACKAGE} access.
+         * <p> This method returns a {@code Lookup} object with private access
+         * on the hidden class which is defined as if calling
+         * {@link #defineHiddenClass(byte[], boolean, ClassOptions...) defineHiddenClass}.
          *
-         * <p> The {@linkplain #lookupModes() lookup modes} for this lookup must
-         * have {@code PRIVATE} and {@code MODULE} access in order to add a new
-         * member in the module of this lookup class.
-         *
-         * <p> The class bytes of a nestmate class must not contain
-         * the {@code NestHost} attribute nor the {@code NestMembers} attribute;
-         * otherwise {@code IllegalArgumentException} will be thrown.
-         *
-         * <p> If there is a security manager, its {@code checkPermission} method is first called
-         * to check {@code RuntimePermission("defineClass")}.
-         *
-         * @apiNote
-         * This method ensures that the newly loaded class is initialized prior
-         * to the invocation of {@code MethodHandle} created from the lookup
-         * of the newly loaded class.
-         *
-         * @param bytes      the class bytes
-         * @param props {@linkplain ClassProperty class properties}
-         * @return the {@code Lookup} object for the defined class
+         * @param bytes the class bytes
+         * @param initialize if {@code true} the class will be initialized.
+         *                   See Section 12.4 of <em>The Java Language Specification</em>.
+         * @param options {@linkplain ClassOptions class options}
+         * @return the {@code Lookup} object on the hidden class
          *
          * @throws IllegalArgumentException the bytes are for a class in a different package
-         *                                  to the lookup class; or if {@code NESTMATE} class
-         *                                  property is specified and the bytes contain
-         *                                  {@code NestHost} or {@code NestMembers} attribute
+         *                                  to the lookup class; or the bytes contain
+         *                                  {@code NestHost}, {@code NestMembers}, {@code InnerClasses} or
+         *                                  {@code EnclosingMethod} attribute.
          * @throws IllegalAccessException   if this lookup does not have {@code PRIVATE} and {@code MODULE} access
          * @throws LinkageError             if the class is malformed ({@code ClassFormatError}), cannot be
          *                                  verified ({@code VerifyError}), is already defined,
          *                                  or another linkage error occurs
-         * @throws SecurityException        if denied by the security manager
+         * @throws SecurityException        if a security manager is present and it
+         *                                  <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
          * @throws NullPointerException     if {@code bytes} is {@code null}
+         *
          * @since 14
-         * @see #defineClass(byte[], ClassProperty...)
+         * @jls 12.7 Unloading of Classes and Interfaces
          */
-        public Lookup defineClassAsLookup(byte[] bytes, ClassProperty... props) throws IllegalAccessException {
+        public Lookup defineHiddenClassAsLookup(byte[] bytes, boolean initialize, ClassOptions... options)
+                throws IllegalAccessException
+        {
+            checkDefineClassPermission();
+
             Objects.requireNonNull(bytes);
-
-            // clone the properties before access
-            Set<ClassProperty> properties;
-            if (props == null || props.length == 0) {
-                properties = Set.of();
-            } else {
-                properties = Set.of(props);
-            }
             if ((lookupModes() & (PRIVATE|MODULE)) != (PRIVATE|MODULE)){
                 throw new IllegalAccessException(this + " does not have PRIVATE or MODULE access");
             }
 
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null)
-                sm.checkPermission(new RuntimePermission("defineClass"));
-
-            return defineClassAsLookupNoCheck(bytes.clone(), classPropertiesToFlags(properties));
+            int flags = HIDDEN_CLASS;
+            if (options != null && options.length > 0) {
+                // clone options parameters
+                Set<ClassOptions> opts = Set.of(options);
+                for (ClassOptions cp : opts) {
+                    flags |= cp.flag;
+                }
+            }
+            bytes = bytes.clone();
+            ClassFileChecker cfc = new ClassFileChecker(bytes).validate();
+            return defineHiddenClassAsLookup(cfc.className(), bytes, initialize, flags);
         }
 
+
         /**
          * Returns a {@code Lookup} on the class defined to the same class loader
          * and in the same runtime package
          * and {@linkplain java.security.ProtectionDomain protection domain} as
          * this lookup's {@linkplain #lookupClass() lookup class} with
-         * the given class properties and {@code classData}.
+         * the given class options and {@code classData}.
          *
          * <p> This method defines a class as if calling
-         * {@link #defineClass(byte[], ClassProperty...) defineClass(bytes, props)}
-         * and then initializes the class as if setting the {@code classData}
-         * in a private static unnamed field and then invoke {@code <clinit>}
-         * to complete the class initialization.
+         * {@link #defineHiddenClass(byte[], boolean, ClassOptions...)  defineHiddenClass(bytes, true, options)}.
+         * Setting the {@code classData} behaves as if assigning it to
+         * a private static unnamed field in the class static initializer.
          *
          * <p> The {@linkplain #lookupModes() lookup modes} for this lookup must
          * have {@code PRIVATE} and {@code MODULE} access in order to add a new
          * member in the module of this lookup class.
          *
-         * <p> The class bytes of a nestmate class must not contain
-         * the {@code NestHost} attribute nor the {@code NestMembers} attribute;
-         * otherwise {@code IllegalArgumentException} will be thrown.
-         *
-         * <p> If there is a security manager, its {@code checkPermission} method is
-         * first called to check {@code RuntimePermission("defineClass")}. </p>
-         *
          * <p>
          * The {@link Lookup#classData(Class)} method can be used to retrieve
          * the {@code classData}.
          *
          * @param bytes      the class bytes
          * @param classData pre-initialized class data
-         * @param props {@linkplain ClassProperty class properties}
+         * @param options {@linkplain ClassOptions class options}
          * @return the {@code Class} object for the class
          *
          * @throws IllegalArgumentException the bytes are for a class in a different package
-         *                                  to the lookup class; or if {@code NESTMATE} class
-         *                                  property is specified and the bytes contain
-         *                                  {@code NestHost} or {@code NestMembers} attribute
+         *                                  to the lookup class; or the bytes contain
+         *                                  {@code NestHost}, {@code NestMembers}, {@code InnerClasses} or
+         *                                  {@code EnclosingMethod} attribute.
          * @throws IllegalAccessException   if this lookup does not have {@code PRIVATE} and {@code MODULE} access
          * @throws LinkageError             if the class is malformed ({@code ClassFormatError}), cannot be
          *                                  verified ({@code VerifyError}), is already defined,
          *                                  or another linkage error occurs
-         * @throws SecurityException        if denied by the security manager
-         * @throws NullPointerException     if {@code bytes} or {@code classData} is {@code null}
+         * @throws SecurityException        if a security manager is present and it
+         *                                  <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws NullPointerException     if {@code bytes} is {@code null}
          *
          * @since 14
-         * @jls 12.7 Unloading of Classes and Interfaces
          * @see #classData(Class)
          */
-        public Lookup defineClassWithClassData(byte[] bytes, Object classData, ClassProperty... props)
+        public Lookup defineHiddenClassWithClassData(byte[] bytes, Object classData, ClassOptions... options)
                 throws IllegalAccessException
         {
+            checkDefineClassPermission();
+
             Objects.requireNonNull(bytes);
             Objects.requireNonNull(classData);
-
-            Set<ClassProperty> properties;
-            if (props == null || props.length == 0) {
-                properties = Set.of();
-            } else {
-                properties = Set.of(props);
-            }
             if ((lookupModes() & (PRIVATE|MODULE)) != (PRIVATE|MODULE)){
                 throw new IllegalAccessException(this + " does not have PRIVATE or MODULE access");
             }
 
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                sm.checkPermission(new RuntimePermission("defineClass"));
+            int flags = HIDDEN_CLASS;
+            if (options != null && options.length > 0) {
+                // clone options parameters
+                Set<ClassOptions> opts = Set.of(options);
+                for (ClassOptions cp : opts) {
+                    flags |= cp.flag;
+                }
             }
 
-            return defineClassAsLookupNoCheck(bytes.clone(), classPropertiesToFlags(properties), classData);
+            bytes = bytes.clone();
+            ClassFileChecker cfc = new ClassFileChecker(bytes).validate();
+            return defineClassAsLookup(cfc.className(), bytes, flags, true, classData);
         }
 
         /**
          * Returns the class data associated with this lookup class.
          * If this lookup class was defined via
-         * {@link #defineClassWithClassData(byte[], Object, ClassProperty...)
-         * defineClassWithClassData(bytes, classData, properties)}
+         * {@link #defineHiddenClassWithClassData(byte[], Object, ClassOptions...)
+         * defineHiddenClassWithClassData(bytes, classData, options)}
          * then the supplied {@code classData} object is returned; otherwise,
          * {@code null}.
          *
@@ -1220,7 +1242,7 @@
          * class data as effective constants in private static final variables
          * in its class initializer.  These can be method handles, lookup objects
          * and arbitrary user objects.  For example, a class data is
-         * {@code List.of(o1, o2, o3....)} passed to {@link #defineClassWithClassData(byte[], Object, ClassProperty...)}
+         * {@code List.of(o1, o2, o3....)} passed to {@link #defineHiddenClassWithClassData(byte[], Object, ClassOptions...)}
          * where {@code <clinit>} can unpack it as follows:
          *
          * <pre>{@code
@@ -1238,7 +1260,7 @@
          * @return the class data if present; otherwise {@code null}.
          * @throws IllegalAccessException if this lookup does not have {@code PRIVATE} and {@code MODULE}access
          * @since 14
-         * @see #defineClassWithClassData(byte[], Object, ClassProperty...)
+         * @see #defineHiddenClassWithClassData(byte[], Object, ClassOptions...)
          */
         @SuppressWarnings("unchecked")
         public <T> T classData(Class<T> clazz) throws IllegalAccessException {
@@ -1248,100 +1270,113 @@
             return (T) MethodHandleNatives.classData(lookupClass);
         }
 
-        private static final ClassProperty[] EMPTY_CLASS_PROPS = new ClassProperty[0];
-
-        /*
-         * map the set of ClassProperty to VM flags
-         */
-        private static int classPropertiesToFlags(Set<ClassProperty> props) {
-            if (props.isEmpty()) return 0;
-
-            int flags = 0;
-            for (ClassProperty cp : props) {
-                flags |= cp.flag;
-                if (cp == WEAK) {
-                    // weak class property implies hidden
-                    flags |= HIDDEN.flag;
+        class ClassFileChecker extends ClassVisitor {
+            private final ClassReader reader;
+            private final String name;
+            private final int accessFlags;
+            private String exMsg;
+
+            ClassFileChecker(byte[] bytes) {
+                super(Opcodes.ASM7);
+                try {
+                    this.reader = new ClassReader(bytes);
+                    this.name = reader.getClassName();
+                    this.accessFlags = reader.getAccess();
+                    if (Modifier.isInterface(accessFlags)) {
+                        setIAE("can't define a hidden interface");
+                    }
+                    if (Modifier.isAbstract(accessFlags)) {
+                        setIAE("can't define an abstract hidden class");
+                    }
+                    if (exMsg == null) {
+                        reader.accept(this, ClassReader.SKIP_CODE|ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES);
+                    }
+                } catch (RuntimeException e) {
+                    // ASM exceptions are poorly specified
+                    ClassFormatError cfe = new ClassFormatError();
+                    cfe.initCause(e);
+                    throw cfe;
                 }
             }
-            return flags;
-        }
-
-        /**
-         * Returns the class name of the given byte stream.
-         *
-         * @throws IllegalArgumentException if it is in a different package from this lookup class.
-         */
-        private String className(byte[] bytes) {
-            // Can't use lambda during bootstrapping
-            String name;
-            try {
-                ClassReader reader = new ClassReader(bytes);
-                name = reader.getClassName();
-            } catch (RuntimeException e) {
-                // ASM exceptions are poorly specified
-                ClassFormatError cfe = new ClassFormatError();
-                cfe.initCause(e);
-                throw cfe;
+
+            String className() {
+                return name.replace('/', '.');
             }
-            // get package and class name in binary form
-            String cn, pn;
-            int index = name.lastIndexOf('/');
-            if (index == -1) { // unnamed package
-                cn = name;
-                pn = "";
-            } else {
-                cn = name.replace('/', '.');
-                pn = cn.substring(0, index);
+
+            @Override
+            public void visitNestHost(String nestHost) {
+                setIAE("can't define a hidden class with NestHost attribute");
             }
-            if (!pn.equals(lookupClass.getPackageName())) {
-                throw new IllegalArgumentException(cn + " not in same package as lookup class: " + lookupClass.getName());
+
+            @Override
+            public void visitNestMember(final String nestMember) {
+                setIAE("can't define a hidden class with NestMembers attribute");
             }
-            return cn;
+
+            @Override
+            public void visitOuterClass(String owner, String name, String desc) {
+                setIAE("can't define a hidden class with EnclosingMethod attribute");
+
+            }
+
+            @Override
+            public void visitInnerClass(String cn, String outerName, String innerName, int access) {
+                if (name.equals(cn)) {
+                    setIAE(name + " is a nested class");
+                }
+                if (name.equals(outerName)) {
+                    setIAE(name + " contains class members " + cn);
+                }
+                if (innerName == null) {
+                    setIAE(name + " encloses an anonymous class " + cn);
+                }
+            }
+
+            void setIAE(String msg) {
+                if (exMsg == null)
+                    exMsg = msg;
+            }
+
+            ClassFileChecker validate() {
+                int index = name.lastIndexOf('/');
+                String cn = className();
+                String pn = (index == -1) ? "" : cn.substring(0, index);
+                if (!pn.equals(lookupClass.getPackageName())) {
+                    throw newIllegalArgumentException(cn + " not in same package as lookup class: " + lookupClass.getName());
+                }
+                if (exMsg != null)
+                    throw newIllegalArgumentException(exMsg);
+                return this;
+            }
         }
 
         /*
          * Invoke class loader's defineClass method to define the class of
          * the given byte stream.
          */
-        private Class<?> defineClass(String cn, byte[] bytes, int flags, Object classData, boolean initialize) {
+        private Class<?> defineClass(String name, byte[] bytes, int flags, boolean initialize, Object classData) {
             ClassLoader loader = lookupClass.getClassLoader();
             ProtectionDomain pd = (loader != null) ? lookupClassProtectionDomain() : null;
-            // TODO: can't pass an illegal name for hidden class here.  Append the name with '$`
-            // for now.  VM set the external name.
-            String name = ((flags & HIDDEN_CLASS) != 0)? cn + "$$" : cn;
             Class<?> clazz = JLA.defineClass(loader, lookupClass, name, bytes, pd, initialize, flags, classData);
-            assert clazz.getClassLoader() == lookupClass.getClassLoader()
-                   && clazz.getPackageName().equals(lookupClass.getPackageName());
-
             return clazz;
         }
 
-        // package-private
-        static final int HIDDEN_NESTMATE = NESTMATE_CLASS|HIDDEN_CLASS|ACCESS_VM_ANNOTATIONS;
-        static final int WEAK_HIDDEN_NESTMATE = WEAK_CLASS|HIDDEN_NESTMATE;
-
         /*
          * Load and initialize the class of the given bytes.
          */
-        Lookup defineClassAsLookupNoCheck(byte[] bytes, int flags) {
-            return defineClassAsLookupNoCheck(className(bytes), bytes, flags);
+        private Lookup defineHiddenClassAsLookup(String name, byte[] bytes, boolean initialize, int flags) {
+            Class<?> c = defineClass(name, bytes, flags, initialize, null);
+            return new Lookup(c, FULL_POWER_MODES);
         }
 
         /*
-         * Load and initialize the class of the given bytes and the given classData
+         * Load and initialize the class of the given bytes and the given classData.
+         * Called by InvokerBytecodeGenerator and BindCaller.makeInjectedInvoker
          */
-        Lookup defineClassAsLookupNoCheck(byte[] bytes, int flags, Object classData) {
-            Class<?> c = defineClass(className(bytes), bytes, flags, classData, true);
-            int modes = (flags & NESTMATE_CLASS) != 0 ? FULL_POWER_MODES : (FULL_POWER_MODES & ~PRIVATE);
-            return new Lookup(c, modes);
-        }
-
-        // called by BindCaller.makeInjectedInvoker
-        Lookup defineClassAsLookupNoCheck(String name, byte[] bytes, int flags) {
-            Class<?> c = defineClass(name, bytes, flags, null, true);
-            int modes = (flags & NESTMATE_CLASS) != 0 ? FULL_POWER_MODES : (FULL_POWER_MODES & ~PRIVATE);
-            return new Lookup(c, modes);
+        Lookup defineClassAsLookup(String name, byte[] bytes, int flags, boolean initialize, Object classData) {
+            assert (initialize || classData == null);  // initialize must be true if classData is non-null
+            Class<?> c = defineClass(name, bytes, flags, initialize, classData);
+            return new Lookup(c, FULL_POWER_MODES);
         }
 
         private ProtectionDomain lookupClassProtectionDomain() {
@@ -2920,14 +2955,12 @@
         static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
 
         /**
-         * Class property representing the kind of classes defined by the
-         * {@link Lookup#defineClass(byte[], ClassProperty[]) Lookup::defineClass} method.
+         * Class options representing the kind of hidden classes defined by the
+         * {@link Lookup#defineHiddenClass(byte[], boolean, ClassOptions...)} method.
          *
          * @since 14
-         * @see Lookup#defineClass(byte[], ClassProperty[])
-         * @see Lookup#defineClassAsLookup(byte[], ClassProperty[])
          */
-        public enum ClassProperty {
+        public enum ClassOptions {
             /**
              * A nestmate is a class that is in the same {@linkplain Class#getNestHost nest}
              * of a lookup class.  It has access to the private members of all
@@ -2938,21 +2971,9 @@
             NESTMATE(NESTMATE_CLASS),
 
             /**
-             * A hidden class is a class that cannot be symbolically referenced by other
-             * classes.  A Java Virtual Machine implementation may hide
-             * the hidden frames from {@linkplain Throwable#getStackTrace()
-             * stack traces}.
-             *
-             * @see Class#isHiddenClass()
-             * @see StackWalker.Option#SHOW_HIDDEN_FRAMES
-             */
-            HIDDEN(HIDDEN_CLASS),
-
-            /**
              * A weak class is a class that may be unloaded independently with
              * its defining class loader when it becomes
              * <a href="../ref/package.html#reachability">reachable</a>.
-             * A weak class is {@linkplain #HIDDEN hidden}.
              *
              * @jls 12.7 Unloading of Classes and Interfaces
              */
@@ -2960,7 +2981,7 @@
 
             /* the flag value is used by VM at define class time */
             private final int flag;
-            ClassProperty(int flag) {
+            ClassOptions(int flag) {
                 this.flag = flag;
             }
         }
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Aug 29 19:32:19 2019 -0700
@@ -25,7 +25,8 @@
 
 package java.lang.invoke;
 
-import jdk.internal.misc.Unsafe;
+import jdk.internal.access.JavaLangAccess;
+import jdk.internal.access.SharedSecrets;
 import jdk.internal.misc.VM;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Label;
@@ -42,7 +43,9 @@
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.Function;
 
-import static java.lang.invoke.MethodHandles.Lookup.*;
+import static java.lang.invoke.MethodHandles.lookup;
+import static java.lang.invoke.MethodType.methodType;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 /**
@@ -134,6 +137,8 @@
      */
     private static final Strategy DEFAULT_STRATEGY = Strategy.MH_INLINE_SIZED_EXACT;
 
+    private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
+
     private enum Strategy {
         /**
          * Bytecode generator, calling into {@link java.lang.StringBuilder}.
@@ -190,8 +195,6 @@
      */
     private static final ProxyClassesDumper DUMPER;
 
-    private static final Class<?> STRING_HELPER;
-
     static {
         // In case we need to double-back onto the StringConcatFactory during this
         // static initialization, make sure we have the reasonable defaults to complete
@@ -203,12 +206,6 @@
         // DEBUG = false;        // implied
         // DUMPER = null;        // implied
 
-        try {
-            STRING_HELPER = Class.forName("java.lang.StringConcatHelper");
-        } catch (Throwable e) {
-            throw new AssertionError(e);
-        }
-
         final String strategy =
                 VM.getSavedProperty("java.lang.invoke.stringConcat");
         CACHE_ENABLE = Boolean.parseBoolean(
@@ -724,8 +721,7 @@
           However, there are two peculiarities:
 
            a) The generated class should stay within the same package as the
-              host class, to allow Unsafe.defineAnonymousClass access controls
-              to work properly. JDK may choose to fail with IllegalAccessException
+              host class. JDK may choose to fail with IllegalAccessException
               when accessing a VM anonymous class with non-privileged callers,
               see JDK-8058575.
 
@@ -748,7 +744,9 @@
                     String pkgName = hostClass.getPackageName();
                     return (pkgName != null && !pkgName.isEmpty() ? pkgName.replace('.', '/') + "/" : "") + "Stubs$$StringConcat";
                 } else {
-                    return hostClass.getName().replace('.', '/') + "$$StringConcat";
+                    String name = hostClass.isHiddenClass() ? hostClass.getName().replace('/', '_')
+                                                            : hostClass.getName();
+                    return name.replace('.', '/') + "$$StringConcat";
                 }
             }
             case MH_SB_SIZED:
@@ -820,7 +818,7 @@
      * chain javac would otherwise emit. This strategy uses only the public API,
      * and comes as the baseline for the current JDK behavior. On other words,
      * this strategy moves the javac generated bytecode to runtime. The
-     * generated bytecode is loaded via Unsafe.defineAnonymousClass, but with
+     * generated bytecode is loaded via Lookup::defineClass, but with
      * the caller class coming from the BSM -- in other words, the protection
      * guarantees are inherited from the method where invokedynamic was
      * originally called. This means, among other things, that the bytecode is
@@ -849,7 +847,6 @@
      * private String API.
      */
     private static final class BytecodeStringBuilderStrategy {
-        static final Unsafe UNSAFE = Unsafe.getUnsafe();
         static final int CLASSFILE_VERSION = 52;
         static final String METHOD_NAME = "concat";
 
@@ -862,7 +859,7 @@
 
             cw.visit(CLASSFILE_VERSION,
                     ACC_SUPER + ACC_PUBLIC + ACC_FINAL + ACC_SYNTHETIC,
-                    className,  // Unsafe.defineAnonymousClass would append an unique ID
+                    className,
                     null,
                     "java/lang/Object",
                     null
@@ -1144,9 +1141,10 @@
 
             byte[] classBytes = cw.toByteArray();
             try {
-                Lookup innerClassLookup = lookup.defineClassAsLookupNoCheck(classBytes, HIDDEN_NESTMATE);
+                // may use @ForceInline; use internal defineClassAsLookup
+                Lookup innerClassLookup = lookup.defineClassAsLookup(className, classBytes, HIDDEN_CLASS|ACCESS_VM_ANNOTATIONS, true, null);
                 Class<?> innerClass = innerClassLookup.lookupClass();
-                dumpIfEnabled(innerClass.getName(), classBytes);
+                dumpIfEnabled(className, classBytes);
                 return innerClassLookup.findStatic(innerClass, METHOD_NAME, args);
             } catch (Exception e) {
                 dumpIfEnabled(className + "$$FAILED", classBytes);
@@ -1270,8 +1268,8 @@
      * computation on MethodHandle combinators. The computation is built with
      * public MethodHandle APIs, resolved from a public Lookup sequence, and
      * ends up calling the public StringBuilder API. Therefore, this strategy
-     * does not use any private API at all, even the Unsafe.defineAnonymousClass,
-     * since everything is handled under cover by java.lang.invoke APIs.
+     * does not use any private API at all since everything is handled under
+     * cover by java.lang.invoke APIs.
      *
      * <p><b>{@link Strategy#MH_SB_SIZED_EXACT}: "MethodHandles StringBuilder,
      * sized exactly".</b>
@@ -1283,7 +1281,6 @@
      * private String API.
      */
     private static final class MethodHandleStringBuilderStrategy {
-
         private MethodHandleStringBuilderStrategy() {
             // no instantiation
         }
@@ -1461,6 +1458,8 @@
             return sum;
         }
 
+        private static final Lookup MHSBS_LOOKUP = lookup();
+
         private static final ConcurrentMap<Integer, MethodHandle> SUMMERS;
 
         // This one is deliberately non-lambdified to optimize startup time:
@@ -1474,9 +1473,9 @@
                     // unroll some initial sizes.
                     Class<?>[] cls = new Class<?>[cnt];
                     Arrays.fill(cls, int.class);
-                    return lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleStringBuilderStrategy.class, "sum", int.class, cls);
+                    return lookupStatic(MHSBS_LOOKUP, MethodHandleStringBuilderStrategy.class, "sum", int.class, cls);
                 } else {
-                    return lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleStringBuilderStrategy.class, "sum", int.class, int.class, int[].class)
+                    return lookupStatic(MHSBS_LOOKUP, MethodHandleStringBuilderStrategy.class, "sum", int.class, int.class, int[].class)
                             .asCollector(int[].class, cnt - 1);
                 }
             }
@@ -1491,8 +1490,8 @@
             STRING_LENGTH = lookupVirtual(publicLookup, String.class, "length", int.class);
             BUILDER_TO_STRING = lookupVirtual(publicLookup, StringBuilder.class, "toString", String.class);
             if (DEBUG) {
-                BUILDER_TO_STRING_CHECKED = lookupStatic(MethodHandles.Lookup.IMPL_LOOKUP,
-                        MethodHandleStringBuilderStrategy.class, "toStringChecked", String.class, StringBuilder.class);
+                BUILDER_TO_STRING_CHECKED = lookupStatic(MHSBS_LOOKUP, MethodHandleStringBuilderStrategy.class,
+                        "toStringChecked", String.class, StringBuilder.class);
             } else {
                 BUILDER_TO_STRING_CHECKED = null;
             }
@@ -1516,8 +1515,6 @@
      * that requires porting if there are private JDK changes occur.
      */
     private static final class MethodHandleInlineCopyStrategy {
-        static final Unsafe UNSAFE = Unsafe.getUnsafe();
-
         private MethodHandleInlineCopyStrategy() {
             // no instantiation
         }
@@ -1736,8 +1733,9 @@
         private static final Function<Class<?>, MethodHandle> PREPEND = new Function<>() {
             @Override
             public MethodHandle apply(Class<?> c) {
-                return lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "prepend", long.class, long.class, byte[].class,
-                        String.class, Wrapper.asPrimitiveType(c), String.class);
+                return JLA.stringConcatHelper("prepend",
+                            methodType(long.class, long.class, byte[].class,
+                                       String.class, Wrapper.asPrimitiveType(c), String.class));
             }
         };
 
@@ -1745,8 +1743,7 @@
         private static final Function<Class<?>, MethodHandle> MIX = new Function<>() {
             @Override
             public MethodHandle apply(Class<?> c) {
-                return lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "mix", long.class, long.class,
-                        Wrapper.asPrimitiveType(c));
+                return JLA.stringConcatHelper("mix", methodType(long.class, long.class, Wrapper.asPrimitiveType(c)));
             }
         };
 
@@ -1759,7 +1756,7 @@
 
         static {
             try {
-                MethodHandle initCoder = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "initialCoder", long.class);
+                MethodHandle initCoder = JLA.stringConcatHelper("initialCoder", methodType(long.class));
                 INITIAL_CODER = (long) initCoder.invoke();
             } catch (Throwable e) {
                 throw new AssertionError(e);
@@ -1768,9 +1765,9 @@
             PREPENDERS = new ConcurrentHashMap<>();
             MIXERS = new ConcurrentHashMap<>();
 
-            SIMPLE     = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "simpleConcat", String.class, Object.class, Object.class);
-            NEW_STRING = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newString", String.class, byte[].class, long.class);
-            NEW_ARRAY  = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newArray", byte[].class, long.class);
+            SIMPLE     = JLA.stringConcatHelper("simpleConcat", methodType(String.class, Object.class, Object.class));
+            NEW_STRING = JLA.stringConcatHelper("newString", methodType(String.class, byte[].class, long.class));
+            NEW_ARRAY  = JLA.stringConcatHelper( "newArray", methodType(byte[].class, long.class));
         }
     }
 
@@ -1784,7 +1781,7 @@
         }
 
         private static final MethodHandle OBJECT_INSTANCE =
-            lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "stringOf", String.class, Object.class);
+                JLA.stringConcatHelper("stringOf", methodType(String.class, Object.class));
 
         private static class FloatStringifiers {
             private static final MethodHandle FLOAT_INSTANCE =
--- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Thu Aug 29 19:32:19 2019 -0700
@@ -292,13 +292,26 @@
             throw new IllegalCallerException();   // should not happen
         }
 
+        Module callerModule = caller.getModule();
+        Module declaringModule = declaringClass.getModule();
+
         if (declaringClass.isHiddenClass()) {
+            if (callerModule == Object.class.getModule()) return true;
+            if (throwExceptionIfDenied) {
+                // not accessible
+                String msg = "Unable to make ";
+                if (this instanceof Field)
+                    msg += "field ";
+                msg += this + " accessible";
+                InaccessibleObjectException e = new InaccessibleObjectException(msg);
+                if (printStackTraceWhenAccessFails()) {
+                    e.printStackTrace(System.err);
+                }
+                throw e;
+            }
             return false;
         }
 
-        Module callerModule = caller.getModule();
-        Module declaringModule = declaringClass.getModule();
-
         if (callerModule == declaringModule) return true;
         if (callerModule == Object.class.getModule()) return true;
         if (!declaringModule.isNamed()) return true;
--- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java	Thu Aug 29 19:32:19 2019 -0700
@@ -26,6 +26,8 @@
 package jdk.internal.access;
 
 import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
 import java.lang.module.ModuleDescriptor;
 import java.lang.reflect.Executable;
 import java.lang.reflect.Method;
@@ -324,4 +326,9 @@
      * @param cause set t's cause to new value
      */
     void setCause(Throwable t, Throwable cause);
+
+    /**
+     * Get a method handle of string concat helper method
+     */
+    MethodHandle stringConcatHelper(String name, MethodType methodType);
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Thu Aug 29 19:32:19 2019 -0700
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
 import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
 import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION;
 import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
@@ -41,6 +41,7 @@
 import java.io.PrintWriter;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup.ClassOptions;
 import java.lang.invoke.MethodType;
 import java.lang.invoke.SwitchPoint;
 import java.lang.ref.ReferenceQueue;
@@ -67,7 +68,6 @@
 import java.security.ProtectionDomain;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
@@ -84,10 +84,12 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javax.script.ScriptEngine;
+
 import jdk.dynalink.DynamicLinker;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
 import jdk.nashorn.api.scripting.ClassFilter;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
@@ -108,7 +110,6 @@
 import jdk.nashorn.internal.runtime.logging.Logger;
 import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
 import jdk.nashorn.internal.runtime.options.Options;
-import jdk.internal.misc.Unsafe;
 
 /**
  * This class manages the global state of execution. Context is immutable.
@@ -318,21 +319,38 @@
     private final WeakValueCache<CodeSource, Class<?>> anonymousHostClasses = new WeakValueCache<>();
 
     private static final class AnonymousContextCodeInstaller extends ContextCodeInstaller {
-        private static final Unsafe UNSAFE = Unsafe.getUnsafe();
         private static final String ANONYMOUS_HOST_CLASS_NAME = Compiler.SCRIPTS_PACKAGE.replace('/', '.') + ".AnonymousHost";
         private static final byte[] ANONYMOUS_HOST_CLASS_BYTES = getAnonymousHostClassBytes();
 
-        private final Class<?> hostClass;
+        private final MethodHandles.Lookup hostLookup;
 
         private AnonymousContextCodeInstaller(final Context context, final CodeSource codeSource, final Class<?> hostClass) {
             super(context, codeSource);
-            this.hostClass = hostClass;
+            this.hostLookup = (MethodHandles.Lookup)staticFieldValue(hostClass, "LOOKUP");
+        }
+
+        private static Object staticFieldValue(Class<?> c, String name) {
+            try {
+                return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+                        @Override
+                        public Object run() throws Exception {
+                            Field f = c.getDeclaredField(name);
+                            return f.get(null);
+                        }
+                });
+            } catch (PrivilegedActionException e) {
+                throw new InternalError(e.getCause());
+            }
         }
 
         @Override
         public Class<?> install(final String className, final byte[] bytecode) {
-            ANONYMOUS_INSTALLED_SCRIPT_COUNT.increment();
-            return UNSAFE.defineAnonymousClass(hostClass, bytecode, null);
+            try {
+                ANONYMOUS_INSTALLED_SCRIPT_COUNT.increment();
+                return hostLookup.defineHiddenClass(bytecode, false, ClassOptions.WEAK);
+            } catch (IllegalAccessException e) {
+                throw new InternalError(e);
+            }
         }
 
         @Override
@@ -350,8 +368,27 @@
         }
 
         private static byte[] getAnonymousHostClassBytes() {
+            // Workaround: define a host class in a non-exported package.
+            // This should be replaced when there is a mechanism to define
+            // a hidden class in a given package of a given module.
             final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
-            cw.visit(V1_7, Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, ANONYMOUS_HOST_CLASS_NAME.replace('.', '/'), null, "java/lang/Object", null);
+            final String cn = ANONYMOUS_HOST_CLASS_NAME.replace('.', '/');
+            cw.visit(V13, ACC_PUBLIC|ACC_INTERFACE |ACC_ABSTRACT, cn, null, "java/lang/Object", null);
+            {
+                FieldVisitor fv = cw.visitField(ACC_PUBLIC|ACC_STATIC|ACC_FINAL, "LOOKUP",
+                        "Ljava/lang/invoke/MethodHandles$Lookup;", null, null);
+                fv.visitEnd();
+            }
+            {
+                MethodVisitor mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+                mv.visitCode();
+                mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup",
+                        "()Ljava/lang/invoke/MethodHandles$Lookup;", false);
+                mv.visitFieldInsn(PUTSTATIC, cn, "LOOKUP", "Ljava/lang/invoke/MethodHandles$Lookup;");
+                mv.visitInsn(RETURN);
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
             cw.visitEnd();
             return cw.toByteArray();
         }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java	Thu Aug 29 19:32:19 2019 -0700
@@ -74,7 +74,8 @@
                     .requires("java.logging")
                     .requires(NASHORN_MODULE.getName())
                     .requires(structMod.getName())
-                    .packages(Set.of(SCRIPTS_PKG));
+                    .packages(Set.of(SCRIPTS_PKG))
+                    .exports(SCRIPTS_PKG, Set.of(NASHORN_MODULE.getName()));
 
         if (Context.javaSqlFound) {
             builder.requires("java.sql");
--- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java	Thu Aug 29 19:32:19 2019 -0700
@@ -822,9 +822,8 @@
      * <li>InterfaceMethodRef: (NYI) a method handle to invoke on that call site's arguments
      * </ul>
      *
-     * @deprecated Use the {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty...)}
-     * and {@link java.lang.invoke.MethodHandles.Lookup#defineClassWithClassData(byte[], Object, MethodHandles.Lookup.ClassProperty...)}
-     * methods instead.
+     * @deprecated Use the {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOptions...)}
+     * method.
      *
      * @param hostClass context for linkage, access control, protection domain, and class loader
      * @param data      bytes of a class file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/cha/ObjectHashCode.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package compiler.cha;
+
+import static compiler.cha.StrengthReduceInterfaceCall.*;
+
+public class ObjectHashCode extends ATest<ObjectHashCode.I> {
+    public ObjectHashCode() {
+        super(I.class, C.class);
+    }
+
+    interface J {}
+    interface I extends J {}
+
+    static class C implements I {}
+
+    interface K1 extends I {}
+    interface K2 extends I { int hashCode(); } // K2.hC() ABSTRACT
+    // interface K3 extends I { default int hashCode() { return CORRECT; } // K2.hC() DEFAULT
+
+    static class D implements I { public int hashCode() { return super.hashCode(); }}
+
+    static class DJ1 implements J {}
+    static class DJ2 implements J { public int hashCode() { return super.hashCode(); }}
+
+    @Override
+    public Object test(I i) {
+        return ObjectHashCodeHelper.test(i); /* invokeinterface I.hashCode() */
+    }
+
+    @TestCase
+    public void testMono() {
+        // 0. Trigger compilation of a monomorphic call site
+        compile(monomophic()); // C1 <: C <: intf I <: intf J <: Object.hashCode()
+        assertCompiled();
+
+        // Dependency: none
+
+        call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
+        assertCompiled();
+    }
+
+    @TestCase
+    public void testBi() {
+        // 0. Trigger compilation of a bimorphic call site
+        compile(bimorphic()); // C1 <: C <: intf I <: intf J <: Object.toString()
+        assertCompiled();
+
+        // Dependency: none
+
+        call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
+        assertCompiled();
+    }
+
+    @TestCase
+    public void testMega() {
+        // 0. Trigger compilation of a megamorphic call site
+        compile(megamorphic()); // C1,C2,C3 <: C <: intf I <: intf J <: Object.hashCode()
+        assertCompiled();
+
+        // Dependency: none
+
+        // No dependency - no invalidation
+        repeat(100, () -> call(new C(){})); // Cn <: C <: intf I
+        assertCompiled();
+
+        initialize(K1.class,   // intf  K1             <: intf I <: intf J
+                   K2.class,   // intf  K2.hC ABSTRACT <: intf I <: intf J
+                   DJ1.class,  //      DJ1                       <: intf J
+                   DJ2.class); //      DJ2.hC                    <: intf J
+        assertCompiled();
+
+        initialize(D.class); // D.hC <: intf I <: intf J
+        assertCompiled();
+
+        call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
+        assertCompiled();
+    }
+
+    @Override
+    public void checkInvalidReceiver() {
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+            test(o);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
+            test(j);
+        });
+        assertCompiled();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/cha/ObjectToString.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package compiler.cha;
+
+import static compiler.cha.StrengthReduceInterfaceCall.*;
+
+public class ObjectToString extends ATest<ObjectToString.I> {
+    public ObjectToString() {
+        super(I.class, C.class);
+    }
+
+    interface J           { String toString(); }
+    interface I extends J {}
+
+    static class C implements I {}
+
+    interface K1 extends I {}
+    interface K2 extends I { String toString(); } // K2.tS() ABSTRACT
+    // interface K3 extends I { default String toString() { return "K3"; } // K2.tS() DEFAULT
+
+    static class D implements I { public String toString() { return "D"; }}
+
+    static class DJ1 implements J {}
+    static class DJ2 implements J { public String toString() { return "DJ2"; }}
+
+    @Override
+    public Object test(I i) { return ObjectToStringHelper.test(i); /* invokeinterface I.toString() */ }
+
+    @TestCase
+    public void testMono() {
+        // 0. Trigger compilation of a monomorphic call site
+        compile(monomophic()); // C1 <: C <: intf I <: intf J <: Object.toString()
+        assertCompiled();
+
+        // Dependency: none
+
+        call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
+        assertCompiled();
+    }
+
+    @TestCase
+    public void testBi() {
+        // 0. Trigger compilation of a bimorphic call site
+        compile(bimorphic()); // C1 <: C <: intf I <: intf J <: Object.toString()
+        assertCompiled();
+
+        // Dependency: none
+
+        call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
+        assertCompiled();
+    }
+
+    @TestCase
+    public void testMega() {
+        // 0. Trigger compilation of a megamorphic call site
+        compile(megamorphic()); // C1,C2,C3 <: C <: intf I <: intf J <: Object.toString()
+        assertCompiled();
+
+        // Dependency: none
+        // compiler.cha.StrengthReduceInterfaceCall$ObjectToString::test (5 bytes)
+        //     @ 1   compiler.cha.StrengthReduceInterfaceCall$ObjectToStringHelper::test (7 bytes)   inline (hot)
+        //       @ 1   java.lang.Object::toString (36 bytes)   virtual call
+
+        // No dependency - no invalidation
+        repeat(100, () -> call(new C(){})); // Cn <: C <: intf I
+        assertCompiled();
+
+        initialize(K1.class,   // intf  K1             <: intf I <: intf J
+                   K2.class,   // intf  K2.tS ABSTRACT <: intf I <: intf J
+                   DJ1.class,  //      DJ1                       <: intf J
+                   DJ2.class); //      DJ2.tS                    <: intf J
+        assertCompiled();
+
+        initialize(D.class); // D.tS <: intf I <: intf J
+        assertCompiled();
+
+        call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
+        assertCompiled();
+    }
+
+    @Override
+    public void checkInvalidReceiver() {
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+            test(o);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
+            test(j);
+        });
+        assertCompiled();
+    }
+}
+
+
--- a/test/hotspot/jtreg/compiler/cha/StrengthReduceInterfaceCall.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/test/hotspot/jtreg/compiler/cha/StrengthReduceInterfaceCall.java	Thu Aug 29 19:32:19 2019 -0700
@@ -79,614 +79,6 @@
         run(ThreeLevelDefaultHierarchy1.class);
     }
 
-    public static class ObjectToString extends ATest<ObjectToString.I> {
-        public ObjectToString() { super(I.class, C.class); }
-
-        interface J           { String toString(); }
-        interface I extends J {}
-
-        static class C implements I {}
-
-        interface K1 extends I {}
-        interface K2 extends I { String toString(); } // K2.tS() ABSTRACT
-        // interface K3 extends I { default String toString() { return "K3"; } // K2.tS() DEFAULT
-
-        static class D implements I { public String toString() { return "D"; }}
-
-        static class DJ1 implements J {}
-        static class DJ2 implements J { public String toString() { return "DJ2"; }}
-
-        @Override
-        public Object test(I i) { return ObjectToStringHelper.test(i); /* invokeinterface I.toString() */ }
-
-        @TestCase
-        public void testMono() {
-            // 0. Trigger compilation of a monomorphic call site
-            compile(monomophic()); // C1 <: C <: intf I <: intf J <: Object.toString()
-            assertCompiled();
-
-            // Dependency: none
-
-            call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
-            assertCompiled();
-        }
-
-        @TestCase
-        public void testBi() {
-            // 0. Trigger compilation of a bimorphic call site
-            compile(bimorphic()); // C1 <: C <: intf I <: intf J <: Object.toString()
-            assertCompiled();
-
-            // Dependency: none
-
-            call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
-            assertCompiled();
-        }
-
-        @TestCase
-        public void testMega() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C <: intf I <: intf J <: Object.toString()
-            assertCompiled();
-
-            // Dependency: none
-            // compiler.cha.StrengthReduceInterfaceCall$ObjectToString::test (5 bytes)
-            //     @ 1   compiler.cha.StrengthReduceInterfaceCall$ObjectToStringHelper::test (7 bytes)   inline (hot)
-            //       @ 1   java.lang.Object::toString (36 bytes)   virtual call
-
-            // No dependency - no invalidation
-            repeat(100, () -> call(new C(){})); // Cn <: C <: intf I
-            assertCompiled();
-
-            initialize(K1.class,   // intf  K1             <: intf I <: intf J
-                       K2.class,   // intf  K2.tS ABSTRACT <: intf I <: intf J
-                       DJ1.class,  //      DJ1                       <: intf J
-                       DJ2.class); //      DJ2.tS                    <: intf J
-            assertCompiled();
-
-            initialize(D.class); // D.tS <: intf I <: intf J
-            assertCompiled();
-
-            call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ObjectHashCode extends ATest<ObjectHashCode.I> {
-        public ObjectHashCode() { super(I.class, C.class); }
-
-        interface J {}
-        interface I extends J {}
-
-        static class C implements I {}
-
-        interface K1 extends I {}
-        interface K2 extends I { int hashCode(); } // K2.hC() ABSTRACT
-        // interface K3 extends I { default int hashCode() { return CORRECT; } // K2.hC() DEFAULT
-
-        static class D implements I { public int hashCode() { return super.hashCode(); }}
-
-        static class DJ1 implements J {}
-        static class DJ2 implements J { public int hashCode() { return super.hashCode(); }}
-
-        @Override
-        public Object test(I i) {
-            return ObjectHashCodeHelper.test(i); /* invokeinterface I.hashCode() */
-        }
-
-        @TestCase
-        public void testMono() {
-            // 0. Trigger compilation of a monomorphic call site
-            compile(monomophic()); // C1 <: C <: intf I <: intf J <: Object.hashCode()
-            assertCompiled();
-
-            // Dependency: none
-
-            call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
-            assertCompiled();
-        }
-
-        @TestCase
-        public void testBi() {
-            // 0. Trigger compilation of a bimorphic call site
-            compile(bimorphic()); // C1 <: C <: intf I <: intf J <: Object.toString()
-            assertCompiled();
-
-            // Dependency: none
-
-            call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
-            assertCompiled();
-        }
-
-        @TestCase
-        public void testMega() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C <: intf I <: intf J <: Object.hashCode()
-            assertCompiled();
-
-            // Dependency: none
-
-            // No dependency - no invalidation
-            repeat(100, () -> call(new C(){})); // Cn <: C <: intf I
-            assertCompiled();
-
-            initialize(K1.class,   // intf  K1             <: intf I <: intf J
-                       K2.class,   // intf  K2.hC ABSTRACT <: intf I <: intf J
-                       DJ1.class,  //      DJ1                       <: intf J
-                       DJ2.class); //      DJ2.hC                    <: intf J
-            assertCompiled();
-
-            initialize(D.class); // D.hC <: intf I <: intf J
-            assertCompiled();
-
-            call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class TwoLevelHierarchyLinear extends ATest<TwoLevelHierarchyLinear.I> {
-        public TwoLevelHierarchyLinear() { super(I.class, C.class); }
-
-        interface J { default Object m() { return WRONG; } }
-
-        interface I extends J { Object m(); }
-        static class C implements I { public Object m() { return CORRECT; }}
-
-        interface K1 extends I {}
-        interface K2 extends I { Object m(); }
-        interface K3 extends I { default Object m() { return WRONG; }}
-
-        static class D implements I { public Object m() { return WRONG;   }}
-
-        static class DJ1 implements J {}
-        static class DJ2 implements J { public Object m() { return WRONG; }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m();
-        }
-
-        @TestCase
-        public void testMega1() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m ABSTRACT <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check is preserved
-
-            // 1. No deoptimization/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertCompiled();
-
-            // 2. No dependency invalidation on class loading of unrelated classes: different context
-            initialize(K1.class,   // intf  K1            <: intf I.m ABSTRACT <: intf J.m DEFAULT
-                       K2.class,   // intf  K2.m ABSTRACT <: intf I.m ABSTRACT <: intf J.m DEFAULT
-                       DJ1.class,  //      DJ1                                 <: intf J.m DEFAULT
-                       DJ2.class); //      DJ2.m                               <: intf J.m DEFAULT
-            assertCompiled();
-
-            // 3. Dependency invalidation on D <: I
-            initialize(D.class); // D.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertNotCompiled();
-
-            // 4. Recompilation: no inlining, no dependencies
-            compile(megamorphic());
-            call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertCompiled();
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        @TestCase
-        public void testMega2() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. Dependency invalidation
-            initialize(K3.class); // intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertNotCompiled();
-
-            // 2. Recompilation: still inlines
-            // FIXME: no default method support in CHA yet
-            compile(megamorphic());
-            call(new K3() { public Object m() { return CORRECT; }}); // K3n.m <: intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m ABSTRACT
-            assertNotCompiled();
-
-            // 3. Recompilation: no inlining, no dependencies
-            compile(megamorphic());
-            call(new K3() { public Object m() { return CORRECT; }}); // Kn.m <: intf K3.m DEFAULT  <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertCompiled();
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ThreeLevelHierarchyLinear extends ATest<ThreeLevelHierarchyLinear.I> {
-        public ThreeLevelHierarchyLinear() { super(I.class, C.class); }
-
-        interface J           { Object m(); }
-        interface I extends J {}
-
-        interface K1 extends I {}
-        interface K2 extends I { Object m(); }
-        interface K3 extends I { default Object m() { return WRONG; }}
-
-        static class C  implements I { public Object m() { return CORRECT; }}
-
-        static class DI implements I { public Object m() { return WRONG;   }}
-        static class DJ implements J { public Object m() { return WRONG;   }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m(); // I <: J.m ABSTRACT
-        }
-
-        @TestCase
-        public void testMega1() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No deoptimization/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I
-            assertCompiled(); // No deopt on not-yet-seen receiver
-
-            // 2. No dependency invalidation: different context
-            initialize(DJ.class,  //      DJ.m                    <: intf J.m ABSTRACT
-                       K1.class,  // intf K1            <: intf I <: intf J.m ABSTRACT
-                       K2.class); // intf K2.m ABSTRACT <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // 3. Dependency invalidation: DI.m <: I
-            initialize(DI.class); //      DI.m          <: intf I <: intf J.m ABSTRACT
-            assertNotCompiled();
-
-            // 4. Recompilation w/o a dependency
-            compile(megamorphic());
-            call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled(); // no dependency
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        @TestCase
-        public void testMega2() {
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // Dependency invalidation
-            initialize(K3.class); // intf K3.m DEFAULT <: intf I;
-            assertNotCompiled(); // FIXME: default methods in sub-interfaces shouldn't be taken into account by CHA
-
-            // Recompilation with a dependency
-            compile(megamorphic());
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            call(new K3() { public Object m() { return CORRECT; }}); // Kn.m <: K3.m DEFAULT <: intf I <: intf J.m ABSTRACT
-            assertNotCompiled();
-
-            // Recompilation w/o a dependency
-            compile(megamorphic());
-            // Dependency: none
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-            call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() { public Object m() { return WRONG; }}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ThreeLevelHierarchyAbstractVsDefault extends ATest<ThreeLevelHierarchyAbstractVsDefault.I> {
-        public ThreeLevelHierarchyAbstractVsDefault() { super(I.class, C.class); }
-
-        interface J1                { default Object m() { return WRONG; } } // intf J1.m DEFAULT
-        interface J2 extends J1     { Object m(); }                          // intf J2.m ABSTRACT <: intf J1
-        interface I  extends J1, J2 {}                                       // intf  I.m OVERPASS <: intf J1,J2
-
-        static class C  implements I { public Object m() { return CORRECT; }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m(); // intf I.m OVERPASS
-        }
-
-        static class DI implements I { public Object m() { return WRONG;   }}
-
-        static class DJ11 implements J1 {}
-        static class DJ12 implements J1 { public Object m() { return WRONG; }}
-
-        static class DJ2 implements J2 { public Object m() { return WRONG;   }}
-
-        interface K11 extends J1 {}
-        interface K12 extends J1 { Object m(); }
-        interface K13 extends J1 { default Object m() { return WRONG; }}
-        interface K21 extends J2 {}
-        interface K22 extends J2 { Object m(); }
-        interface K23 extends J2 { default Object m() { return WRONG; }}
-
-
-        public void testMega1() {
-            // 0. Trigger compilation of megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No deopt/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
-            assertCompiled();
-
-            // 2. No dependency invalidation: different context
-            initialize(K11.class, K12.class, K13.class,
-                       K21.class, K22.class, K23.class);
-
-            // 3. Dependency invalidation: Cn.m <: C <: I
-            call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
-            assertNotCompiled();
-
-            // 4. Recompilation w/o a dependency
-            compile(megamorphic());
-            call(new C() { public Object m() { return CORRECT; }});
-            assertCompiled(); // no inlining
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        public void testMega2() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic());
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No dependency invalidation: different context
-            initialize(DJ11.class,
-                       DJ12.class,
-                       DJ2.class);
-            assertCompiled();
-
-            // 2. Dependency invalidation: DI.m <: I
-            initialize(DI.class);
-            assertNotCompiled();
-
-            // 3. Recompilation w/o a dependency
-            compile(megamorphic());
-            call(new C() { public Object m() { return CORRECT; }});
-            assertCompiled(); // no inlining
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J1() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J2() { public Object m() { return WRONG; }}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ThreeLevelDefaultHierarchy extends ATest<ThreeLevelDefaultHierarchy.I> {
-        public ThreeLevelDefaultHierarchy() { super(I.class, C.class); }
-
-        interface J           { default Object m() { return WRONG; }}
-        interface I extends J {}
-
-        static class C  implements I { public Object m() { return CORRECT; }}
-
-        interface K1 extends I {}
-        interface K2 extends I { Object m(); }
-        interface K3 extends I { default Object m() { return WRONG; }}
-
-        static class DI implements I { public Object m() { return WRONG; }}
-        static class DJ implements J { public Object m() { return WRONG; }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m(); // no inlining since J.m is a default method
-        }
-
-        @TestCase
-        public void testMega() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // Dependency: none
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No deoptimization/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C() {}));
-            assertCompiled();
-
-            // 2. No dependency and no inlining
-            initialize(DJ.class,  //      DJ.m                    <: intf J.m ABSTRACT
-                       DI.class,  //      DI.m          <: intf I <: intf J.m ABSTRACT
-                       K1.class,  // intf K1            <: intf I <: intf J.m ABSTRACT
-                       K2.class); // intf K2.m ABSTRACT <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ThreeLevelDefaultHierarchy1 extends ATest<ThreeLevelDefaultHierarchy1.I> {
-        public ThreeLevelDefaultHierarchy1() { super(I.class, C.class); }
-
-        interface J1                { Object m();}
-        interface J2 extends J1     { default Object m() { return WRONG; }  }
-        interface I  extends J1, J2 {}
-
-        static class C  implements I { public Object m() { return CORRECT; }}
-
-        interface K1 extends I {}
-        interface K2 extends I { Object m(); }
-        interface K3 extends I { default Object m() { return WRONG; }}
-
-        static class DI implements I { public Object m() { return WRONG; }}
-        static class DJ1 implements J1 { public Object m() { return WRONG; }}
-        static class DJ2 implements J2 { public Object m() { return WRONG; }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m(); // no inlining since J.m is a default method
-        }
-
-        @TestCase
-        public void testMega() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic());
-            assertCompiled();
-
-            // Dependency: none
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No deoptimization/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C() {}));
-            assertCompiled();
-
-            // 2. No dependency, no inlining
-            // CHA doesn't support default methods yet.
-            initialize(DJ1.class,
-                       DJ2.class,
-                       DI.class,
-                       K1.class,
-                       K2.class,
-                       K3.class);
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J1() { public Object m() { return WRONG; } }); // super interface
-                test(j);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J2() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
     /* =========================================================== */
 
     interface Action {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/cha/ThreeLevelDefaultHierarchy.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package compiler.cha;
+
+import jdk.internal.vm.annotation.DontInline;
+import static compiler.cha.StrengthReduceInterfaceCall.*;
+
+public class ThreeLevelDefaultHierarchy extends ATest<ThreeLevelDefaultHierarchy.I> {
+    public ThreeLevelDefaultHierarchy() {
+        super(I.class, C.class);
+    }
+
+    interface J           { default Object m() { return WRONG; }}
+    interface I extends J {}
+
+    static class C  implements I { public Object m() { return CORRECT; }}
+
+    interface K1 extends I {}
+    interface K2 extends I { Object m(); }
+    interface K3 extends I { default Object m() { return WRONG; }}
+
+    static class DI implements I { public Object m() { return WRONG; }}
+    static class DJ implements J { public Object m() { return WRONG; }}
+
+    @DontInline
+    public Object test(I i) {
+        return i.m(); // no inlining since J.m is a default method
+    }
+
+    @TestCase
+    public void testMega() {
+        // 0. Trigger compilation of a megamorphic call site
+        compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
+        assertCompiled();
+
+        // Dependency: none
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+        // 1. No deoptimization/invalidation on not-yet-seen receiver
+        repeat(100, () -> call(new C() {}));
+        assertCompiled();
+
+        // 2. No dependency and no inlining
+        initialize(DJ.class,  //      DJ.m                    <: intf J.m ABSTRACT
+                   DI.class,  //      DI.m          <: intf I <: intf J.m ABSTRACT
+                   K1.class,  // intf K1            <: intf I <: intf J.m ABSTRACT
+                   K2.class); // intf K2.m ABSTRACT <: intf I <: intf J.m ABSTRACT
+        assertCompiled();
+    }
+
+    @Override
+    public void checkInvalidReceiver() {
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+            test(o);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object) new J() {
+            }); // super interface
+            test(j);
+        });
+        assertCompiled();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/cha/ThreeLevelDefaultHierarchy1.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package compiler.cha;
+
+import jdk.internal.vm.annotation.DontInline;
+import static compiler.cha.StrengthReduceInterfaceCall.*;
+
+public class ThreeLevelDefaultHierarchy1 extends ATest<ThreeLevelDefaultHierarchy1.I> {
+    public ThreeLevelDefaultHierarchy1() {
+        super(I.class, C.class);
+    }
+
+    interface J1                { Object m();}
+    interface J2 extends J1     { default Object m() { return WRONG; }  }
+    interface I  extends J1, J2 {}
+
+    static class C  implements I { public Object m() { return CORRECT; }}
+
+    interface K1 extends I {}
+    interface K2 extends I { Object m(); }
+    interface K3 extends I { default Object m() { return WRONG; }}
+
+    static class DI implements I { public Object m() { return WRONG; }}
+    static class DJ1 implements J1 { public Object m() { return WRONG; }}
+    static class DJ2 implements J2 { public Object m() { return WRONG; }}
+
+    @DontInline
+    public Object test(I i) {
+        return i.m(); // no inlining since J.m is a default method
+    }
+
+    @TestCase
+    public void testMega() {
+        // 0. Trigger compilation of a megamorphic call site
+        compile(megamorphic());
+        assertCompiled();
+
+        // Dependency: none
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+        // 1. No deoptimization/invalidation on not-yet-seen receiver
+        repeat(100, () -> call(new C() {}));
+        assertCompiled();
+
+        // 2. No dependency, no inlining
+        // CHA doesn't support default methods yet.
+        initialize(DJ1.class,
+                   DJ2.class,
+                   DI.class,
+                   K1.class,
+                   K2.class,
+                   K3.class);
+        assertCompiled();
+    }
+
+    @Override
+    public void checkInvalidReceiver() {
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+            test(o);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object) new J1() {
+                public Object m() {
+                    return WRONG;
+                }
+            }); // super interface
+            test(j);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object) new J2() {
+            }); // super interface
+            test(j);
+        });
+        assertCompiled();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/cha/ThreeLevelHierarchyAbstractVsDefault.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package compiler.cha;
+
+import jdk.internal.vm.annotation.DontInline;
+import static compiler.cha.StrengthReduceInterfaceCall.*;
+
+public class ThreeLevelHierarchyAbstractVsDefault extends ATest<ThreeLevelHierarchyAbstractVsDefault.I> {
+    public ThreeLevelHierarchyAbstractVsDefault() {
+        super(I.class, C.class);
+    }
+
+    interface J1                { default Object m() { return WRONG; } } // intf J1.m DEFAULT
+    interface J2 extends J1     { Object m(); }                          // intf J2.m ABSTRACT <: intf J1
+    interface I  extends J1, J2 {}                                       // intf  I.m OVERPASS <: intf J1,J2
+
+    static class C  implements I { public Object m() { return CORRECT; }}
+
+    @DontInline
+    public Object test(I i) {
+        return i.m(); // intf I.m OVERPASS
+    }
+
+    static class DI implements I { public Object m() { return WRONG;   }}
+
+    static class DJ11 implements J1 {}
+    static class DJ12 implements J1 { public Object m() { return WRONG; }}
+
+    static class DJ2 implements J2 { public Object m() { return WRONG;   }}
+
+    interface K11 extends J1 {}
+    interface K12 extends J1 { Object m(); }
+    interface K13 extends J1 { default Object m() { return WRONG; }}
+    interface K21 extends J2 {}
+    interface K22 extends J2 { Object m(); }
+    interface K23 extends J2 { default Object m() { return WRONG; }}
+
+    public void testMega1() {
+        // 0. Trigger compilation of megamorphic call site
+        compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
+        assertCompiled();
+
+        // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+        // 1. No deopt/invalidation on not-yet-seen receiver
+        repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
+        assertCompiled();
+
+        // 2. No dependency invalidation: different context
+        initialize(K11.class, K12.class, K13.class,
+                K21.class, K22.class, K23.class);
+
+        // 3. Dependency invalidation: Cn.m <: C <: I
+        call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
+        assertNotCompiled();
+
+        // 4. Recompilation w/o a dependency
+        compile(megamorphic());
+        call(new C() { public Object m() { return CORRECT; }});
+        assertCompiled(); // no inlining
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+    }
+
+    public void testMega2() {
+        // 0. Trigger compilation of a megamorphic call site
+        compile(megamorphic());
+        assertCompiled();
+
+        // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+        // 1. No dependency invalidation: different context
+        initialize(DJ11.class,
+                DJ12.class,
+                DJ2.class);
+        assertCompiled();
+
+        // 2. Dependency invalidation: DI.m <: I
+        initialize(DI.class);
+        assertNotCompiled();
+
+        // 3. Recompilation w/o a dependency
+        compile(megamorphic());
+        call(new C() { public Object m() { return CORRECT; }});
+        assertCompiled(); // no inlining
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+    }
+
+    @Override
+    public void checkInvalidReceiver() {
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+            test(o);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object) new J1() {
+            }); // super interface
+            test(j);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object) new J2() {
+                public Object m() {
+                    return WRONG;
+                }
+            }); // super interface
+            test(j);
+        });
+        assertCompiled();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/cha/ThreeLevelHierarchyLinear.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package compiler.cha;
+
+import jdk.internal.vm.annotation.DontInline;
+import static compiler.cha.StrengthReduceInterfaceCall.*;
+
+public class ThreeLevelHierarchyLinear extends ATest<ThreeLevelHierarchyLinear.I> {
+    public ThreeLevelHierarchyLinear() {
+        super(I.class, C.class);
+    }
+
+    interface J           { Object m(); }
+    interface I extends J {}
+
+    interface K1 extends I {}
+    interface K2 extends I { Object m(); }
+    interface K3 extends I { default Object m() { return WRONG; }}
+
+    static class C  implements I { public Object m() { return CORRECT; }}
+
+    static class DI implements I { public Object m() { return WRONG;   }}
+    static class DJ implements J { public Object m() { return WRONG;   }}
+
+    @DontInline
+    public Object test(I i) {
+        return i.m(); // I <: J.m ABSTRACT
+    }
+
+    @TestCase
+    public void testMega1() {
+        // 0. Trigger compilation of a megamorphic call site
+        compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
+        assertCompiled();
+
+        // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+        // 1. No deoptimization/invalidation on not-yet-seen receiver
+        repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I
+        assertCompiled(); // No deopt on not-yet-seen receiver
+
+        // 2. No dependency invalidation: different context
+        initialize(DJ.class,  //      DJ.m                    <: intf J.m ABSTRACT
+                   K1.class,  // intf K1            <: intf I <: intf J.m ABSTRACT
+                   K2.class); // intf K2.m ABSTRACT <: intf I <: intf J.m ABSTRACT
+        assertCompiled();
+
+        // 3. Dependency invalidation: DI.m <: I
+        initialize(DI.class); //      DI.m          <: intf I <: intf J.m ABSTRACT
+        assertNotCompiled();
+
+        // 4. Recompilation w/o a dependency
+        compile(megamorphic());
+        call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I <: intf J.m ABSTRACT
+
+        assertCompiled(); // no dependency
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+    }
+
+    @TestCase
+    public void testMega2() {
+        compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
+        assertCompiled();
+
+        // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+        // Dependency invalidation
+        initialize(K3.class); // intf K3.m DEFAULT <: intf I;
+        assertNotCompiled(); // FIXME: default methods in sub-interfaces shouldn't be taken into account by CHA
+
+        // Recompilation with a dependency
+        compile(megamorphic());
+        assertCompiled();
+
+        // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+        call(new K3() { public Object m() { return CORRECT; }}); // Kn.m <: K3.m DEFAULT <: intf I <: intf J.m ABSTRACT
+        assertNotCompiled();
+
+        // Recompilation w/o a dependency
+        compile(megamorphic());
+        // Dependency: none
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+        call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I <: intf J.m ABSTRACT
+        assertCompiled();
+    }
+
+    @Override
+    public void checkInvalidReceiver() {
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+            test(o);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object) new J() {
+                public Object m() {
+                    return WRONG;
+                }
+            }); // super interface
+            test(j);
+        });
+        assertCompiled();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/cha/TwoLevelHierarchyLinear.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+package compiler.cha;
+
+import jdk.internal.vm.annotation.DontInline;
+import static compiler.cha.StrengthReduceInterfaceCall.*;
+
+public class TwoLevelHierarchyLinear extends ATest<TwoLevelHierarchyLinear.I> {
+    public TwoLevelHierarchyLinear() {
+        super(I.class, C.class);
+    }
+
+    interface J { default Object m() { return WRONG; } }
+
+    interface I extends J { Object m(); }
+    static class C implements I { public Object m() { return CORRECT; }}
+
+    interface K1 extends I {}
+    interface K2 extends I { Object m(); }
+    interface K3 extends I { default Object m() { return WRONG; }}
+
+    static class D implements I { public Object m() { return WRONG;   }}
+
+    static class DJ1 implements J {}
+    static class DJ2 implements J { public Object m() { return WRONG; }}
+
+    @DontInline
+    public Object test(I i) {
+        return i.m();
+    }
+
+    @TestCase
+    public void testMega1() {
+        // 0. Trigger compilation of a megamorphic call site
+        compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m ABSTRACT <: intf J.m ABSTRACT
+        assertCompiled();
+
+        // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+        checkInvalidReceiver(); // ensure proper type check is preserved
+
+        // 1. No deoptimization/invalidation on not-yet-seen receiver
+        repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
+        assertCompiled();
+
+        // 2. No dependency invalidation on class loading of unrelated classes: different context
+        initialize(K1.class,   // intf  K1            <: intf I.m ABSTRACT <: intf J.m DEFAULT
+                   K2.class,   // intf  K2.m ABSTRACT <: intf I.m ABSTRACT <: intf J.m DEFAULT
+                   DJ1.class,  //      DJ1                                 <: intf J.m DEFAULT
+                   DJ2.class); //      DJ2.m                               <: intf J.m DEFAULT
+        assertCompiled();
+
+        // 3. Dependency invalidation on D <: I
+        initialize(D.class); // D.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
+        assertNotCompiled();
+
+        // 4. Recompilation: no inlining, no dependencies
+        compile(megamorphic());
+        call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
+        assertCompiled();
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+    }
+
+    @TestCase
+    public void testMega2() {
+        // 0. Trigger compilation of a megamorphic call site
+        compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
+        assertCompiled();
+
+        // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+        // 1. Dependency invalidation
+        initialize(K3.class); // intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m DEFAULT
+        assertNotCompiled();
+
+        // 2. Recompilation: still inlines
+        // FIXME: no default method support in CHA yet
+        compile(megamorphic());
+        call(new K3() { public Object m() { return CORRECT; }}); // K3n.m <: intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m ABSTRACT
+        assertNotCompiled();
+
+        // 3. Recompilation: no inlining, no dependencies
+        compile(megamorphic());
+        call(new K3() { public Object m() { return CORRECT; }}); // Kn.m <: intf K3.m DEFAULT  <: intf I.m ABSTRACT <: intf J.m DEFAULT
+        assertCompiled();
+
+        checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+    }
+
+    @Override
+    public void checkInvalidReceiver() {
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+            test(o);
+        });
+        assertCompiled();
+
+        shouldThrow(IncompatibleClassChangeError.class, () -> {
+            I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
+            test(j);
+        });
+        assertCompiled();
+    }
+}
+
--- a/test/hotspot/jtreg/runtime/Nestmates/membership/TestDynamicNestmateMembership.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/test/hotspot/jtreg/runtime/Nestmates/membership/TestDynamicNestmateMembership.java	Thu Aug 29 19:32:19 2019 -0700
@@ -32,9 +32,8 @@
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.Path;
-import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
-import static java.lang.invoke.MethodHandles.Lookup.ClassProperty.*;
+import static java.lang.invoke.MethodHandles.Lookup.ClassOptions.*;
 
 /* package */ class DynamicNestmate { }
 
@@ -98,13 +97,13 @@
     // Try to inject a class that is already part of another nest
     static void test_alreadyNestMember() {
         String name = "StaticHost$StaticMember";
-        inject(name, ClassFormatError.class);
+        inject(name, IllegalArgumentException.class);
     }
 
     // Try to inject a class that is already a nest host
     static void test_alreadyNestHost() {
         String name = "StaticHost";
-        inject(name, ClassFormatError.class);
+        inject(name, IllegalArgumentException.class);
     }
 
     // Try to inject a class that is in another package
@@ -125,7 +124,7 @@
 
         try {
             byte[] bytes = getBytesForClass(name);
-            Class<?> nestmate = lookup.defineClass(bytes, NESTMATE);
+            Class<?> nestmate = lookup.defineHiddenClass(bytes, false, NESTMATE);
             if (ex != null) {
                 throw new RuntimeException(action + " was expected to throw " +
                                            ex.getSimpleName());
--- a/test/jdk/java/lang/StackWalker/VerifyStackTrace.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/test/jdk/java/lang/StackWalker/VerifyStackTrace.java	Thu Aug 29 19:32:19 2019 -0700
@@ -202,7 +202,6 @@
             // out before comparing. We also erase the hash-like names of
             // synthetic frames introduced by lambdas & method handles
             return produced.replaceAll(":[1-9][0-9]*\\)", ":00)")
-                    .replaceAll("\\$\\$/0x", "/0x")
                     .replaceAll("/0x[0-9a-f]+\\.run", "/xxxxxxxx.run")
                     .replaceAll("/0x[0-9a-f]+\\.invoke", "/xxxxxxxx.invoke")
                     // LFs may or may not be pre-generated, making frames differ
--- a/test/jdk/java/lang/invoke/defineClass/DefineClassTest.java	Wed Jun 26 22:16:31 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 2018, 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
- * @library /test/lib
- * @modules java.base/jdk.internal.org.objectweb.asm
- * @build  DefineClassTest
- * @run testng/othervm DefineClassTest
- */
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.stream.Stream;
-
-import jdk.internal.org.objectweb.asm.*;
-import org.testng.annotations.Test;
-
-import static java.lang.invoke.MethodHandles.Lookup.ClassProperty.*;
-import static java.lang.invoke.MethodHandles.Lookup.PRIVATE;
-import static java.lang.invoke.MethodType.*;
-
-import static jdk.internal.org.objectweb.asm.Opcodes.*;
-import static org.testng.Assert.*;
-
-public class DefineClassTest {
-    private static final byte[] bytes = classBytes("Injected");
-    private static byte[] classBytes(String classname) {
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
-        MethodVisitor mv;
-
-        cw.visit(V12, ACC_FINAL, classname, null, "java/lang/Object", null);
-
-        {
-            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
-            mv.visitCode();
-            mv.visitVarInsn(ALOAD, 0);
-            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
-            mv.visitInsn(RETURN);
-            mv.visitMaxs(0, 0);
-            mv.visitEnd();
-        }
-        {
-            // access a private member of the nest host class
-            mv = cw.visitMethod(ACC_PUBLIC, "test", "(LDefineClassTest;)I", null, null);
-            mv.visitCode();
-            mv.visitVarInsn(ALOAD, 0);
-            mv.visitVarInsn(ALOAD, 1);
-            mv.visitMethodInsn(INVOKEVIRTUAL, "DefineClassTest", "privMethod", "()I");
-            mv.visitInsn(IRETURN);
-            mv.visitMaxs(0, 0);
-            mv.visitEnd();
-        }
-        cw.visitEnd();
-
-        return cw.toByteArray();
-    }
-
-    private int privMethod() { return 1234; }
-
-    @Test
-    public void defineNestMate() throws Throwable {
-        // define a nestmate
-        Lookup lookup = MethodHandles.lookup();
-        Class<?> c = lookup.defineClass(bytes, NESTMATE);
-        assertTrue(c.getNestHost() == DefineClassTest.class);
-        assertTrue(c == Class.forName("Injected"));
-
-        // invoke int test(DefineClassTest o)
-        int x = testInjectedClass(c);
-        assertTrue(x == privMethod());
-
-        // dynamic nestmate is not listed in the return array of getNestMembers
-        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
-        assertTrue(c.isNestmateOf(DefineClassTest.class));
-    }
-
-    @Test
-    public void defineNestMateAsLookup() throws Throwable {
-        // define a nestmate
-        byte[] bytes = classBytes("Injected2");
-        Lookup lookup = MethodHandles.lookup().defineClassAsLookup(bytes, NESTMATE);
-        Class<?> c = lookup.lookupClass();
-        assertTrue(c.getNestHost() == DefineClassTest.class);
-        assertTrue(c == Class.forName("Injected2"));
-
-        // invoke int test(DefineClassTest o) via MethodHandle
-        MethodHandle ctor = lookup.findConstructor(c, methodType(void.class));
-        MethodHandle mh = lookup.findVirtual(c, "test", methodType(int.class, DefineClassTest.class));
-        int x = (int)mh.bindTo(ctor.invoke()).invokeExact( this);
-        // int x =(int)mh.invoke(c.newInstance(), this);
-        assertTrue(x == privMethod());
-
-        // dynamic nestmate is not listed in the return array of getNestMembers
-        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
-        assertTrue(c.isNestmateOf(DefineClassTest.class));
-    }
-
-    @Test
-    public void defineHiddenClass() throws Throwable {
-        // define a hidden class
-        Lookup lookup = MethodHandles.lookup();
-        Class<?> c = lookup.defineClass(bytes, NESTMATE, HIDDEN);
-        System.out.println(c.getName());
-        assertTrue(c.getNestHost() == DefineClassTest.class);
-        assertTrue(c.isHiddenClass());
-
-        // invoke int test(DefineClassTest o)
-        int x = testInjectedClass(c);
-        assertTrue(x == privMethod());
-
-        // dynamic nestmate is not listed in the return array of getNestMembers
-        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
-        assertTrue(c.isNestmateOf(DefineClassTest.class));
-    }
-
-    @Test
-    public void defineHiddenClassAsLookup() throws Throwable {
-        // define a hidden class
-        Lookup lookup = MethodHandles.lookup().defineClassAsLookup(bytes, NESTMATE, HIDDEN);
-        Class<?> c = lookup.lookupClass();
-        System.out.println(c.getName());
-        assertTrue(c.getNestHost() == DefineClassTest.class);
-        assertTrue(c.isHiddenClass());
-
-        // invoke int test(DefineClassTest o) via MethodHandle
-        MethodHandle ctor = lookup.findConstructor(c, methodType(void.class));
-        MethodHandle mh = lookup.findVirtual(c, "test", methodType(int.class, DefineClassTest.class));
-        int x = (int)mh.bindTo(ctor.invoke()).invokeExact( this);
-        assertTrue(x == privMethod());
-
-        // dynamic nestmate is not listed in the return array of getNestMembers
-        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
-        assertTrue(c.isNestmateOf(DefineClassTest.class));
-    }
-
-    @Test
-    public void defineWeakClass() throws Throwable {
-        // define a weak class
-        Class<?> c = MethodHandles.lookup().defineClass(bytes, WEAK);
-        System.out.println(c.getName());
-        assertTrue(c.getNestHost() == c);
-        assertTrue(c.isHiddenClass());
-    }
-
-    @Test(expectedExceptions = IllegalAccessException.class)
-    public void definePackageAccessClass() throws Throwable {
-        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
-        Class<?> c = lookup.defineClass(bytes, HIDDEN);
-    }
-
-    @Test(expectedExceptions = IllegalAccessException.class)
-    public void noPrivateLookupAccess() throws Throwable {
-        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
-        lookup.defineClass(bytes, NESTMATE);
-    }
-
-    @Test(expectedExceptions = IllegalAccessException.class)
-    public void teleportToNestmate() throws Throwable {
-        Class<?> c = MethodHandles.lookup().defineClass(bytes, NESTMATE, HIDDEN);
-        assertTrue(c.getNestHost() == DefineClassTest.class);
-        assertTrue(c.isHiddenClass());
-
-        // Teleport to a nestmate
-        Lookup lookup =  MethodHandles.lookup().in(c);
-        assertTrue((lookup.lookupModes() & PRIVATE) == 0);
-        // fail to define a nestmate
-        lookup.defineClass(bytes, NESTMATE, HIDDEN);
-    }
-
-    @Test(expectedExceptions = IllegalArgumentException.class)
-    public void notSamePackage() throws Throwable {
-        MethodHandles.lookup().defineClass(classBytes("p/Injected"), NESTMATE);
-    }
-
-    /*
-     * invoke int test(DefineClassTest o) method defined in the injected class
-     */
-    private int testInjectedClass(Class<?> c) throws Throwable {
-        try {
-            Method m = c.getMethod("test", DefineClassTest.class);
-            return (int) m.invoke(c.newInstance(), this);
-        } catch (InvocationTargetException e) {
-            throw e.getCause();
-        }
-    }
-}
--- a/test/jdk/java/lang/invoke/defineClass/DefineClassWithClassData.java	Wed Jun 26 22:16:31 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2018, 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
- * @library /test/lib
- * @modules java.base/jdk.internal.org.objectweb.asm
- * @build  DefineClassWithClassData
- * @run testng/othervm DefineClassWithClassData
- */
-
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.stream.Stream;
-
-import jdk.internal.org.objectweb.asm.*;
-import org.testng.annotations.Test;
-
-import static java.lang.invoke.MethodHandles.Lookup.ClassProperty.*;
-import static java.lang.invoke.MethodHandles.Lookup.PRIVATE;
-import static jdk.internal.org.objectweb.asm.Opcodes.*;
-import static org.testng.Assert.*;
-
-public class DefineClassWithClassData {
-    private static final byte[] T_CLASS_BYTES = ClassByteBuilder.classBytes("T");
-    private static final byte[] T2_CLASS_BYTES = ClassByteBuilder.classBytes("T2");
-
-    private int privMethod() { return 1234; }
-
-    /*
-     * invoke int test(DefineClassWithClassData o) method defined in the injected class
-     */
-    private int testInjectedClass(Class<?> c) throws Throwable {
-        try {
-            Method m = c.getMethod("test", DefineClassWithClassData.class);
-            return (int) m.invoke(c.newInstance(), this);
-        } catch (InvocationTargetException e) {
-            throw e.getCause();
-        }
-    }
-
-    /*
-     * Returns the value of the static final "data" field in the injected class
-     */
-    private Object injectedData(Class<?> c) throws Throwable {
-        return c.getDeclaredField("data").get(null);
-    }
-
-    private static final List<String> classData = List.of("nestmate", "classdata");
-
-    @Test
-    public void defineNestMate() throws Throwable {
-        // define a nestmate
-        Lookup lookup = MethodHandles.lookup().defineClassWithClassData(T_CLASS_BYTES, classData, NESTMATE, HIDDEN);
-        Class<?> c = lookup.lookupClass();
-        assertTrue(c.getNestHost() == DefineClassWithClassData.class);
-        assertEquals(classData, injectedData(c));
-
-        // invoke int test(DefineClassWithClassData o)
-        int x = testInjectedClass(c);
-        assertTrue(x == privMethod());
-
-        // dynamic nestmate is not listed in the return array of getNestMembers
-        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
-        assertTrue(c.isNestmateOf(DefineClassWithClassData.class));
-    }
-
-    @Test
-    public void defineHiddenClass() throws Throwable {
-        // define a hidden class
-        Lookup lookup = MethodHandles.lookup().defineClassWithClassData(T_CLASS_BYTES, classData, NESTMATE, HIDDEN);
-        Class<?> c = lookup.lookupClass();
-        assertTrue(c.getNestHost() == DefineClassWithClassData.class);
-        assertTrue(c.isHiddenClass());
-        assertEquals(classData, injectedData(c));
-
-        // invoke int test(DefineClassWithClassData o)
-        int x = testInjectedClass(c);
-        assertTrue(x == privMethod());
-
-        // dynamic nestmate is not listed in the return array of getNestMembers
-        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
-        assertTrue(c.isNestmateOf(DefineClassWithClassData.class));
-    }
-
-    @Test
-    public void defineWeakClass() throws Throwable {
-        // define a weak class
-        Lookup lookup = MethodHandles.lookup().defineClassWithClassData(T_CLASS_BYTES, classData, WEAK);
-        Class<?> c = lookup.lookupClass();
-        assertTrue(c.getNestHost() == c);
-        assertTrue(c.isHiddenClass());
-    }
-
-    @Test(expectedExceptions = IllegalAccessException.class)
-    public void noPrivateLookupAccess() throws Throwable {
-        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
-        lookup.defineClassWithClassData(T2_CLASS_BYTES, classData, NESTMATE, HIDDEN);
-    }
-
-    @Test(expectedExceptions = IllegalAccessException.class)
-    public void teleportToNestmate() throws Throwable {
-        Lookup lookup = MethodHandles.lookup()
-            .defineClassWithClassData(T_CLASS_BYTES, classData, NESTMATE, HIDDEN);
-        Class<?> c = lookup.lookupClass();
-        assertTrue(c.getNestHost() == DefineClassWithClassData.class);
-        assertEquals(classData, injectedData(c));
-        assertTrue(c.isHiddenClass());
-
-        // Teleport to a nestmate
-        Lookup lookup2 =  MethodHandles.lookup().in(c);
-        assertTrue((lookup2.lookupModes() & PRIVATE) == 0);
-        // fail to define a nestmate
-        lookup2.defineClassWithClassData(T2_CLASS_BYTES, classData, NESTMATE, HIDDEN);
-    }
-
-    static class ClassByteBuilder {
-        static final String OBJECT_CLS = "java/lang/Object";
-        static final String STRING_CLS = "java/lang/String";
-        static final String LIST_CLS = "java/util/List";
-        static final String MH_CLS = "java/lang/invoke/MethodHandles";
-        static final String LOOKUP_CLS = "java/lang/invoke/MethodHandles$Lookup";
-        static final String LOOKUP_SIG = "Ljava/lang/invoke/MethodHandles$Lookup;";
-        static final String LIST_SIG = "Ljava/util/List;";
-
-        static byte[] classBytes(String classname) {
-            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
-            MethodVisitor mv;
-            FieldVisitor fv;
-
-            String hostClassName = DefineClassWithClassData.class.getName();
-
-            cw.visit(V11, ACC_FINAL, classname, null, OBJECT_CLS, null);
-            {
-                fv = cw.visitField(ACC_STATIC | ACC_FINAL, "data", LIST_SIG, null, null);
-                fv.visitEnd();
-            }
-            {
-                mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
-                mv.visitCode();
-
-                // set up try block
-                Label lTryBlockStart =   new Label();
-                Label lTryBlockEnd =     new Label();
-                Label lCatchBlockStart = new Label();
-                Label lCatchBlockEnd =   new Label();
-                mv.visitTryCatchBlock(lTryBlockStart, lTryBlockEnd, lCatchBlockStart, "java/lang/IllegalAccessException");
-
-                mv.visitLabel(lTryBlockStart);
-                mv.visitMethodInsn(INVOKESTATIC, MH_CLS, "lookup", "()" + LOOKUP_SIG);
-                mv.visitLdcInsn(Type.getType(List.class));
-                mv.visitMethodInsn(INVOKEVIRTUAL, LOOKUP_CLS, "classData", "(Ljava/lang/Class;)Ljava/lang/Object;");
-                mv.visitTypeInsn(CHECKCAST, LIST_CLS);
-                mv.visitFieldInsn(PUTSTATIC, classname, "data", LIST_SIG);
-                mv.visitLabel(lTryBlockEnd);
-                mv.visitJumpInsn(GOTO, lCatchBlockEnd);
-
-                mv.visitLabel(lCatchBlockStart);
-                mv.visitVarInsn(ASTORE, 0);
-                mv.visitTypeInsn(NEW, "java/lang/Error");
-                mv.visitInsn(DUP);
-                mv.visitVarInsn(ALOAD, 0);
-                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Error", "<init>", "(Ljava/lang/Throwable;)V");
-                mv.visitInsn(ATHROW);
-                mv.visitLabel(lCatchBlockEnd);
-                mv.visitInsn(RETURN);
-                mv.visitMaxs(0, 0);
-                mv.visitEnd();
-            }
-
-            {
-                mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
-                mv.visitCode();
-                mv.visitVarInsn(ALOAD, 0);
-                mv.visitMethodInsn(INVOKESPECIAL, OBJECT_CLS, "<init>", "()V");
-                mv.visitInsn(RETURN);
-                mv.visitMaxs(0, 0);
-                mv.visitEnd();
-            }
-            {
-                mv = cw.visitMethod(ACC_PUBLIC, "test", "(L" + hostClassName + ";)I", null, null);
-                mv.visitCode();
-                mv.visitVarInsn(ALOAD, 0);
-                mv.visitVarInsn(ALOAD, 1);
-                mv.visitMethodInsn(INVOKEVIRTUAL, hostClassName, "privMethod", "()I");
-                mv.visitInsn(IRETURN);
-                mv.visitMaxs(0, 0);
-                mv.visitEnd();
-            }
-
-            {
-                mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "printData", "()V", null, null);
-                mv.visitCode();
-                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
-                mv.visitFieldInsn(GETSTATIC, classname, "data", LIST_SIG);
-                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V");
-                mv.visitInsn(RETURN);
-                mv.visitMaxs(0, 0);
-                mv.visitEnd();
-            }
-            cw.visitEnd();
-            return cw.toByteArray();
-        }
-    }
-}
-
-
--- a/test/jdk/java/lang/invoke/defineClass/DefineNonFindableClass.java	Wed Jun 26 22:16:31 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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
- * @modules java.base/jdk.internal.misc
- * @library /test/lib
- * @build jdk.test.lib.JDKToolLauncher
- *        jdk.test.lib.process.ProcessTools
- *        jdk.test.lib.Utils
- * @run main/othervm -Xverify:remote DefineNonFindableClass
- */
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import static java.lang.invoke.MethodHandles.Lookup.ClassProperty.*;
-import static java.lang.invoke.MethodHandles.Lookup.PRIVATE;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import jdk.internal.misc.Unsafe;
-
-import jdk.test.lib.JDKToolLauncher;
-import jdk.test.lib.process.ProcessTools;
-import jdk.test.lib.Utils;
-
-/* package-private */ interface Test {
-  void test();
-}
-
-
-public class DefineNonFindableClass {
-
-    static final Class<?> klass = DefineNonFindableClass.class;
-    static final Path SRC_DIR = Paths.get(Utils.TEST_SRC, "nonFindable");
-    static final Path CLASSES_DIR = Paths.get(Utils.TEST_CLASSES, "nonFindable");
-
-    static void compileSources(String sourceFile) throws Throwable {
-        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("javac");
-        launcher.addToolArg("-cp")
-                .addToolArg(Utils.TEST_CLASSES.toString())
-                .addToolArg("-d")
-                .addToolArg(CLASSES_DIR.toString())
-            .addToolArg(Paths.get(SRC_DIR.toString(), sourceFile).toString());
-
-        int exitCode = ProcessTools.executeCommand(launcher.getCommand())
-                                   .getExitValue();
-        if (exitCode != 0) {
-            throw new RuntimeException("Compilation of the test failed. "
-                    + "Unexpected exit code: " + exitCode);
-        }
-    }
-
-    static byte[] readClassFile(String classFileName) throws Exception {
-        File classFile = new File(CLASSES_DIR + File.separator + classFileName);
-        try (FileInputStream in = new FileInputStream(classFile);
-             ByteArrayOutputStream out = new ByteArrayOutputStream())
-        {
-            int b;
-            while ((b = in.read()) != -1) {
-                out.write(b);
-            }
-            return out.toByteArray();
-        }
-    }
-
-    public static void main(String[] args) throws Throwable {
-        compileSources("NonFindable.java");
-        Lookup lookup = MethodHandles.lookup();
-        byte[] bytes = readClassFile("NonFindable.class");
-        Class<?> c = lookup.defineClass(bytes, NESTMATE, HIDDEN);
-        Test t = (Test) c.newInstance();
-        t.test();
-
-
-        // Test that a nonFindable class cannot use its own name in a field
-        // signature.
-        compileSources("NonFindableField.java");
-        Lookup lookup2 = MethodHandles.lookup();
-        byte[] bytes2 = readClassFile("NonFindableField.class");
-        try {
-            Class<?> c2 = lookup2.defineClass(bytes2, NESTMATE, HIDDEN);
-            throw new RuntimeException(
-                "Expected NoClassDefFoundError exception not thrown");
-        } catch (java.lang.NoClassDefFoundError e) {
-            if (!e.getMessage().contains("NonFindableField")) {
-                throw new RuntimeException(
-                    "Unexpected NoClassDefFoundError: " + e.getMessage());
-            }
-        }
-
-        // Test that a nonFindable class cannot use its own name in a method
-        // signature.
-        compileSources("NonFindableMethod.java");
-        Lookup lookup3 = MethodHandles.lookup();
-        byte[] bytes3 = readClassFile("NonFindableMethod.class");
-        try {
-	    Class<?> c3 = lookup3.defineClass(bytes3, NESTMATE, HIDDEN);
-            throw new RuntimeException(
-                "Expected NoClassDefFoundError exception not thrown");
-        } catch (java.lang.NoClassDefFoundError e) {
-            if (!e.getMessage().contains("NonFindableMethod")) {
-                throw new RuntimeException(
-                    "Unexpected NoClassDefFoundError: " + e.getMessage());
-            }
-        }
-    }
-
-}
--- a/test/jdk/java/lang/invoke/defineClass/nonFindable/NonFindable.java	Wed Jun 26 22:16:31 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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.
- */
-
-/*
- *  The classfile for this class will be loaded directly and used to define
- *  a non-findable class.
- */
-public class NonFindable implements Test {
-
-    NonFindable other = null;
-
-    private String realTest() {
-        Object o = other;
-        NonFindable local = this;
-        local = other;
-        local = (NonFindable) o;
-        local = new NonFindable();
-
-        set_other(null);
-
-        local = getThis();
-
-        set_other_maybe(new Object());
-        set_other_maybe(this);
-        return "NonFindable";
-    }
-
-    private NonFindable getThis() {
-        return null;
-    }
-
-    private void set_other(NonFindable t) {
-        other = t;
-    }
-
-    private void set_other_maybe(Object o) {
-        if (o instanceof NonFindable) {
-        }
-    }
-
-    public void test() {
-        String result = realTest();
-        // Make sure that the Utf8 constant pool entry for "NonFindable" is okay.
-        if (!result.substring(0, 7).equals("NonFind") ||
-            !result.substring(7).equals("able")) {
-            throw new RuntimeException("'NonFindable string is bad: " + result);
-        }
-
-    }
-}
--- a/test/jdk/java/lang/invoke/defineClass/nonFindable/NonFindableField.java	Wed Jun 26 22:16:31 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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.
- */
-
-/*
- *  The classfile for this class will be used to define a non-findable
- *  class.  The load of this class will fail because non-findable classes
- *  cannot user their name in field signatures.
- */
-public class NonFindableField implements Test {
-
-    NonFindableField other = null;
-
-    private void realTest() {
-        other = this;  // field signature test
-    }
-
-    public void test() {
-        realTest();
-    }
-}
--- a/test/jdk/java/lang/invoke/defineClass/nonFindable/NonFindableMethod.java	Wed Jun 26 22:16:31 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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.
- */
-
-/*
- *  The classfile for this class will be used to define a non-findable
- *  class.  The load of this class will fail because non-findable classes
- *  cannot use their names in method signatures.
- */
-public class NonFindableMethod implements Test {
-
-    private void realTest() {
-        NonFindableMethod local = this;
-        set_other(local); // method signature test
-    }
-
-    private void set_other(NonFindableMethod t) {
-    }
-
-    public void test() {
-        realTest();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @library /test/lib
+ * @build jdk.test.lib.Utils
+ *        jdk.test.lib.compiler.CompilerUtils
+ *        BasicTest
+ * @run testng/othervm BasicTest
+ */
+
+import java.io.File;
+import java.io.IOException;
+import static java.lang.invoke.MethodHandles.Lookup.ClassOptions.*;
+import static java.lang.invoke.MethodHandles.lookup;
+
+import java.lang.reflect.InaccessibleObjectException;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+import jdk.test.lib.compiler.CompilerUtils;
+
+import jdk.test.lib.Utils;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/* package-private */ interface HiddenTest {
+  void test();
+}
+
+public class BasicTest {
+
+    private static final Path SRC_DIR = Paths.get(Utils.TEST_SRC, "src");
+    private static final Path CLASSES_DIR = Paths.get("classes");
+    private static final Path CLASSES_10_DIR = Paths.get("classes_10");
+
+    @BeforeTest
+    static void setup() throws IOException {
+        if (!CompilerUtils.compile(SRC_DIR, CLASSES_DIR, false, "-cp", Utils.TEST_CLASSES)) {
+            throw new RuntimeException("Compilation of the test failed");
+        }
+    }
+
+    static void compileSources(Path sourceFile, Path dest, String... options) throws IOException {
+        Stream<String> ops = Stream.of("-cp", Utils.TEST_CLASSES + File.pathSeparator + CLASSES_DIR);
+        if (options != null && options.length > 0) {
+            ops = Stream.concat(ops, Arrays.stream(options));
+        }
+        if (!CompilerUtils.compile(sourceFile, dest, ops.toArray(String[]::new))) {
+            throw new RuntimeException("Compilation of the test failed: " + sourceFile);
+        }
+    }
+
+    static byte[] readClassFile(String classFileName) throws IOException {
+        return Files.readAllBytes(CLASSES_DIR.resolve(classFileName));
+    }
+
+    static Class<HiddenTest> defineHiddenClass(String name) throws Exception {
+        byte[] bytes = readClassFile(name + ".class");
+        return (Class<HiddenTest>)lookup().defineHiddenClass(bytes, false, NESTMATE);
+    }
+
+    @Test
+    public void hiddenClass() throws Throwable {
+        HiddenTest t = defineHiddenClass("HiddenClass").newInstance();
+        t.test();
+
+        Class<?> c = t.getClass();
+        Class<?>[] intfs = c.getInterfaces();
+        assertTrue(intfs.length == 1);
+        assertTrue(intfs[0] == HiddenTest.class);
+
+        // test setAccessible
+        checkSetAccessible(c, "realTest");
+        checkSetAccessible(c, "test");
+    }
+
+    public void checkSetAccessible(Class<?> c, String name, Class<?>... ptypes) throws Exception {
+        Method m = c.getDeclaredMethod(name, ptypes);
+        assertFalse(m.trySetAccessible());
+        try {
+            m.setAccessible(true);
+        } catch (InaccessibleObjectException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testLambda() throws Throwable {
+        HiddenTest t = defineHiddenClass("Lambda").newInstance();
+        try {
+            t.test();
+        } catch (Error e) {
+            if (!e.getMessage().equals("thrown by " + t.getClass().getName())) {
+                throw e;
+            }
+        }
+    }
+
+    @Test
+    public void hiddenCantReflect() throws Throwable {
+        HiddenTest t = defineHiddenClass("HiddenCantReflect").newInstance();
+        t.test();
+
+        Class<?> c = t.getClass();
+        Class<?>[] intfs = c.getInterfaces();
+        assertTrue(intfs.length == 1);
+        assertTrue(intfs[0] == HiddenTest.class);
+
+        try {
+            // this will cause class loading of HiddenCantReflect and fail
+            c.getDeclaredMethods();
+        } catch (NoClassDefFoundError e) {
+            Throwable x = e.getCause();
+            if (x == null || !(x instanceof ClassNotFoundException && x.getMessage().contains("HiddenCantReflect"))) {
+                throw e;
+            }
+        }
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void hiddenInterface() throws Exception {
+        byte[] bytes = readClassFile("HiddenInterface.class");
+        Class<?> c = lookup().defineHiddenClass(bytes, false);
+    }
+
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void abstractHiddenClass() throws Exception {
+        byte[] bytes = readClassFile("AbstractClass.class");
+        Class<?> c = lookup().defineHiddenClass(bytes, false);
+    }
+
+    @Test(expectedExceptions = NoClassDefFoundError.class)
+    public void hiddenSuperClass() throws Exception {
+        byte[] bytes = readClassFile("HiddenSuper.class");
+        Class<?> c = lookup().defineHiddenClass(bytes, false);
+    }
+
+    @Test
+    public void hiddenNestmates() throws Throwable {
+        try {
+            byte[] bytes = readClassFile("Outer.class");
+            lookup().defineHiddenClass(bytes, false);
+        } catch (IllegalArgumentException e) {
+            if (!e.getMessage().contains("NestMembers attribute")) throw e;
+        }
+
+        try {
+            byte[] bytes = readClassFile("Outer$Inner.class");
+            lookup().defineHiddenClass(bytes, false);
+        } catch (IllegalArgumentException e) {
+            if (!e.getMessage().contains("NestHost attribute")) throw e;
+        }
+    }
+
+    @Test
+    public void hiddenNestedClass() throws Throwable {
+        // compile with --release 10 with no NestHost and NestMembers attribute
+        compileSources(SRC_DIR.resolve("Outer.java"), CLASSES_10_DIR, "--release", "10");
+        try {
+            byte[] bytes = Files.readAllBytes(CLASSES_10_DIR.resolve("Outer.class"));
+            lookup().defineHiddenClass(bytes, false);
+        } catch (IllegalArgumentException e) {
+            if (!e.getMessage().contains("Outer$Inner")) throw e;
+        }
+
+        try {
+            byte[] bytes = Files.readAllBytes(CLASSES_10_DIR.resolve("Outer$Inner.class"));
+            lookup().defineHiddenClass(bytes, false);
+        } catch (IllegalArgumentException e) {
+            if (!e.getMessage().contains("Outer$Inner")) throw e;
+        }
+    }
+
+    @Test
+    public void hiddenAnonymous() throws Throwable {
+        // compile with --release 10 with no NestHost and NestMembers attribute
+        compileSources(SRC_DIR.resolve("EnclosingClass.java"), CLASSES_10_DIR, "--release", "10");
+        try {
+            byte[] bytes = Files.readAllBytes(CLASSES_10_DIR.resolve("EnclosingClass.class"));
+            lookup().defineHiddenClass(bytes, false);
+        } catch (IllegalArgumentException e) {
+            if (!e.getMessage().contains("EnclosingClass$1")) throw e;
+        }
+
+        try {
+            byte[] bytes = Files.readAllBytes(CLASSES_10_DIR.resolve("EnclosingClass$1.class"));
+            lookup().defineHiddenClass(bytes, false);
+        } catch (IllegalArgumentException e) {
+            if (!e.getMessage().contains("EnclosingMethod attribute")) throw e;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/DefineClassWithClassData.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2018, 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
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @build  DefineClassWithClassData
+ * @run testng/othervm DefineClassWithClassData
+ */
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.internal.org.objectweb.asm.*;
+import org.testng.annotations.Test;
+
+import static java.lang.invoke.MethodHandles.Lookup.ClassOptions.*;
+import static java.lang.invoke.MethodHandles.Lookup.PRIVATE;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+import static org.testng.Assert.*;
+
+public class DefineClassWithClassData {
+    private static final byte[] T_CLASS_BYTES = ClassByteBuilder.classBytes("T");
+    private static final byte[] T2_CLASS_BYTES = ClassByteBuilder.classBytes("T2");
+
+    private int privMethod() { return 1234; }
+
+    /*
+     * invoke int test(DefineClassWithClassData o) method defined in the injected class
+     */
+    private int testInjectedClass(Class<?> c) throws Throwable {
+        try {
+            Method m = c.getMethod("test", DefineClassWithClassData.class);
+            return (int) m.invoke(c.newInstance(), this);
+        } catch (InvocationTargetException e) {
+            throw e.getCause();
+        }
+    }
+
+    /*
+     * Returns the value of the static final "data" field in the injected class
+     */
+    private Object injectedData(Class<?> c) throws Throwable {
+        return c.getDeclaredField("data").get(null);
+    }
+
+    private static final List<String> classData = List.of("nestmate", "classdata");
+
+    @Test
+    public void defineNestMate() throws Throwable {
+        // define a nestmate
+        Lookup lookup = MethodHandles.lookup().defineHiddenClassWithClassData(T_CLASS_BYTES, classData, NESTMATE);
+        Class<?> c = lookup.lookupClass();
+        assertTrue(c.getNestHost() == DefineClassWithClassData.class);
+        assertEquals(classData, injectedData(c));
+
+        // invoke int test(DefineClassWithClassData o)
+        int x = testInjectedClass(c);
+        assertTrue(x == privMethod());
+
+        // dynamic nestmate is not listed in the return array of getNestMembers
+        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
+        assertTrue(c.isNestmateOf(DefineClassWithClassData.class));
+    }
+
+    @Test
+    public void defineHiddenClass() throws Throwable {
+        // define a hidden class
+        Lookup lookup = MethodHandles.lookup().defineHiddenClassWithClassData(T_CLASS_BYTES, classData, NESTMATE);
+        Class<?> c = lookup.lookupClass();
+        assertTrue(c.getNestHost() == DefineClassWithClassData.class);
+        assertTrue(c.isHiddenClass());
+        assertEquals(classData, injectedData(c));
+
+        // invoke int test(DefineClassWithClassData o)
+        int x = testInjectedClass(c);
+        assertTrue(x == privMethod());
+
+        // dynamic nestmate is not listed in the return array of getNestMembers
+        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
+        assertTrue(c.isNestmateOf(DefineClassWithClassData.class));
+    }
+
+    @Test
+    public void defineWeakClass() throws Throwable {
+        // define a weak class
+        Lookup lookup = MethodHandles.lookup().defineHiddenClassWithClassData(T_CLASS_BYTES, classData, WEAK);
+        Class<?> c = lookup.lookupClass();
+        assertTrue(c.getNestHost() == c);
+        assertTrue(c.isHiddenClass());
+    }
+
+    @Test(expectedExceptions = IllegalAccessException.class)
+    public void noPrivateLookupAccess() throws Throwable {
+        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
+        lookup.defineHiddenClassWithClassData(T2_CLASS_BYTES, classData, NESTMATE);
+    }
+
+    @Test(expectedExceptions = IllegalAccessException.class)
+    public void teleportToNestmate() throws Throwable {
+        Lookup lookup = MethodHandles.lookup()
+            .defineHiddenClassWithClassData(T_CLASS_BYTES, classData, NESTMATE);
+        Class<?> c = lookup.lookupClass();
+        assertTrue(c.getNestHost() == DefineClassWithClassData.class);
+        assertEquals(classData, injectedData(c));
+        assertTrue(c.isHiddenClass());
+
+        // Teleport to a nestmate
+        Lookup lookup2 =  MethodHandles.lookup().in(c);
+        assertTrue((lookup2.lookupModes() & PRIVATE) == 0);
+        // fail to define a nestmate
+        lookup2.defineHiddenClassWithClassData(T2_CLASS_BYTES, classData, NESTMATE);
+    }
+
+    static class ClassByteBuilder {
+        static final String OBJECT_CLS = "java/lang/Object";
+        static final String STRING_CLS = "java/lang/String";
+        static final String LIST_CLS = "java/util/List";
+        static final String MH_CLS = "java/lang/invoke/MethodHandles";
+        static final String LOOKUP_CLS = "java/lang/invoke/MethodHandles$Lookup";
+        static final String LOOKUP_SIG = "Ljava/lang/invoke/MethodHandles$Lookup;";
+        static final String LIST_SIG = "Ljava/util/List;";
+
+        static byte[] classBytes(String classname) {
+            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+            MethodVisitor mv;
+            FieldVisitor fv;
+
+            String hostClassName = DefineClassWithClassData.class.getName();
+
+            cw.visit(V11, ACC_FINAL, classname, null, OBJECT_CLS, null);
+            {
+                fv = cw.visitField(ACC_STATIC | ACC_FINAL, "data", LIST_SIG, null, null);
+                fv.visitEnd();
+            }
+            {
+                mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+                mv.visitCode();
+
+                // set up try block
+                Label lTryBlockStart =   new Label();
+                Label lTryBlockEnd =     new Label();
+                Label lCatchBlockStart = new Label();
+                Label lCatchBlockEnd =   new Label();
+                mv.visitTryCatchBlock(lTryBlockStart, lTryBlockEnd, lCatchBlockStart, "java/lang/IllegalAccessException");
+
+                mv.visitLabel(lTryBlockStart);
+                mv.visitMethodInsn(INVOKESTATIC, MH_CLS, "lookup", "()" + LOOKUP_SIG, false);
+                mv.visitLdcInsn(Type.getType(List.class));
+                mv.visitMethodInsn(INVOKEVIRTUAL, LOOKUP_CLS, "classData", "(Ljava/lang/Class;)Ljava/lang/Object;", false);
+                mv.visitTypeInsn(CHECKCAST, LIST_CLS);
+                mv.visitFieldInsn(PUTSTATIC, classname, "data", LIST_SIG);
+                mv.visitLabel(lTryBlockEnd);
+                mv.visitJumpInsn(GOTO, lCatchBlockEnd);
+
+                mv.visitLabel(lCatchBlockStart);
+                mv.visitVarInsn(ASTORE, 0);
+                mv.visitTypeInsn(NEW, "java/lang/Error");
+                mv.visitInsn(DUP);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Error", "<init>", "(Ljava/lang/Throwable;)V", false);
+                mv.visitInsn(ATHROW);
+                mv.visitLabel(lCatchBlockEnd);
+                mv.visitInsn(RETURN);
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+
+            {
+                mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+                mv.visitCode();
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitMethodInsn(INVOKESPECIAL, OBJECT_CLS, "<init>", "()V", false);
+                mv.visitInsn(RETURN);
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+            {
+                mv = cw.visitMethod(ACC_PUBLIC, "test", "(L" + hostClassName + ";)I", null, null);
+                mv.visitCode();
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(ALOAD, 1);
+                mv.visitMethodInsn(INVOKEVIRTUAL, hostClassName, "privMethod", "()I", false);
+                mv.visitInsn(IRETURN);
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+
+            {
+                mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "printData", "()V", null, null);
+                mv.visitCode();
+                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+                mv.visitFieldInsn(GETSTATIC, classname, "data", LIST_SIG);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false);
+                mv.visitInsn(RETURN);
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+            cw.visitEnd();
+            return cw.toByteArray();
+        }
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/DefineHiddenClassTest.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @build  DefineHiddenClassTest
+ * @run testng/othervm DefineHiddenClassTest
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.stream.Stream;
+
+import jdk.internal.org.objectweb.asm.*;
+import org.testng.annotations.Test;
+
+import static java.lang.invoke.MethodHandles.Lookup.ClassOptions.*;
+import static java.lang.invoke.MethodHandles.Lookup.PRIVATE;
+import static java.lang.invoke.MethodType.*;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+import static org.testng.Assert.*;
+
+public class DefineHiddenClassTest {
+    private static final byte[] bytes = classBytes("Injected");
+    private static byte[] classBytes(String classname) {
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+        MethodVisitor mv;
+
+        cw.visit(V12, ACC_FINAL, classname, null, "java/lang/Object", null);
+
+        {
+            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+        {
+            // access a private member of the nest host class
+            mv = cw.visitMethod(ACC_PUBLIC, "test", "(LDefineHiddenClassTest;)I", null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitMethodInsn(INVOKEVIRTUAL, "DefineHiddenClassTest", "privMethod", "()I");
+            mv.visitInsn(IRETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+
+    private int privMethod() { return 1234; }
+
+    @Test
+    public void defineHiddenClass() throws Throwable {
+        // define a hidden class
+        Lookup lookup = MethodHandles.lookup();
+        Class<?> c = lookup.defineHiddenClass(bytes, false, NESTMATE);
+        System.out.println(c.getName());
+        assertTrue(c.getNestHost() == DefineHiddenClassTest.class);
+        assertTrue(c.isHiddenClass());
+
+        // invoke int test(DefineHiddenClassTest o)
+        int x = testInjectedClass(c);
+        assertTrue(x == privMethod());
+
+        // dynamic nestmate is not listed in the return array of getNestMembers
+        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
+        assertTrue(c.isNestmateOf(DefineHiddenClassTest.class));
+    }
+
+    @Test
+    public void defineHiddenClassAsLookup() throws Throwable {
+        // define a hidden class
+        Lookup lookup = MethodHandles.lookup().defineHiddenClassAsLookup(bytes, false, NESTMATE);
+        Class<?> c = lookup.lookupClass();
+        assertTrue(c.getNestHost() == DefineHiddenClassTest.class);
+        assertTrue(c.isHiddenClass());
+
+        // invoke int test(DefineHiddenClassTest o) via MethodHandle
+        MethodHandle ctor = lookup.findConstructor(c, methodType(void.class));
+        MethodHandle mh = lookup.findVirtual(c, "test", methodType(int.class, DefineHiddenClassTest.class));
+        int x = (int)mh.bindTo(ctor.invoke()).invokeExact( this);
+        assertTrue(x == privMethod());
+
+        // dynamic nestmate is not listed in the return array of getNestMembers
+        assertTrue(Stream.of(c.getNestHost().getNestMembers()).noneMatch(k -> k == c));
+        assertTrue(c.isNestmateOf(DefineHiddenClassTest.class));
+    }
+
+    @Test
+    public void defineWeakClass() throws Throwable {
+        // define a weak class
+        Class<?> c = MethodHandles.lookup().defineHiddenClass(bytes, false, WEAK);
+        assertTrue(c.getNestHost() == c);
+        assertTrue(c.isHiddenClass());
+    }
+
+    @Test(expectedExceptions = IllegalAccessException.class)
+    public void definePackageAccessClass() throws Throwable {
+        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
+        lookup.defineHiddenClass(bytes, false, NESTMATE);
+    }
+
+    @Test(expectedExceptions = IllegalAccessException.class)
+    public void noPrivateLookupAccess() throws Throwable {
+        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
+        lookup.defineHiddenClass(bytes, false, NESTMATE);
+    }
+
+    @Test(expectedExceptions = IllegalAccessException.class)
+    public void teleportToNestmate() throws Throwable {
+        Class<?> c = MethodHandles.lookup().defineHiddenClass(bytes, false, NESTMATE);
+        assertTrue(c.getNestHost() == DefineHiddenClassTest.class);
+        assertTrue(c.isHiddenClass());
+
+        // Teleport to a nestmate
+        Lookup lookup =  MethodHandles.lookup().in(c);
+        assertTrue((lookup.lookupModes() & PRIVATE) == 0);
+        // fail to define a nestmate
+        lookup.defineHiddenClass(bytes, false, NESTMATE);
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void notSamePackage() throws Throwable {
+        MethodHandles.lookup().defineHiddenClass(classBytes("p/Injected"), false, NESTMATE);
+    }
+
+    /*
+     * invoke int test(DefineHiddenClassTest o) method defined in the injected class
+     */
+    private int testInjectedClass(Class<?> c) throws Throwable {
+        try {
+            Method m = c.getMethod("test", DefineHiddenClassTest.class);
+            return (int) m.invoke(c.newInstance(), this);
+        } catch (InvocationTargetException e) {
+            throw e.getCause();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/SelfRefField.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ *  The classfile for this class will be used to define a hidden class
+ *  The load of this class will fail because hidden classes cannot
+ *  use their name in field signatures.
+ */
+public class SelfRefField implements Test {
+
+    SelfRefField other = null;
+
+    private void realTest() {
+        other = this;  // field signature test
+    }
+
+    public void test() {
+        realTest();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/SelfRefMethod.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ *  The classfile for this class will be used to define a hidden class
+ *  The load of this class will fail because hidden classes cannot
+ *  use their names in method signatures.
+ */
+public class SelfRefMethod implements Test {
+
+    private void realTest() {
+        SelfRefMethod local = this;
+        set_other(local); // method signature test
+    }
+
+    private void set_other(SelfRefMethod t) {
+    }
+
+    public void test() {
+        realTest();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/SelfReferenceDescriptor.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @library /test/lib
+ * @build jdk.test.lib.Utils
+ *        jdk.test.lib.compiler.CompilerUtils
+ *        SelfReferenceDescriptor
+ * @run main/othervm -Xverify:remote SelfReferenceDescriptor
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import static java.lang.invoke.MethodHandles.Lookup.ClassOptions.*;
+import static java.lang.invoke.MethodHandles.lookup;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+import jdk.test.lib.compiler.CompilerUtils;
+
+import jdk.test.lib.Utils;
+
+/* package-private */ interface Test {
+  void test();
+}
+
+public class SelfReferenceDescriptor {
+
+    private static final Path SRC_DIR = Paths.get(Utils.TEST_SRC);
+    private static final Path CLASSES_DIR = Paths.get("classes");
+
+    static void compileSources(Path sourceFile, String... options) throws IOException {
+        Stream<String> ops = Stream.of("-cp", Utils.TEST_CLASSES + File.pathSeparator + CLASSES_DIR);
+        if (options != null && options.length > 0) {
+            ops = Stream.concat(ops, Arrays.stream(options));
+        }
+        if (!CompilerUtils.compile(sourceFile, CLASSES_DIR, ops.toArray(String[]::new))) {
+            throw new RuntimeException("Compilation of the test failed: " + sourceFile);
+        }
+    }
+
+    static byte[] readClassFile(String classFileName) throws IOException {
+        File classFile = new File(CLASSES_DIR + File.separator + classFileName);
+        try (FileInputStream in = new FileInputStream(classFile);
+             ByteArrayOutputStream out = new ByteArrayOutputStream())
+        {
+            int b;
+            while ((b = in.read()) != -1) {
+                out.write(b);
+            }
+            return out.toByteArray();
+        }
+    }
+
+    // Test that a nonFindable class cannot use its own name in a field
+    // signature.
+    public static void hiddenClassInFieldDescriptor() throws Exception {
+        compileSources(SRC_DIR.resolve("SelfRefField.java"));
+        byte[] bytes = readClassFile("SelfRefField.class");
+        try {
+            Class<?> c = lookup().defineHiddenClass(bytes, false, NESTMATE);
+        } catch (NoClassDefFoundError e) {
+            if (!e.getMessage().contains("SelfRefField")) throw e;
+        }
+    }
+
+    // Test that a nonFindable class cannot use its own name in a method
+    // signature.
+    public static void hiddenClassInMethodDescriptor() throws Exception {
+        compileSources(SRC_DIR.resolve("SelfRefMethod.java"));
+        byte[] bytes = readClassFile("SelfRefMethod.class");
+        try {
+            Class<?> c = lookup().defineHiddenClass(bytes, false, NESTMATE);
+        } catch (NoClassDefFoundError e) {
+            if (!e.getMessage().contains("SelfRefMethod")) throw e;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        hiddenClassInMethodDescriptor();
+        hiddenClassInFieldDescriptor();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/AbstractClass.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+public abstract class AbstractClass {
+    abstract void test();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/EnclosingClass.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+public class EnclosingClass {
+    public static void run() {
+        Runnable r = new Runnable() {
+             public void run() {}
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenCantReflect.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * The classfile does not fail verification but would fail when
+ * getMethod
+ */
+public class HiddenCantReflect implements HiddenTest {
+
+    HiddenCantReflect other = null;
+
+    private String realTest() {
+        Object o = other;
+        HiddenCantReflect local = this;
+        local = other;
+        local = (HiddenCantReflect) o;
+        local = new HiddenCantReflect();
+
+        set_other(null);
+
+        local = getThis();
+
+        set_other_maybe(new Object());
+        set_other_maybe(this);
+        return "HiddenCantReflect";
+    }
+
+    private HiddenCantReflect getThis() {
+        return null;
+    }
+
+    private void set_other(HiddenCantReflect t) {
+        other = t;
+    }
+
+    private void set_other_maybe(Object o) {
+        if (o instanceof HiddenCantReflect) {
+        }
+    }
+
+    public void test() {
+        String result = realTest();
+        // Make sure that the Utf8 constant pool entry for "HiddenCantReflect" is okay.
+        if (!result.substring(0, 7).equals("HiddenC") ||
+            !result.substring(7).equals("antReflect")) {
+            throw new RuntimeException("'HiddenCantReflect string is bad: " + result);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenClass.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ *  The classfile for this class will be loaded directly and used to define
+ *  a hidden class.
+ */
+public class HiddenClass implements HiddenTest {
+
+    HiddenClass other = null;
+
+    private String realTest() {
+        Object o = other;
+        HiddenClass local = this;
+        local = other;
+        local = (HiddenClass) o;
+        local = new HiddenClass();
+
+        set_other_maybe(new Object());
+        set_other_maybe(this);
+        return "HiddenClass";
+    }
+
+    private void set_other_maybe(Object o) {
+        if (o instanceof HiddenClass) {
+        }
+    }
+
+    public void test() {
+        String result = realTest();
+        // Make sure that the Utf8 constant pool entry for "HiddenClass" is okay.
+        if (!result.substring(0, 7).equals("HiddenC") ||
+            !result.substring(7).equals("lass")) {
+            throw new RuntimeException("'HiddenClass string is bad: " + result);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenClassThrow.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ *  The classfile for this class will be loaded directly and used to define
+ *  a non-findable class.
+ */
+public class HiddenClassThrow implements HiddenTest {
+
+    public void test() {
+        throw new RuntimeException(this.getClass().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenInterface.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ *  The classfile for this class will be used to define a non-findable
+ *  interface.  The load of this class will fail because non-findable classes
+ *  cannot user their name in field signatures.
+ */
+public interface HiddenInterface {
+    default void test() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/HiddenSuper.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+public class HiddenSuper extends HiddenClass implements HiddenTest {
+    private void realTest() {
+    }
+
+    public void test() {
+        realTest();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/Lambda.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.function.Function;
+
+public class Lambda implements HiddenTest {
+     public void test() {
+         Function<Object, String> f = Object::toString;
+         String s = f.apply(this);
+         throw new Error("thrown by " + s);
+     }
+
+     public String toString() {
+         return getClass().getName();
+     }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineHiddenClass/src/Outer.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,4 @@
+public class Outer {
+    public static class Inner {
+    }
+}
--- a/test/langtools/jdk/javadoc/doclet/testSingletonLists/TestSingletonLists.java	Wed Jun 26 22:16:31 2019 -0700
+++ b/test/langtools/jdk/javadoc/doclet/testSingletonLists/TestSingletonLists.java	Thu Aug 29 19:32:19 2019 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @ignore 8227415
  * @bug 8219998 8221991
  * @summary Eliminate inherently singleton lists
  * @library /tools/lib ../../lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/invoke/LookupDefineClass.java	Thu Aug 29 19:32:19 2019 -0700
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+package org.openjdk.bench.java.lang.invoke;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.concurrent.TimeUnit;
+
+import static java.lang.invoke.MethodHandles.Lookup.ClassOptions.*;
+
+public class LookupDefineClass {
+    private static final byte[] X_BYTECODE = new byte[]{
+            (byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE, 0x00, 0x00, 0x00, 0x38, 0x00, 0x10, 0x0A, 0x00,
+            0x03, 0x00, 0x0C, 0x07, 0x00, 0x0D, 0x07, 0x00, 0x0E, 0x07, 0x00, 0x0F,
+            0x01, 0x00, 0x06, 0x3C, 0x69, 0x6E, 0x69, 0x74, 0x3E, 0x01, 0x00, 0x03,
+            0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43, 0x6F, 0x64, 0x65, 0x01, 0x00,
+            0x0F, 0x4C, 0x69, 0x6E, 0x65, 0x4E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x54,
+            0x61, 0x62, 0x6C, 0x65, 0x01, 0x00, 0x03, 0x72, 0x75, 0x6E, 0x01, 0x00,
+            0x0A, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6C, 0x65, 0x01,
+            0x00, 0x08, 0x46, 0x6F, 0x6F, 0x2E, 0x6A, 0x61, 0x76, 0x61, 0x0C, 0x00,
+            0x05, 0x00, 0x06, 0x01, 0x00, 0x07, 0x66, 0x6F, 0x6F, 0x2F, 0x46, 0x6F,
+            0x6F, 0x01, 0x00, 0x10, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E,
+            0x67, 0x2F, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x01, 0x00, 0x12, 0x6A,
+            0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x52, 0x75, 0x6E,
+            0x6E, 0x61, 0x62, 0x6C, 0x65, 0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00,
+            0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00,
+            0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x01, 0x00,
+            0x01, 0x00, 0x00, 0x00, 0x05, 0x2A, (byte)0xB7, 0x00, 0x01, (byte)0xB1, 0x00, 0x00,
+            0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00,
+            0x00, 0x03, 0x00, 0x01, 0x00, 0x09, 0x00, 0x06, 0x00, 0x01, 0x00, 0x07,
+            0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+            (byte)0xB1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00,
+            0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00,
+            0x02, 0x00, 0x0B
+    };
+
+    /**
+     * Our own crippled classloader, that can only load a simple class over and over again.
+     */
+    public static class XLoader extends URLClassLoader {
+        public XLoader() {
+            super("X-Loader", new URL[0], ClassLoader.getSystemClassLoader());
+        }
+
+        @Override
+        protected Class<?> findClass(final String name) throws ClassNotFoundException {
+            return defineClass(name, X_BYTECODE, 0, X_BYTECODE.length);
+        }
+
+        public Class<?> install(final String name, byte[] bytes) {
+            return defineClass(name, bytes, 0, bytes.length);
+        }
+    }
+
+    public static class Loader extends URLClassLoader {
+        public Loader(String name) {
+            super(name, new URL[0], ClassLoader.getSystemClassLoader());
+        }
+
+        public Class<?> install(final String name, byte[] bytes) {
+            return defineClass(name, bytes, 0, bytes.length);
+        }
+    }
+
+    @State(Scope.Thread)
+    @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Fork(3)
+    @BenchmarkMode(Mode.AverageTime)
+    @OutputTimeUnit(TimeUnit.NANOSECONDS)
+    public static class OneClassPerLoader {
+        ClassLoader loader;
+        @Benchmark
+        public Class<?> load() throws ClassNotFoundException {
+            return Class.forName("foo.Foo", false, loader);
+        }
+
+        public static void main(String[] args) throws RunnerException {
+            Options opt = new OptionsBuilder()
+                    .include(LookupDefineClass.OneClassPerLoader.class.getSimpleName())
+                    // .addProfiler(ClassloaderProfiler.class)
+                    // .addProfiler(CompilerProfiler.class)
+                    .build();
+
+            new Runner(opt).run();
+        }
+
+        @Setup(Level.Invocation)
+        public void doSetup() {
+            loader = new XLoader();
+        }
+    }
+
+    private static final byte[] FOO_HOST_BYTES = new byte[]{
+            (byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE, 0x00, 0x00, 0x00, 0x33, 0x00, 0x12, 0x01, 0x00,
+            0x11, 0x66, 0x6F, 0x6F, 0x2F, 0x41, 0x6E, 0x6F, 0x6E, 0x79, 0x6D, 0x6F,
+            0x75, 0x73, 0x48, 0x6F, 0x73, 0x74, 0x07, 0x00, 0x01, 0x01, 0x00, 0x10,
+            0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x4F, 0x62,
+            0x6A, 0x65, 0x63, 0x74, 0x07, 0x00, 0x03, 0x01, 0x00, 0x06, 0x4C, 0x4F,
+            0x4F, 0x4B, 0x55, 0x50, 0x01, 0x00, 0x27, 0x4C, 0x6A, 0x61, 0x76, 0x61,
+            0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x69, 0x6E, 0x76, 0x6F, 0x6B, 0x65,
+            0x2F, 0x4D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x48, 0x61, 0x6E, 0x64, 0x6C,
+            0x65, 0x73, 0x24, 0x4C, 0x6F, 0x6F, 0x6B, 0x75, 0x70, 0x3B, 0x01, 0x00,
+            0x08, 0x3C, 0x63, 0x6C, 0x69, 0x6E, 0x69, 0x74, 0x3E, 0x01, 0x00, 0x03,
+            0x28, 0x29, 0x56, 0x01, 0x00, 0x1E, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C,
+            0x61, 0x6E, 0x67, 0x2F, 0x69, 0x6E, 0x76, 0x6F, 0x6B, 0x65, 0x2F, 0x4D,
+            0x65, 0x74, 0x68, 0x6F, 0x64, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x73,
+            0x07, 0x00, 0x09, 0x01, 0x00, 0x06, 0x6C, 0x6F, 0x6F, 0x6B, 0x75, 0x70,
+            0x01, 0x00, 0x29, 0x28, 0x29, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C,
+            0x61, 0x6E, 0x67, 0x2F, 0x69, 0x6E, 0x76, 0x6F, 0x6B, 0x65, 0x2F, 0x4D,
+            0x65, 0x74, 0x68, 0x6F, 0x64, 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x73,
+            0x24, 0x4C, 0x6F, 0x6F, 0x6B, 0x75, 0x70, 0x3B, 0x0C, 0x00, 0x0B, 0x00,
+            0x0C, 0x0A, 0x00, 0x0A, 0x00, 0x0D, 0x0C, 0x00, 0x05, 0x00, 0x06, 0x09,
+            0x00, 0x02, 0x00, 0x0F, 0x01, 0x00, 0x04, 0x43, 0x6F, 0x64, 0x65, 0x06,
+            0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x19, 0x00,
+            0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x07, 0x00,
+            0x08, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x01, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x07, (byte)0xB8, 0x00, 0x0E, (byte)0xB3, 0x00, 0x10, (byte)0xB1,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+
+    private static MethodHandles.Lookup defineHostClass(Loader loader, String name, byte[] bytes) {
+        try {
+            Class<?> c = loader.install(name, bytes);
+            Field f = c.getDeclaredField("LOOKUP");
+            return (MethodHandles.Lookup)f.get(null);
+        } catch (NoSuchFieldException|IllegalAccessException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    @State(Scope.Thread)
+    @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Fork(3)
+    @BenchmarkMode(Mode.AverageTime)
+    @OutputTimeUnit(TimeUnit.NANOSECONDS)
+    public static class TwoClassPerLoader {
+        XLoader loader;
+        @Benchmark
+        public Class<?> load() throws ClassNotFoundException {
+            return Class.forName("foo.Foo", false, loader);
+        }
+
+        public static void main(String[] args) throws RunnerException {
+            Options opt = new OptionsBuilder()
+                    .include(LookupDefineClass.TwoClassPerLoader.class.getSimpleName())
+                    // .addProfiler(ClassloaderProfiler.class)
+                    // .addProfiler(CompilerProfiler.class)
+                    .build();
+
+            new Runner(opt).run();
+        }
+
+        @Setup(Level.Invocation)
+        public void doSetup() {
+            loader = new XLoader();
+            loader.install("foo.AnonymousHost", FOO_HOST_BYTES);
+        }
+    }
+
+
+    @State(Scope.Thread)
+    @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Fork(3)
+    @BenchmarkMode(Mode.AverageTime)
+    @OutputTimeUnit(TimeUnit.NANOSECONDS)
+    public static class WeakClass {
+        private static final MethodHandles.Lookup HOST_LOOKUP =
+                defineHostClass(new Loader("weak-class-loader"), "foo.AnonymousHost", FOO_HOST_BYTES);
+
+        @Benchmark
+        public Class<?> load() throws ClassNotFoundException {
+            try {
+                return HOST_LOOKUP.defineHiddenClass(X_BYTECODE, false, WEAK);
+            } catch (IllegalAccessException e) {
+                throw new InternalError(e);
+            }
+        }
+
+        public static void main(String[] args) throws RunnerException {
+            Options opt = new OptionsBuilder()
+                    .include(LookupDefineClass.WeakClass.class.getSimpleName())
+                    // .addProfiler(ClassloaderProfiler.class)
+                    // .addProfiler(CompilerProfiler.class)
+                    .build();
+
+            new Runner(opt).run();
+        }
+    }
+
+    @State(Scope.Thread)
+    @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Fork(3)
+    @BenchmarkMode(Mode.AverageTime)
+    @OutputTimeUnit(TimeUnit.NANOSECONDS)
+    public static class UnsafeAnonymousClass {
+        static final sun.misc.Unsafe unsafe = getUnsafe();
+
+        private static final MethodHandles.Lookup lookup =
+                defineHostClass(new Loader("anonymous-class-loader"),"foo.AnonymousHost", FOO_HOST_BYTES);
+
+        @Benchmark
+        public Class<?> load() throws ClassNotFoundException {
+            return unsafe.defineAnonymousClass(lookup.lookupClass(), X_BYTECODE, null);
+        }
+
+        public static void main(String[] args) throws RunnerException {
+            Options opt = new OptionsBuilder()
+                    .include(LookupDefineClass.UnsafeAnonymousClass.class.getSimpleName())
+                    // .addProfiler(ClassloaderProfiler.class)
+                    // .addProfiler(CompilerProfiler.class)
+                    .build();
+
+            new Runner(opt).run();
+        }
+    }
+
+    static sun.misc.Unsafe getUnsafe() {
+        try {
+            Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
+            f.setAccessible(true);
+            return (sun.misc.Unsafe)f.get(null);
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @State(Scope.Thread)
+    @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+    @Fork(3)
+    @BenchmarkMode(Mode.AverageTime)
+    @OutputTimeUnit(TimeUnit.NANOSECONDS)
+    public static class HiddenClass {
+        private static final MethodHandles.Lookup HOST_LOOKUP =
+                defineHostClass(new Loader("hidden-class-loader"),"foo.AnonymousHost", FOO_HOST_BYTES);
+
+        @Benchmark
+        public Class<?> load() throws ClassNotFoundException {
+            try {
+                return HOST_LOOKUP.defineHiddenClass(X_BYTECODE, false);
+            } catch (IllegalAccessException e) {
+                throw new InternalError(e);
+            }
+        }
+
+        public static void main(String[] args) throws RunnerException {
+            Options opt = new OptionsBuilder()
+                    .include(LookupDefineClass.HiddenClass.class.getSimpleName())
+                    // .addProfiler(ClassloaderProfiler.class)
+                    // .addProfiler(CompilerProfiler.class)
+                    .build();
+
+            new Runner(opt).run();
+        }
+    }
+}