diff --git a/src/hotspot/share/classfile/verificationType.cpp b/src/hotspot/share/classfile/verificationType.cpp index aedb620aabe..25b2418229a 100644 --- a/src/hotspot/share/classfile/verificationType.cpp +++ b/src/hotspot/share/classfile/verificationType.cpp @@ -82,7 +82,11 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* current_kl target_klass == vmClasses::Serializable_klass(); } else if (from_is_object) { Klass* from_klass; +#if HOTSPOT_TARGET_CLASSLIB == 8 + if (current_klass->name() == from_name) { +#else if (current_klass->is_hidden() && current_klass->name() == from_name) { +#endif from_klass = current_klass; } else { from_klass = SystemDictionary::resolve_or_fail( diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp index 0f1468f0309..9253b65c593 100644 --- a/src/hotspot/share/classfile/verifier.cpp +++ b/src/hotspot/share/classfile/verifier.cpp @@ -132,8 +132,15 @@ bool Verifier::relax_access_for(oop loader) { // or pass true for redefinition of any class. static bool is_eligible_for_verification(InstanceKlass* klass, bool should_verify_class) { Symbol* name = klass->name(); +#if HOTSPOT_TARGET_CLASSLIB == 8 + Klass* refl_magic_klass = vmClasses::reflect_MagicAccessorImpl_klass(); + bool is_reflect = refl_magic_klass != nullptr && klass->is_subtype_of(refl_magic_klass); + + return (should_verify_class && (!is_reflect) && +#else return (should_verify_class && +#endif // Can not verify the bytecodes for shared classes because they have // already been rewritten to contain constant pool cache indices, // which the verifier can't understand. @@ -2911,8 +2918,20 @@ void ClassVerifier::verify_invoke_instructions( // and we loaded the class. For any other "true" returns (e.g. same class // or Object) we either can't get here (same class already excluded above) // or we know it is not an interface (i.e. Object). +#if HOTSPOT_TARGET_CLASSLIB == 8 + bool subtype = false; + if (!current_class()->is_hidden()) { + subtype = ref_class_type.is_reference_assignable_from(current_type(), this, false, + &is_interface, CHECK_VERIFY(this)); + } else { + VerificationType host_klass_type = + VerificationType::reference_type(current_class()->nest_host(THREAD)->name()); + subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this)); + } +#else bool subtype = ref_class_type.is_reference_assignable_from(current_type(), this, false, &is_interface, CHECK_VERIFY(this)); +#endif if (!subtype) { // Totally unrelated class verify_error(ErrorContext::bad_code(bci), "Bad invokespecial instruction: " @@ -2950,7 +2969,28 @@ void ClassVerifier::verify_invoke_instructions( } else { // other methods // Ensures that target class is assignable to method class. if (opcode == Bytecodes::_invokespecial) { +#if HOTSPOT_TARGET_CLASSLIB == 8 + if (!current_class()->is_hidden()) { + current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); + } else { + // anonymous class invokespecial calls: check if the + // objectref is a subtype of the host_klass of the current class + // to allow an anonymous class to reference methods in the host_klass + VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this)); + VerificationType hosttype = + VerificationType::reference_type(current_class()->nest_host(THREAD)->name()); + bool subtype = hosttype.is_assignable_from(top, this, false, CHECK_VERIFY(this)); + if (!subtype) { + verify_error( ErrorContext::bad_type(current_frame->offset(), + current_frame->stack_top_ctx(), + TypeOrigin::implicit(top)), + "Bad type on operand stack"); + return; + } + } +#else current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); +#endif } else if (opcode == Bytecodes::_invokevirtual) { VerificationType stack_object_type = current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this)); diff --git a/src/hotspot/share/classfile/vmClassMacros.hpp b/src/hotspot/share/classfile/vmClassMacros.hpp index 5e7f045cd2e..8fa5831173a 100644 --- a/src/hotspot/share/classfile/vmClassMacros.hpp +++ b/src/hotspot/share/classfile/vmClassMacros.hpp @@ -106,6 +106,7 @@ do_klass(reflect_ConstantPool_klass, reflect_ConstantPool ) \ do_klass(reflect_CallerSensitive_klass, reflect_CallerSensitive ) \ do_klass(reflect_DirectConstructorHandleAccessor_NativeAccessor_klass, reflect_DirectConstructorHandleAccessor_NativeAccessor) \ + do_klass(reflect_MagicAccessorImpl_klass, reflect_MagicAccessorImpl ) \ \ /* support for dynamic typing */ \ do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle ) \ diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index 7774572a202..b30988c4568 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -64,6 +64,7 @@ class SerializeClosure; template(reflect_MethodAccessorImpl, "sun/reflect/MethodAccessorImpl") \ template(reflect_CallerSensitive, "sun/reflect/CallerSensitive") \ template(reflect_CallerSensitive_signature, "Lsun/reflect/CallerSensitive;") \ + template(reflect_MagicAccessorImpl, "sun/reflect/MagicAccessorImpl") \ template(vmloader_name, "vmloader") \ template(java_security_PrivilegedActionException, "java/security/PrivilegedActionException") \ template(exception_void_signature, "(Ljava/lang/Exception;)V") \ diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index 6085456a90c..f9e0f051135 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -1216,7 +1216,18 @@ Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, Klass* current_klass = link_info.current_klass(); if (current_klass != nullptr && resolved_klass->is_interface()) { InstanceKlass* klass_to_check = InstanceKlass::cast(current_klass); +#if HOTSPOT_TARGET_CLASSLIB == 8 + if (klass_to_check->is_hidden()) { + klass_to_check = klass_to_check->nest_host(THREAD); + } + // Disable verification for the dynamically-generated reflection bytecodes. + bool is_reflect = klass_to_check->is_subclass_of( + vmClasses::reflect_MagicAccessorImpl_klass()); + if (!is_reflect && + !klass_to_check->is_same_or_direct_interface(resolved_klass)) { +#else if (!klass_to_check->is_same_or_direct_interface(resolved_klass)) { +#endif ResourceMark rm(THREAD); stringStream ss; ss.print("Interface method reference: '");