changeset 52594:55aafa38f559 nestmates

Initial prototype of Lookup::defineClass to define a dynamic nestmate. javac is updated not to generate the bridge method for lambda. Also experiment to replace the use of Unsafe VM anonmyous class and constant pool patching. Unsafe::defineAnonymousClass supports the following properties: 1. Hidden / non-findable / unregister class The class is not registered in the system dictionary Should a non-findable class forbid any reference to this_class? 2. Weak class The class has a different life cycle as its defining class loader. i.e. it may be reclaimed when the class loader is alive 3. Access to VM annotations VM annotations are internal. 4. Live constants Explore the class data idea to replace the constant pool patching mechanism.
author mchung
date Tue, 23 Oct 2018 13:05:14 -0700
parents 2253132a50a5
children e247c324456d
files make/hotspot/symbols/symbols-unix src/hotspot/share/aot/aotCodeHeap.cpp src/hotspot/share/aot/aotLoader.cpp src/hotspot/share/ci/ciField.cpp src/hotspot/share/ci/ciInstanceKlass.cpp src/hotspot/share/ci/ciInstanceKlass.hpp src/hotspot/share/classfile/classFileParser.cpp src/hotspot/share/classfile/classFileParser.hpp src/hotspot/share/classfile/classLoader.cpp src/hotspot/share/classfile/classLoaderData.cpp src/hotspot/share/classfile/classLoaderData.hpp src/hotspot/share/classfile/classLoaderDataGraph.cpp src/hotspot/share/classfile/classLoaderDataGraph.hpp src/hotspot/share/classfile/classLoaderExt.cpp src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp src/hotspot/share/classfile/classLoaderStats.cpp src/hotspot/share/classfile/defaultMethods.cpp src/hotspot/share/classfile/javaClasses.hpp src/hotspot/share/classfile/klassFactory.cpp src/hotspot/share/classfile/klassFactory.hpp src/hotspot/share/classfile/moduleEntry.hpp src/hotspot/share/classfile/systemDictionary.cpp src/hotspot/share/classfile/systemDictionary.hpp src/hotspot/share/classfile/systemDictionaryShared.cpp src/hotspot/share/include/jvm.h src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp src/hotspot/share/jvmci/vmStructs_jvmci.cpp src/hotspot/share/memory/metaspace.cpp src/hotspot/share/memory/metaspace.hpp src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp src/hotspot/share/memory/metaspace/spaceManager.cpp src/hotspot/share/memory/metaspaceShared.cpp src/hotspot/share/memory/metaspaceTracer.cpp src/hotspot/share/oops/instanceKlass.cpp src/hotspot/share/oops/instanceKlass.hpp src/hotspot/share/oops/instanceMirrorKlass.inline.hpp src/hotspot/share/prims/jvm.cpp src/hotspot/share/prims/jvmtiRedefineClasses.cpp src/hotspot/share/prims/methodHandles.cpp src/hotspot/share/prims/unsafe.cpp src/hotspot/share/runtime/reflection.cpp src/hotspot/share/runtime/vmStructs.cpp src/java.base/share/classes/java/lang/Class.java src/java.base/share/classes/java/lang/ClassLoader.java src/java.base/share/classes/java/lang/System.java src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.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/jdk/internal/misc/JavaLangAccess.java src/java.base/share/native/libjava/ClassLoader.c src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java test/hotspot/gtest/memory/test_metaspace_allocation.cpp test/jdk/java/lang/invoke/defineClass/DefineClassTest.java test/jdk/java/lang/invoke/defineClass/DefineClassWithClassData.java
diffstat 61 files changed, 1529 insertions(+), 285 deletions(-) [+]
line wrap: on
line diff
--- a/make/hotspot/symbols/symbols-unix	Fri Oct 19 03:08:53 2018 -0400
+++ b/make/hotspot/symbols/symbols-unix	Tue Oct 23 13:05:14 2018 -0700
@@ -151,6 +151,7 @@
 JVM_IsVMGeneratedMethodIx
 JVM_LatestUserDefinedLoader
 JVM_LoadLibrary
+JVM_LookupDefineClass
 JVM_MaxMemory
 JVM_MaxObjectInspectionAge
 JVM_MonitorNotify
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -1022,7 +1022,7 @@
 
   InstanceKlass* dyno = InstanceKlass::cast(dyno_klass);
 
-  if (!dyno->is_unsafe_anonymous()) {
+  if (!dyno->is_nonfindable() && !dyno->is_unsafe_anonymous()) {
     if (_klasses_got[dyno_data->_got_index] != dyno) {
       // compile-time class different from runtime class, fail and deoptimize
       sweep_dependent_methods(holder_data);
--- a/src/hotspot/share/aot/aotLoader.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/aot/aotLoader.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -42,7 +42,7 @@
 #define FOR_ALL_AOT_LIBRARIES(lib) for (GrowableArrayIterator<AOTLib*> lib = libraries()->begin(); lib != libraries()->end(); ++lib)
 
 void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) {
-  if (ik->is_unsafe_anonymous()) {
+  if (ik->is_nonfindable() || ik->is_unsafe_anonymous()) {
     // don't even bother
     return;
   }
@@ -62,7 +62,7 @@
 
 uint64_t AOTLoader::get_saved_fingerprint(InstanceKlass* ik) {
   assert(UseAOT, "called only when AOT is enabled");
-  if (ik->is_unsafe_anonymous()) {
+  if (ik->is_nonfindable() || ik->is_unsafe_anonymous()) {
     // don't even bother
     return 0;
   }
--- a/src/hotspot/share/ci/ciField.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/ci/ciField.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -222,9 +222,10 @@
   // Even if general trusting is disabled, trust system-built closures in these packages.
   if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke"))
     return true;
-  // Trust VM unsafe anonymous classes. They are private API (jdk.internal.misc.Unsafe)
-  // and can't be serialized, so there is no hacking of finals going on with them.
-  if (holder->is_unsafe_anonymous())
+  // Trust VM nonfindable and unsafe anonymous classes. They are created via Lookup.defineClass or
+  // the private API (jdk.internal.misc.Unsafe) and can't be serialized, so there is no hacking
+  // of finals going on with them.
+  if (holder->is_nonfindable() || holder->is_unsafe_anonymous())
     return true;
   // Trust final fields in all boxed classes
   if (holder->is_box_klass())
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -63,6 +63,7 @@
   _has_nonstatic_fields = ik->has_nonstatic_fields();
   _has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods();
   _is_unsafe_anonymous = ik->is_unsafe_anonymous();
+  _is_nonfindable = ik->is_nonfindable();
   _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
   _has_injected_fields = -1;
   _implementor = NULL; // we will fill these lazily
@@ -72,14 +73,14 @@
   // by the GC but need to be strong roots if reachable from a current compilation.
   // InstanceKlass are created for both weak and strong metadata.  Ensuring this metadata
   // alive covers the cases where there are weak roots without performance cost.
-  oop holder = ik->holder_phantom();
-  if (ik->is_unsafe_anonymous()) {
+  if (ik->class_loader_data()->is_shortlived()) {
     // Though ciInstanceKlass records class loader oop, it's not enough to keep
-    // VM unsafe anonymous classes alive (loader == NULL). Klass holder should
+    // VM weak nonfindable and unsafe anonymous classes alive (loader == NULL). Klass holder should
     // be used instead. It is enough to record a ciObject, since cached elements are never removed
     // during ciObjectFactory lifetime. ciObjectFactory itself is created for
     // every compilation and lives for the whole duration of the compilation.
-    assert(holder != NULL, "holder of unsafe anonymous class is the mirror which is never null");
+    oop holder = ik->holder_phantom();
+    assert(holder != NULL, "holder of nonfindable or unsafe anonymous class is the mirror which is never null");
     (void)CURRENT_ENV->get_object(holder);
   }
 
@@ -123,6 +124,7 @@
   _nonstatic_fields = NULL;
   _has_injected_fields = -1;
   _is_unsafe_anonymous = false;
+  _is_nonfindable = false;
   _loader = loader;
   _protection_domain = protection_domain;
   _is_shared = false;
--- a/src/hotspot/share/ci/ciInstanceKlass.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/ci/ciInstanceKlass.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -54,6 +54,7 @@
   bool                   _has_nonstatic_fields;
   bool                   _has_nonstatic_concrete_methods;
   bool                   _is_unsafe_anonymous;
+  bool                   _is_nonfindable;
 
   ciFlags                _flags;
   jint                   _nonstatic_field_size;
@@ -182,6 +183,10 @@
   bool is_unsafe_anonymous() {
     return _is_unsafe_anonymous;
   }
+ 
+  bool is_nonfindable() {
+    return _is_nonfindable;
+  }
 
   ciInstanceKlass* get_canonical_holder(int offset);
   ciField* get_field_by_offset(int field_offset, bool is_static);
--- a/src/hotspot/share/classfile/classFileParser.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -2091,7 +2091,7 @@
   // Privileged code can use all annotations.  Other code silently drops some.
   const bool privileged = loader_data->is_the_null_class_loader_data() ||
                           loader_data->is_platform_class_loader_data() ||
-                          loader_data->is_unsafe_anonymous();
+                          loader_data->is_shortlived();
   switch (sid) {
     case vmSymbols::VM_SYMBOL_ENUM_NAME(reflect_CallerSensitive_signature): {
       if (_location != _in_method)  break;  // only allow for methods
@@ -5591,11 +5591,11 @@
 
   ik->set_this_class_index(_this_class_index);
 
-  if (is_unsafe_anonymous()) {
+  if (_is_nonfindable || is_unsafe_anonymous()) {
     // _this_class_index is a CONSTANT_Class entry that refers to this
-    // anonymous class itself. If this class needs to refer to its own methods or
-    // fields, it would use a CONSTANT_MethodRef, etc, which would reference
-    // _this_class_index. However, because this class is anonymous (it's
+    // nonfindable or anonymous class itself. If this class needs to refer to its own
+    // methods or fields, it would use a CONSTANT_MethodRef, etc, which would reference
+    // _this_class_index. However, because this class is nonfindable or anonymous (it's
     // not stored in SystemDictionary), _this_class_index cannot be resolved
     // with ConstantPool::klass_at_impl, which does a SystemDictionary lookup.
     // Therefore, we must eagerly resolve _this_class_index now.
@@ -5617,6 +5617,10 @@
   Handle clh = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(cl));
   ClassLoaderData* cld = ClassLoaderData::class_loader_data_or_null(clh());
   ik->set_package(cld, CHECK);
+  // Obtain this_klass' module entry
+  ModuleEntry* module_entry = ik->module();
+  assert(module_entry != NULL, "module_entry should always be set");
+
 
   const Array<Method*>* const methods = ik->methods();
   assert(methods != NULL, "invariant");
@@ -5672,10 +5676,6 @@
     check_illegal_static_method(ik, CHECK);
   }
 
-  // Obtain this_klass' module entry
-  ModuleEntry* module_entry = ik->module();
-  assert(module_entry != NULL, "module_entry should always be set");
-
   // Obtain java.lang.Module
   Handle module_handle(THREAD, module_entry->module());
 
@@ -5827,6 +5827,7 @@
                                  Handle protection_domain,
                                  const InstanceKlass* unsafe_anonymous_host,
                                  GrowableArray<Handle>* cp_patches,
+                                 bool is_nonfindable,
                                  Publicity pub_level,
                                  TRAPS) :
   _stream(stream),
@@ -5834,6 +5835,7 @@
   _loader_data(loader_data),
   _unsafe_anonymous_host(unsafe_anonymous_host),
   _cp_patches(cp_patches),
+  _is_nonfindable(is_nonfindable),
   _num_patched_klasses(0),
   _max_num_patched_klasses(0),
   _orig_cp_size(0),
@@ -6166,9 +6168,10 @@
         warning("DumpLoadedClassList and CDS are not supported in exploded build");
         DumpLoadedClassList = NULL;
       } else if (SystemDictionaryShared::is_sharing_possible(_loader_data) &&
+                 !_is_nonfindable &&
                  _unsafe_anonymous_host == NULL) {
         // Only dump the classes that can be stored into CDS archive.
-        // Unsafe anonymous classes such as generated LambdaForm classes are also not included.
+        // Nonfindable and unsafe anonymous classes such as generated LambdaForm classes are also not included.
         oop class_loader = _loader_data->class_loader();
         ResourceMark rm(THREAD);
         bool skip = false;
--- a/src/hotspot/share/classfile/classFileParser.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classFileParser.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -84,6 +84,7 @@
   mutable ClassLoaderData* _loader_data;
   const InstanceKlass* _unsafe_anonymous_host;
   GrowableArray<Handle>* _cp_patches; // overrides for CP entries
+  const bool _is_nonfindable;
   int _num_patched_klasses;
   int _max_num_patched_klasses;
   int _orig_cp_size;
@@ -503,6 +504,7 @@
                   Handle protection_domain,
                   const InstanceKlass* unsafe_anonymous_host,
                   GrowableArray<Handle>* cp_patches,
+                  bool is_nonfindable,
                   Publicity pub_level,
                   TRAPS);
 
@@ -525,6 +527,7 @@
   u2 super_class_index() const { return _super_class_index; }
 
   bool is_unsafe_anonymous() const { return _unsafe_anonymous_host != NULL; }
+  bool is_nonfindable() const { return _is_nonfindable; }
   bool is_interface() const { return _access_flags.is_interface(); }
 
   const InstanceKlass* unsafe_anonymous_host() const { return _unsafe_anonymous_host; }
--- a/src/hotspot/share/classfile/classLoader.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classLoader.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -1399,8 +1399,9 @@
                                                            name,
                                                            loader_data,
                                                            protection_domain,
-                                                           NULL, // unsafe_anonymous_host
-                                                           NULL, // cp_patches
+                                                           NULL,  // unsafe_anonymous_host
+                                                           NULL,  // cp_patches
+                                                           false, // is_nonfindable
                                                            THREAD);
   if (HAS_PENDING_EXCEPTION) {
     if (DumpSharedSpaces) {
@@ -1442,8 +1443,8 @@
   assert(DumpSharedSpaces, "sanity");
   assert(stream != NULL, "sanity");
 
-  if (ik->is_unsafe_anonymous()) {
-    // We do not archive unsafe anonymous classes.
+  if (ik->is_nonfindable() || ik->is_unsafe_anonymous()) {
+    // We do not archive nonfindable or unsafe anonymous classes.
     return;
   }
 
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -129,16 +129,16 @@
   _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id, CATCH);
 }
 
-ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous) :
+ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_shortlived) :
   _metaspace(NULL),
   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
                             Monitor::_safepoint_check_never)),
-  _unloading(false), _is_unsafe_anonymous(is_unsafe_anonymous),
+  _unloading(false), _is_shortlived(is_shortlived),
   _modified_oops(true), _accumulated_modified_oops(false),
   // An unsafe anonymous class loader data doesn't have anything to keep
   // it from being unloaded during parsing of the unsafe anonymous class.
   // The null-class-loader should always be kept alive.
-  _keep_alive((is_unsafe_anonymous || h_class_loader.is_null()) ? 1 : 0),
+  _keep_alive((is_shortlived || h_class_loader.is_null()) ? 1 : 0),
   _claim(0),
   _handles(),
   _klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL),
@@ -153,13 +153,13 @@
     initialize_name(h_class_loader);
   }
 
-  if (!is_unsafe_anonymous) {
-    // The holder is initialized later for unsafe anonymous classes, and before calling anything
-    // that call class_loader().
+  if (!is_shortlived) {
+    // The holder is initialized later for weak nonfindable and unsafe anonymous classes,
+    // and before calling anything that call class_loader().
     initialize_holder(h_class_loader);
 
-    // A ClassLoaderData created solely for an unsafe anonymous class should never have a
-    // ModuleEntryTable or PackageEntryTable created for it. The defining package
+    // A ClassLoaderData created solely for an weak nonfindable or unsafe anonymous class should
+    // never have a ModuleEntryTable or PackageEntryTable created for it. The defining package
     // and module for an unsafe anonymous class will be found in its host class.
     _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
     if (h_class_loader.is_null()) {
@@ -281,20 +281,20 @@
   }
 }
 
-// Unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive
+// Weak nonfindable and unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive
 // while the class is being parsed, and if the class appears on the module fixup list.
-// Due to the uniqueness that no other class shares the unsafe anonymous class' name or
-// ClassLoaderData, no other non-GC thread has knowledge of the unsafe anonymous class while
+// Due to the uniqueness that no other class shares the nonfindable or unsafe anonymous class' name or
+// ClassLoaderData, no other non-GC thread has knowledge of the nonfindable or unsafe anonymous class while
 // it is being defined, therefore _keep_alive is not volatile or atomic.
 void ClassLoaderData::inc_keep_alive() {
-  if (is_unsafe_anonymous()) {
+  if (is_shortlived()) {
     assert(_keep_alive >= 0, "Invalid keep alive increment count");
     _keep_alive++;
   }
 }
 
 void ClassLoaderData::dec_keep_alive() {
-  if (is_unsafe_anonymous()) {
+  if (is_shortlived()) {
     assert(_keep_alive > 0, "Invalid keep alive decrement count");
     _keep_alive--;
   }
@@ -401,20 +401,20 @@
   // Do not need to record dependency if the dependency is to a class whose
   // class loader data is never freed.  (i.e. the dependency's class loader
   // is one of the three builtin class loaders and the dependency is not
-  // unsafe anonymous.)
+  // short-lived.)
   if (to_cld->is_permanent_class_loader_data()) {
     return;
   }
 
   oop to;
-  if (to_cld->is_unsafe_anonymous()) {
-    // Just return if an unsafe anonymous class is attempting to record a dependency
-    // to itself.  (Note that every unsafe anonymous class has its own unique class
+  if (to_cld->is_shortlived()) {
+    // Just return if a weak nonfindable or unsafe anonymous class is attempting to record a dependency
+    // to itself.  (Note that every weak nonfindable or unsafe anonymous class has its own unique class
     // loader data.)
     if (to_cld == from_cld) {
       return;
     }
-    // Unsafe anonymous class dependencies are through the mirror.
+    // Nonfindable and unsafe anonymous class dependencies are through the mirror.
     to = k->java_mirror();
   } else {
     to = to_cld->class_loader();
@@ -562,7 +562,7 @@
 const int _default_loader_dictionary_size = 107;
 
 Dictionary* ClassLoaderData::create_dictionary() {
-  assert(!is_unsafe_anonymous(), "unsafe anonymous class loader data do not have a dictionary");
+  assert(!is_shortlived(), "short lived class loader data do not have a dictionary");
   int size;
   bool resizable = false;
   if (_the_null_class_loader_data == NULL) {
@@ -608,7 +608,7 @@
 
 // Unloading support
 bool ClassLoaderData::is_alive() const {
-  bool alive = keep_alive()         // null class loader and incomplete unsafe anonymous klasses.
+  bool alive = keep_alive()         // null class loader and incomplete weak nonfindable or unsafe anonymous klasses.
       || (_holder.peek() != NULL);  // and not cleaned by the GC weak handle processing.
 
   return alive;
@@ -706,13 +706,13 @@
 
 // Returns true if this class loader data is for the app class loader
 // or a user defined system class loader.  (Note that the class loader
-// data may be unsafe anonymous.)
+// data may be short-lived.)
 bool ClassLoaderData::is_system_class_loader_data() const {
   return SystemDictionary::is_system_class_loader(class_loader());
 }
 
 // Returns true if this class loader data is for the platform class loader.
-// (Note that the class loader data may be unsafe anonymous.)
+// (Note that the class loader data may be short-lived.)
 bool ClassLoaderData::is_platform_class_loader_data() const {
   return SystemDictionary::is_platform_class_loader(class_loader());
 }
@@ -720,8 +720,8 @@
 // Returns true if the class loader for this class loader data is one of
 // the 3 builtin (boot application/system or platform) class loaders,
 // including a user-defined system class loader.  Note that if the class
-// loader data is for an unsafe anonymous class then it may get freed by a GC
-// even if its class loader is one of these loaders.
+// loader data is for a weak nonfindable or unsafe anonymous class then it may
+// get freed by a GC even if its class loader is one of these loaders.
 bool ClassLoaderData::is_builtin_class_loader_data() const {
   return (is_boot_class_loader_data() ||
           SystemDictionary::is_system_class_loader(class_loader()) ||
@@ -730,9 +730,9 @@
 
 // Returns true if this class loader data is a class loader data
 // that is not ever freed by a GC.  It must be the CLD for one of the builtin
-// class loaders and not the CLD for an unsafe anonymous class.
+// class loaders and not the CLD for a weak nonfindable or unsafe anonymous class.
 bool ClassLoaderData::is_permanent_class_loader_data() const {
-  return is_builtin_class_loader_data() && !is_unsafe_anonymous();
+  return is_builtin_class_loader_data() && !is_shortlived();
 }
 
 ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() {
@@ -749,8 +749,8 @@
       if (this == the_null_class_loader_data()) {
         assert (class_loader() == NULL, "Must be");
         metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::BootMetaspaceType);
-      } else if (is_unsafe_anonymous()) {
-        metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::UnsafeAnonymousMetaspaceType);
+      } else if (is_shortlived()) {
+        metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ShortLivedMetaspaceType);
       } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) {
         metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType);
       } else {
@@ -867,8 +867,8 @@
   }
 }
 
-// These CLDs are to contain unsafe anonymous classes used for JSR292
-ClassLoaderData* ClassLoaderData::unsafe_anonymous_class_loader_data(Handle loader) {
+// These CLDs are to contain weak nonfindable or unsafe anonymous classes used for JSR292
+ClassLoaderData* ClassLoaderData::shortlived_class_loader_data(Handle loader) {
   // Add a new class loader data to the graph.
   return ClassLoaderDataGraph::add(loader, true);
 }
@@ -910,8 +910,8 @@
     // loader data: 0xsomeaddr of 'bootstrap'
     out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name_and_id());
   }
-  if (is_unsafe_anonymous()) {
-    out->print(" unsafe anonymous");
+  if (_is_shortlived) {
+    out->print(" short-lived");
   }
 }
 
@@ -919,7 +919,7 @@
 void ClassLoaderData::print_on(outputStream* out) const {
   out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {",
               p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id());
-  if (is_unsafe_anonymous()) out->print(" unsafe anonymous");
+  if (is_shortlived()) out->print(" short-lived");
   if (claimed()) out->print(" claimed");
   if (is_unloading()) out->print(" unloading");
   out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
@@ -937,8 +937,8 @@
   assert_locked_or_safepoint(_metaspace_lock);
   oop cl = class_loader();
 
-  guarantee(this == class_loader_data(cl) || is_unsafe_anonymous(), "Must be the same");
-  guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_unsafe_anonymous(), "must be");
+  guarantee(this == class_loader_data(cl) || is_shortlived(), "Must be the same");
+  guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_shortlived(), "must be");
 
   // Verify the integrity of the allocated space.
   if (metaspace_or_null() != NULL) {
--- a/src/hotspot/share/classfile/classLoaderData.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classLoaderData.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -116,17 +116,17 @@
                                     // classes in the class loader are allocated.
   Mutex* _metaspace_lock;  // Locks the metaspace for allocations and setup.
   bool _unloading;         // true if this class loader goes away
-  bool _is_unsafe_anonymous; // CLD is dedicated to one class and that class determines the CLDs lifecycle.
-                             // For example, an unsafe anonymous class.
+  bool _is_shortlived;     // CLD is dedicated to one class and that class determines the CLDs lifecycle.
+                           // For example, a weak nonfindable or an unsafe anonymous class.
 
   // Remembered sets support for the oops in the class loader data.
   bool _modified_oops;             // Card Table Equivalent (YC/CMS support)
   bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
 
   s2 _keep_alive;          // if this CLD is kept alive.
-                           // Used for unsafe anonymous classes and the boot class
-                           // loader. _keep_alive does not need to be volatile or
-                           // atomic since there is one unique CLD per unsafe anonymous class.
+                           // Used for weak nonfindable classes, unsafe anonymous classes and the
+                           // boot class loader. _keep_alive does not need to be volatile or
+                           // atomic since there is one unique CLD per weak nonfindable or unsafe anonymous class.
 
   volatile int _claim; // non-zero if claimed, for example during GC traces.
                        // To avoid applying oop closure more than once.
@@ -161,7 +161,7 @@
   void set_next(ClassLoaderData* next) { _next = next; }
   ClassLoaderData* next() const        { return _next; }
 
-  ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous);
+  ClassLoaderData(Handle h_class_loader, bool is_shortlived);
   ~ClassLoaderData();
 
   // The CLD are not placed in the Heap, so the Card Table or
@@ -229,7 +229,7 @@
 
   Mutex* metaspace_lock() const { return _metaspace_lock; }
 
-  bool is_unsafe_anonymous() const { return _is_unsafe_anonymous; }
+  bool is_shortlived() const { return _is_shortlived; }
 
   static void init_null_class_loader_data();
 
@@ -238,15 +238,15 @@
   }
 
   // Returns true if this class loader data is for the system class loader.
-  // (Note that the class loader data may be unsafe anonymous.)
+  // (Note that the class loader data may be for an weak nonfindable or unsafe anonymous class)
   bool is_system_class_loader_data() const;
 
   // Returns true if this class loader data is for the platform class loader.
-  // (Note that the class loader data may be unsafe anonymous.)
+  // (Note that the class loader data may be for an weak nonfindable or unsafe anonymous class)
   bool is_platform_class_loader_data() const;
 
   // Returns true if this class loader data is for the boot class loader.
-  // (Note that the class loader data may be unsafe anonymous.)
+  // (Note that the class loader data may be for an weak nonfindable unsafe anonymous class)
   inline bool is_boot_class_loader_data() const;
 
   bool is_builtin_class_loader_data() const;
@@ -267,7 +267,7 @@
     return _unloading;
   }
 
-  // Used to refcount an unsafe anonymous class's CLD in order to
+  // Used to refcount an weak nonfindable or unsafe anonymous class's CLD in order to
   // indicate their aliveness.
   void inc_keep_alive();
   void dec_keep_alive();
@@ -307,7 +307,7 @@
 
   static ClassLoaderData* class_loader_data(oop loader);
   static ClassLoaderData* class_loader_data_or_null(oop loader);
-  static ClassLoaderData* unsafe_anonymous_class_loader_data(Handle loader);
+  static ClassLoaderData* shortlived_class_loader_data(Handle loader);
 
   // Returns Klass* of associated class loader, or NULL if associated loader is 'bootstrap'.
   // Also works if unloading.
--- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -179,7 +179,7 @@
 
 // Add a new class loader data node to the list.  Assign the newly created
 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field
-ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_unsafe_anonymous) {
+ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_shortlived) {
 
   assert_lock_strong(ClassLoaderDataGraph_lock);
 
@@ -187,7 +187,7 @@
 
   // First check if another thread beat us to creating the CLD and installing
   // it into the loader while we were waiting for the lock.
-  if (!is_unsafe_anonymous && loader.not_null()) {
+  if (!is_shortlived && loader.not_null()) {
     cld = java_lang_ClassLoader::loader_data_acquire(loader());
     if (cld != NULL) {
       return cld;
@@ -199,14 +199,14 @@
   // loader oop in all collections, particularly young collections.
   NoSafepointVerifier no_safepoints;
 
-  cld = new ClassLoaderData(loader, is_unsafe_anonymous);
+  cld = new ClassLoaderData(loader, is_shortlived);
 
   // First install the new CLD to the Graph.
   cld->set_next(_head);
   _head = cld;
 
   // Next associate with the class_loader.
-  if (!is_unsafe_anonymous) {
+  if (!is_shortlived) {
     // Use OrderAccess, since readers need to get the loader_data only after
     // it's added to the Graph
     java_lang_ClassLoader::release_set_loader_data(loader(), cld);
@@ -224,9 +224,9 @@
   return cld;
 }
 
-ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_unsafe_anonymous) {
+ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_shortlived) {
   MutexLocker ml(ClassLoaderDataGraph_lock);
-  ClassLoaderData* loader_data = add_to_graph(loader, is_unsafe_anonymous);
+  ClassLoaderData* loader_data = add_to_graph(loader, is_shortlived);
   return loader_data;
 }
 
--- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -60,8 +60,8 @@
   static volatile size_t  _num_instance_classes;
   static volatile size_t  _num_array_classes;
 
-  static ClassLoaderData* add_to_graph(Handle class_loader, bool is_unsafe_anonymous);
-  static ClassLoaderData* add(Handle class_loader, bool is_unsafe_anonymous);
+  static ClassLoaderData* add_to_graph(Handle class_loader, bool is_shortlived);
+  static ClassLoaderData* add(Handle class_loader, bool is_shortlived);
 
  public:
   static ClassLoaderData* find_or_create(Handle class_loader);
@@ -77,7 +77,7 @@
   // Walking classes through the ClassLoaderDataGraph include array classes.  It also includes
   // classes that are allocated but not loaded, classes that have errors, and scratch classes
   // for redefinition.  These classes are removed during the next class unloading.
-  // Walking the ClassLoaderDataGraph also includes unsafe anonymous classes.
+  // Walking the ClassLoaderDataGraph also includes nonfindable and unsafe anonymous classes.
   static void classes_do(KlassClosure* klass_closure);
   static void classes_do(void f(Klass* const));
   static void methods_do(void f(Method*));
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -298,8 +298,9 @@
                                                            name,
                                                            loader_data,
                                                            protection_domain,
-                                                           NULL, // unsafe_anonymous_host
-                                                           NULL, // cp_patches
+                                                           NULL,  // unsafe_anonymous_host
+                                                           NULL,  // cp_patches
+                                                           false, // is_nonfindable
                                                            THREAD);
 
   if (HAS_PENDING_EXCEPTION) {
--- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -129,7 +129,7 @@
 
 class LoaderTreeNode : public ResourceObj {
 
-  // We walk the CLDG and, for each CLD which is non-unsafe_anonymous, add
+  // We walk the CLDG and, for each CLD which is findable, add
   // a tree node.
   // To add a node we need its parent node; if the parent node does not yet
   // exist - because we have not yet encountered the CLD for the parent loader -
@@ -220,7 +220,7 @@
       if (print_classes) {
         if (_classes != NULL) {
           for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) {
-            // Non-unsafe anonymous classes should live in the primary CLD of its loader
+            // Nonfindable and unsafe anonymous classes should live in the primary CLD of its loader
             assert(lci->_cld == _cld, "must be");
 
             branchtracker.print(st);
@@ -258,7 +258,7 @@
               st->print("%*s ", indentation, "");
             }
             st->print("%s", lci->_klass->external_name());
-            // For unsafe anonymous classes, also print CLD if verbose. Should be a different one than the primary CLD.
+            // For nonfindable and unsafe anonymous classes, also print CLD if verbose. Should be a different one than the primary CLD.
             assert(lci->_cld != _cld, "must be");
             if (verbose) {
               st->print("  (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld));
@@ -319,14 +319,14 @@
     _next = info;
   }
 
-  void add_classes(LoadedClassInfo* first_class, int num_classes, bool is_unsafe_anonymous) {
-    LoadedClassInfo** p_list_to_add_to = is_unsafe_anonymous ? &_anon_classes : &_classes;
+  void add_classes(LoadedClassInfo* first_class, int num_classes, bool is_nonfindable) {
+    LoadedClassInfo** p_list_to_add_to = is_nonfindable ? &_anon_classes : &_classes;
     // Search tail.
     while ((*p_list_to_add_to) != NULL) {
       p_list_to_add_to = &(*p_list_to_add_to)->_next;
     }
     *p_list_to_add_to = first_class;
-    if (is_unsafe_anonymous) {
+    if (is_nonfindable) {
       _num_anon_classes += num_classes;
     } else {
       _num_classes += num_classes;
@@ -421,7 +421,7 @@
     LoadedClassCollectClosure lccc(cld);
     const_cast<ClassLoaderData*>(cld)->classes_do(&lccc);
     if (lccc._num_classes > 0) {
-      info->add_classes(lccc._list, lccc._num_classes, cld->is_unsafe_anonymous());
+      info->add_classes(lccc._list, lccc._num_classes, cld->is_shortlived());
     }
   }
 
@@ -481,7 +481,7 @@
     assert(info != NULL, "must be");
 
     // Update CLD in node, but only if this is the primary CLD for this loader.
-    if (cld->is_unsafe_anonymous() == false) {
+    if (cld->is_shortlived() == false) {
       assert(info->cld() == NULL, "there should be only one primary CLD per loader");
       info->set_cld(cld);
     }
--- a/src/hotspot/share/classfile/classLoaderStats.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/classLoaderStats.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -59,7 +59,7 @@
     cls = *cls_ptr;
   }
 
-  if (!cld->is_unsafe_anonymous()) {
+  if (!cld->is_shortlived()) {
     cls->_cld = cld;
   }
 
@@ -71,7 +71,7 @@
 
   ClassStatsClosure csc;
   cld->classes_do(&csc);
-  if(cld->is_unsafe_anonymous()) {
+  if(cld->is_shortlived()) {
     cls->_anon_classes_count += csc._num_classes;
   } else {
     cls->_classes_count = csc._num_classes;
@@ -80,7 +80,7 @@
 
   ClassLoaderMetaspace* ms = cld->metaspace_or_null();
   if (ms != NULL) {
-    if(cld->is_unsafe_anonymous()) {
+    if(cld->is_shortlived()) {
       cls->_anon_chunk_sz += ms->allocated_chunks_bytes();
       cls->_anon_block_sz += ms->allocated_blocks_bytes();
     } else {
--- a/src/hotspot/share/classfile/defaultMethods.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/defaultMethods.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -885,7 +885,7 @@
     ConstantPool* cp = bpool->create_constant_pool(CHECK);
     if (cp != klass->constants()) {
       // Copy resolved anonymous class into new constant pool.
-      if (klass->is_unsafe_anonymous()) {
+      if (klass->is_unsafe_anonymous() || klass->is_nonfindable()) {
         cp->klass_at_put(klass->this_class_index(), klass);
       }
       klass->class_loader_data()->add_to_deallocate_list(klass->constants());
--- a/src/hotspot/share/classfile/javaClasses.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -1109,16 +1109,20 @@
 
   // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
   enum {
-    MN_IS_METHOD            = 0x00010000, // method (not constructor)
-    MN_IS_CONSTRUCTOR       = 0x00020000, // constructor
-    MN_IS_FIELD             = 0x00040000, // field
-    MN_IS_TYPE              = 0x00080000, // nested type
-    MN_CALLER_SENSITIVE     = 0x00100000, // @CallerSensitive annotation detected
-    MN_REFERENCE_KIND_SHIFT = 24, // refKind
-    MN_REFERENCE_KIND_MASK  = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+    MN_IS_METHOD             = 0x00010000, // method (not constructor)
+    MN_IS_CONSTRUCTOR        = 0x00020000, // constructor
+    MN_IS_FIELD              = 0x00040000, // field
+    MN_IS_TYPE               = 0x00080000, // nested type
+    MN_CALLER_SENSITIVE      = 0x00100000, // @CallerSensitive annotation detected
+    MN_REFERENCE_KIND_SHIFT  = 24, // refKind
+    MN_REFERENCE_KIND_MASK   = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
     // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
-    MN_SEARCH_SUPERCLASSES  = 0x00100000, // walk super classes
-    MN_SEARCH_INTERFACES    = 0x00200000  // walk implemented interfaces
+    MN_SEARCH_SUPERCLASSES   = 0x00100000, // walk super classes
+    MN_SEARCH_INTERFACES     = 0x00200000, // walk implemented interfaces
+    MN_NESTMATE_CLASS        = 0x00000001,
+    MN_NONFINDABLE_CLASS     = 0x00000002,
+    MN_WEAK_CLASS            = 0x00000004,
+    MN_ACCESS_VM_ANNOTATIONS = 0x00100000
   };
 
   // Accessors for code generation:
--- a/src/hotspot/share/classfile/klassFactory.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/klassFactory.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -99,8 +99,9 @@
                              class_name,
                              loader_data,
                              protection_domain,
-                             NULL,
-                             NULL,
+                             NULL,  // unsafe_anonymous_host
+                             NULL,  // cp_patches
+                             false, // is_nonfindable
                              ClassFileParser::BROADCAST, // publicity level
                              CHECK_NULL);
       InstanceKlass* new_ik = parser.create_instance_klass(true /* changed_by_loadhook */,
@@ -185,6 +186,7 @@
                                                 Handle protection_domain,
                                                 const InstanceKlass* unsafe_anonymous_host,
                                                 GrowableArray<Handle>* cp_patches,
+                                                bool is_nonfindable,
                                                 TRAPS) {
   assert(stream != NULL, "invariant");
   assert(loader_data != NULL, "invariant");
@@ -200,8 +202,8 @@
   // increment counter
   THREAD->statistical_info().incr_define_class_count();
 
-  // Skip this processing for VM anonymous classes
-  if (unsafe_anonymous_host == NULL) {
+  // Skip this processing for VM nonfindable or anonymous classes
+  if (is_nonfindable || (unsafe_anonymous_host == NULL)) {
     stream = check_class_file_load_hook(stream,
                                         name,
                                         loader_data,
@@ -216,6 +218,7 @@
                          protection_domain,
                          unsafe_anonymous_host,
                          cp_patches,
+                         is_nonfindable,
                          ClassFileParser::BROADCAST, // publicity level
                          CHECK_NULL);
 
--- a/src/hotspot/share/classfile/klassFactory.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/klassFactory.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -74,6 +74,7 @@
                                            Handle protection_domain,
                                            const InstanceKlass* unsafe_anonymous_host,
                                            GrowableArray<Handle>* cp_patches,
+                                           bool is_nonfindable,
                                            TRAPS);
  public:
   static InstanceKlass* check_shared_class_file_load_hook(
--- a/src/hotspot/share/classfile/moduleEntry.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/moduleEntry.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -110,7 +110,7 @@
   ClassLoaderData* loader_data() const                 { return _loader_data; }
 
   void set_loader_data(ClassLoaderData* cld) {
-    assert(!cld->is_unsafe_anonymous(), "Unexpected unsafe anonymous class loader data");
+    assert(!cld->is_shortlived(), "Unexpected short-lived class loader data");
     _loader_data = cld;
   }
 
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -987,24 +987,37 @@
 
 // Note: this method is much like resolve_from_stream, but
 // does not publish the classes via the SystemDictionary.
-// Handles unsafe_DefineAnonymousClass and redefineclasses
-// RedefinedClasses do not add to the class hierarchy
+// Handles Lookup.defineClass nonfindable, unsafe_DefineAnonymousClass
+// and redefineclasses. RedefinedClasses do not add to the class hierarchy.
 InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
                                               Handle class_loader,
                                               Handle protection_domain,
                                               ClassFileStream* st,
                                               const InstanceKlass* unsafe_anonymous_host,
                                               GrowableArray<Handle>* cp_patches,
+                                              const bool is_nonfindable,
+                                              const bool is_weaknonfindable,
                                               TRAPS) {
 
   EventClassLoad class_load_start_event;
 
   ClassLoaderData* loader_data;
+ 
   if (unsafe_anonymous_host != NULL) {
-    // Create a new CLD for an unsafe anonymous class, that uses the same class loader
-    // as the unsafe_anonymous_host
+    // - for unsafe anonymous class: create a new short-lived CLD that uses the same
+    //                               class loader as the unsafe_anonymous_host.
     guarantee(oopDesc::equals(unsafe_anonymous_host->class_loader(), class_loader()), "should be the same");
-    loader_data = ClassLoaderData::unsafe_anonymous_class_loader_data(class_loader);
+    loader_data = ClassLoaderData::shortlived_class_loader_data(class_loader);
+  } else if (is_nonfindable) {
+    // - for weak nonfindable class: create a new short-lived CLD whose loader is
+    //                               the Lookup class' loader.
+    // - for nonfindable class: add the class to the Lookup class' loader's CLD. 
+    if (is_weaknonfindable) {
+      loader_data = ClassLoaderData::shortlived_class_loader_data(class_loader);
+    } else {
+      // This nonfindable class goes into the regular CLD pool for this loader.
+      loader_data = register_loader(class_loader);
+    }
   } else {
     loader_data = ClassLoaderData::class_loader_data(class_loader());
   }
@@ -1023,12 +1036,15 @@
                                                       protection_domain,
                                                       unsafe_anonymous_host,
                                                       cp_patches,
+                                                      is_nonfindable,
                                                       CHECK_NULL);
 
-  if (unsafe_anonymous_host != NULL && k != NULL) {
-    // Unsafe anonymous classes must update ClassLoaderData holder (was unsafe_anonymous_host loader)
+  if ((is_nonfindable || (unsafe_anonymous_host != NULL)) && k != NULL) {
+    // Weak nonfindable and unsafe anonymous classes must update ClassLoaderData holder
     // so that they can be unloaded when the mirror is no longer referenced.
-    k->class_loader_data()->initialize_holder(Handle(THREAD, k->java_mirror()));
+    if (is_weaknonfindable || (unsafe_anonymous_host != NULL)) {
+      k->class_loader_data()->initialize_holder(Handle(THREAD, k->java_mirror()));
+    }
 
     {
       MutexLocker mu_r(Compile_lock, THREAD);
@@ -1049,7 +1065,7 @@
       k->constants()->patch_resolved_references(cp_patches);
     }
 
-    // If it's anonymous, initialize it now, since nobody else will.
+    // Initialize it now, since nobody else will.
     k->eager_initialize(CHECK_NULL);
 
     // notify jvmti
@@ -1120,8 +1136,9 @@
                                          class_name,
                                          loader_data,
                                          protection_domain,
-                                         NULL, // unsafe_anonymous_host
-                                         NULL, // cp_patches
+                                         NULL,  // unsafe_anonymous_host
+                                         NULL,  // cp_patches
+                                         false, // is_nonfindable
                                          CHECK_NULL);
   }
 
@@ -3021,7 +3038,7 @@
       _master_dictionary(master_dictionary) {}
     void do_cld(ClassLoaderData* cld) {
       ResourceMark rm;
-      if (cld->is_unsafe_anonymous()) {
+      if (cld->is_shortlived()) {
         return;
       }
       if (cld->is_system_class_loader_data() || cld->is_platform_class_loader_data()) {
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -281,8 +281,10 @@
                         class_loader,
                         protection_domain,
                         st,
-                        NULL, // unsafe_anonymous_host
-                        NULL, // cp_patches
+                        NULL,  // unsafe_anonymous_host
+                        NULL,  // cp_patches
+                        false, // is_nonfindable
+                        false, // is_weaknonfindable
                         THREAD);
   }
   static InstanceKlass* parse_stream(Symbol* class_name,
@@ -291,6 +293,8 @@
                                      ClassFileStream* st,
                                      const InstanceKlass* unsafe_anonymous_host,
                                      GrowableArray<Handle>* cp_patches,
+                                     const bool is_nonfindable,
+                                     const bool is_weaknonfindable,
                                      TRAPS);
 
   // Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -581,7 +581,7 @@
   if (shared_dictionary() == NULL) {
     return NULL;
   }
-  if (class_name == NULL) {  // don't do this for anonymous classes
+  if (class_name == NULL) {  // don't do this for nonfindable and unsafe anonymous classes
     return NULL;
   }
   if (class_loader.is_null() ||
@@ -754,11 +754,11 @@
          Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
   assert(DumpSharedSpaces, "called at dump time only");
 
-  // Skip unsafe anonymous classes, which are not archived as they are not in
-  // dictionary (see assert_no_unsafe_anonymous_classes_in_dictionaries() in
+  // Skip nonfindable and unsafe anonymous classes, which are not archived as they
+  // are not in dictionary (see assert_no_nonfindable_classes_in_dictionaries() in
   // VM_PopulateDumpSharedSpace::doit()).
-  if (k->class_loader_data()->is_unsafe_anonymous()) {
-    return true; // unsafe anonymous classes are not archived, skip
+  if (k->is_nonfindable()) {
+    return true; // nonfindable and unsafe anonymous classes are not archived, skip
   }
 
   SharedDictionaryEntry* entry = ((SharedDictionary*)(k->class_loader_data()->dictionary()))->find_entry_for(k);
--- a/src/hotspot/share/include/jvm.h	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/include/jvm.h	Tue Oct 23 13:05:14 2018 -0700
@@ -386,6 +386,21 @@
                           const char *source);
 
 /*
+ * Define a class with the specified lookup class.
+ *  lookup:  Lookup class
+ *  name:    the name of the class
+ *  loader:  defining class loader
+ *  buf:     class bytes
+ *  len:     length of class bytes
+ *  pd:      protection domain
+ *  flags:   properties of the class
+ *  classData: private static pre-initialized field; may be null
+ */
+JNIEXPORT jclass JNICALL
+JVM_LookupDefineClass(JNIEnv *env, jclass lookup, const char *name, jobject loader,
+                      const jbyte *buf, jsize len, jobject pd, int flags, jobject classData);
+
+/*
  * Module support funcions
  */
 
--- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -1409,8 +1409,9 @@
                              class_name,
                              cld,
                              pd,
-                             NULL, // host klass
-                             NULL, // cp_patches
+                             NULL,  // host klass
+                             NULL,  // cp_patches
+                             false, // is_nonfindable
                              ClassFileParser::INTERNAL, // internal visibility
                              THREAD);
   if (HAS_PENDING_EXCEPTION) {
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -77,7 +77,7 @@
 
 static traceid cld_id(CldPtr cld) {
   assert(cld != NULL, "invariant");
-  return cld->is_unsafe_anonymous() ? 0 : TRACE_ID(cld);
+  return cld->is_shortlived() ? 0 : TRACE_ID(cld);
 }
 
 static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) {
@@ -92,7 +92,7 @@
   }
   CldPtr cld = k->class_loader_data();
   assert(cld != NULL, "invariant");
-  if (!cld->is_unsafe_anonymous()) {
+  if (!cld->is_shortlived()) {
     tag_leakp_artifact(cld, class_unload);
   }
 }
@@ -230,7 +230,7 @@
 int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) {
   assert(c != NULL, "invariant");
   CldPtr cld = (CldPtr)c;
-  assert(!cld->is_unsafe_anonymous(), "invariant");
+  assert(!cld->is_shortlived(), "invariant");
   const traceid cld_id = TRACE_ID(cld);
   // class loader type
   const Klass* class_loader_klass = cld->class_loader_klass();
@@ -358,7 +358,7 @@
       }
       CldPtr cld = klass->class_loader_data();
       assert(cld != NULL, "invariant");
-      if (!cld->is_unsafe_anonymous()) {
+      if (!cld->is_shortlived()) {
         count += class_loader_symbols(cld);
       }
       if (_method_used_predicate(klass)) {
@@ -432,7 +432,7 @@
 template <template <typename> class Predicate>
 int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) {
   assert(cld != NULL, "invariant");
-  assert(!cld->is_unsafe_anonymous(), "invariant");
+  assert(!cld->is_shortlived(), "invariant");
   int count = 0;
   // class loader type
   const Klass* class_loader_klass = cld->class_loader_klass();
@@ -696,7 +696,7 @@
   static TypePtr select(KlassPtr klass) {
     assert(klass != NULL, "invariant");
     CldPtr cld = klass->class_loader_data();
-    return cld->is_unsafe_anonymous() ? NULL : cld;
+    return cld->is_shortlived() ? NULL : cld;
   }
 };
 
@@ -922,7 +922,7 @@
   CLDCallback(bool class_unload) : _class_unload(class_unload) {}
   void do_cld(ClassLoaderData* cld) {
      assert(cld != NULL, "invariant");
-    if (cld->is_unsafe_anonymous()) {
+    if (cld->is_shortlived()) {
       return;
     }
     if (_class_unload) {
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -120,7 +120,7 @@
 
 void JfrTraceId::assign(const ClassLoaderData* cld) {
   assert(cld != NULL, "invariant");
-  if (cld->is_unsafe_anonymous()) {
+  if (cld->is_shortlived()) {
     cld->set_trace_id(0);
     return;
   }
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -96,7 +96,7 @@
 
 inline traceid JfrTraceId::use(const ClassLoaderData* cld, bool leakp /* false */) {
   assert(cld != NULL, "invariant");
-  return cld->is_unsafe_anonymous() ? 0 : set_used_and_get_shifted(cld, leakp);
+  return cld->is_shortlived() ? 0 : set_used_and_get_shifted(cld, leakp);
 }
 
 inline bool JfrTraceId::in_visible_set(const Klass* klass) {
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -528,6 +528,7 @@
   declare_constant(InstanceKlass::linked)                                 \
   declare_constant(InstanceKlass::fully_initialized)                      \
   declare_constant(InstanceKlass::_misc_is_unsafe_anonymous)              \
+  declare_constant(InstanceKlass::_misc_is_nonfindable)                   \
                                                                           \
   declare_constant(JumpData::taken_off_set)                               \
   declare_constant(JumpData::displacement_off_set)                        \
--- a/src/hotspot/share/memory/metaspace.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/memory/metaspace.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -62,7 +62,7 @@
   switch (t) {
     case Metaspace::StandardMetaspaceType: s = "Standard"; break;
     case Metaspace::BootMetaspaceType: s = "Boot"; break;
-    case Metaspace::UnsafeAnonymousMetaspaceType: s = "UnsafeAnonymous"; break;
+    case Metaspace::ShortLivedMetaspaceType: s = "ShortLived"; break;
     case Metaspace::ReflectionMetaspaceType: s = "Reflection"; break;
     default: ShouldNotReachHere();
   }
--- a/src/hotspot/share/memory/metaspace.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/memory/metaspace.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -103,8 +103,8 @@
     ZeroMetaspaceType = 0,
     StandardMetaspaceType = ZeroMetaspaceType,
     BootMetaspaceType = StandardMetaspaceType + 1,
-    UnsafeAnonymousMetaspaceType = BootMetaspaceType + 1,
-    ReflectionMetaspaceType = UnsafeAnonymousMetaspaceType + 1,
+    ShortLivedMetaspaceType = BootMetaspaceType + 1,
+    ReflectionMetaspaceType = ShortLivedMetaspaceType + 1,
     MetaspaceTypeCount
   };
 
@@ -242,7 +242,7 @@
 
   // Initialize the first chunk for a Metaspace.  Used for
   // special cases such as the boot class loader, reflection
-  // class loader and anonymous class loader.
+  // class loader and nonfindable class loader.
   void initialize_first_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype);
   metaspace::Metachunk* get_initialization_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype);
 
@@ -396,7 +396,7 @@
     rf_show_loaders                 = (1 << 0),
     // Breaks report down by chunk type (small, medium, ...).
     rf_break_down_by_chunktype      = (1 << 1),
-    // Breaks report down by space type (anonymous, reflection, ...).
+    // Breaks report down by space type (nonfindable, reflection, ...).
     rf_break_down_by_spacetype      = (1 << 2),
     // Print details about the underlying virtual spaces.
     rf_show_vslist                  = (1 << 3),
--- a/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -78,7 +78,7 @@
     _out->print(UINTX_FORMAT_W(4) ": ", _num_loaders);
 
     // Print "CLD for [<loader name>,] instance of <loader class name>"
-    // or    "CLD for <anonymous class>, loaded by [<loader name>,] instance of <loader class name>"
+    // or    "CLD for <weak nonfindable class>, loaded by [<loader name>,] instance of <loader class name>"
 
     ResourceMark rm;
     const char* name = NULL;
@@ -102,8 +102,12 @@
       _out->print(" (unloading)");
     }
     _out->print(":");
-    if (cld->is_unsafe_anonymous()) {
-      _out->print(" <anonymous class>, loaded by");
+    if (cld->is_shortlived()) {
+      if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {
+        _out->print(" <unsafe anonymous class>, loaded by");
+      } else { 
+        _out->print(" <weak nonfindable class>, loaded by");
+      }
     }
     if (name != NULL) {
       _out->print(" \"%s\"", name);
--- a/src/hotspot/share/memory/metaspace/spaceManager.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/memory/metaspace/spaceManager.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -75,14 +75,14 @@
   if (is_class()) {
     switch (type) {
     case Metaspace::BootMetaspaceType:              requested = Metaspace::first_class_chunk_word_size(); break;
-    case Metaspace::UnsafeAnonymousMetaspaceType:   requested = ClassSpecializedChunk; break;
+    case Metaspace::ShortLivedMetaspaceType:        requested = ClassSpecializedChunk; break;
     case Metaspace::ReflectionMetaspaceType:        requested = ClassSpecializedChunk; break;
     default:                                        requested = ClassSmallChunk; break;
     }
   } else {
     switch (type) {
     case Metaspace::BootMetaspaceType:              requested = Metaspace::first_chunk_word_size(); break;
-    case Metaspace::UnsafeAnonymousMetaspaceType:   requested = SpecializedChunk; break;
+    case Metaspace::ShortLivedMetaspaceType:        requested = SpecializedChunk; break;
     case Metaspace::ReflectionMetaspaceType:        requested = SpecializedChunk; break;
     default:                                        requested = SmallChunk; break;
     }
@@ -114,15 +114,15 @@
   // After that a medium chunk is preferred.
   size_t chunk_word_size;
 
-  // Special case for unsafe anonymous metadata space.
-  // UnsafeAnonymous metadata space is usually small since it is used for
-  // class loader data's whose life cycle is governed by one class such as an
-  // unsafe anonymous class.  The majority within 1K - 2K range and
+  // Special case for nonfindable metadata space.
+  // ShortLived metadata space is usually small since it is used for
+  // class loader data's whose life cycle is governed by one class such as a
+  // weak nonfindable or unsafe anonymous class.  The majority within 1K - 2K range and
   // rarely about 4K (64-bits JVM).
   // Instead of jumping to SmallChunk after initial chunk exhausted, keeping allocation
   // from SpecializeChunk up to _anon_or_delegating_metadata_specialize_chunk_limit (4)
   // reduces space waste from 60+% to around 30%.
-  if ((_space_type == Metaspace::UnsafeAnonymousMetaspaceType || _space_type == Metaspace::ReflectionMetaspaceType) &&
+  if ((_space_type == Metaspace::ShortLivedMetaspaceType || _space_type == Metaspace::ReflectionMetaspaceType) &&
       _mdtype == Metaspace::NonClassType &&
       num_chunks_by_type(SpecializedIndex) < anon_and_delegating_metadata_specialize_chunk_limit &&
       word_size + Metachunk::overhead() <= SpecializedChunk) {
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -584,13 +584,13 @@
 }
 
 NOT_PRODUCT(
-static void assert_not_unsafe_anonymous_class(InstanceKlass* k) {
-  assert(!(k->is_unsafe_anonymous()), "cannot archive unsafe anonymous classes");
+static void assert_nonfindable_class(InstanceKlass* k) {
+  assert(!(k->is_nonfindable() || k->is_unsafe_anonymous()), "cannot archive nonfindable or unsafe anonymous classes");
 }
 
-// Unsafe anonymous classes are not stored inside any dictionaries.
-static void assert_no_unsafe_anonymous_classes_in_dictionaries() {
-  ClassLoaderDataGraph::dictionary_classes_do(assert_not_unsafe_anonymous_class);
+// Nonfindable and unsafe anonymous classes are not stored inside any dictionaries.
+static void assert_no_nonfindable_classes_in_dictionaries() {
+  ClassLoaderDataGraph::dictionary_classes_do(assert_nonfindable_class);
 })
 
 // Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables.
@@ -1417,9 +1417,9 @@
   remove_unshareable_in_classes();
   tty->print_cr("done. ");
 
-  // We don't support archiving unsafe anonymous classes. Verify that they are not stored in
-  // any dictionaries.
-  NOT_PRODUCT(assert_no_unsafe_anonymous_classes_in_dictionaries());
+  // We don't support archiving nonfindable and unsafe anonymous classes.
+  // Verify that they are not stored in any dictionaries.
+  NOT_PRODUCT(assert_no_nonfindable_classes_in_dictionaries());
 
   SystemDictionaryShared::finalize_verification_constraints();
 
--- a/src/hotspot/share/memory/metaspaceTracer.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/memory/metaspaceTracer.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -62,7 +62,7 @@
   E event;
   if (event.should_commit()) {
     event.set_classLoader(cld);
-    if (cld->is_unsafe_anonymous()) {
+    if (cld->is_shortlived()) {
       event.set_unsafeAnonymousClassLoader(true);
     } else {
       event.set_unsafeAnonymousClassLoader(false);
--- a/src/hotspot/share/oops/instanceKlass.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -345,7 +345,7 @@
                                        parser.itable_size(),
                                        nonstatic_oop_map_size(parser.total_oop_map_count()),
                                        parser.is_interface(),
-                                       parser.is_unsafe_anonymous(),
+                                       (parser.is_nonfindable() || parser.is_unsafe_anonymous()),
                                        should_store_fingerprint(parser.is_unsafe_anonymous()));
 
   const Symbol* const class_name = parser.class_name();
@@ -416,6 +416,7 @@
     set_vtable_length(parser.vtable_size());
     set_kind(kind);
     set_access_flags(parser.access_flags());
+    set_is_nonfindable(parser.is_nonfindable());
     set_is_unsafe_anonymous(parser.is_unsafe_anonymous());
     set_layout_helper(Klass::instance_layout_helper(parser.layout_size(),
                                                     false));
@@ -2179,7 +2180,7 @@
   return true;
 }
 
-bool InstanceKlass::should_store_fingerprint(bool is_unsafe_anonymous) {
+bool InstanceKlass::should_store_fingerprint(bool is_nonfindable) {
 #if INCLUDE_AOT
   // We store the fingerprint into the InstanceKlass only in the following 2 cases:
   if (CalculateClassFingerprint) {
@@ -2190,8 +2191,8 @@
     // (2) We are running -Xshare:dump to create a shared archive
     return true;
   }
-  if (UseAOT && is_unsafe_anonymous) {
-    // (3) We are using AOT code from a shared library and see an unsafe anonymous class
+  if (UseAOT && is_nonfindable) {
+    // (3) We are using AOT code from a shared library and see a nonfindable or unsafe anonymous class
     return true;
   }
 #endif
@@ -2560,6 +2561,17 @@
     return unsafe_anonymous_host()->module();
   }
 
+  if (is_nonfindable() && in_unnamed_package()) {
+    // For a nonfindable class defined to an unnamed package, the CLD
+    // will not have an unnamed module created for it.
+    // Two choices to find the correct ModuleEntry:
+    // 1. If nonfindable class is within a nest, use nest host's module
+    // 2. Find the unnamed module off from the class loader
+    oop module = java_lang_ClassLoader::unnamedModule(class_loader_data()->class_loader());
+    assert(java_lang_Module::is_instance(module), "Not an instance of java.lang.Module");
+    return java_lang_Module::module_entry(module);
+  }
+
   // Class is in a named package
   if (!in_unnamed_package()) {
     return _package_entry->module();
--- a/src/hotspot/share/oops/instanceKlass.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -237,12 +237,13 @@
     _misc_is_shared_boot_class                = 1 << 12, // defining class loader is boot class loader
     _misc_is_shared_platform_class            = 1 << 13, // defining class loader is platform class loader
     _misc_is_shared_app_class                 = 1 << 14, // defining class loader is app class loader
-    _misc_has_resolved_methods                = 1 << 15  // resolved methods table entries added for this class
+    _misc_has_resolved_methods                = 1 << 15, // resolved methods table entries added for this class
+    _misc_is_nonfindable                      = 1 << 16  // is a non findable class, not stored in the SystemDictionary.
   };
   u2 loader_type_bits() {
     return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
   }
-  u2              _misc_flags;
+  u4              _misc_flags;
   u2              _minor_version;        // minor version number of class file
   u2              _major_version;        // major version number of class file
   Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recusive initialization)
@@ -457,6 +458,8 @@
   // nest-host index
   jushort nest_host_index() const { return _nest_host_index; }
   void set_nest_host_index(u2 i)  { _nest_host_index = i; }
+  void set_nest_host(InstanceKlass* host) { assert(_nest_host == NULL, "nest host already set"); _nest_host = host; }
+  InstanceKlass* raw_nest_host() const { return _nest_host; }
 
 private:
   // Called to verify that k is a member of this nest - does not look at k's nest-host
@@ -676,10 +679,21 @@
     }
   }
 
+  bool is_nonfindable() const                {
+    return (_misc_flags & _misc_is_nonfindable) != 0;
+  }
+  void set_is_nonfindable(bool value)        {
+    if (value) {
+      _misc_flags |= _misc_is_nonfindable;
+    } else {
+      _misc_flags &= ~_misc_is_nonfindable;
+    }
+  }
+
   // Oop that keeps the metadata for this class from being unloaded
   // in places where the metadata is stored in other places, like nmethods
   oop klass_holder() const {
-    return (is_unsafe_anonymous()) ? java_mirror() : class_loader();
+    return (class_loader_data()->is_shortlived()) ? java_mirror() : class_loader();
   }
 
   bool is_contended() const                {
@@ -773,8 +787,8 @@
   }
   bool supers_have_passed_fingerprint_checks();
 
-  static bool should_store_fingerprint(bool is_unsafe_anonymous);
-  bool should_store_fingerprint() const { return should_store_fingerprint(is_unsafe_anonymous()); }
+  static bool should_store_fingerprint(bool is_nonfindable);
+  bool should_store_fingerprint() const { return should_store_fingerprint(is_nonfindable() || is_unsafe_anonymous()); }
   bool has_stored_fingerprint() const;
   uint64_t get_stored_fingerprint() const;
   void store_fingerprint(uint64_t fingerprint);
@@ -1056,20 +1070,20 @@
 
   static int size(int vtable_length, int itable_length,
                   int nonstatic_oop_map_size,
-                  bool is_interface, bool is_unsafe_anonymous, bool has_stored_fingerprint) {
+                  bool is_interface, bool is_nonfindable, bool has_stored_fingerprint) {
     return align_metadata_size(header_size() +
            vtable_length +
            itable_length +
            nonstatic_oop_map_size +
            (is_interface ? (int)sizeof(Klass*)/wordSize : 0) +
-           (is_unsafe_anonymous ? (int)sizeof(Klass*)/wordSize : 0) +
+           (is_nonfindable ? (int)sizeof(Klass*)/wordSize : 0) +
            (has_stored_fingerprint ? (int)sizeof(uint64_t*)/wordSize : 0));
   }
   int size() const                    { return size(vtable_length(),
                                                itable_length(),
                                                nonstatic_oop_map_size(),
                                                is_interface(),
-                                               is_unsafe_anonymous(),
+                                               (is_nonfindable() || is_unsafe_anonymous()),
                                                has_stored_fingerprint());
   }
 #if INCLUDE_SERVICES
--- a/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp	Tue Oct 23 13:05:14 2018 -0700
@@ -51,10 +51,9 @@
     Klass* klass = java_lang_Class::as_Klass_raw(obj);
     // We'll get NULL for primitive mirrors.
     if (klass != NULL) {
-      if (klass->is_instance_klass() &&
-          InstanceKlass::cast(klass)->is_unsafe_anonymous()) {
-        // An unsafe anonymous class doesn't have its own class loader, so
-        // when handling the java mirror for the class we need to make sure its class
+      if (klass->is_instance_klass() && klass->class_loader_data()->is_shortlived()) {
+        // A weak nonfindable or an unsafe anonymous class doesn't have its own class loader,
+        // so when handling the java mirror for the class we need to make sure its class
         // loader data is claimed, this is done by calling do_cld explicitly.
         // For non-anonymous classes the call to do_cld is made when the class
         // loader itself is handled.
--- a/src/hotspot/share/prims/jvm.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/prims/jvm.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -941,6 +941,125 @@
   return (jclass) JNIHandles::make_local(env, k->java_mirror());
 }
 
+enum {
+  NESTMATE              = java_lang_invoke_MemberName::MN_NESTMATE_CLASS,
+  NONFINDABLE_CLASS     = java_lang_invoke_MemberName::MN_NONFINDABLE_CLASS,
+  WEAK_CLASS            = java_lang_invoke_MemberName::MN_WEAK_CLASS,
+  ACCESS_VM_ANNOTATIONS = java_lang_invoke_MemberName::MN_ACCESS_VM_ANNOTATIONS
+};
+
+/*
+ * Define a class with the specified flags that indicates if it's a nestmate,
+ * not findable, or weakly reachable from class loader.
+ *
+ * Same class may be defined by multiple threads at the same time.
+ * Should the VM keep the classData (the one successfully defined the class)
+ * as if a private static field is declared in the class?
+ */
+static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *name,
+                                      jobject loader, const jbyte *buf, jsize len, jobject pd,
+                                      int flags, jobject classData, TRAPS) {
+  assert(THREAD->is_Java_thread(), "must be a JavaThread");
+  JavaThread* jt = (JavaThread*) THREAD;
+  ResourceMark rm(THREAD);
+
+  const Klass* lookup_class = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup));
+  jboolean is_nestmate = (flags & NESTMATE) == NESTMATE;
+  jboolean is_nonfindable = (flags & NONFINDABLE_CLASS) == NONFINDABLE_CLASS;
+  jboolean is_weak = (flags & WEAK_CLASS) == WEAK_CLASS;
+  jboolean vm_annotations = (flags & ACCESS_VM_ANNOTATIONS) == ACCESS_VM_ANNOTATIONS;
+
+  // Lookup class must be a non-null instance
+  if (lookup_class == NULL) {
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null");
+  }
+  assert(lookup_class->is_instance_klass(), "Lookup class must be an instance klass");
+
+  // classData (constant pool patching replacement) is only applicable for nonfindable classes 
+  if (classData != NULL && !is_nonfindable) {
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "classData is only applicable for nonfindable classes");
+  }
+
+  // vm_annotations only allowed for nonfindable classes
+  if (vm_annotations && !is_nonfindable) {
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "vm annotations only allowed for weak nonfindable classes");
+  }
+
+  if (log_is_enabled(Info, class, nestmates)) {
+    log_info(class, nestmates)("Lookup define class %s is_nestmate %d is_nonfindable %d is_weak %d vm annotations %d name %s",
+                                lookup_class->external_name(), is_nestmate, is_nonfindable, is_weak, vm_annotations, name);
+  }
+
+  // Since exceptions can be thrown, class initialization can take place
+  // if name is NULL no check for class name in .class stream has to be made.
+  TempNewSymbol class_name = NULL;
+  if (name != NULL) {
+    const int str_len = (int)strlen(name);
+    if (str_len > Symbol::max_length()) {
+      // It's impossible to create this class;  the name cannot fit
+      // into the constant pool.
+      Exceptions::fthrow(THREAD_AND_LOCATION,
+                         vmSymbols::java_lang_NoClassDefFoundError(),
+                         "Class name exceeds maximum length of %d: %s",
+                         Symbol::max_length(),
+                         name);
+      return 0;
+    }
+    class_name = SymbolTable::new_symbol(name, str_len, CHECK_NULL);
+  }
+
+  Klass* k;
+  const InstanceKlass* nest_host = InstanceKlass::cast(lookup_class);
+  Handle class_loader (THREAD, JNIHandles::resolve(loader));
+  Handle protection_domain (THREAD, JNIHandles::resolve(pd));
+  const char* source = is_nestmate ? nest_host->external_name() : "__JVM_LookupDefineClass__";
+  ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);
+
+  if (!is_nonfindable) {
+    k = SystemDictionary::resolve_from_stream(class_name,
+                                              class_loader,
+                                              protection_domain,
+                                              &st,
+                                              CHECK_NULL);
+
+    if (log_is_enabled(Debug, class, resolve) && k != NULL) {
+      trace_class_resolution(k);
+    }
+  } else { //nonfindable
+    k = SystemDictionary::parse_stream(class_name,
+                                       class_loader,
+                                       protection_domain,
+                                       &st,
+                                       NULL, // unsafe_anonymous_host
+                                       NULL, // cp_patches
+                                       is_nonfindable,
+                                       true, // is_weak - workaround to allow access to VM annotations
+                                       CHECK_NULL);
+    if (k == NULL) {
+      THROW_MSG_0(vmSymbols::java_lang_Error(), "Failure to define a nonfindable class");
+    }
+
+    // The nonfindable class loader data has been artificially been kept alive to
+    // this point. The mirror and any instances of this class have to keep
+    // it alive afterwards.
+    InstanceKlass::cast(k)->class_loader_data()->dec_keep_alive();
+  }
+
+  // set nest host
+  if (is_nestmate) {
+    InstanceKlass* ik = InstanceKlass::cast(k);
+    ik->set_nest_host((InstanceKlass*)nest_host);
+    if (log_is_enabled(Debug, class, nestmates)) {
+      ModuleEntry* module = ik->module();
+      const char * module_name = module->is_named() ? module->name()->as_C_string() : UNNAMED_MODULE;
+      log_debug(class, nestmates)("Dynamic nestmate: %s module %s nest_host %s is_nonfindable %s",
+                                  ik->external_name(), module_name, nest_host->external_name(),
+                                  ik->is_nonfindable() ? "true" : "false");
+    }
+  }
+
+  return (jclass) JNIHandles::make_local(env, k->java_mirror());
+}
 
 JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
   JVMWrapper("JVM_DefineClass");
@@ -948,6 +1067,29 @@
   return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
 JVM_END
 
+/*
+ * Define a class with the specified lookup class.
+ *  lookup:  Lookup class
+ *  name:    the name of the class
+ *  loader:  defining class loader
+ *  buf:     class bytes
+ *  len:     length of class bytes
+ *  pd:      protection domain
+ *  flags:   properties of the class
+ *  classData: private static pre-initialized field
+ */
+JVM_ENTRY(jclass, JVM_LookupDefineClass(JNIEnv *env, jclass lookup, const char *name, jobject loader,
+                      const jbyte *buf, jsize len, jobject pd, int flags, jobject classData))
+  JVMWrapper("JVM_LookupDefineClass");
+
+  if (lookup == NULL) {
+    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null");
+  }
+
+  assert(buf != NULL, "buf must not be NULL");
+
+  return jvm_lookup_define_class(env, lookup, name, loader, buf, len, pd, flags, classData, THREAD);
+JVM_END
 
 JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))
   JVMWrapper("JVM_DefineClassWithSource");
@@ -1514,7 +1656,7 @@
     = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))
                           )->compute_enclosing_class(&inner_is_member, CHECK_NULL);
   if (outer_klass == NULL)  return NULL;  // already a top-level class
-  if (!inner_is_member)  return NULL;     // an anonymous class (inside a method)
+  if (!inner_is_member)  return NULL;     // a nonfindable or unsafe anonymous class (inside a method)
   return (jclass) JNIHandles::make_local(env, outer_klass->java_mirror());
 }
 JVM_END
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -137,8 +137,9 @@
     }
 
     oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
-    // classes for primitives and arrays and vm unsafe anonymous classes cannot be redefined
-    // check here so following code can assume these classes are InstanceKlass
+    // classes for primitives, arrays, nonfindable and vm unsafe anonymous classes
+    // cannot be redefined.  Check here so following code can assume these classes
+    // are InstanceKlass.
     if (!is_modifiable_class(mirror)) {
       _res = JVMTI_ERROR_UNMODIFIABLE_CLASS;
       return false;
@@ -279,8 +280,9 @@
     return false;
   }
 
-  // Cannot redefine or retransform an unsafe anonymous class.
-  if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {
+  // Cannot redefine or retransform a nonfindable or an unsafe anonymous class.
+  if (InstanceKlass::cast(k)->is_nonfindable() ||
+      InstanceKlass::cast(k)->is_unsafe_anonymous()) {
     return false;
   }
   return true;
--- a/src/hotspot/share/prims/methodHandles.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/prims/methodHandles.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -1153,6 +1153,10 @@
     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
+    template(java_lang_invoke_MemberName,MN_NESTMATE_CLASS) \
+    template(java_lang_invoke_MemberName,MN_NONFINDABLE_CLASS) \
+    template(java_lang_invoke_MemberName,MN_WEAK_CLASS) \
+    template(java_lang_invoke_MemberName,MN_ACCESS_VM_ANNOTATIONS) \
     /*end*/
 
 #define IGNORE_REQ(req_expr) /* req_expr */
--- a/src/hotspot/share/prims/unsafe.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/prims/unsafe.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -819,6 +819,8 @@
                                                 &st,
                                                 InstanceKlass::cast(host_klass),
                                                 cp_patches,
+                                                false, // is_nonfindable
+                                                false, // is_weak
                                                 CHECK_NULL);
   if (anonk == NULL) {
     return NULL;
--- a/src/hotspot/share/runtime/reflection.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/runtime/reflection.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -711,6 +711,22 @@
     return true;
   }
 
+  /*
+   * Dynamic nestmate C attempts to access R where R's nest host is H.
+   * This is a temporary hack to allow C to access private R.m until
+   * properly resolved.
+   *
+   * e.g. jdk.internal.module.SystemModuleFinders$1$$Lambda$1/0x0000000800061040
+   * is a static nest member of jdk.internal.module.SystemModuleFinders
+   * but access jdk.internal.module.SystemModuleFinders$1.lambda$find$0
+   */
+  InstanceKlass* nest_host = InstanceKlass::cast((Klass*) current_class)->raw_nest_host();
+  if (access.is_private() && nest_host != NULL && nest_host != current_class) {
+    if (nest_host == InstanceKlass::cast(member_class)->raw_nest_host()) {
+      return true;
+    }
+  }
+
   // private access between different classes needs a nestmate check, but
   // not for unsafe anonymous classes - so check host_class
   if (access.is_private() && host_class == current_class) {
@@ -744,7 +760,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 unsafe anonymous (a non-member).
+// If !inner_is_member, require the inner to be a nonfindable or unsafe anonymous (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/hotspot/share/runtime/vmStructs.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -235,7 +235,7 @@
   nonstatic_field(InstanceKlass,               _static_oop_field_count,                       u2)                                    \
   nonstatic_field(InstanceKlass,               _nonstatic_oop_map_size,                       int)                                   \
   nonstatic_field(InstanceKlass,               _is_marked_dependent,                          bool)                                  \
-  nonstatic_field(InstanceKlass,               _misc_flags,                                   u2)                                    \
+  nonstatic_field(InstanceKlass,               _misc_flags,                                   u4)                                    \
   nonstatic_field(InstanceKlass,               _minor_version,                                u2)                                    \
   nonstatic_field(InstanceKlass,               _major_version,                                u2)                                    \
   nonstatic_field(InstanceKlass,               _init_state,                                   u1)                                    \
@@ -509,7 +509,7 @@
   nonstatic_field(ClassLoaderData,             _class_loader,                                 OopHandle)                             \
   nonstatic_field(ClassLoaderData,             _next,                                         ClassLoaderData*)                      \
   volatile_nonstatic_field(ClassLoaderData,    _klasses,                                      Klass*)                                \
-  nonstatic_field(ClassLoaderData,             _is_unsafe_anonymous,                          bool)                                  \
+  nonstatic_field(ClassLoaderData,             _is_shortlived,                                bool)                                  \
   volatile_nonstatic_field(ClassLoaderData,    _dictionary,                                   Dictionary*)                           \
                                                                                                                                      \
      static_field(ClassLoaderDataGraph,        _head,                                         ClassLoaderData*)                      \
@@ -2270,6 +2270,7 @@
   declare_constant(InstanceKlass::_misc_is_shared_boot_class)             \
   declare_constant(InstanceKlass::_misc_is_shared_platform_class)         \
   declare_constant(InstanceKlass::_misc_is_shared_app_class)              \
+  declare_constant(InstanceKlass::_misc_is_nonfindable)                   \
                                                                           \
   /*********************************/                                     \
   /* Symbol* - symbol max length */                                       \
--- a/src/java.base/share/classes/java/lang/Class.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/Class.java	Tue Oct 23 13:05:14 2018 -0700
@@ -26,6 +26,7 @@
 package java.lang;
 
 import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandles;
 import java.lang.module.ModuleReader;
 import java.lang.ref.SoftReference;
 import java.io.IOException;
@@ -305,7 +306,10 @@
      * @exception LinkageError if the linkage fails
      * @exception ExceptionInInitializerError if the initialization provoked
      *            by this method fails
-     * @exception ClassNotFoundException if the class cannot be located
+     * @exception ClassNotFoundException if the class cannot be located, or
+     *            the class is {@linkplain #isHidden() hidden}
+     *
+     * @see Class#isHidden
      */
     @CallerSensitive
     public static Class<?> forName(String className)
@@ -364,7 +368,8 @@
      * @exception ExceptionInInitializerError if the initialization provoked
      *            by this method fails
      * @exception ClassNotFoundException if the class cannot be located by
-     *            the specified class loader
+     *            the specified class loader, or
+     *            the class is {@linkplain #isHidden() hidden}
      * @exception SecurityException
      *            if a security manager is present, and the {@code loader} is
      *            {@code null}, and the caller's class loader is not
@@ -373,6 +378,7 @@
      *
      * @see       java.lang.Class#forName(String)
      * @see       java.lang.ClassLoader
+     * @see       java.lang.Class#isHidden
      * @since     1.2
      */
     @CallerSensitive
@@ -430,7 +436,8 @@
      * @param  name     The <a href="ClassLoader.html#name">binary name</a>
      *                  of the class
      * @return {@code Class} object of the given name defined in the given module;
-     *         {@code null} if not found.
+     *         {@code null} if not found or the class is defined in
+     *         the given module but {@linkplain #isHidden() hidden}
      *
      * @throws NullPointerException if the given module or name is {@code null}
      *
@@ -446,6 +453,7 @@
      *         in a module.</li>
      *         </ul>
      *
+     * @see       java.lang.Class#isHidden
      * @since 9
      * @spec JPMS
      */
@@ -847,6 +855,12 @@
     // set by VM
     private transient Module module;
 
+    // set by VM (to be revisited if needed)
+    // for static nestmate, set to non-null when the first time Class::getNestHost is called
+    // for dynamic nestmate, set to non-null when it's defined and this keeps the host alive
+    // (the host may be temporary)
+    private transient Class<?> nestHost;
+
     // Initialized in JVM not by private constructor
     // This field is filtered from reflection access, i.e. getDeclaredField
     // will throw NoSuchFieldException
@@ -2784,6 +2798,11 @@
         if (sm != null) {
             sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
         }
+        return protectionDomain();
+    }
+
+    // package-private
+    java.security.ProtectionDomain protectionDomain() {
         java.security.ProtectionDomain pd = getProtectionDomain0();
         if (pd == null) {
             if (allPermDomain == null) {
@@ -2798,7 +2817,6 @@
         return pd;
     }
 
-
     /**
      * Returns the ProtectionDomain of this class.
      */
@@ -3888,6 +3906,10 @@
      * {@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.
      *
      * @return the nest host of this class or interface
      *
@@ -3979,6 +4001,17 @@
      * 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.
+     *
      * @return an array of all classes and interfaces in the same nest as
      * this class
      *
@@ -3995,6 +4028,7 @@
      *
      * @since 11
      * @see #getNestHost()
+     * @see MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty...)
      */
     @CallerSensitive
     public Class<?>[] getNestMembers() {
@@ -4016,4 +4050,33 @@
         }
         return members;
     }
+
+    /**
+     * Returns {@code true} if this class is hidden from being referenced
+     * by other classes; otherwise, {@code false}.
+     *
+     * <p> A <em>hidden class</em> is a class that cannot be referenced
+     * by other classes and cannot be loaded by its name.
+     * <p> A hidden class can be defined via
+     * {@link MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty[])
+     * Lookup.defineClass} with
+     * {@link MethodHandles.Lookup.ClassProperty#HIDDEN HIDDEN} property.
+     *
+     * <p> If this class is hidden then it cannot be found via its name.
+     * For example, {@code Class.forName(this.getName())} cannot find this class
+     * and {@code ClassNotFoundException} will be thrown.
+     *
+     * <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}.
+     *
+     * @since 12
+     * @see MethodHandles.Lookup#defineClass(byte[], MethodHandles.Lookup.ClassProperty[])
+     */
+    public boolean isHidden() {
+        // TODO: replace this with VM support
+        return ReflectUtil.isVMAnonymousClass(this);
+    }
 }
--- a/src/java.base/share/classes/java/lang/ClassLoader.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java	Tue Oct 23 13:05:14 2018 -0700
@@ -1117,6 +1117,27 @@
                                         int off, int len, ProtectionDomain pd,
                                         String source);
 
+    /**
+     * Defines a class of the given flags via Lookup.defineClass.
+     *
+     * @param loader the defining loader
+     * @param lookup nest host of the Class to be defined
+     * @param name the binary name or {@code null} if not findable
+     * @param b class bytes
+     * @param off the start offset in {@code b} of the class bytes
+     * @param len the length of the class bytes
+     * @param pd protection domain
+     * @param flags flags
+     * @param classData class data
+     */
+    static native Class<?> defineClass0(ClassLoader loader,
+                                        Class<?> lookup,
+                                        String name,
+                                        byte[] b, int off, int len,
+                                        ProtectionDomain pd,
+                                        int flags,
+                                        Object classData);
+
     // true if the name is null or has the potential to be a valid binary name
     private boolean checkName(String name) {
         if ((name == null) || (name.length() == 0))
--- a/src/java.base/share/classes/java/lang/System.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/System.java	Tue Oct 23 13:05:14 2018 -0700
@@ -2168,6 +2168,10 @@
             public Class<?> defineClass(ClassLoader loader, String name, byte[] b, ProtectionDomain pd, String source) {
                 return ClassLoader.defineClass1(loader, name, b, 0, b.length, pd, source);
             }
+            public Class<?> defineClass(ClassLoader loader, Class<?> lookup, String name, byte[] b, ProtectionDomain pd,
+                                        int flags, Object classData) {
+                return ClassLoader.defineClass0(loader, lookup, name, b, 0, b.length, pd, flags, classData);
+            }
             public Class<?> findBootstrapClassOrNull(ClassLoader cl, String name) {
                 return cl.findBootstrapClassOrNull(name);
             }
@@ -2250,6 +2254,10 @@
             public void setCause(Throwable t, Throwable cause) {
                 t.setCause(cause);
             }
+
+            public ProtectionDomain protectionDomain(Class<?> c) {
+                return c.protectionDomain();
+            }
         });
     }
 }
--- a/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java	Tue Oct 23 13:05:14 2018 -0700
@@ -183,26 +183,22 @@
     private static byte[] generateCodeBytesForLFs(String className,
             String[] names, LambdaForm[] forms) {
 
+
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
         cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
                 className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null);
         cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
 
         for (int i = 0; i < forms.length; i++) {
-            addMethod(className, names[i], forms[i],
-                    forms[i].methodType(), cw);
+            InvokerBytecodeGenerator g
+                = new InvokerBytecodeGenerator(className, names[i], forms[i], forms[i].methodType());
+            g.setClassWriter(cw);
+            g.addMethod();
         }
+
         return cw.toByteArray();
     }
 
-    private static void addMethod(String className, String methodName, LambdaForm form,
-            MethodType type, ClassWriter cw) {
-        InvokerBytecodeGenerator g
-                = new InvokerBytecodeGenerator(className, methodName, form, type);
-        g.setClassWriter(cw);
-        g.addMethod();
-    }
-
     private static LambdaForm makeReinvokerFor(MethodType type) {
         MethodHandle emptyHandle = MethodHandles.empty(type);
         return DelegatingMethodHandle.makeReinvokerForm(emptyHandle,
--- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Tue Oct 23 13:05:14 2018 -0700
@@ -32,6 +32,7 @@
 
 import java.io.FilePermission;
 import java.io.Serializable;
+import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.Constructor;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -40,6 +41,7 @@
 import java.util.PropertyPermission;
 import java.util.Set;
 
+import static java.lang.invoke.MethodHandles.Lookup.*;
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 /**
@@ -316,8 +318,13 @@
             // createDirectories may need it
             new PropertyPermission("user.dir", "read"));
         }
-
-        return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
+        try {
+            Lookup lookup = MethodHandles.privateLookupIn(targetClass, IMPL_LOOKUP);
+            // this class is linked at the indy callsite.  No need to be weak class
+            return lookup.defineClassWithNoCheck(classBytes, HIDDEN_NESTMATE);
+        } catch (ReflectiveOperationException e) {
+            throw new LambdaConversionException(e);
+        }
     }
 
     /**
--- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Oct 23 13:05:14 2018 -0700
@@ -26,6 +26,7 @@
 package java.lang.invoke;
 
 import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
@@ -42,6 +43,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.stream.Stream;
 
 import static java.lang.invoke.LambdaForm.BasicType;
@@ -49,6 +51,7 @@
 import static java.lang.invoke.LambdaForm.*;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.*;
 
 /**
  * Code generation backend for LambdaForm.
@@ -67,6 +70,8 @@
 
     private static final String LOOP_CLAUSES = MHI + "$LoopClauses";
     private static final String MHARY2       = "[[L" + MH + ";";
+    private static final String MH_SIG       = "L" + MH + ";";
+
 
     private static final String LF_SIG  = "L" + LF + ";";
     private static final String LFN_SIG = "L" + LFN + ";";
@@ -92,6 +97,7 @@
     /** ASM bytecode generation. */
     private ClassWriter cw;
     private MethodVisitor mv;
+    private final List<ClassData> classData = new ArrayList<>();
 
     /** Single element internal class name lookup cache. */
     private Class<?> lastClass;
@@ -99,6 +105,15 @@
 
     private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
     private static final Class<?> HOST_CLASS = LambdaForm.class;
+    private static final MethodHandles.Lookup LOOKUP = lookup();
+
+    private static MethodHandles.Lookup lookup() {
+        try {
+            return MethodHandles.privateLookupIn(HOST_CLASS, IMPL_LOOKUP);
+        } catch (IllegalAccessException e) {
+            throw newInternalError(e);
+        }
+    }
 
     /** Main constructor; other constructors delegate to this one. */
     private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
@@ -217,41 +232,52 @@
         return className;
     }
 
-    class CpPatch {
-        final int index;
+    public static class ClassData {
+        final String name;
+        final String desc;
         final Object value;
-        CpPatch(int index, Object value) {
-            this.index = index;
+
+        ClassData(String name, String desc, Object value) {
+            this.name = name;
+            this.desc = desc;
             this.value = value;
         }
+
+        public String name() { return name; }
         public String toString() {
-            return "CpPatch/index="+index+",value="+value;
+            return name + ",value="+value;
         }
     }
 
-    private final ArrayList<CpPatch> cpPatches = new ArrayList<>();
+    String classData(Object arg) {
+        String desc;
+        if (arg instanceof Class) {
+            desc = "Ljava/lang/Class;";
+        } else if (arg instanceof MethodHandle) {
+            desc = MH_SIG;
+        } else if (arg instanceof LambdaForm) {
+            desc = LF_SIG;
+        } else {
+            desc = "Ljava/lang/Object;";
+        }
 
-    private int cph = 0;  // for counting constant placeholders
-
-    String constantPlaceholder(Object arg) {
-        String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
-        if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>";
-        // TODO check if arg is already in the constant pool
-        // insert placeholder in CP and remember the patch
-        int index = cw.newConst((Object) cpPlaceholder);
-        cpPatches.add(new CpPatch(index, arg));
-        return cpPlaceholder;
+        Class<?> c = arg.getClass();
+        while (c.isArray()) {
+            c = c.getComponentType();
+        }
+        // unique static variable name
+        String name = "_DATA_" + c.getSimpleName() + "_" + classData.size();
+        ClassData cd = new ClassData(name, desc, arg);
+        classData.add(cd);
+        return cd.name();
     }
 
-    Object[] cpPatches(byte[] classFile) {
-        int size = getConstantPoolSize(classFile);
-        Object[] res = new Object[size];
-        for (CpPatch p : cpPatches) {
-            if (p.index >= size)
-                throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
-            res[p.index] = p.value;
+    List<Object> classDataValues() {
+        Object[] data = new Object[classData.size()];
+        for (int i = 0; i < classData.size(); i++) {
+            data[i] = classData.get(i).value;
         }
-        return res;
+        return List.of(data);
     }
 
     private static String debugString(Object arg) {
@@ -283,20 +309,21 @@
     /**
      * Extract the MemberName of a newly-defined method.
      */
-    private MemberName loadMethod(byte[] classFile) {
-        Class<?> invokerClass = loadAndInitializeInvokerClass(classFile, cpPatches(classFile));
+    private MemberName loadMethod(byte[] classFile, List<Object> classData) {
+        Class<?> invokerClass = loadAndInitializeInvokerClass(classFile, classData);
         return resolveInvokerMember(invokerClass, invokerName, invokerType);
     }
 
     /**
      * Define a given class as anonymous class in the runtime system.
      */
-    private static Class<?> loadAndInitializeInvokerClass(byte[] classBytes, Object[] patches) {
-        Class<?> invokerClass = UNSAFE.defineAnonymousClass(HOST_CLASS, classBytes, patches);
+    private static Class<?> loadAndInitializeInvokerClass(byte[] classBytes, List<Object> classData) {
+        Class<?> invokerClass = LOOKUP.defineClassWithNoCheck(classBytes, WEAK_HIDDEN_NESTMATE, classData);
         UNSAFE.ensureClassInitialized(invokerClass);  // Make sure the class is initialized; VM might complain.
         return invokerClass;
     }
 
+
     private static MemberName resolveInvokerMember(Class<?> invokerClass, String name, MethodType type) {
         MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic);
         try {
@@ -312,7 +339,8 @@
      */
     private ClassWriter classFilePrologue() {
         final int NOT_ACC_PUBLIC = 0;  // not ACC_PUBLIC
-        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+        setClassWriter(cw);
         cw.visit(Opcodes.V1_8, NOT_ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
                 CLASS_PREFIX + className, null, INVOKER_SUPER_NAME, null);
         cw.visitSource(SOURCE_PREFIX + className, null);
@@ -332,6 +360,48 @@
         mv.visitEnd();
     }
 
+    private String className() {
+        return CLASS_PREFIX + className;
+    }
+
+    private void clinit() {
+        clinit(cw, className(), classData);
+    }
+
+    static void clinit(ClassWriter cw, String className, List<ClassData> classData) {
+        if (classData.isEmpty())
+            return;
+
+        for (ClassData p : classData) {
+            // add the static field
+            FieldVisitor fv = cw.visitField(Opcodes.ACC_STATIC|Opcodes.ACC_FINAL, p.name, p.desc, null, null);
+            fv.visitEnd();
+        }
+
+        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
+        mv.visitCode();
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/invoke/MethodHandles",
+                           "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false);
+        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup",
+                           "classData", "()Ljava/lang/Object;", false);
+        // we should optimize one single element case that does not need to create a List
+        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/List");
+        mv.visitVarInsn(Opcodes.ASTORE, 0);
+        int index = 0;
+        for (ClassData p : classData) {
+            // initialize the static field
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            emitIconstInsn(mv, index++);
+            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
+                               "get", "(I)Ljava/lang/Object;", true);
+            mv.visitTypeInsn(Opcodes.CHECKCAST, p.desc.substring(1, p.desc.length()-1));
+            mv.visitFieldInsn(Opcodes.PUTSTATIC, className, p.name, p.desc);
+        }
+        mv.visitInsn(Opcodes.RETURN);
+        mv.visitMaxs(2, 1);
+        mv.visitEnd();
+    }
+
     /*
      * Low-level emit helpers.
      */
@@ -404,6 +474,10 @@
     }
 
     private void emitIconstInsn(final int cst) {
+        emitIconstInsn(mv, cst);
+    }
+
+    private static void emitIconstInsn(MethodVisitor mv, int cst) {
         if (cst >= -1 && cst <= 5) {
             mv.visitInsn(Opcodes.ICONST_0 + cst);
         } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
@@ -573,8 +647,7 @@
             String sig = getInternalName(cls);
             mv.visitTypeInsn(Opcodes.CHECKCAST, sig);
         } else {
-            mv.visitLdcInsn(constantPlaceholder(cls));
-            mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
+            mv.visitFieldInsn(Opcodes.GETSTATIC, className(), classData(cls), "Ljava/lang/Class;");
             mv.visitInsn(Opcodes.SWAP);
             mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CLS, "cast", LL_SIG, false);
             if (Object[].class.isAssignableFrom(cls))
@@ -690,7 +763,7 @@
         if (pregenerated != null)  return pregenerated; // pre-generated bytecode
 
         InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType);
-        return g.loadMethod(g.generateCustomizedCodeBytes());
+        return g.loadMethod(g.generateCustomizedCodeBytes(), g.classDataValues());
     }
 
     /** Generates code to check that actual receiver and LambdaForm matches */
@@ -733,6 +806,7 @@
     private byte[] generateCustomizedCodeBytes() {
         classFilePrologue();
         addMethod();
+        clinit();
         bogusMethod(lambdaForm);
 
         final byte[] classFile = toByteArray();
@@ -760,14 +834,14 @@
             mv.visitAnnotation(DONTINLINE_SIG, true);
         }
 
-        constantPlaceholder(lambdaForm); // keep LambdaForm instance & its compiled form lifetime tightly coupled.
+        classData(lambdaForm); // keep LambdaForm instance & its compiled form lifetime tightly coupled.
 
         if (lambdaForm.customized != null) {
             // Since LambdaForm is customized for a particular MethodHandle, it's safe to substitute
             // receiver MethodHandle (at slot #0) with an embedded constant and use it instead.
             // It enables more efficient code generation in some situations, since embedded constants
             // are compile-time constants for JIT compiler.
-            mv.visitLdcInsn(constantPlaceholder(lambdaForm.customized));
+            mv.visitFieldInsn(Opcodes.GETSTATIC, className(), classData(lambdaForm.customized), MH_SIG);
             mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
             assert(checkActualReceiver()); // expects MethodHandle on top of the stack
             mv.visitVarInsn(Opcodes.ASTORE, localsMap[0]);
@@ -897,7 +971,7 @@
             // push receiver
             MethodHandle target = name.function.resolvedHandle();
             assert(target != null) : name.exprString();
-            mv.visitLdcInsn(constantPlaceholder(target));
+            mv.visitFieldInsn(Opcodes.GETSTATIC, className(), classData(target), MH_SIG);
             emitReferenceCast(MethodHandle.class, target);
         } else {
             // load receiver
@@ -1056,7 +1130,7 @@
             }
             assert(java.lang.reflect.Array.getLength(emptyArray) == 0);
             assert(emptyArray.getClass() == rtype);  // exact typing
-            mv.visitLdcInsn(constantPlaceholder(emptyArray));
+            mv.visitFieldInsn(Opcodes.GETSTATIC, className(), classData(emptyArray), "Ljava/lang/Object;");
             emitReferenceCast(rtype, emptyArray);
             return;
         }
@@ -1597,7 +1671,7 @@
             if (Wrapper.isWrapperType(arg.getClass()) && bptype != L_TYPE) {
                 emitConst(arg);
             } else {
-                mv.visitLdcInsn(constantPlaceholder(arg));
+                mv.visitFieldInsn(Opcodes.GETSTATIC, className(), classData(arg), "Ljava/lang/Object;");
                 emitImplicitConversion(L_TYPE, ptype, arg);
             }
         }
@@ -1744,7 +1818,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());
+        return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes(), g.classDataValues());
     }
 
     private byte[] generateLambdaFormInterpreterEntryPointBytes() {
@@ -1789,6 +1863,7 @@
         emitReturnInsn(basicType(rtype));
 
         methodEpilogue();
+        clinit();
         bogusMethod(invokerType);
 
         final byte[] classFile = cw.toByteArray();
@@ -1803,7 +1878,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));
+        return g.loadMethod(g.generateNamedFunctionInvokerImpl(typeForm), g.classDataValues());
     }
 
     private byte[] generateNamedFunctionInvokerImpl(MethodTypeForm typeForm) {
@@ -1857,6 +1932,7 @@
         emitReturnInsn(L_TYPE);  // NOTE: NamedFunction invokers always return a reference value.
 
         methodEpilogue();
+        clinit();
         bogusMethod(dstType);
 
         final byte[] classFile = cw.toByteArray();
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Oct 23 13:05:14 2018 -0700
@@ -1216,6 +1216,13 @@
 
         private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
             try {
+                /* ## TODO
+                 * The invoker class defined to the same class loader as the lookup class
+                 * but in an unnamed package so that the class bytes can be cached and
+                 * reused for any @CSM.
+                 *
+                 * @CSM must be public and exported if called by any module.
+                 */
                 Class<?> invokerClass = UNSAFE.defineAnonymousClass(hostClass, INJECTED_INVOKER_TEMPLATE, null);
                 assert checkInjectedInvoker(hostClass, invokerClass);
                 return IMPL_LOOKUP.findStatic(invokerClass, "invoke_V", INVOKER_MT);
@@ -1846,7 +1853,6 @@
                         .generateInvokersHolderClassBytes(className,
                                 invokerMethodTypes, callSiteMethodTypes);
             }
-
         });
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Oct 23 13:05:14 2018 -0700
@@ -136,6 +136,15 @@
             REF_newInvokeSpecial        = 8,
             REF_invokeInterface         = 9,
             REF_LIMIT                  = 10;
+
+        /**
+         * Flags for Lookup.ClassProperty
+         */
+        static final int
+            NESTMATE_CLASS            = 0x00000001,
+            NONFINDABLE_CLASS         = 0x00000002,
+            WEAK_CLASS                = 0x00000004,
+            ACCESS_VM_ANNOTATIONS     = 0x00100000;
     }
 
     static boolean refKindIsValid(int refKind) {
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Tue Oct 23 13:05:14 2018 -0700
@@ -25,6 +25,7 @@
 
 package java.lang.invoke;
 
+import jdk.internal.misc.JavaLangAccess;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.module.IllegalAccessLogger;
 import jdk.internal.org.objectweb.asm.ClassReader;
@@ -45,8 +46,6 @@
 import java.lang.reflect.Modifier;
 import java.lang.reflect.ReflectPermission;
 import java.nio.ByteOrder;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -55,10 +54,12 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 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;
@@ -180,7 +181,7 @@
      * @param targetClass the target class
      * @param lookup the caller lookup object
      * @return a lookup object for the target class, with private access
-     * @throws IllegalArgumentException if {@code targetClass} is a primitve type or array class
+     * @throws IllegalArgumentException if {@code targetClass} is a primitive type or array class
      * @throws NullPointerException if {@code targetClass} or {@code caller} is {@code null}
      * @throws IllegalAccessException if the access check specified above fails
      * @throws SecurityException if denied by the security manager
@@ -189,6 +190,10 @@
      * @see Lookup#dropLookupMode
      */
     public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
+        if (lookup.allowedModes == Lookup.TRUSTED) {
+            return new Lookup(targetClass);
+        }
+
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
         if (targetClass.isPrimitive())
@@ -771,13 +776,12 @@
          */
         Lookup(Class<?> lookupClass) {
             this(lookupClass, FULL_POWER_MODES);
-            // make sure we haven't accidentally picked up a privileged class:
-            checkUnprivilegedlookupClass(lookupClass);
         }
 
         private Lookup(Class<?> lookupClass, int allowedModes) {
             this.lookupClass = lookupClass;
             this.allowedModes = allowedModes;
+            assert !lookupClass.isPrimitive() && !lookupClass.isArray();
         }
 
         /**
@@ -815,6 +819,8 @@
          * @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
@@ -822,6 +828,11 @@
          */
         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);
             if (requestedLookupClass == this.lookupClass)
@@ -896,6 +907,10 @@
          * {@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, (ClassProperty[])null)}.
+         *
          * <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
@@ -930,13 +945,286 @@
          * @see ClassLoader#defineClass(String,byte[],int,int,ProtectionDomain)
          */
         public Class<?> defineClass(byte[] bytes) throws IllegalAccessException {
+            return defineClass(bytes, (ClassProperty[])null);
+        }
+
+        /**
+         * 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.
+         *
+         * <p> A class can be defined 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 referenced by 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:
+         *     The Java virtual machine does not find a hidden class with
+         *     its name.  A hidden class can reference its members
+         *     locally with the name of the class in the class bytes as if
+         *     a non-hidden class. The name returned by {@link Class#getName()}
+         *     is not known when the class bytes are generated.
+         *     <li>Class retransformation:
+         *     The class is not modifiable by Java agents or tool agents using
+         *     the <a href="{@docRoot}/../specs/jvmti.html">JVM Tool Interface</a>.
+         *     </ul>
+         *     </li>
+         * <li>A {@linkplain ClassProperty#WEAK <em>weak</em>} class,
+         *     i.e. a class may be unloaded even if its defining class loader is
+         *     <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> 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).
+         * If the class is defined as a {@linkplain ClassProperty#NESTMATE nestmate}
+         * then the {@linkplain #lookupModes() lookup modes} for this lookup must
+         * include {@link #PRIVATE PRIVATE} access. </p>
+         *
+         * <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.
+         * The class bytes of a nestmate class must not contain
+         * the {@code NestHost} attribute nor the {@code NestMembers} attribute. </p>
+         *
+         * <p> If there is a security manager, its {@code checkPermission} method is first called
+         * to check {@code RuntimePermission("defineClass")}. </p>
+         *
+         * <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 The Java Language Specification.
+         *
+         * <p> The class can obtain {@code classData} by calling
+         * the {@link Lookup#classData()} method of its {@code Lookup} object.
+         *
+         * @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 as if the defining class loader would
+         * only hold a {@linkplain java.lang.ref.WeakReference weak reference}
+         * of the class.
+         *
+         * @param bytes      the class bytes
+         * @param props {@linkplain ClassProperty class properties}
+         * @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 PACKAGE} access, or
+         *                                  if {@code properties} contains {@code NESTMATE} but this lookup
+         *                                  does not have {@code PRIVATE} 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} is {@code null}
+         *
+         * @since 12
+         * @jls 12.7 Unloading of Classes and Interfaces
+         * @see Lookup#privateLookupIn(Class, Lookup)
+         * @see Lookup#dropLookupMode(int)
+         */
+        public Class<?> defineClass(byte[] bytes, ClassProperty... props) throws IllegalAccessException {
+            Objects.requireNonNull(bytes);
+
+            // clone the properties before access
+            Set<ClassProperty> properties;
+            if (props == null || props.length == 0) {
+                properties = EMPTY_PROPS;
+            } else {
+                properties = Set.of(props);
+            }
+
+            // Is it ever possible to create Lookup for int.class or Object[].class?
+            assert !lookupClass.isPrimitive() && !lookupClass.isArray();
+
+            if ((lookupModes() & PACKAGE) == 0){
+                throw new IllegalAccessException("Lookup does not have PACKAGE access");
+            }
+
+            if (properties.contains(NESTMATE) && (lookupModes() & PRIVATE) == 0){
+                throw new IllegalAccessException("Lookup does not have PRIVATE access");
+            }
+
+            assert (lookupModes() & (MODULE | PUBLIC)) != 0;
+
             SecurityManager sm = System.getSecurityManager();
             if (sm != null)
                 sm.checkPermission(new RuntimePermission("defineClass"));
-            if ((lookupModes() & PACKAGE) == 0)
+
+            return defineClassWithNoCheck(bytes, toClassPropertyFlags(properties));
+        }
+
+        /**
+         * 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} with
+         * the given class properties and {@code classData}.
+         *
+         * <p> This method defines a class as if calling
+         * {@link #defineClass(byte[], ClassProperty...) defineClass(bytes, props)}
+         * and then the class initializer with an injected the {@code classData}
+         * as a pre-initialized static unnamed field.
+         * The injected pre-initialized static unnamed field can be
+         * obtained by calling the {@link Lookup#classData()} method of
+         * its {@code Lookup} object.
+         *
+         * <p> If there is a security manager, its {@code checkPermission} method is first called
+         * to check {@code RuntimePermission("defineClass")}. </p>
+         *
+         * @apiNote
+         * This method initializes the class, as opposed to the {@link #defineClass(byte[], ClassProperty...)}
+         * method which does not invoke {@code <clinit>}, because the returned {@code Class}
+         * is as if it contains a private static unnamed field that is initialized to
+         * the given {@code classData} along with other declared static fields
+         * via {@code <clinit>}.
+         *
+         * @param bytes      the class bytes
+         * @param classData pre-initialized class data
+         * @param props {@linkplain ClassProperty class properties}
+         * @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 PACKAGE} access, or
+         *                                  if {@code properties} contains {@code NESTMATE} but this lookup
+         *                                  does not have {@code PRIVATE} 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}
+         *
+         * @since 12
+         * @jls 12.7 Unloading of Classes and Interfaces
+         * @see Lookup#privateLookupIn(Class, Lookup)
+         * @see Lookup#dropLookupMode(int)
+         */
+        public Class<?> defineClassWithClassData(byte[] bytes, Object classData, ClassProperty... props)
+                throws IllegalAccessException
+        {
+            Objects.requireNonNull(bytes);
+            Objects.requireNonNull(classData);
+
+
+            // Is it ever possible to create Lookup for int.class or Object[].class?
+            assert !lookupClass.isPrimitive() && !lookupClass.isArray();
+
+            if ((lookupModes() & PACKAGE) == 0){
                 throw new IllegalAccessException("Lookup does not have PACKAGE access");
-            assert (lookupModes() & (MODULE|PUBLIC)) != 0;
-
+            }
+
+            Set<ClassProperty> properties;
+            if (props == null || props.length == 0) {
+                properties = EMPTY_PROPS;
+            } else {
+                properties = Set.of(props);
+            }
+
+            if (properties.contains(NESTMATE) && (lookupModes() & PRIVATE) == 0){
+                throw new IllegalAccessException("Lookup does not have PRIVATE access");
+            }
+
+            assert (lookupModes() & (MODULE | PUBLIC)) != 0;
+
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkPermission(new RuntimePermission("defineClass"));
+
+            return defineClassWithNoCheck(bytes, toClassPropertyFlags(properties), classData);
+        }
+
+        private static int toClassPropertyFlags(Set<ClassProperty> props) {
+            int flags = 0;
+            for (ClassProperty cp : props) {
+                flags |= cp.flag;
+            }
+            // a weak class implies a hidden class
+            if (props.contains(WEAK)) {
+                flags |= HIDDEN.flag;
+            }
+            return flags;
+        }
+
+        /**
+         * 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)}
+         * then the supplied {@code classData} object is returned; otherwise,
+         * {@code null}.
+         *
+         * <p> This method will invoke the static class initializer of
+         * this lookup class if it has not been initialized.
+         *
+         * @apiNote
+         * A class data can be considered as
+         * private static unnamed field that has been pre-initialized
+         * and supplied at define class time.
+         *
+         * <p> For example a class can pack one or more pre-initialized objects
+         * in a {@code List} as the class data and at class initialization
+         * time unpack them for subsequent access.
+         * The class data is {@code List.of(o1, o2, o3....)}
+         * passed to {@link #defineClassWithClassData(byte[], Object, ClassProperty...)} where
+         * {@code <clinit>} of the class bytes does the following:
+         *
+         * <pre>{@code
+         *     private static final T t;
+         *     private static final R r;
+         *     static {
+         *        List<Object> data = (List<Object>) MethodHandles.lookup().classData();
+         *        t = (T)data.get(0);
+         *        r = (R)data.get(1);
+         *     }
+         *}</pre>
+         *
+         * @return the class data if this lookup class was defined via
+         * {@link #defineClassWithClassData(byte[], Object, ClassProperty...)}; otherwise {@code null}.
+         *
+         * @throws IllegalAccessException if this lookup does not have {@code PRIVATE} access
+         * @since 12
+         */
+        public Object classData() throws IllegalAccessException {
+            if ((lookupModes() & PRIVATE) == 0){
+                throw new IllegalAccessException("Lookup does not have PRIVATE access");
+            }
+
+            // should we allow clearing?  getAndClearClassData
+            return CLASS_DATA_MAP.get(lookupClass);
+        }
+
+        // package-private
+        static final int HIDDEN_NESTMATE = NESTMATE_CLASS|NONFINDABLE_CLASS|ACCESS_VM_ANNOTATIONS;
+        static final int WEAK_HIDDEN_NESTMATE =  WEAK_CLASS|NESTMATE_CLASS|NONFINDABLE_CLASS|ACCESS_VM_ANNOTATIONS;
+        static final Set<ClassProperty> EMPTY_PROPS = Set.of();
+
+        Class<?> defineClassWithNoCheck(byte[] bytes, int flags) {
+            return defineClassWithNoCheck(bytes, flags, null);
+        }
+
+        Class<?> defineClassWithNoCheck(byte[] bytes, int flags, Object classData) {
+            // Can't use lambda during bootstrapping
             // parse class bytes to get class name (in internal form)
             bytes = bytes.clone();
             String name;
@@ -961,33 +1249,51 @@
                 pn = cn.substring(0, index);
             }
             if (!pn.equals(lookupClass.getPackageName())) {
-                throw new IllegalArgumentException("Class not in same package as lookup class");
+                throw new IllegalArgumentException(cn + " not in same package as lookup class: " + lookupClass.getName());
+            }
+
+            Class<?> host = lookupClass;
+            if ((flags & NESTMATE_CLASS) != 0) {
+                // cached in the Class object
+                host = lookupClass.getNestHost();
+            }
+
+            if ((flags & NONFINDABLE_CLASS) != 0) {
+                // assign a new name
+                // cn = cn + "\\" + ++seq;
+                cn = null;
             }
 
             // invoke the class loader's defineClass method
             ClassLoader loader = lookupClass.getClassLoader();
             ProtectionDomain pd = (loader != null) ? lookupClassProtectionDomain() : null;
-            String source = "__Lookup_defineClass__";
-            Class<?> clazz = SharedSecrets.getJavaLangAccess().defineClass(loader, cn, bytes, pd, source);
+            Class<?> clazz = JLA.defineClass(loader, host, cn, bytes, pd, flags, classData);
+            assert clazz.getClassLoader() == lookupClass.getClassLoader()
+                   && clazz.getPackageName().equals(lookupClass.getPackageName());
+
+            // ## TBD what if multiple threads defining this same class??
+            // may need VM to inject the classData in a Class itself at define class time
+            if (classData != null) {
+                CLASS_DATA_MAP.putIfAbsent(clazz, classData);
+            }
             return clazz;
         }
 
+        private static volatile int seq = 0;
+
         private ProtectionDomain lookupClassProtectionDomain() {
             ProtectionDomain pd = cachedProtectionDomain;
             if (pd == null) {
-                cachedProtectionDomain = pd = protectionDomain(lookupClass);
+                cachedProtectionDomain = pd = JLA.protectionDomain(lookupClass);
             }
             return pd;
         }
 
-        private ProtectionDomain protectionDomain(Class<?> clazz) {
-            PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
-            return AccessController.doPrivileged(pa);
-        }
-
         // cached protection domain
         private volatile ProtectionDomain cachedProtectionDomain;
 
+        // don't see the need to use ClassValue
+        private static final WeakHashMap<Class<?>, Object> CLASS_DATA_MAP = new WeakHashMap<>();
 
         // Make sure outer class is initialized first.
         static { IMPL_NAMES.getClass(); }
@@ -1001,6 +1307,8 @@
          */
         static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
 
+        static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
+
         private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
             String name = lookupClass.getName();
             if (name.startsWith("java.lang.invoke."))
@@ -1282,14 +1590,14 @@
          * @param targetName the fully qualified name of the class to be looked up.
          * @return the requested class.
          * @exception SecurityException if a security manager is present and it
-         *            <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
          * @throws LinkageError if the linkage fails
-         * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
-         * @throws IllegalAccessException if the class is not accessible, using the allowed access
-         * modes.
-         * @exception SecurityException if a security manager is present and it
-         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+         * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader
+         *                                or the class is not {@linkplain Class#isHidden hidden}
+         * @throws IllegalAccessException if the class is not accessible, using the allowed access modes.
+
          * @since 9
+         * @see Class#isHidden
          */
         public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
             Class<?> targetClass = Class.forName(targetName, false, lookupClass.getClassLoader());
@@ -2535,6 +2843,52 @@
         }
 
         static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
+
+        /**
+         * Property of a class to be defined via the
+         * {@link Lookup#defineClass(byte[], ClassProperty[]) Lookup.defineClass} method.
+         *
+         * @since 12
+         * @see Lookup#defineClass(byte[], ClassProperty[])
+         * @see Lookup#defineClassWithClassData(byte[], Object, ClassProperty[])
+         */
+        public enum ClassProperty {
+            /**
+             * 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
+             * classes and interfaces in the same nest.
+             *
+             * @see Class#getNestHost()
+             */
+            NESTMATE(NESTMATE_CLASS),
+
+            /**
+             * A hidden class is a class that cannot be referenced by other
+             * classes.  A Java Virtual Machine implementation may hide
+             * the hidden frames from {@linkplain Throwable#getStackTrace()
+             * stack traces}.
+             *
+             * @see Class#isHidden()
+             * @see StackWalker.Option#SHOW_HIDDEN_FRAMES
+             */
+            HIDDEN(NONFINDABLE_CLASS),
+
+            /**
+             * A weak class is a class that may be unloaded even if
+             * its defining class loader is
+             * <a href="../ref/package.html#reachability">reachable</a>.
+             * A weak class is {@linkplain #HIDDEN hidden}.
+             *
+             * @jls 12.7 Unloading of Classes and Interfaces
+             */
+            WEAK(WEAK_CLASS);
+
+            /* the flag value is used by VM at define class time */
+            final int flag;
+            ClassProperty(int flag) {
+                this.flag = flag;
+            }
+        }
     }
 
     /**
@@ -4626,7 +4980,7 @@
      * <li>Examine and collect the suffixes of the step, pred, and fini parameter lists, after removing the iteration variable types.
      * (They must have the form {@code (V... A*)}; collect the {@code (A*)} parts only.)
      * <li>Do not collect suffixes from step, pred, and fini parameter lists that do not begin with all the iteration variable types.
-     * (These types will be checked in step 2, along with all the clause function types.)
+     * (These types will checked in step 2, along with all the clause function types.)
      * <li>Omitted clause functions are ignored.  (Equivalently, they are deemed to have empty parameter lists.)
      * <li>All of the collected parameter lists must be effectively identical.
      * <li>The longest parameter list (which is necessarily unique) is called the "external parameter list" ({@code (A...)}).
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Tue Oct 23 13:05:14 2018 -0700
@@ -44,6 +44,7 @@
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.Function;
 
+import static java.lang.invoke.MethodHandles.Lookup.*;
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 /**
@@ -1122,8 +1123,7 @@
 
             byte[] classBytes = cw.toByteArray();
             try {
-                Class<?> hostClass = lookup.lookupClass();
-                Class<?> innerClass = UNSAFE.defineAnonymousClass(hostClass, classBytes, null);
+                Class<?> innerClass = lookup.defineClassWithNoCheck(classBytes, HIDDEN_NESTMATE);
                 UNSAFE.ensureClassInitialized(innerClass);
                 dumpIfEnabled(innerClass.getName(), classBytes);
                 return Lookup.IMPL_LOOKUP.findStatic(innerClass, METHOD_NAME, args);
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java	Tue Oct 23 13:05:14 2018 -0700
@@ -148,6 +148,14 @@
     Class<?> defineClass(ClassLoader cl, String name, byte[] b, ProtectionDomain pd, String source);
 
     /**
+     * Defines a class with the given name to a class loader with
+     * the given flags and class data.
+     *
+     * @see java.lang.invoke.MethodHandles.Lookup#defineClass
+     */
+    Class<?> defineClass(ClassLoader cl, Class<?> lookup, String name, byte[] b, ProtectionDomain pd, int flags, Object classData);
+
+    /**
      * Returns a class loaded by the bootstrap class loader.
      */
     Class<?> findBootstrapClassOrNull(ClassLoader cl, String name);
@@ -307,6 +315,11 @@
     byte[] getBytesUTF8NoRepl(String s);
 
     /**
+     * Get protection domain of the given Class
+     */
+    ProtectionDomain protectionDomain(Class<?> c);
+
+    /**
      * Set the cause of Throwable
      * @param cause set t's cause to new value
      */
--- a/src/java.base/share/native/libjava/ClassLoader.c	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/java.base/share/native/libjava/ClassLoader.c	Tue Oct 23 13:05:14 2018 -0700
@@ -211,6 +211,65 @@
     return result;
 }
 
+JNIEXPORT jclass JNICALL
+Java_java_lang_ClassLoader_defineClass0(JNIEnv *env,
+                                        jclass cls,
+                                        jobject loader,
+                                        jclass lookup,
+                                        jstring name,
+                                        jbyteArray data,
+                                        jint offset,
+                                        jint length,
+                                        jobject pd,
+                                        jint flags,
+                                        jobject classData)
+{
+    jbyte *body;
+    char *utfName;
+    jclass result = 0;
+    char buf[128];
+
+    if (data == NULL) {
+        JNU_ThrowNullPointerException(env, 0);
+        return 0;
+    }
+
+    /* Work around 4153825. malloc crashes on Solaris when passed a
+     * negative size.
+     */
+    if (length < 0) {
+        JNU_ThrowArrayIndexOutOfBoundsException(env, 0);
+        return 0;
+    }
+
+    body = (jbyte *)malloc(length);
+    if (body == 0) {
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    }
+
+    (*env)->GetByteArrayRegion(env, data, offset, length, body);
+
+    if ((*env)->ExceptionOccurred(env))
+        goto free_body;
+
+    if (name != NULL) {
+        utfName = getUTF(env, name, buf, sizeof(buf));
+        if (utfName == NULL) {
+            goto free_body;
+        }
+        VerifyFixClassname(utfName);
+    } else {
+        utfName = NULL;
+    }
+
+    return JVM_LookupDefineClass(env, lookup, utfName, loader, body, length, pd, flags, classData);
+
+ free_body:
+    free(body);
+    return result;
+}
+
 /*
  * Returns NULL if class not found.
  */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri Oct 19 03:08:53 2018 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Oct 23 13:05:14 2018 -0700
@@ -1262,8 +1262,6 @@
         } else {
             if (refSym.isStatic()) {
                 return ClassFile.REF_invokeStatic;
-            } else if ((refSym.flags() & PRIVATE) != 0) {
-                return ClassFile.REF_invokeSpecial;
             } else if (refSym.enclClass().isInterface()) {
                 return ClassFile.REF_invokeInterface;
             } else {
@@ -2337,17 +2335,6 @@
                 return tree.ownerAccessible;
             }
 
-            /**
-             * The VM does not support access across nested classes (8010319).
-             * Were that ever to change, this should be removed.
-             */
-            boolean isPrivateInOtherClass() {
-                return  (tree.sym.flags() & PRIVATE) != 0 &&
-                        !types.isSameType(
-                              types.erasure(tree.sym.enclClass().asType()),
-                              types.erasure(owner.enclClass().asType()));
-            }
-
             boolean isProtectedInSuperClassOfEnclosingClassInOtherPackage() {
                 return ((tree.sym.flags() & PROTECTED) != 0 &&
                         tree.sym.packge() != owner.packge() &&
@@ -2386,7 +2373,6 @@
                         isSuper ||
                         needsVarArgsConversion() ||
                         isArrayOp() ||
-                        isPrivateInOtherClass() ||
                         isProtectedInSuperClassOfEnclosingClassInOtherPackage() ||
                         !receiverAccessible() ||
                         (tree.getMode() == ReferenceMode.NEW &&
--- a/test/hotspot/gtest/memory/test_metaspace_allocation.cpp	Fri Oct 19 03:08:53 2018 -0400
+++ b/test/hotspot/gtest/memory/test_metaspace_allocation.cpp	Tue Oct 23 13:05:14 2018 -0700
@@ -102,9 +102,9 @@
       _spaces[i].lock = new Mutex(Monitor::native, "gtest-MetaspaceAllocationTest-lock", false, Monitor::_safepoint_check_never);
       ASSERT_TRUE(_spaces[i].lock != NULL);
     }
-    // Let every ~10th space be an unsafe anonymous one to test different allocation patterns.
+    // Let every ~10th space be a short-lived one to test different allocation patterns.
     const Metaspace::MetaspaceType msType = (os::random() % 100 < 10) ?
-      Metaspace::UnsafeAnonymousMetaspaceType : Metaspace::StandardMetaspaceType;
+      Metaspace::ShortLivedMetaspaceType : Metaspace::StandardMetaspaceType;
     {
       // Pull lock during space creation, since this is what happens in the VM too
       // (see ClassLoaderData::metaspace_non_null(), which we mimick here).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineClass/DefineClassTest.java	Tue Oct 23 13:05:14 2018 -0700
@@ -0,0 +1,175 @@
+/*
+ * 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.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 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(V11, 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 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.isHidden());
+
+        // 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 defineWeakClass() throws Throwable {
+        // define a weak class
+        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
+        Class<?> c = lookup.defineClass(bytes, WEAK);
+        System.out.println(c.getName());
+        assertTrue(c.getNestHost() == c);
+        // assertTrue(c.isHidden());
+    }
+
+    @Test(expectedExceptions = IllegalAccessError.class)
+    public void definePackageAccessClass() throws Throwable {
+        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
+        Class<?> c = lookup.defineClass(bytes, HIDDEN);
+        assertTrue(c.getNestHost() == c);
+        // assertTrue(c.isHidden());
+
+        // fail to access DefineClassTest::privMethod method
+        testInjectedClass(c);
+    }
+
+    @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.isHidden());
+
+        // 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();
+        }
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/defineClass/DefineClassWithClassData.java	Tue Oct 23 13:05:14 2018 -0700
@@ -0,0 +1,212 @@
+/*
+ * 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 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();
+        Class<?> c = lookup.defineClassWithClassData(ClassByteBuilder.classBytes("T"), classData, NESTMATE, HIDDEN);
+        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();
+        Class<?> c = lookup.defineClassWithClassData(ClassByteBuilder.classBytes("T"), classData, NESTMATE, HIDDEN);
+        assertTrue(c.getNestHost() == DefineClassWithClassData.class);
+        assertTrue(c.isHidden());
+        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().dropLookupMode(Lookup.PRIVATE);
+        Class<?> c = lookup.defineClassWithClassData(ClassByteBuilder.classBytes("T"), WEAK);
+        assertTrue(c.getNestHost() == c);
+        assertTrue(c.isHidden());
+    }
+
+    @Test(expectedExceptions = IllegalAccessException.class)
+    public void noPrivateLookupAccess() throws Throwable {
+        Lookup lookup = MethodHandles.lookup().dropLookupMode(Lookup.PRIVATE);
+        lookup.defineClassWithClassData(ClassByteBuilder.classBytes("T2"), classData, NESTMATE, HIDDEN);
+    }
+
+    @Test(expectedExceptions = IllegalAccessException.class)
+    public void teleportToNestmate() throws Throwable {
+        byte[] classBytes = ClassByteBuilder.classBytes("T");
+        Class<?> c = MethodHandles.lookup()
+            .defineClassWithClassData(classBytes, classData, NESTMATE, HIDDEN);
+        assertTrue(c.getNestHost() == DefineClassWithClassData.class);
+        assertEquals(classData, injectedData(c));
+        assertTrue(c.isHidden());
+
+        // Teleport to a nestmate
+        Lookup lookup =  MethodHandles.lookup().in(c);
+        assertTrue((lookup.lookupModes() & PRIVATE) == 0);
+        // fail to define a nestmate
+        lookup.defineClassWithClassData(ClassByteBuilder.classBytes("T2"), 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 byte[] classBytes(String classname) throws Exception {
+            ClassWriter cw = new ClassWriter(0);
+            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", "Ljava/lang/String;", null, null);
+                fv.visitEnd();
+            }
+            {
+                mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+                mv.visitCode();
+                mv.visitMethodInsn(INVOKESTATIC, MH_CLS, "lookup", "()" + LOOKUP_SIG);
+                mv.visitMethodInsn(INVOKEVIRTUAL, LOOKUP_CLS, "classData", "()Ljava/lang/Object;");
+                mv.visitTypeInsn(CHECKCAST, LIST_CLS);
+                mv.visitVarInsn(ASTORE, 0);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitInsn(Opcodes.ICONST_0);
+                mv.visitMethodInsn(INVOKEINTERFACE, LIST_CLS, "get", "(I)Ljava/lang/Object;");
+                mv.visitTypeInsn(CHECKCAST, STRING_CLS);
+                mv.visitFieldInsn(PUTSTATIC, classname, "data", "Ljava/lang/String;");
+                mv.visitInsn(RETURN);
+                mv.visitMaxs(-1, -1);
+                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(-1, -1);
+                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(-1, -1);
+                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", "Ljava/lang/Object;");
+                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V");
+                mv.visitInsn(RETURN);
+                mv.visitMaxs(-1, -1);
+                mv.visitEnd();
+            }
+            cw.visitEnd();
+
+            return cw.toByteArray();
+        }
+    }
+}
+
+