--- old/src/hotspot/share/classfile/systemDictionary.cpp 2019-10-08 18:53:00.000000000 -0700 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2019-10-08 18:53:00.000000000 -0700 @@ -987,24 +987,40 @@ // 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 hidden, 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* cp_patches, + const bool is_hidden, + const bool is_weakhidden, + const bool can_access_vm_annotations, + InstanceKlass* dynamic_nest_host, + Handle classData, 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(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_hidden) { + // - for weak hidden class: create a new short-lived CLD whose loader is + // the Lookup class' loader. + // - for hidden class: add the class to the Lookup class' loader's CLD. + if (is_weakhidden) { + loader_data = ClassLoaderData::shortlived_class_loader_data(class_loader); + } else { + // This hidden 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 +1039,18 @@ protection_domain, unsafe_anonymous_host, cp_patches, + is_hidden, + can_access_vm_annotations, + dynamic_nest_host, + classData, CHECK_NULL); - if (unsafe_anonymous_host != NULL && k != NULL) { - // Unsafe anonymous classes must update ClassLoaderData holder (was unsafe_anonymous_host loader) + if ((is_hidden || (unsafe_anonymous_host != NULL)) && k != NULL) { + // Weak hidden 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_weakhidden || (unsafe_anonymous_host != NULL)) { + k->class_loader_data()->initialize_holder(Handle(THREAD, k->java_mirror())); + } { MutexLocker mu_r(Compile_lock, THREAD); @@ -1045,7 +1067,8 @@ 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. + // FIXME: why must we eager initialize? It should be initialized upon use. k->eager_initialize(CHECK_NULL); // notify jvmti @@ -1072,6 +1095,7 @@ Handle class_loader, Handle protection_domain, ClassFileStream* st, + InstanceKlass* dynamic_nest_host, TRAPS) { HandleMark hm(THREAD); @@ -1116,8 +1140,12 @@ class_name, loader_data, protection_domain, - NULL, // unsafe_anonymous_host - NULL, // cp_patches + NULL, // unsafe_anonymous_host + NULL, // cp_patches + false, // is_hidden + false, // can_access_vm_annotations + dynamic_nest_host, + Handle(), // classData CHECK_NULL); }