# HG changeset patch # User dholmes # Date 1529731961 14400 # Node ID 2f2af62dfac7a9ca1655c532dd2b0769f859f25a # Parent 0828a0f6676b25fa3cc7b3c29db2dcb1f8d62329 8010319: Implementation of JEP 181: Nest-Based Access Control Reviewed-by: alanb, psandoz, mchung, coleenp, acorn, mcimadamore, forax, jlahoda, sspitsyn, abuckley Contributed-by: alex.buckley@oracle.com, maurizio.mimadamore@oracle.com, mandy.chung@oracle.com, tobias.hartmann@oracle.com, david.holmes@oracle.com, vladimir.x.ivanov@oracle.com, karen.kinnear@oracle.com, vladimir.kozlov@oracle.com, john.r.rose@oracle.com, daniel.smith@oracle.com, serguei.spitsyn@oracle.com, kumardotsrinivasan@gmail.com, boris.ulasevich@bell-sw.com diff -r 0828a0f6676b -r 2f2af62dfac7 make/data/jdwp/jdwp.spec --- a/make/data/jdwp/jdwp.spec Fri Jun 22 17:49:21 2018 -0700 +++ b/make/data/jdwp/jdwp.spec Sat Jun 23 01:32:41 2018 -0400 @@ -395,8 +395,8 @@ "Can the VM add methods when redefining " "classes?") (boolean canUnrestrictedlyRedefineClasses - "Can the VM redefine classes" - "in arbitrary ways?") + "Can the VM redefine classes " + "in ways that are normally restricted?") (boolean canPopFrames "Can the VM pop stack frames?") (boolean canUseInstanceFilters @@ -460,12 +460,23 @@ "PopFrames command can be used " "to pop frames with obsolete methods." "

" + "Unless the canUnrestrictedlyRedefineClasses capability is present the following " + "redefinitions are restricted: " + "

" + "

" "Requires canRedefineClasses capability - see " "CapabilitiesNew. " "In addition to the canRedefineClasses capability, the target VM must " "have the canAddMethod capability to add methods when redefining classes, " - "or the canUnrestrictedlyRedefineClasses to redefine classes in arbitrary " - "ways." + "or the canUnrestrictedlyRedefineClasses capability to redefine classes in ways " + "that are normally restricted." (Out (Repeat classes "Number of reference types that follow." (Group ClassDef @@ -496,6 +507,7 @@ (Error DELETE_METHOD_NOT_IMPLEMENTED) (Error CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED) (Error METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED) + (Error CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED) (Error VM_DEAD) ) ) @@ -3148,12 +3160,16 @@ "different from the name in the old class object.") (Constant CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED =70 "The new class version has different modifiers and " - "and canUnrestrictedlyRedefineClasses is false.") + "canUnrestrictedlyRedefineClasses is false.") (Constant METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED =71 "A method in the new class version has " "different modifiers " "than its counterpart in the old class version and " - "and canUnrestrictedlyRedefineClasses is false.") + "canUnrestrictedlyRedefineClasses is false.") + (Constant CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED + =72 "The new class version has different NestHost or " + "NestMembers class attribute and " + "canUnrestrictedlyRedefineClasses is false.") (Constant NOT_IMPLEMENTED =99 "The functionality is not implemented in " "this virtual machine.") (Constant NULL_POINTER =100 "Invalid pointer.") diff -r 0828a0f6676b -r 2f2af62dfac7 make/hotspot/symbols/symbols-unix --- a/make/hotspot/symbols/symbols-unix Fri Jun 22 17:49:21 2018 -0700 +++ b/make/hotspot/symbols/symbols-unix Sat Jun 23 01:32:41 2018 -0400 @@ -22,6 +22,7 @@ # JVM_ActiveProcessorCount +JVM_AreNestMates JVM_ArrayCopy JVM_AssertionStatusDirectives JVM_BeforeHalt @@ -118,6 +119,8 @@ JVM_GetMethodParameters JVM_GetMethodTypeAnnotations JVM_GetNanoTimeAdjustment +JVM_GetNestHost +JVM_GetNestMembers JVM_GetPrimitiveArrayElement JVM_GetProtectionDomain JVM_GetSimpleBinaryName diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/cpu/aarch64/templateTable_aarch64.cpp --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -3362,22 +3362,45 @@ // r2: receiver // r3: flags + // First check for Object case, then private interface method, + // then regular interface method. + // Special case of invokeinterface called for virtual method of - // java.lang.Object. See cpCacheOop.cpp for details. - // This code isn't produced by javac, but could be produced by - // another compliant java compiler. - Label notMethod; - __ tbz(r3, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod); + // java.lang.Object. See cpCache.cpp for details. + Label notObjectMethod; + __ tbz(r3, ConstantPoolCacheEntry::is_forced_virtual_shift, notObjectMethod); invokevirtual_helper(rmethod, r2, r3); - __ bind(notMethod); + __ bind(notObjectMethod); + + Label no_such_interface; + + // Check for private method invocation - indicated by vfinal + Label notVFinal; + __ tbz(r3, ConstantPoolCacheEntry::is_vfinal_shift, notVFinal); + + // Get receiver klass into r3 - also a null check + __ null_check(r2, oopDesc::klass_offset_in_bytes()); + __ load_klass(r3, r2); + + Label subtype; + __ check_klass_subtype(r3, r0, r4, subtype); + // If we get here the typecheck failed + __ b(no_such_interface); + __ bind(subtype); + + __ profile_final_call(r0); + __ profile_arguments_type(r0, rmethod, r4, true); + __ jump_from_interpreted(rmethod, r0); + + __ bind(notVFinal); // Get receiver klass into r3 - also a null check __ restore_locals(); __ null_check(r2, oopDesc::klass_offset_in_bytes()); __ load_klass(r3, r2); - Label no_such_interface, no_such_method; + Label no_such_method; // Preserve method for throw_AbstractMethodErrorVerbose. __ mov(r16, rmethod); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/cpu/arm/templateTable_arm.cpp --- a/src/hotspot/cpu/arm/templateTable_arm.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/cpu/arm/templateTable_arm.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -4276,25 +4276,41 @@ const Register Rinterf = R5_tmp; const Register Rindex = R4_tmp; const Register Rflags = R3_tmp; - const Register Rklass = R3_tmp; + const Register Rklass = R2_tmp; // Note! Same register with Rrecv prepare_invoke(byte_no, Rinterf, Rmethod, Rrecv, Rflags); + // First check for Object case, then private interface method, + // then regular interface method. + // Special case of invokeinterface called for virtual method of - // java.lang.Object. See cpCacheOop.cpp for details. - // This code isn't produced by javac, but could be produced by - // another compliant java compiler. - Label notMethod; - __ tbz(Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod); - + // java.lang.Object. See cpCache.cpp for details. + Label notObjectMethod; + __ tbz(Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift, notObjectMethod); invokevirtual_helper(Rmethod, Rrecv, Rflags); - __ bind(notMethod); + __ bind(notObjectMethod); // Get receiver klass into Rklass - also a null check __ load_klass(Rklass, Rrecv); + // Check for private method invocation - indicated by vfinal Label no_such_interface; + Label notVFinal; + __ tbz(Rflags, ConstantPoolCacheEntry::is_vfinal_shift, notVFinal); + + Label subtype; + __ check_klass_subtype(Rklass, Rinterf, R1_tmp, R3_tmp, noreg, subtype); + // If we get here the typecheck failed + __ b(no_such_interface); + __ bind(subtype); + + // do the call + __ profile_final_call(R0_tmp); + __ jump_from_interpreted(Rmethod); + + __ bind(notVFinal); + // Receiver subtype check against REFC. __ lookup_interface_method(// inputs: rec. class, interface Rklass, Rinterf, noreg, diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/cpu/ppc/templateTable_ppc_64.cpp --- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -3583,14 +3583,46 @@ prepare_invoke(byte_no, Rinterface_klass, Rret_addr, Rmethod, Rreceiver, Rflags, Rscratch1); - // Get receiver klass. + // First check for Object case, then private interface method, + // then regular interface method. + + // Get receiver klass - this is also a null check __ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2); __ load_klass(Rrecv_klass, Rreceiver); // Check corner case object method. - Label LobjectMethod, L_no_such_interface, Lthrow_ame; + // Special case of invokeinterface called for virtual method of + // java.lang.Object. See ConstantPoolCacheEntry::set_method() for details: + // The invokeinterface was rewritten to a invokevirtual, hence we have + // to handle this corner case. + + Label LnotObjectMethod, Lthrow_ame; __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift); - __ btrue(CCR0, LobjectMethod); + __ bfalse(CCR0, LnotObjectMethod); + invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2); + __ bind(LnotObjectMethod); + + // Check for private method invocation - indicated by vfinal + Label LnotVFinal, L_no_such_interface, L_subtype; + + __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift); + __ bfalse(CCR0, LnotVFinal); + + __ check_klass_subtype(Rrecv_klass, Rinterface_klass, Rscratch1, Rscratch2, L_subtype); + // If we get here the typecheck failed + __ b(L_no_such_interface); + __ bind(L_subtype); + + // do the call + + Register Rscratch = Rflags; // Rflags is dead now. + + __ profile_final_call(Rscratch1, Rscratch); + __ profile_arguments_type(Rindex, Rscratch, Rrecv_klass /* scratch */, true); + + __ call_from_interpreter(Rindex, Rret_addr, Rscratch, Rrecv_klass /* scratch */); + + __ bind(LnotVFinal); __ lookup_interface_method(Rrecv_klass, Rinterface_klass, noreg, noreg, Rscratch1, Rscratch2, L_no_such_interface, /*return_method=*/false); @@ -3631,14 +3663,6 @@ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose), Rrecv_klass, Rinterface_klass); DEBUG_ONLY( __ should_not_reach_here(); ) - - // Special case of invokeinterface called for virtual method of - // java.lang.Object. See ConstantPoolCacheEntry::set_method() for details: - // The invokeinterface was rewritten to a invokevirtual, hence we have - // to handle this corner case. This code isn't produced by javac, but could - // be produced by another compliant java compiler. - __ bind(LobjectMethod); - invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2); } void TemplateTable::invokedynamic(int byte_no) { diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/cpu/s390/templateTable_s390.cpp --- a/src/hotspot/cpu/s390/templateTable_s390.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -3610,20 +3610,43 @@ BLOCK_COMMENT("invokeinterface {"); - prepare_invoke(byte_no, interface, method, // Get f1 klassOop, f2 itable index. + prepare_invoke(byte_no, interface, method, // Get f1 klassOop, f2 Method*. receiver, flags); // Z_R14 (== Z_bytecode) : return entry + // First check for Object case, then private interface method, + // then regular interface method. + // Special case of invokeinterface called for virtual method of - // java.lang.Object. See cpCacheOop.cpp for details. - // This code isn't produced by javac, but could be produced by - // another compliant java compiler. - NearLabel notMethod, no_such_interface, no_such_method; + // java.lang.Object. See cpCache.cpp for details. + NearLabel notObjectMethod, no_such_method; __ testbit(flags, ConstantPoolCacheEntry::is_forced_virtual_shift); - __ z_brz(notMethod); + __ z_brz(notObjectMethod); invokevirtual_helper(method, receiver, flags); - __ bind(notMethod); + __ bind(notObjectMethod); + + // Check for private method invocation - indicated by vfinal + NearLabel notVFinal; + __ testbit(flags, ConstantPoolCacheEntry::is_vfinal_shift); + __ z_brz(notVFinal); + + // Get receiver klass into klass - also a null check. + __ load_klass(klass, receiver); + + NearLabel subtype, no_such_interface; + + __ check_klass_subtype(klass, interface, Z_tmp_2, Z_tmp_3, subtype); + // If we get here the typecheck failed + __ z_bru(no_such_interface); + __ bind(subtype); + + // do the call + __ profile_final_call(Z_tmp_2); + __ profile_arguments_type(Z_tmp_2, method, Z_ARG5, true); + __ jump_from_interpreted(method, Z_tmp_2); + + __ bind(notVFinal); // Get receiver klass into klass - also a null check. __ restore_locals(); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/cpu/sparc/templateTable_sparc.cpp --- a/src/hotspot/cpu/sparc/templateTable_sparc.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/cpu/sparc/templateTable_sparc.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -3202,28 +3202,56 @@ prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags); - // get receiver klass + // First check for Object case, then private interface method, + // then regular interface method. + + // get receiver klass - this is also a null check __ null_check(O0_recv, oopDesc::klass_offset_in_bytes()); __ load_klass(O0_recv, O2_Klass); // Special case of invokeinterface called for virtual method of - // java.lang.Object. See cpCacheOop.cpp for details. - // This code isn't produced by javac, but could be produced by - // another compliant java compiler. - Label notMethod; + // java.lang.Object. See cpCache.cpp for details. + Label notObjectMethod; __ set((1 << ConstantPoolCacheEntry::is_forced_virtual_shift), Rscratch); __ btst(O1_flags, Rscratch); - __ br(Assembler::zero, false, Assembler::pt, notMethod); + __ br(Assembler::zero, false, Assembler::pt, notObjectMethod); __ delayed()->nop(); invokeinterface_object_method(O2_Klass, Rinterface, Rret, O1_flags); - __ bind(notMethod); + __ bind(notObjectMethod); + + Label L_no_such_interface; + + // Check for private method invocation - indicated by vfinal + Label notVFinal; + { + __ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), Rscratch); + __ btst(O1_flags, Rscratch); + __ br(Assembler::zero, false, Assembler::pt, notVFinal); + __ delayed()->nop(); + + Label subtype; + Register Rtemp = O1_flags; + __ check_klass_subtype(O2_Klass, Rinterface, Rscratch, Rtemp, subtype); + // If we get here the typecheck failed + __ ba(L_no_such_interface); + __ delayed()->nop(); + __ bind(subtype); + + // do the call + Register Rcall = Rinterface; + __ mov(Rmethod, G5_method); + assert_different_registers(Rcall, G5_method, Gargs, Rret); + + __ profile_arguments_type(G5_method, Rcall, Gargs, true); + __ profile_final_call(Rscratch); + __ call_from_interpreter(Rcall, Gargs, Rret); + } + __ bind(notVFinal); Register Rtemp = O1_flags; - Label L_no_such_interface; - // Receiver subtype check against REFC. __ lookup_interface_method(// inputs: rec. class, interface, itable index O2_Klass, Rinterface, noreg, diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/cpu/x86/templateTable_x86.cpp --- a/src/hotspot/cpu/x86/templateTable_x86.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/cpu/x86/templateTable_x86.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -3792,30 +3792,61 @@ prepare_invoke(byte_no, rax, rbx, // get f1 Klass*, f2 Method* rcx, rdx); // recv, flags - // rax: reference klass (from f1) + // rax: reference klass (from f1) if interface method // rbx: method (from f2) // rcx: receiver // rdx: flags + // First check for Object case, then private interface method, + // then regular interface method. + // Special case of invokeinterface called for virtual method of - // java.lang.Object. See cpCacheOop.cpp for details. - // This code isn't produced by javac, but could be produced by - // another compliant java compiler. - Label notMethod; + // java.lang.Object. See cpCache.cpp for details. + Label notObjectMethod; __ movl(rlocals, rdx); __ andl(rlocals, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift)); - - __ jcc(Assembler::zero, notMethod); - + __ jcc(Assembler::zero, notObjectMethod); invokevirtual_helper(rbx, rcx, rdx); - __ bind(notMethod); + // no return from above + __ bind(notObjectMethod); + + Label no_such_interface; // for receiver subtype check + Register recvKlass; // used for exception processing + + // Check for private method invocation - indicated by vfinal + Label notVFinal; + __ movl(rlocals, rdx); + __ andl(rlocals, (1 << ConstantPoolCacheEntry::is_vfinal_shift)); + __ jcc(Assembler::zero, notVFinal); + + // Get receiver klass into rlocals - also a null check + __ null_check(rcx, oopDesc::klass_offset_in_bytes()); + __ load_klass(rlocals, rcx); + + Label subtype; + __ check_klass_subtype(rlocals, rax, rbcp, subtype); + // If we get here the typecheck failed + recvKlass = rdx; + __ mov(recvKlass, rlocals); // shuffle receiver class for exception use + __ jmp(no_such_interface); + + __ bind(subtype); + + // do the call - rbx is actually the method to call + + __ profile_final_call(rdx); + __ profile_arguments_type(rdx, rbx, rbcp, true); + + __ jump_from_interpreted(rbx, rdx); + // no return from above + __ bind(notVFinal); // Get receiver klass into rdx - also a null check __ restore_locals(); // restore r14 __ null_check(rcx, oopDesc::klass_offset_in_bytes()); __ load_klass(rdx, rcx); - Label no_such_interface, no_such_method; + Label no_such_method; // Preserve method for throw_AbstractMethodErrorVerbose. __ mov(rcx, rbx); @@ -3877,12 +3908,12 @@ __ restore_locals(); // make sure locals pointer is correct as well (was destroyed) // Pass arguments for generating a verbose error message. #ifdef _LP64 - Register recvKlass = c_rarg1; + recvKlass = c_rarg1; Register method = c_rarg2; if (recvKlass != rdx) { __ movq(recvKlass, rdx); } if (method != rcx) { __ movq(method, rcx); } #else - Register recvKlass = rdx; + recvKlass = rdx; Register method = rcx; #endif __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose), diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/ci/ciField.cpp --- a/src/hotspot/share/ci/ciField.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/ci/ciField.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -70,22 +70,22 @@ ciField::ciField(ciInstanceKlass* klass, int index) : _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { ASSERT_IN_VM; - CompilerThread *thread = CompilerThread::current(); + CompilerThread *THREAD = CompilerThread::current(); assert(ciObjectFactory::is_initialized(), "not a shared field"); assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constant-pool"); - constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); + constantPoolHandle cpool(THREAD, klass->get_instanceKlass()->constants()); // Get the field's name, signature, and type. Symbol* name = cpool->name_ref_at(index); - _name = ciEnv::current(thread)->get_symbol(name); + _name = ciEnv::current(THREAD)->get_symbol(name); int nt_index = cpool->name_and_type_ref_index_at(index); int sig_index = cpool->signature_ref_index_at(nt_index); Symbol* signature = cpool->symbol_at(sig_index); - _signature = ciEnv::current(thread)->get_symbol(signature); + _signature = ciEnv::current(THREAD)->get_symbol(signature); BasicType field_type = FieldType::basic_type(signature); @@ -95,12 +95,12 @@ bool ignore; // This is not really a class reference; the index always refers to the // field's type signature, as a symbol. Linkage checks do not apply. - _type = ciEnv::current(thread)->get_klass_by_index(cpool, sig_index, ignore, klass); + _type = ciEnv::current(THREAD)->get_klass_by_index(cpool, sig_index, ignore, klass); } else { _type = ciType::make(field_type); } - _name = (ciSymbol*)ciEnv::current(thread)->get_symbol(name); + _name = (ciSymbol*)ciEnv::current(THREAD)->get_symbol(name); // Get the field's declared holder. // @@ -109,7 +109,7 @@ int holder_index = cpool->klass_ref_index_at(index); bool holder_is_accessible; - ciKlass* generic_declared_holder = ciEnv::current(thread)->get_klass_by_index(cpool, holder_index, + ciKlass* generic_declared_holder = ciEnv::current(THREAD)->get_klass_by_index(cpool, holder_index, holder_is_accessible, klass); @@ -126,7 +126,7 @@ // handling in ciField::will_link and will result in a // java.lang.NoSuchFieldError exception being thrown by the compiled // code (the expected behavior in this case). - _holder = ciEnv::current(thread)->Object_klass(); + _holder = ciEnv::current(THREAD)->Object_klass(); _offset = -1; _is_constant = false; return; @@ -164,10 +164,22 @@ // to check access because it can erroneously succeed. If this check fails, // propagate the declared holder to will_link() which in turn will bail out // compilation for this field access. - if (!Reflection::verify_field_access(klass->get_Klass(), declared_holder->get_Klass(), canonical_holder, field_desc.access_flags(), true)) { + bool can_access = Reflection::verify_member_access(klass->get_Klass(), + declared_holder->get_Klass(), + canonical_holder, + field_desc.access_flags(), + true, false, THREAD); + if (!can_access) { _holder = declared_holder; _offset = -1; _is_constant = false; + // It's possible the access check failed due to a nestmate access check + // encountering an exception. We can't propagate the exception from here + // so we have to clear it. If the access check happens again in a different + // context then the exception will be thrown there. + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + } return; } diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/classfile/classFileParser.cpp --- a/src/hotspot/share/classfile/classFileParser.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/classfile/classFileParser.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -3148,7 +3148,6 @@ _inner_classes = inner_classes; int index = 0; - const int cp_size = _cp->length(); cfs->guarantee_more(8 * length, CHECK_0); // 4-tuples of u2 for (int n = 0; n < length; n++) { // Inner class index @@ -3222,6 +3221,38 @@ return length; } +u2 ClassFileParser::parse_classfile_nest_members_attribute(const ClassFileStream* const cfs, + const u1* const nest_members_attribute_start, + TRAPS) { + const u1* const current_mark = cfs->current(); + u2 length = 0; + if (nest_members_attribute_start != NULL) { + cfs->set_current(nest_members_attribute_start); + cfs->guarantee_more(2, CHECK_0); // length + length = cfs->get_u2_fast(); + } + const int size = length; + Array* const nest_members = MetadataFactory::new_array(_loader_data, size, CHECK_0); + _nest_members = nest_members; + + int index = 0; + cfs->guarantee_more(2 * length, CHECK_0); + for (int n = 0; n < length; n++) { + const u2 class_info_index = cfs->get_u2_fast(); + check_property( + valid_klass_reference_at(class_info_index), + "Nest member class_info_index %u has bad constant type in class file %s", + class_info_index, CHECK_0); + nest_members->at_put(index++, class_info_index); + } + assert(index == size, "wrong size"); + + // Restore buffer's current position. + cfs->set_current(current_mark); + + return length; +} + void ClassFileParser::parse_classfile_synthetic_attribute(TRAPS) { set_class_synthetic_flag(true); } @@ -3329,10 +3360,14 @@ // Set inner classes attribute to default sentinel _inner_classes = Universe::the_empty_short_array(); + // Set nest members attribute to default sentinel + _nest_members = Universe::the_empty_short_array(); cfs->guarantee_more(2, CHECK); // attributes_count u2 attributes_count = cfs->get_u2_fast(); bool parsed_sourcefile_attribute = false; bool parsed_innerclasses_attribute = false; + bool parsed_nest_members_attribute = false; + bool parsed_nest_host_attribute = false; bool parsed_enclosingmethod_attribute = false; bool parsed_bootstrap_methods_attribute = false; const u1* runtime_visible_annotations = NULL; @@ -3350,6 +3385,9 @@ u4 inner_classes_attribute_length = 0; u2 enclosing_method_class_index = 0; u2 enclosing_method_method_index = 0; + const u1* nest_members_attribute_start = NULL; + u4 nest_members_attribute_length = 0; + // Iterate over attributes while (attributes_count--) { cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length @@ -3498,6 +3536,40 @@ assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); } cfs->skip_u1(attribute_length, CHECK); + } else if (_major_version >= JAVA_11_VERSION) { + if (tag == vmSymbols::tag_nest_members()) { + // Check for NestMembers tag + if (parsed_nest_members_attribute) { + classfile_parse_error("Multiple NestMembers attributes in class file %s", CHECK); + } else { + parsed_nest_members_attribute = true; + } + if (parsed_nest_host_attribute) { + classfile_parse_error("Conflicting NestHost and NestMembers attributes in class file %s", CHECK); + } + nest_members_attribute_start = cfs->current(); + nest_members_attribute_length = attribute_length; + cfs->skip_u1(nest_members_attribute_length, CHECK); + } else if (tag == vmSymbols::tag_nest_host()) { + if (parsed_nest_host_attribute) { + classfile_parse_error("Multiple NestHost attributes in class file %s", CHECK); + } else { + parsed_nest_host_attribute = true; + } + if (parsed_nest_members_attribute) { + classfile_parse_error("Conflicting NestMembers and NestHost attributes in class file %s", CHECK); + } + if (_need_verify) { + guarantee_property(attribute_length == 2, "Wrong NestHost attribute length in class file %s", CHECK); + } + cfs->guarantee_more(2, CHECK); + u2 class_info_index = cfs->get_u2_fast(); + check_property( + valid_klass_reference_at(class_info_index), + "Nest-host class_info_index %u has bad constant type in class file %s", + class_info_index, CHECK); + _nest_host = class_info_index; + } } else { // Unknown attribute cfs->skip_u1(attribute_length, CHECK); @@ -3526,13 +3598,25 @@ enclosing_method_class_index, enclosing_method_method_index, CHECK); - if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) { + if (parsed_innerclasses_attribute && _need_verify && _major_version >= JAVA_1_5_VERSION) { guarantee_property( inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes, "Wrong InnerClasses attribute length in class file %s", CHECK); } } + if (parsed_nest_members_attribute) { + const u2 num_of_classes = parse_classfile_nest_members_attribute( + cfs, + nest_members_attribute_start, + CHECK); + if (_need_verify) { + guarantee_property( + nest_members_attribute_length == sizeof(num_of_classes) + sizeof(u2) * num_of_classes, + "Wrong NestMembers attribute length in class file %s", CHECK); + } + } + if (_max_bootstrap_specifier_index >= 0) { guarantee_property(parsed_bootstrap_methods_attribute, "Missing BootstrapMethods attribute in class file %s", CHECK); @@ -3595,6 +3679,8 @@ this_klass->set_fields(_fields, java_fields_count); this_klass->set_methods(_methods); this_klass->set_inner_classes(_inner_classes); + this_klass->set_nest_members(_nest_members); + this_klass->set_nest_host_index(_nest_host); this_klass->set_local_interfaces(_local_interfaces); this_klass->set_annotations(_combined_annotations); // Delay the setting of _transitive_interfaces until after initialize_supers() in @@ -4605,24 +4691,26 @@ } if (super_m->is_final() && !super_m->is_static() && - // matching method in super is final, and not static - (Reflection::verify_field_access(this_klass, - super_m->method_holder(), - super_m->method_holder(), - super_m->access_flags(), false)) - // this class can access super final method and therefore override - ) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_VerifyError(), - "class %s overrides final method %s.%s%s", - this_klass->external_name(), - super_m->method_holder()->external_name(), - name->as_C_string(), - signature->as_C_string() - ); - return; + !super_m->access_flags().is_private()) { + // matching method in super is final, and not static or private + bool can_access = Reflection::verify_member_access(this_klass, + super_m->method_holder(), + super_m->method_holder(), + super_m->access_flags(), + false, false, CHECK); + if (can_access) { + // this class can access super final method and therefore override + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_VerifyError(), + "class %s overrides final method %s.%s%s", + this_klass->external_name(), + super_m->method_holder()->external_name(), + name->as_C_string(), + signature->as_C_string() + ); + return; + } } // continue to look from super_m's holder's super. @@ -5470,6 +5558,7 @@ assert(NULL == _fields, "invariant"); assert(NULL == _methods, "invariant"); assert(NULL == _inner_classes, "invariant"); + assert(NULL == _nest_members, "invariant"); assert(NULL == _local_interfaces, "invariant"); assert(NULL == _combined_annotations, "invariant"); @@ -5739,6 +5828,8 @@ _fields(NULL), _methods(NULL), _inner_classes(NULL), + _nest_members(NULL), + _nest_host(0), _local_interfaces(NULL), _transitive_interfaces(NULL), _combined_annotations(NULL), @@ -5843,6 +5934,7 @@ _fields = NULL; _methods = NULL; _inner_classes = NULL; + _nest_members = NULL; _local_interfaces = NULL; _combined_annotations = NULL; _annotations = _type_annotations = NULL; @@ -5868,6 +5960,10 @@ MetadataFactory::free_array(_loader_data, _inner_classes); } + if (_nest_members != NULL && _nest_members != Universe::the_empty_short_array()) { + MetadataFactory::free_array(_loader_data, _nest_members); + } + // Free interfaces InstanceKlass::deallocate_interfaces(_loader_data, _super_klass, _local_interfaces, _transitive_interfaces); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/classfile/classFileParser.hpp --- a/src/hotspot/share/classfile/classFileParser.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/classfile/classFileParser.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -97,6 +97,8 @@ Array* _fields; Array* _methods; Array* _inner_classes; + Array* _nest_members; + u2 _nest_host; Array* _local_interfaces; Array* _transitive_interfaces; Annotations* _combined_annotations; @@ -290,6 +292,10 @@ u2 enclosing_method_method_index, TRAPS); + u2 parse_classfile_nest_members_attribute(const ClassFileStream* const cfs, + const u1* const nest_members_attribute_start, + TRAPS); + void parse_classfile_attributes(const ClassFileStream* const cfs, ConstantPool* cp, ClassAnnotationCollector* parsed_annotations, diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/classfile/systemDictionary.cpp --- a/src/hotspot/share/classfile/systemDictionary.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/classfile/systemDictionary.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -245,10 +245,6 @@ // Forwards to resolve_instance_class_or_null Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { - assert(THREAD->can_call_java(), - "can not load classes with compiler thread: class=%s, classloader=%s", - class_name->as_C_string(), - class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string()); if (FieldType::is_array(class_name)) { return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD); } else if (FieldType::is_obj(class_name)) { @@ -692,6 +688,10 @@ PlaceholderEntry* placeholder; Symbol* superclassname = NULL; + assert(THREAD->can_call_java(), + "can not load classes with compiler thread: class=%s, classloader=%s", + name->as_C_string(), + class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string()); { MutexLocker mu(SystemDictionary_lock, THREAD); InstanceKlass* check = find_class(d_hash, name, dictionary); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/classfile/vmSymbols.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -142,6 +142,8 @@ /* class file format tags */ \ template(tag_source_file, "SourceFile") \ template(tag_inner_classes, "InnerClasses") \ + template(tag_nest_members, "NestMembers") \ + template(tag_nest_host, "NestHost") \ template(tag_constant_value, "ConstantValue") \ template(tag_code, "Code") \ template(tag_exceptions, "Exceptions") \ diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/code/dependencies.cpp --- a/src/hotspot/share/code/dependencies.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/code/dependencies.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -33,6 +33,7 @@ #include "compiler/compileBroker.hpp" #include "compiler/compileTask.hpp" #include "memory/resourceArea.hpp" +#include "oops/klass.hpp" #include "oops/oop.inline.hpp" #include "oops/objArrayKlass.hpp" #include "runtime/flags/flagSetting.hpp" @@ -1228,8 +1229,9 @@ } else if (!k->is_instance_klass()) { return false; // no methods to find in an array type } else { - // Search class hierarchy first. - Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature); + // Search class hierarchy first, skipping private implementations + // as they never override any inherited methods + Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature, Klass::skip_private); if (!Dependencies::is_concrete_method(m, k)) { // Check for re-abstraction of method if (!k->is_interface() && m != NULL && m->is_abstract()) { diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/include/jvm.h --- a/src/hotspot/share/include/jvm.h Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/include/jvm.h Sat Jun 23 01:32:41 2018 -0400 @@ -522,6 +522,17 @@ JNIEXPORT jint JNICALL JVM_GetClassAccessFlags(JNIEnv *env, jclass cls); +/* Nestmates - since JDK 11 */ + +JNIEXPORT jboolean JNICALL +JVM_AreNestMates(JNIEnv *env, jclass current, jclass member); + +JNIEXPORT jclass JNICALL +JVM_GetNestHost(JNIEnv *env, jclass current); + +JNIEXPORT jobjectArray JNICALL +JVM_GetNestMembers(JNIEnv *env, jclass current); + /* The following two reflection routines are still needed due to startup time issues */ /* * java.lang.reflect.Method diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/interpreter/linkResolver.cpp --- a/src/hotspot/share/interpreter/linkResolver.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/interpreter/linkResolver.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -387,12 +387,13 @@ // Looks up method in classes, then looks up local default methods methodHandle LinkResolver::lookup_instance_method_in_klasses(Klass* klass, Symbol* name, - Symbol* signature, TRAPS) { - Method* result = klass->uncached_lookup_method(name, signature, Klass::find_overpass); + Symbol* signature, + Klass::PrivateLookupMode private_mode, TRAPS) { + Method* result = klass->uncached_lookup_method(name, signature, Klass::find_overpass, private_mode); while (result != NULL && result->is_static() && result->method_holder()->super() != NULL) { Klass* super_klass = result->method_holder()->super(); - result = super_klass->uncached_lookup_method(name, signature, Klass::find_overpass); + result = super_klass->uncached_lookup_method(name, signature, Klass::find_overpass, private_mode); } if (klass->is_array_klass()) { @@ -582,11 +583,14 @@ } // assert(extra_arg_result_or_null != NULL, "must be able to return extra argument"); - if (!Reflection::verify_field_access(ref_klass, - resolved_klass, - sel_klass, - flags, - true)) { + bool can_access = Reflection::verify_member_access(ref_klass, + resolved_klass, + sel_klass, + flags, + true, false, CHECK); + // Any existing exceptions that may have been thrown, for example LinkageErrors + // from nest-host resolution, have been allowed to propagate. + if (!can_access) { ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, @@ -757,7 +761,7 @@ nested_exception, NULL); } - // 5. access checks, access checking may be turned off when calling from within the VM. + // 6. access checks, access checking may be turned off when calling from within the VM. Klass* current_klass = link_info.current_klass(); if (link_info.check_access()) { assert(current_klass != NULL , "current_klass should not be null"); @@ -773,6 +777,24 @@ check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL); } + // For private method invocation we should only find the method in the resolved class. + // If that is not the case then we have a found a supertype method that we have nestmate + // access to. + if (resolved_method->is_private() && resolved_method->method_holder() != resolved_klass) { + ResourceMark rm(THREAD); + DEBUG_ONLY(bool is_nestmate = InstanceKlass::cast(link_info.current_klass())->has_nestmate_access_to(InstanceKlass::cast(resolved_klass), THREAD);) + assert(is_nestmate, "was only expecting nestmates to get here!"); + Exceptions::fthrow( + THREAD_AND_LOCATION, + vmSymbols::java_lang_NoSuchMethodError(), + "%s: method %s%s not found", + resolved_klass->external_name(), + resolved_method->name()->as_C_string(), + resolved_method->signature()->as_C_string() + ); + return NULL; + } + return resolved_method; } @@ -874,19 +896,6 @@ THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } - if (code == Bytecodes::_invokeinterface && resolved_method->is_private()) { - ResourceMark rm(THREAD); - char buf[200]; - - Klass* current_klass = link_info.current_klass(); - jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s, caller-class:%s", - Method::name_and_sig_as_C_string(resolved_klass, - resolved_method->name(), - resolved_method->signature()), - (current_klass == NULL ? "" : current_klass->internal_name())); - THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); - } - if (log_develop_is_enabled(Trace, itables)) { char buf[200]; jio_snprintf(buf, sizeof(buf), "%s resolved interface method: caller-class:", @@ -906,11 +915,14 @@ Klass* sel_klass, const fieldDescriptor& fd, TRAPS) { - if (!Reflection::verify_field_access(ref_klass, - resolved_klass, - sel_klass, - fd.access_flags(), - true)) { + bool can_access = Reflection::verify_member_access(ref_klass, + resolved_klass, + sel_klass, + fd.access_flags(), + true, false, CHECK); + // Any existing exceptions that may have been thrown, for example LinkageErrors + // from nest-host resolution, have been allowed to propagate. + if (!can_access) { ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, @@ -1128,7 +1140,8 @@ return NULL; } - // check if invokespecial's interface method reference is in an indirect superinterface + // ensure that invokespecial's interface method reference is in + // a direct superinterface, not an indirect superinterface Klass* current_klass = link_info.current_klass(); if (current_klass != NULL && resolved_klass->is_interface()) { InstanceKlass* ck = InstanceKlass::cast(current_klass); @@ -1146,8 +1159,8 @@ jio_snprintf(buf, sizeof(buf), "Interface method reference: %s, is in an indirect superinterface of %s", Method::name_and_sig_as_C_string(resolved_klass, - resolved_method->name(), - resolved_method->signature()), + resolved_method->name(), + resolved_method->signature()), current_klass->external_name()); THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } @@ -1192,7 +1205,7 @@ resolved_method->name() != vmSymbols::object_initializer_name()) { // check if this is an old-style super call and do a new lookup if so - // a) check if ACC_SUPER flag is set for the current class + // a) check if ACC_SUPER flag is set for the current class Klass* current_klass = link_info.current_klass(); if ((current_klass->is_super() || !AllowNonVirtualCalls) && // b) check if the class of the resolved_klass is a superclass @@ -1200,12 +1213,14 @@ // This check is not performed for super.invoke for interface methods // in super interfaces. current_klass->is_subclass_of(resolved_klass) && - current_klass != resolved_klass) { + current_klass != resolved_klass + ) { // Lookup super method Klass* super_klass = current_klass->super(); sel_method = lookup_instance_method_in_klasses(super_klass, - resolved_method->name(), - resolved_method->signature(), CHECK); + resolved_method->name(), + resolved_method->signature(), + Klass::find_private, CHECK); // check if found if (sel_method.is_null()) { ResourceMark rm(THREAD); @@ -1356,11 +1371,12 @@ // a default or miranda method; therefore, it must have a valid vtable index. assert(!resolved_method->has_itable_index(), ""); vtable_index = resolved_method->vtable_index(); - // We could get a negative vtable_index for final methods, - // because as an optimization they are never put in the vtable, - // unless they override an existing method. - // If we do get a negative, it means the resolved method is the the selected - // method, and it can never be changed by an override. + // We could get a negative vtable_index of nonvirtual_vtable_index for private + // methods, or for final methods. Private methods never appear in the vtable + // and never override other methods. As an optimization, final methods are + // never put in the vtable, unless they override an existing method. + // So if we do get nonvirtual_vtable_index, it means the selected method is the + // resolved method, and it can never be changed by an override. if (vtable_index == Method::nonvirtual_vtable_index) { assert(resolved_method->can_be_statically_bound(), "cannot override this method"); selected_method = resolved_method; @@ -1415,6 +1431,7 @@ Handle recv, Klass* recv_klass, bool check_null_and_abstract, TRAPS) { + // check if receiver exists if (check_null_and_abstract && recv.is_null()) { THROW(vmSymbols::java_lang_NullPointerException()); @@ -1430,35 +1447,43 @@ THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } - // do lookup based on receiver klass - // This search must match the linktime preparation search for itable initialization - // to correctly enforce loader constraints for interface method inheritance - methodHandle selected_method = lookup_instance_method_in_klasses(recv_klass, - resolved_method->name(), - resolved_method->signature(), CHECK); - if (selected_method.is_null() && !check_null_and_abstract) { - // In theory this is a harmless placeholder value, but - // in practice leaving in null affects the nsk default method tests. - // This needs further study. - selected_method = resolved_method; - } - // check if method exists - if (selected_method.is_null()) { - // Pass arguments for generating a verbose error message. - throw_abstract_method_error(resolved_method, recv_klass, CHECK); - } - // check access - // Throw Illegal Access Error if selected_method is not public. - if (!selected_method->is_public()) { - ResourceMark rm(THREAD); - THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), - Method::name_and_sig_as_C_string(recv_klass, - selected_method->name(), - selected_method->signature())); - } - // check if abstract - if (check_null_and_abstract && selected_method->is_abstract()) { - throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK); + methodHandle selected_method = resolved_method; + + // resolve the method in the receiver class, unless it is private + if (!resolved_method()->is_private()) { + // do lookup based on receiver klass + // This search must match the linktime preparation search for itable initialization + // to correctly enforce loader constraints for interface method inheritance. + // Private methods are skipped as the resolved method was not private. + selected_method = lookup_instance_method_in_klasses(recv_klass, + resolved_method->name(), + resolved_method->signature(), + Klass::skip_private, CHECK); + + if (selected_method.is_null() && !check_null_and_abstract) { + // In theory this is a harmless placeholder value, but + // in practice leaving in null affects the nsk default method tests. + // This needs further study. + selected_method = resolved_method; + } + // check if method exists + if (selected_method.is_null()) { + // Pass arguments for generating a verbose error message. + throw_abstract_method_error(resolved_method, recv_klass, CHECK); + } + // check access + // Throw Illegal Access Error if selected_method is not public. + if (!selected_method->is_public()) { + ResourceMark rm(THREAD); + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), + Method::name_and_sig_as_C_string(recv_klass, + selected_method->name(), + selected_method->signature())); + } + // check if abstract + if (check_null_and_abstract && selected_method->is_abstract()) { + throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK); + } } if (log_develop_is_enabled(Trace, itables)) { @@ -1466,13 +1491,25 @@ recv_klass, resolved_klass, selected_method, true); } // setup result - if (!resolved_method->has_itable_index()) { + if (resolved_method->has_vtable_index()) { int vtable_index = resolved_method->vtable_index(); + log_develop_trace(itables)(" -- vtable index: %d", vtable_index); assert(vtable_index == selected_method->vtable_index(), "sanity check"); result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); - } else { + } else if (resolved_method->has_itable_index()) { int itable_index = resolved_method()->itable_index(); + log_develop_trace(itables)(" -- itable index: %d", itable_index); result.set_interface(resolved_klass, recv_klass, resolved_method, selected_method, itable_index, CHECK); + } else { + int index = resolved_method->vtable_index(); + log_develop_trace(itables)(" -- non itable/vtable index: %d", index); + assert(index == Method::nonvirtual_vtable_index, "Oops hit another case!"); + assert(resolved_method()->is_private() || + (resolved_method()->is_final() && resolved_method->method_holder() == SystemDictionary::Object_klass()), + "Should only have non-virtual invokeinterface for private or final-Object methods!"); + assert(resolved_method()->can_be_statically_bound(), "Should only have non-virtual invokeinterface for statically bound methods!"); + // This sets up the nonvirtual form of "virtual" call (as needed for final and private methods) + result.set_virtual(resolved_klass, resolved_klass, resolved_method, resolved_method, index, CHECK); } } diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/interpreter/linkResolver.hpp --- a/src/hotspot/share/interpreter/linkResolver.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/interpreter/linkResolver.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -211,8 +211,8 @@ Handle *method_type_result, TRAPS); JVMCI_ONLY(public:) // Needed for CompilerToVM.resolveMethod() // Not Linktime so doesn't take LinkInfo - static methodHandle lookup_instance_method_in_klasses ( - Klass* klass, Symbol* name, Symbol* signature, TRAPS); + static methodHandle lookup_instance_method_in_klasses (Klass* klass, Symbol* name, Symbol* signature, + Klass::PrivateLookupMode private_mode, TRAPS); JVMCI_ONLY(private:) // Similar loader constraint checking functions that throw diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/logging/logTag.hpp --- a/src/hotspot/share/logging/logTag.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/logging/logTag.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -100,6 +100,7 @@ LOG_TAG(module) \ LOG_TAG(monitorinflation) \ LOG_TAG(monitormismatch) \ + LOG_TAG(nestmates) \ LOG_TAG(nmethod) \ LOG_TAG(normalize) \ LOG_TAG(objecttagging) \ diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/memory/heapInspection.hpp --- a/src/hotspot/share/memory/heapInspection.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/memory/heapInspection.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -86,6 +86,8 @@ "Number of bytes used by the InstanceKlass::fields() array") \ f(inner_classes_bytes, IK_inner_classes, \ "Number of bytes used by the InstanceKlass::inner_classes() array") \ + f(nest_members_bytes, IK_nest_members, \ + "Number of bytes used by the InstanceKlass::nest_members() array") \ f(signers_bytes, IK_signers, \ "Number of bytes used by the InstanceKlass::singers() array") \ f(class_annotations_bytes, class_annotations, \ diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/oops/arrayKlass.cpp --- a/src/hotspot/share/oops/arrayKlass.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/oops/arrayKlass.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -71,13 +71,14 @@ Method* ArrayKlass::uncached_lookup_method(const Symbol* name, const Symbol* signature, - OverpassLookupMode overpass_mode) const { + OverpassLookupMode overpass_mode, + PrivateLookupMode private_mode) const { // There are no methods in an array klass but the super class (Object) has some assert(super(), "super klass must be present"); // Always ignore overpass methods in superclasses, although technically the // super klass of an array, (j.l.Object) should not have // any overpass methods present. - return super()->uncached_lookup_method(name, signature, Klass::skip_overpass); + return super()->uncached_lookup_method(name, signature, Klass::skip_overpass, private_mode); } ArrayKlass::ArrayKlass(Symbol* name) : diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/oops/arrayKlass.hpp --- a/src/hotspot/share/oops/arrayKlass.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/oops/arrayKlass.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -87,7 +87,8 @@ // Lookup operations Method* uncached_lookup_method(const Symbol* name, const Symbol* signature, - OverpassLookupMode overpass_mode) const; + OverpassLookupMode overpass_mode, + PrivateLookupMode private_mode = find_private) const; static ArrayKlass* cast(Klass* k) { return const_cast(cast(const_cast(k))); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/oops/cpCache.cpp --- a/src/hotspot/share/oops/cpCache.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/oops/cpCache.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -174,17 +174,37 @@ int byte_no = -1; bool change_to_virtual = false; - + InstanceKlass* holder = NULL; // have to declare this outside the switch switch (invoke_code) { case Bytecodes::_invokeinterface: - // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface - // instruction somehow links to a non-interface method (in Object). - // In that case, the method has no itable index and must be invoked as a virtual. - // Set a flag to keep track of this corner case. - assert(method->is_public(), "Calling non-public method in Object with invokeinterface"); - change_to_virtual = true; + holder = method->method_holder(); + // check for private interface method invocations + if (vtable_index == Method::nonvirtual_vtable_index && holder->is_interface() ) { + assert(method->is_private(), "unexpected non-private method"); + assert(method->can_be_statically_bound(), "unexpected non-statically-bound method"); + // set_f2_as_vfinal_method checks if is_vfinal flag is true. + set_method_flags(as_TosState(method->result_type()), + ( 1 << is_vfinal_shift) | + ((method->is_final_method() ? 1 : 0) << is_final_shift), + method()->size_of_parameters()); + set_f2_as_vfinal_method(method()); + byte_no = 2; + set_f1(holder); // interface klass* + break; + } + else { + // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface + // instruction links to a non-interface method (in Object). This can happen when + // an interface redeclares an Object method (like CharSequence declaring toString()) + // or when invokeinterface is used explicitly. + // In that case, the method has no itable index and must be invoked as a virtual. + // Set a flag to keep track of this corner case. + assert(holder->is_interface() || holder == SystemDictionary::Object_klass(), "unexpected holder class"); + assert(method->is_public(), "Calling non-public method in Object with invokeinterface"); + change_to_virtual = true; - // ...and fall through as if we were handling invokevirtual: + // ...and fall through as if we were handling invokevirtual: + } case Bytecodes::_invokevirtual: { if (!is_vtable_call) { @@ -237,7 +257,7 @@ // is executed. if (invoke_code != Bytecodes::_invokespecial || !sender_is_interface || method->name() == vmSymbols::object_initializer_name()) { - set_bytecode_1(invoke_code); + set_bytecode_1(invoke_code); } } else if (byte_no == 2) { if (change_to_virtual) { @@ -257,7 +277,18 @@ // We set bytecode_2() to _invokevirtual. // See also interpreterRuntime.cpp. (8/25/2000) } else { - assert(invoke_code == Bytecodes::_invokevirtual, ""); + assert(invoke_code == Bytecodes::_invokevirtual || + (invoke_code == Bytecodes::_invokeinterface && + ((method->is_private() || + (method->is_final() && method->method_holder() == SystemDictionary::Object_klass())))), + "unexpected invocation mode"); + if (invoke_code == Bytecodes::_invokeinterface && + (method->is_private() || method->is_final())) { + // We set bytecode_1() to _invokeinterface, because that is the + // bytecode # used by the interpreter to see if it is resolved. + // We set bytecode_2() to _invokevirtual. + set_bytecode_1(invoke_code); + } } // set up for invokevirtual, even if linking for invokeinterface also: set_bytecode_2(Bytecodes::_invokevirtual); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/oops/instanceKlass.cpp --- a/src/hotspot/share/oops/instanceKlass.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/oops/instanceKlass.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -145,6 +145,198 @@ return false; } +// called to verify that k is a member of this nest +bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const { + if (_nest_members == NULL || _nest_members == Universe::the_empty_short_array()) { + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Checked nest membership of %s in non-nest-host class %s", + k->external_name(), this->external_name()); + } + return false; + } + + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Checking nest membership of %s in %s", + k->external_name(), this->external_name()); + } + + // Check names first and if they match then check actual klass. This avoids + // resolving anything unnecessarily. + for (int i = 0; i < _nest_members->length(); i++) { + int cp_index = _nest_members->at(i); + Symbol* name = _constants->klass_name_at(cp_index); + if (name == k->name()) { + log_trace(class, nestmates)("- Found it at nest_members[%d] => cp[%d]", i, cp_index); + + // names match so check actual klass - this may trigger class loading if + // it doesn't match (but that should be impossible) + Klass* k2 = _constants->klass_at(cp_index, CHECK_false); + if (k2 == k) { + log_trace(class, nestmates)("- class is listed as a nest member"); + return true; + } else { + // same name but different klass! + log_trace(class, nestmates)(" - klass comparison failed!"); + // can't have different classes for the same name, so we're done + return false; + } + } + } + log_trace(class, nestmates)("- class is NOT a nest member!"); + return false; +} + +// Return nest-host class, resolving, validating and saving it if needed. +// In cases where this is called from a thread that can not do classloading +// (such as a native JIT thread) then we simply return NULL, which in turn +// causes the access check to return false. Such code will retry the access +// from a more suitable environment later. +InstanceKlass* InstanceKlass::nest_host(Symbol* validationException, TRAPS) { + InstanceKlass* nest_host_k = _nest_host; + if (nest_host_k == NULL) { + // need to resolve and save our nest-host class. This could be attempted + // concurrently but as the result is idempotent and we don't use the class + // then we do not need any synchronization beyond what is implicitly used + // during class loading. + if (_nest_host_index != 0) { // we have a real nest_host + // Before trying to resolve check if we're in a suitable context + if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) { + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread", + this->external_name()); + } + return NULL; + } + + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s", + this->external_name(), + _constants->klass_name_at(_nest_host_index)->as_C_string()); + } + + Klass* k = _constants->klass_at(_nest_host_index, THREAD); + if (HAS_PENDING_EXCEPTION) { + Handle exc_h = Handle(THREAD, PENDING_EXCEPTION); + if (exc_h->is_a(SystemDictionary::NoClassDefFoundError_klass())) { + // throw a new CDNFE with the original as its cause, and a clear msg + ResourceMark rm(THREAD); + char buf[200]; + CLEAR_PENDING_EXCEPTION; + jio_snprintf(buf, sizeof(buf), + "Unable to load nest-host class (%s) of %s", + _constants->klass_name_at(_nest_host_index)->as_C_string(), + this->external_name()); + log_trace(class, nestmates)("%s - NoClassDefFoundError", buf); + THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), buf, exc_h); + } + // All other exceptions pass through (OOME, StackOverflowError, LinkageErrors etc). + return NULL; + } + + // A valid nest-host is an instance class in the current package that lists this + // class as a nest member. If any of these conditions are not met we post the + // requested exception type (if any) and return NULL + + const char* error = NULL; + + // JVMS 5.4.4 indicates package check comes first + if (is_same_class_package(k)) { + + // Now check actual membership. We can't be a member if our "host" is + // not an instance class. + if (k->is_instance_klass()) { + nest_host_k = InstanceKlass::cast(k); + + bool is_member = nest_host_k->has_nest_member(this, CHECK_NULL); + if (is_member) { + // save resolved nest-host value + _nest_host = nest_host_k; + + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Resolved nest-host of %s to %s", + this->external_name(), k->external_name()); + } + return nest_host_k; + } + } + error = "current type is not listed as a nest member"; + } else { + error = "types are in different packages"; + } + + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Type %s is not a nest member of resolved type %s: %s", + this->external_name(), + k->external_name(), + error); + } + + if (validationException != NULL) { + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, + validationException, + "Type %s is not a nest member of %s: %s", + this->external_name(), + k->external_name(), + error + ); + } + return NULL; + } else { + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", + this->external_name()); + } + // save resolved nest-host value + return (_nest_host = this); + } + } + return nest_host_k; +} + +// check if 'this' and k are nestmates (same nest_host), or k is our nest_host, +// or we are k's nest_host - all of which is covered by comparing the two +// resolved_nest_hosts +bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) { + + assert(this != k, "this should be handled by higher-level code"); + + // Per JVMS 5.4.4 we first resolve and validate the current class, then + // the target class k. Resolution exceptions will be passed on by upper + // layers. IncompatibleClassChangeErrors from membership validation failures + // will also be passed through. + + Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError(); + InstanceKlass* cur_host = nest_host(icce, CHECK_false); + if (cur_host == NULL) { + return false; + } + + Klass* k_nest_host = k->nest_host(icce, CHECK_false); + if (k_nest_host == NULL) { + return false; + } + + bool access = (cur_host == k_nest_host); + + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Class %s does %shave nestmate access to %s", + this->external_name(), + access ? "" : "NOT ", + k->external_name()); + } + + return access; +} + InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { const int size = InstanceKlass::size(parser.vtable_size(), parser.itable_size(), @@ -169,13 +361,11 @@ else if (is_class_loader(class_name, parser)) { // class loader ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser); - } - else { + } else { // normal ik = new (loader_data, size, THREAD) InstanceKlass(parser, InstanceKlass::_misc_kind_other); } - } - else { + } else { // reference ik = new (loader_data, size, THREAD) InstanceRefKlass(parser); } @@ -215,7 +405,10 @@ _static_field_size(parser.static_field_size()), _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())), _itable_len(parser.itable_size()), - _reference_type(parser.reference_type()) { + _reference_type(parser.reference_type()), + _nest_members(NULL), + _nest_host_index(0), + _nest_host(NULL) { set_vtable_length(parser.vtable_size()); set_kind(kind); set_access_flags(parser.access_flags()); @@ -359,6 +552,13 @@ } set_inner_classes(NULL); + if (nest_members() != NULL && + nest_members() != Universe::the_empty_short_array() && + !nest_members()->is_shared()) { + MetadataFactory::free_array(loader_data, nest_members()); + } + set_nest_members(NULL); + // We should deallocate the Annotations instance if it's not in shared spaces. if (annotations() != NULL && !annotations()->is_shared()) { MetadataFactory::free_metadata(loader_data, annotations()); @@ -643,7 +843,6 @@ return true; } - // Rewrite the byte codes of all of the methods of a class. // The rewriter must be called exactly once. Rewriting must happen after // verification but before the first method of the class is executed. @@ -1359,13 +1558,14 @@ // and skips over static methods Method* InstanceKlass::find_instance_method(const Array* methods, const Symbol* name, - const Symbol* signature) { + const Symbol* signature, + PrivateLookupMode private_mode) { Method* const meth = InstanceKlass::find_method_impl(methods, name, signature, find_overpass, skip_static, - find_private); + private_mode); assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics"); return meth; @@ -1373,8 +1573,10 @@ // find_instance_method looks up the name/signature in the local methods array // and skips over static methods -Method* InstanceKlass::find_instance_method(const Symbol* name, const Symbol* signature) const { - return InstanceKlass::find_instance_method(methods(), name, signature); +Method* InstanceKlass::find_instance_method(const Symbol* name, + const Symbol* signature, + PrivateLookupMode private_mode) const { + return InstanceKlass::find_instance_method(methods(), name, signature, private_mode); } // Find looks up the name/signature in the local methods array @@ -1475,7 +1677,7 @@ // Do linear search to find matching signature. First, quick check // for common case, ignoring overpasses if requested. if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { - return hit; + return hit; } // search downwards through overloaded methods @@ -1531,10 +1733,12 @@ } // uncached_lookup_method searches both the local class methods array and all -// superclasses methods arrays, skipping any overpass methods in superclasses. +// superclasses methods arrays, skipping any overpass methods in superclasses, +// and possibly skipping private methods. Method* InstanceKlass::uncached_lookup_method(const Symbol* name, const Symbol* signature, - OverpassLookupMode overpass_mode) const { + OverpassLookupMode overpass_mode, + PrivateLookupMode private_mode) const { OverpassLookupMode overpass_local_mode = overpass_mode; const Klass* klass = this; while (klass != NULL) { @@ -1542,7 +1746,7 @@ signature, overpass_local_mode, find_static, - find_private); + private_mode); if (method != NULL) { return method; } @@ -2044,6 +2248,8 @@ } } } + + it->push(&_nest_members); } void InstanceKlass::remove_unshareable_info() { @@ -2087,10 +2293,12 @@ guarantee(_previous_versions == NULL, "must be"); #endif - _init_thread = NULL; - _methods_jmethod_ids = NULL; - _jni_ids = NULL; - _oop_map_cache = NULL; + _init_thread = NULL; + _methods_jmethod_ids = NULL; + _jni_ids = NULL; + _oop_map_cache = NULL; + // clear _nest_host to ensure re-load at runtime + _nest_host = NULL; } void InstanceKlass::remove_java_mirror() { @@ -2946,6 +3154,7 @@ st->cr(); } st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); + st->print(BULLET"nest members: "); nest_members()->print_value_on(st); st->cr(); st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), p2i(start_of_vtable())); st->cr(); if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st); @@ -3188,6 +3397,7 @@ n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces())); n += (sz->_fields_bytes = sz->count_array(fields())); n += (sz->_inner_classes_bytes = sz->count_array(inner_classes())); + n += (sz->_nest_members_bytes = sz->count_array(nest_members())); sz->_ro_bytes += n; const ConstantPool* cp = constants(); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/oops/instanceKlass.hpp --- a/src/hotspot/share/oops/instanceKlass.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/oops/instanceKlass.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -165,6 +165,19 @@ // number_of_inner_classes * 4 + enclosing_method_attribute_size. Array* _inner_classes; + // The NestMembers attribute. An array of shorts, where each is a + // class info index for the class that is a nest member. This data + // has not been validated. + Array* _nest_members; + + // The NestHost attribute. The class info index for the class + // that is the nest-host of this class. This data has not been validated. + jushort _nest_host_index; + + // Resolved nest-host klass: either true nest-host or self if we are not nested. + // By always being set it makes nest-member access checks simpler. + InstanceKlass* _nest_host; + // the source debug extension for this klass, NULL if not specified. // Specified as UTF-8 string without terminating zero byte in the classfile, // it is stored in the instanceklass as a NULL-terminated UTF-8 string @@ -435,6 +448,24 @@ Array* inner_classes() const { return _inner_classes; } void set_inner_classes(Array* f) { _inner_classes = f; } + // nest members + Array* nest_members() const { return _nest_members; } + void set_nest_members(Array* m) { _nest_members = m; } + + // nest-host index + jushort nest_host_index() const { return _nest_host_index; } + void set_nest_host_index(u2 i) { _nest_host_index = i; } + +private: + // Called to verify that k is a member of this nest - does not look at k's nest-host + bool has_nest_member(InstanceKlass* k, TRAPS) const; +public: + // Returns nest-host class, resolving and validating it if needed + // Returns NULL if an exception occurs during loading, or validation fails + InstanceKlass* nest_host(Symbol* validationException, TRAPS); + // Check if this klass is a nestmate of k - resolves this nest-host and k's + bool has_nestmate_access_to(InstanceKlass* k, TRAPS); + enum InnerClassAttributeOffset { // From http://mirror.eng/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc10.html#18814 inner_class_inner_class_info_offset = 0, @@ -554,10 +585,12 @@ const Symbol* signature); // find a local method, but skip static methods - Method* find_instance_method(const Symbol* name, const Symbol* signature) const; + Method* find_instance_method(const Symbol* name, const Symbol* signature, + PrivateLookupMode private_mode = find_private) const; static Method* find_instance_method(const Array* methods, const Symbol* name, - const Symbol* signature); + const Symbol* signature, + PrivateLookupMode private_mode = find_private); // find a local method (returns NULL if not found) Method* find_local_method(const Symbol* name, @@ -585,7 +618,8 @@ // lookup operation (returns NULL if not found) Method* uncached_lookup_method(const Symbol* name, const Symbol* signature, - OverpassLookupMode overpass_mode) const; + OverpassLookupMode overpass_mode, + PrivateLookupMode private_mode = find_private) const; // lookup a method in all the interfaces that this class implements // (returns NULL if not found) diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/oops/klass.cpp --- a/src/hotspot/share/oops/klass.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/oops/klass.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -168,7 +168,9 @@ return NULL; } -Method* Klass::uncached_lookup_method(const Symbol* name, const Symbol* signature, OverpassLookupMode overpass_mode) const { +Method* Klass::uncached_lookup_method(const Symbol* name, const Symbol* signature, + OverpassLookupMode overpass_mode, + PrivateLookupMode private_mode) const { #ifdef ASSERT tty->print_cr("Error: uncached_lookup_method called on a klass oop." " Likely error: reflection method does not correctly" diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/oops/klass.hpp --- a/src/hotspot/share/oops/klass.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/oops/klass.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -467,7 +467,9 @@ // lookup operation for MethodLookupCache friend class MethodLookupCache; virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const; - virtual Method* uncached_lookup_method(const Symbol* name, const Symbol* signature, OverpassLookupMode overpass_mode) const; + virtual Method* uncached_lookup_method(const Symbol* name, const Symbol* signature, + OverpassLookupMode overpass_mode, + PrivateLookupMode = find_private) const; public: Method* lookup_method(const Symbol* name, const Symbol* signature) const { return uncached_lookup_method(name, signature, find_overpass); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/oops/klassVtable.cpp --- a/src/hotspot/share/oops/klassVtable.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/oops/klassVtable.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -1122,7 +1122,7 @@ inline bool interface_method_needs_itable_index(Method* m) { if (m->is_static()) return false; // e.g., Stream.empty if (m->is_initializer()) return false; // or - if (m->is_private()) return false; // requires invokeSpecial + if (m->is_private()) return false; // uses direct call // If an interface redeclares a method from java.lang.Object, // it should already have a vtable index, don't touch it. // e.g., CharSequence.toString (from initialize_vtable) @@ -1211,8 +1211,13 @@ methodHandle target; if (m->has_itable_index()) { // This search must match the runtime resolution, i.e. selection search for invokeinterface - // to correctly enforce loader constraints for interface method inheritance - target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK); + // to correctly enforce loader constraints for interface method inheritance. + // Private methods are skipped as a private class method can never be the implementation + // of an interface method. + // Invokespecial does not perform selection based on the receiver, so it does not use + // the cached itable. + target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), + Klass::skip_private, CHECK); } if (target == NULL || !target->is_public() || target->is_abstract() || target->is_overpass()) { assert(target == NULL || !target->is_overpass() || target->is_public(), diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/opto/doCall.cpp --- a/src/hotspot/share/opto/doCall.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/opto/doCall.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -505,28 +505,36 @@ speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL; } - // invoke-super-special + // Additional receiver subtype checks for interface calls via invokespecial or invokeinterface. + ciKlass* receiver_constraint = NULL; if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) { ciInstanceKlass* calling_klass = method()->holder(); ciInstanceKlass* sender_klass = calling_klass->is_anonymous() ? calling_klass->host_klass() : calling_klass; if (sender_klass->is_interface()) { - Node* receiver_node = stack(sp() - nargs); - Node* cls_node = makecon(TypeKlassPtr::make(sender_klass)); - Node* bad_type_ctrl = NULL; - Node* casted_receiver = gen_checkcast(receiver_node, cls_node, &bad_type_ctrl); - if (bad_type_ctrl != NULL) { - PreserveJVMState pjvms(this); - set_control(bad_type_ctrl); - uncommon_trap(Deoptimization::Reason_class_check, - Deoptimization::Action_none); - } - if (stopped()) { - return; // MUST uncommon-trap? - } - set_stack(sp() - nargs, casted_receiver); + receiver_constraint = sender_klass; } + } else if (iter().cur_bc_raw() == Bytecodes::_invokeinterface && orig_callee->is_private()) { + assert(holder->is_interface(), "How did we get a non-interface method here!"); + receiver_constraint = holder; + } + + if (receiver_constraint != NULL) { + Node* receiver_node = stack(sp() - nargs); + Node* cls_node = makecon(TypeKlassPtr::make(receiver_constraint)); + Node* bad_type_ctrl = NULL; + Node* casted_receiver = gen_checkcast(receiver_node, cls_node, &bad_type_ctrl); + if (bad_type_ctrl != NULL) { + PreserveJVMState pjvms(this); + set_control(bad_type_ctrl); + uncommon_trap(Deoptimization::Reason_class_check, + Deoptimization::Action_none); + } + if (stopped()) { + return; // MUST uncommon-trap? + } + set_stack(sp() - nargs, casted_receiver); } // Note: It's OK to try to inline a virtual call. diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/jvm.cpp --- a/src/hotspot/share/prims/jvm.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/jvm.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -1892,6 +1892,98 @@ } JVM_END +JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member)) +{ + JVMWrapper("JVM_AreNestMates"); + Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); + assert(c->is_instance_klass(), "must be"); + InstanceKlass* ck = InstanceKlass::cast(c); + Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member)); + assert(m->is_instance_klass(), "must be"); + InstanceKlass* mk = InstanceKlass::cast(m); + return ck->has_nestmate_access_to(mk, THREAD); +} +JVM_END + +JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current)) +{ + // current is not a primitive or array class + JVMWrapper("JVM_GetNestHost"); + Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); + assert(c->is_instance_klass(), "must be"); + InstanceKlass* ck = InstanceKlass::cast(c); + // Don't post exceptions if validation fails + InstanceKlass* host = ck->nest_host(NULL, THREAD); + return (jclass) (host == NULL ? NULL : + JNIHandles::make_local(THREAD, host->java_mirror())); +} +JVM_END + +JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current)) +{ + // current is not a primitive or array class + JVMWrapper("JVM_GetNestMembers"); + Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); + assert(c->is_instance_klass(), "must be"); + InstanceKlass* ck = InstanceKlass::cast(c); + // Get the nest host for this nest - throw ICCE if validation fails + Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError(); + InstanceKlass* host = ck->nest_host(icce, CHECK_NULL); + + { + JvmtiVMObjectAllocEventCollector oam; + Array* members = host->nest_members(); + int length = members == NULL ? 0 : members->length(); + // nest host is first in the array so make it one bigger + objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), + length + 1, CHECK_NULL); + objArrayHandle result (THREAD, r); + result->obj_at_put(0, host->java_mirror()); + if (length != 0) { + int i; + for (i = 0; i < length; i++) { + int cp_index = members->at(i); + Klass* k = host->constants()->klass_at(cp_index, CHECK_NULL); + if (k->is_instance_klass()) { + InstanceKlass* nest_host_k = + InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL); + if (nest_host_k == host) { + result->obj_at_put(i+1, k->java_mirror()); + } + else { + // k's nest host is legal but it isn't our host so + // throw ICCE + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, + icce, + "Nest member %s in %s declares a different nest host of %s", + k->external_name(), + host->external_name(), + nest_host_k->external_name() + ); + return NULL; + } + } + else { + // we have a bad nest member entry - throw ICCE + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, + icce, + "Class %s can not be a nest member of %s", + k->external_name(), + host->external_name() + ); + return NULL; + } + } + } + else { + assert(host == ck, "must be singleton nest"); + } + return (jobjectArray)JNIHandles::make_local(THREAD, result()); + } +} +JVM_END // Constant pool access ////////////////////////////////////////////////////////// diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/jvmti.xml --- a/src/hotspot/share/prims/jvmti.xml Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/jvmti.xml Sat Jun 23 01:32:41 2018 -0400 @@ -358,7 +358,7 @@ ]> @@ -7631,9 +7631,12 @@ <eventlink id="ClassFileLoadHook"/> event will be sent. <p/> - The retransformation may change method bodies, the constant pool and attributes. + The retransformation may change method bodies, the constant pool and attributes + (unless explicitly prohibited). The retransformation must not add, remove or rename fields or methods, change the signatures of methods, change modifiers, or change inheritance. + The retransformation must not change the <code>NestHost</code> or + <code>NestMembers</code> attributes. These restrictions may be lifted in future versions. See the error return description below for information on error codes returned if an unsupported retransformation is attempted. @@ -7704,6 +7707,9 @@ A retransformed class file does not declare a method declared in the old class version. </error> + <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED"> + A retransformed class file has unsupported differences in class attributes. + </error> <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED"> A retransformed class file has different class modifiers. </error> @@ -7778,9 +7784,12 @@ <eventlink id="ClassFileLoadHook">Class File Load Hook</eventlink> will be sent (if enabled), but no other <jvmti/> events will be sent. <p/> - The redefinition may change method bodies, the constant pool and attributes. + The redefinition may change method bodies, the constant pool and attributes + (unless explicitly prohibited). The redefinition must not add, remove or rename fields or methods, change the signatures of methods, change modifiers, or change inheritance. + The retransformation must not change the <code>NestHost</code> or + <code>NestMembers</code> attributes. These restrictions may be lifted in future versions. See the error return description below for information on error codes returned if an unsupported redefinition is attempted. @@ -7855,6 +7864,9 @@ A new class version does not declare a method declared in the old class version. </error> + <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED"> + A new class version has unsupported differences in class attributes. + </error> <error id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED"> A new class version has different modifiers. </error> @@ -11788,6 +11800,9 @@ A method in the new class version has different modifiers than its counterpart in the old class version. </errorid> + <errorid id="JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED" num="72"> + A new class version has unsupported differences in class attributes. + </errorid> </errorcategory> </errorsection> @@ -14927,6 +14942,13 @@ - The function may return NULL in the start phase if the can_generate_early_vmstart capability is enabled. </change> + <change date="7 February 2018" version="11.0.0"> + Minor update for new class file NestHost and NestMembers attributes: + - Specify that RedefineClasses and RetransformClasses are not allowed + to change the class file NestHost and NestMembers attributes. + - Add new error JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED + that can be returned by RedefineClasses and RetransformClasses. + </change> </changehistory> </specification> diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp --- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -388,6 +388,40 @@ } } +// NestHost_attribute { +// u2 attribute_name_index; +// u4 attribute_length; +// u2 host_class_index; +// } +void JvmtiClassFileReconstituter::write_nest_host_attribute() { + int length = sizeof(u2); + int host_class_index = ik()->nest_host_index(); + + write_attribute_name_index("NestHost"); + write_u4(length); + write_u2(host_class_index); +} + +// NestMembers_attribute { +// u2 attribute_name_index; +// u4 attribute_length; +// u2 number_of_classes; +// u2 classes[number_of_classes]; +// } +void JvmtiClassFileReconstituter::write_nest_members_attribute() { + Array<u2>* nest_members = ik()->nest_members(); + int number_of_classes = nest_members->length(); + int length = sizeof(u2) * (1 + number_of_classes); + + write_attribute_name_index("NestMembers"); + write_u4(length); + write_u2(number_of_classes); + for (int i = 0; i < number_of_classes; i++) { + u2 class_cp_index = nest_members->at(i); + write_u2(class_cp_index); + } +} + // Write InnerClasses attribute // JVMSpec| InnerClasses_attribute { @@ -658,6 +692,12 @@ if (cpool()->operands() != NULL) { ++attr_count; } + if (ik()->nest_host_index() != 0) { + ++attr_count; + } + if (ik()->nest_members() != Universe::the_empty_short_array()) { + ++attr_count; + } write_u2(attr_count); @@ -682,6 +722,12 @@ if (cpool()->operands() != NULL) { write_bootstrapmethod_attribute(); } + if (ik()->nest_host_index() != 0) { + write_nest_host_attribute(); + } + if (ik()->nest_members() != Universe::the_empty_short_array()) { + write_nest_members_attribute(); + } } // Write the method information portion of ClassFile structure diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp --- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -116,6 +116,8 @@ void write_attribute_name_index(const char* name); void write_annotations_attribute(const char* attr_name, AnnotationArray* annos); void write_bootstrapmethod_attribute(); + void write_nest_host_attribute(); + void write_nest_members_attribute(); address writeable_address(size_t size); void write_u1(u1 x); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/jvmtiExport.cpp --- a/src/hotspot/share/prims/jvmtiExport.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/jvmtiExport.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -370,6 +370,14 @@ return JNI_EVERSION; // unsupported minor version number } break; + case 11: + switch (minor) { + case 0: // version 11.0.<micro> is recognized + break; + default: + return JNI_EVERSION; // unsupported minor version number + } + break; default: return JNI_EVERSION; // unsupported major version number } diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/jvmtiH.xsl --- a/src/hotspot/share/prims/jvmtiH.xsl Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/jvmtiH.xsl Sat Jun 23 01:32:41 2018 -0400 @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 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 @@ -20,7 +20,7 @@ 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. - + --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" @@ -47,7 +47,7 @@ /* Constants */ </xsl:text> <xsl:apply-templates select="//constants"/> - + <xsl:text> /* Errors */ @@ -91,7 +91,7 @@ <xsl:apply-templates select="functionsection"/> <xsl:call-template name="outro"/> - + </xsl:template> <xsl:template name="intro"> @@ -114,6 +114,7 @@ JVMTI_VERSION_1_1 = 0x30010100, JVMTI_VERSION_1_2 = 0x30010200, JVMTI_VERSION_9 = 0x30090000, + JVMTI_VERSION_11 = 0x300B0000, JVMTI_VERSION = 0x30000000 + (</xsl:text> <xsl:value-of select="//specification/@majorversion"/> @@ -298,7 +299,7 @@ </xsl:when> <xsl:otherwise> <xsl:text> RESERVED */ - void *reserved</xsl:text> + void *reserved</xsl:text> <xsl:value-of select="$index"/> </xsl:otherwise> </xsl:choose> diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/jvmtiRedefineClasses.cpp --- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -683,6 +683,95 @@ _operands_index_map_count = 0; } // end finalize_operands_merge() +// Symbol* comparator for qsort +// The caller must have an active ResourceMark. +static int symcmp(const void* a, const void* b) { + char* astr = (*(Symbol**)a)->as_C_string(); + char* bstr = (*(Symbol**)b)->as_C_string(); + return strcmp(astr, bstr); +} + +static jvmtiError check_nest_attributes(InstanceKlass* the_class, + InstanceKlass* scratch_class) { + // Check whether the class NestHost attribute has been changed. + Thread* thread = Thread::current(); + ResourceMark rm(thread); + JvmtiThreadState *state = JvmtiThreadState::state_for((JavaThread*)thread); + u2 the_nest_host_idx = the_class->nest_host_index(); + u2 scr_nest_host_idx = scratch_class->nest_host_index(); + + if (the_nest_host_idx != 0 && scr_nest_host_idx != 0) { + Symbol* the_sym = the_class->constants()->klass_name_at(the_nest_host_idx); + Symbol* scr_sym = scratch_class->constants()->klass_name_at(scr_nest_host_idx); + if (the_sym != scr_sym) { + log_trace(redefine, class, nestmates) + ("redefined class %s attribute change error: NestHost class: %s replaced with: %s", + the_class->external_name(), the_sym->as_C_string(), scr_sym->as_C_string()); + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; + } + } else if ((the_nest_host_idx == 0) ^ (scr_nest_host_idx == 0)) { + const char* action_str = (the_nest_host_idx != 0) ? "removed" : "added"; + log_trace(redefine, class, nestmates) + ("redefined class %s attribute change error: NestHost attribute %s", + the_class->external_name(), action_str); + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; + } + + // Check whether the class NestMembers attribute has been changed. + Array<u2>* the_nest_members = the_class->nest_members(); + Array<u2>* scr_nest_members = scratch_class->nest_members(); + bool the_members_exists = the_nest_members != Universe::the_empty_short_array(); + bool scr_members_exists = scr_nest_members != Universe::the_empty_short_array(); + + int members_len = the_nest_members->length(); + if (the_members_exists && scr_members_exists) { + if (members_len != scr_nest_members->length()) { + log_trace(redefine, class, nestmates) + ("redefined class %s attribute change error: NestMember len=%d changed to len=%d", + the_class->external_name(), members_len, scr_nest_members->length()); + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; + } + + // The order of entries in the NestMembers array is not specified so we + // have to explicitly check for the same contents. We do this by copying + // the referenced symbols into their own arrays, sorting them and then + // comparing each element pair. + + Symbol** the_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, members_len); + Symbol** scr_syms = NEW_RESOURCE_ARRAY_RETURN_NULL(Symbol*, members_len); + + if (the_syms == NULL || scr_syms == NULL) { + return JVMTI_ERROR_OUT_OF_MEMORY; + } + + for (int i = 0; i < members_len; i++) { + int the_cp_index = the_nest_members->at(i); + int scr_cp_index = scr_nest_members->at(i); + the_syms[i] = the_class->constants()->klass_name_at(the_cp_index); + scr_syms[i] = scratch_class->constants()->klass_name_at(scr_cp_index); + } + + qsort(the_syms, members_len, sizeof(Symbol*), symcmp); + qsort(scr_syms, members_len, sizeof(Symbol*), symcmp); + + for (int i = 0; i < members_len; i++) { + if (the_syms[i] != scr_syms[i]) { + log_trace(redefine, class, nestmates) + ("redefined class %s attribute change error: NestMembers[%d]: %s changed to %s", + the_class->external_name(), i, the_syms[i]->as_C_string(), scr_syms[i]->as_C_string()); + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; + } + } + } else if (the_members_exists ^ scr_members_exists) { + const char* action_str = (the_members_exists) ? "removed" : "added"; + log_trace(redefine, class, nestmates) + ("redefined class %s attribute change error: NestMembers attribute %s", + the_class->external_name(), action_str); + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; + } + + return JVMTI_ERROR_NONE; +} jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( InstanceKlass* the_class, @@ -725,6 +814,12 @@ return JVMTI_ERROR_INVALID_CLASS; } + // Check whether the nest-related attributes have been changed. + jvmtiError err = check_nest_attributes(the_class, scratch_class); + if (err != JVMTI_ERROR_NONE) { + return err; + } + // Check whether class modifiers are the same. jushort old_flags = (jushort) the_class->access_flags().get_flags(); jushort new_flags = (jushort) scratch_class->access_flags().get_flags(); @@ -1598,6 +1693,12 @@ bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class, TRAPS) { + // rewrite constant pool references in the nest attributes: + if (!rewrite_cp_refs_in_nest_attributes(scratch_class)) { + // propagate failure back to caller + return false; + } + // rewrite constant pool references in the methods: if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) { // propagate failure back to caller @@ -1680,6 +1781,22 @@ return true; } // end rewrite_cp_refs() +// Rewrite constant pool references in the NestHost and NestMembers attributes. +bool VM_RedefineClasses::rewrite_cp_refs_in_nest_attributes( + InstanceKlass* scratch_class) { + + u2 cp_index = scratch_class->nest_host_index(); + if (cp_index != 0) { + scratch_class->set_nest_host_index(find_new_index(cp_index)); + } + Array<u2>* nest_members = scratch_class->nest_members(); + for (int i = 0; i < nest_members->length(); i++) { + u2 cp_index = nest_members->at(i); + nest_members->at_put(i, find_new_index(cp_index)); + } + return true; +} + // Rewrite constant pool references in the methods. bool VM_RedefineClasses::rewrite_cp_refs_in_methods( InstanceKlass* scratch_class, TRAPS) { diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/jvmtiRedefineClasses.hpp --- a/src/hotspot/share/prims/jvmtiRedefineClasses.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -469,6 +469,7 @@ AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS); bool rewrite_cp_refs_in_fields_annotations( InstanceKlass* scratch_class, TRAPS); + bool rewrite_cp_refs_in_nest_attributes(InstanceKlass* scratch_class); void rewrite_cp_refs_in_method(methodHandle method, methodHandle * new_method_p, TRAPS); bool rewrite_cp_refs_in_methods(InstanceKlass* scratch_class, TRAPS); diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/prims/methodHandles.cpp --- a/src/hotspot/share/prims/methodHandles.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/prims/methodHandles.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -238,7 +238,12 @@ vmindex); m->access_flags().print_on(tty); if (!m->is_abstract()) { - tty->print("default"); + if (!m->is_private()) { + tty->print("default"); + } + else { + tty->print("private-intf"); + } } tty->cr(); } @@ -292,6 +297,9 @@ } else if (m->is_initializer()) { flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); } else { + // "special" reflects that this is a direct call, not that it + // necessarily originates from an invokespecial. We can also do + // direct calls for private and/or final non-static methods. flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); } break; diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/runtime/reflection.cpp --- a/src/hotspot/share/runtime/reflection.cpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/runtime/reflection.cpp Sat Jun 23 01:32:41 2018 -0400 @@ -650,26 +650,27 @@ return msg; } -bool Reflection::verify_field_access(const Klass* current_class, - const Klass* resolved_class, - const Klass* field_class, - AccessFlags access, - bool classloader_only, - bool protected_restriction) { - // Verify that current_class can access a field of field_class, where that +bool Reflection::verify_member_access(const Klass* current_class, + const Klass* resolved_class, + const Klass* member_class, + AccessFlags access, + bool classloader_only, + bool protected_restriction, + TRAPS) { + // Verify that current_class can access a member of member_class, where that // field's access bits are "access". We assume that we've already verified - // that current_class can access field_class. + // that current_class can access member_class. // // If the classloader_only flag is set, we automatically allow any accesses // in which current_class doesn't have a classloader. // - // "resolved_class" is the runtime type of "field_class". Sometimes we don't + // "resolved_class" is the runtime type of "member_class". Sometimes we don't // need this distinction (e.g. if all we have is the runtime type, or during // class file parsing when we only care about the static type); in that case - // callers should ensure that resolved_class == field_class. + // callers should ensure that resolved_class == member_class. // if ((current_class == NULL) || - (current_class == field_class) || + (current_class == member_class) || access.is_public()) { return true; } @@ -683,18 +684,18 @@ InstanceKlass::cast(host_class)->is_anonymous()), "host_class should not be anonymous"); } - if (host_class == field_class) { + if (host_class == member_class) { return true; } if (access.is_protected()) { if (!protected_restriction) { - // See if current_class (or outermost host class) is a subclass of field_class + // See if current_class (or outermost host class) is a subclass of member_class // An interface may not access protected members of j.l.Object - if (!host_class->is_interface() && host_class->is_subclass_of(field_class)) { + if (!host_class->is_interface() && host_class->is_subclass_of(member_class)) { if (access.is_static() || // static fields are ok, see 6622385 current_class == resolved_class || - field_class == resolved_class || + member_class == resolved_class || host_class->is_subclass_of(resolved_class) || resolved_class->is_subclass_of(host_class)) { return true; @@ -703,18 +704,35 @@ } } - if (!access.is_private() && is_same_class_package(current_class, field_class)) { + // package access + if (!access.is_private() && is_same_class_package(current_class, member_class)) { return true; } + // private access between different classes needs a nestmate check, but + // not for anonymous classes - so check host_class + if (access.is_private() && host_class == current_class) { + if (current_class->is_instance_klass() && member_class->is_instance_klass() ) { + InstanceKlass* cur_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(current_class)); + InstanceKlass* field_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(member_class)); + // Nestmate access checks may require resolution and validation of the nest-host. + // It is up to the caller to check for pending exceptions and handle appropriately. + bool access = cur_ik->has_nestmate_access_to(field_ik, CHECK_false); + if (access) { + guarantee(resolved_class->is_subclass_of(member_class), "must be!"); + return true; + } + } + } + // Allow all accesses from jdk/internal/reflect/MagicAccessorImpl subclasses to // succeed trivially. if (current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { return true; } - return can_relax_access_check_for( - current_class, field_class, classloader_only); + // Check for special relaxations + return can_relax_access_check_for(current_class, member_class, classloader_only); } bool Reflection::is_same_class_package(const Klass* class1, const Klass* class2) { diff -r 0828a0f6676b -r 2f2af62dfac7 src/hotspot/share/runtime/reflection.hpp --- a/src/hotspot/share/runtime/reflection.hpp Fri Jun 22 17:49:21 2018 -0700 +++ b/src/hotspot/share/runtime/reflection.hpp Sat Jun 23 01:32:41 2018 -0400 @@ -90,12 +90,13 @@ const InstanceKlass* new_class, const VerifyClassAccessResults result); - static bool verify_field_access(const Klass* current_class, - const Klass* resolved_class, - const Klass* field_class, - AccessFlags access, - bool classloader_only, - bool protected_restriction = false); + static bool verify_member_access(const Klass* current_class, + const Klass* resolved_class, + const Klass* member_class, + AccessFlags access, + bool classloader_only, + bool protected_restriction, + TRAPS); static bool is_same_class_package(const Klass* class1, const Klass* class2); // inner class reflection diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/com/sun/java/util/jar/pack/intrinsic.properties --- a/src/java.base/share/classes/com/sun/java/util/jar/pack/intrinsic.properties Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/com/sun/java/util/jar/pack/intrinsic.properties Sat Jun 23 01:32:41 2018 -0400 @@ -13,6 +13,8 @@ pack.code.attribute.CharacterRangeTable = NH[PHPOHIIH] pack.class.attribute.SourceID = RUH pack.class.attribute.CompilationID = RUH +pack.class.attribute.NestHost = RCH +pack.class.attribute.NestMembers = NH[RCH] # Note: Zero-length ("marker") attributes do not need to be specified here. # They are automatically defined to have an empty layout. diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/java/lang/Class.java --- a/src/java.base/share/classes/java/lang/Class.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/java/lang/Class.java Sat Jun 23 01:32:41 2018 -0400 @@ -82,9 +82,9 @@ import sun.reflect.misc.ReflectUtil; /** - * Instances of the class {@code Class} represent classes and - * interfaces in a running Java application. An enum is a kind of - * class and an annotation is a kind of interface. Every array also + * Instances of the class {@code Class} represent classes and interfaces + * in a running Java application. An enum type is a kind of class and an + * annotation type is a kind of interface. Every array also * belongs to a class that is reflected as a {@code Class} object * that is shared by all arrays with the same element type and number * of dimensions. The primitive Java types ({@code boolean}, @@ -93,10 +93,34 @@ * {@code double}), and the keyword {@code void} are also * represented as {@code Class} objects. * - * <p> {@code Class} has no public constructor. Instead {@code Class} - * objects are constructed automatically by the Java Virtual Machine as classes - * are loaded and by calls to the {@code defineClass} method in the class - * loader. + * <p> {@code Class} has no public constructor. Instead a {@code Class} + * object is constructed automatically by the Java Virtual Machine + * when a class loader invokes one of the + * {@link ClassLoader#defineClass(String,byte[], int,int) defineClass} methods + * and passes the bytes of a {@code class} file. + * + * <p> The methods of class {@code Class} expose many characteristics of a + * class or interface. Most characteristics are derived from the {@code class} + * file that the class loader passed to the Java Virtual Machine. A few + * characteristics are determined by the class loading environment at run time, + * such as the module returned by {@link #getModule() getModule()}. + * + * <p> Some methods of class {@code Class} expose whether the declaration of + * a class or interface in Java source code was <em>enclosed</em> within + * another declaration. Other methods describe how a class or interface + * is situated in a <em>nest</em>. A <a id="nest">nest</a> is a set of + * classes and interfaces, in the same run-time package, that + * allow mutual access to their {@code private} members. + * The classes and interfaces are known as <em>nestmates</em>. + * One nestmate acts as the + * <em>nest host</em>, and enumerates the other nestmates which + * belong to the nest; each of them in turn records it as the nest host. + * The classes and interfaces which belong to a nest, including its host, are + * determined when + * {@code class} files are generated, for example, a Java compiler + * will typically record a top-level class as the host of a nest where the + * other members are the classes and interfaces whose declarations are + * enclosed within the top-level class declaration. * * <p> The following example uses a {@code Class} object to print the * class name of an object: @@ -3848,4 +3872,161 @@ public AnnotatedType[] getAnnotatedInterfaces() { return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this); } + + private native Class<?> getNestHost0(); + + /** + * Returns the nest host of the <a href=#nest>nest</a> to which the class + * or interface represented by this {@code Class} object belongs. + * Every class and interface is a member of exactly one nest. + * A class or interface that is not recorded as belonging to a nest + * belongs to the nest consisting only of itself, and is the nest + * host. + * + * <p>Each of the {@code Class} objects representing array types, + * primitive types, and {@code void} returns {@code this} to indicate + * that the represented entity belongs to the nest consisting only of + * itself, and is the nest host. + * + * <p>If there is a {@linkplain LinkageError linkage error} accessing + * the nest host, or if this class or interface is not enumerated as + * a member of the nest by the nest host, then it is considered to belong + * to its own nest and {@code this} is returned as the host. + * + * @apiNote A {@code class} file of version 55.0 or greater may record the + * host of the nest to which it belongs by using the {@code NestHost} + * attribute (JVMS 4.7.28). Alternatively, a {@code class} file of + * version 55.0 or greater may act as a nest host by enumerating the nest's + * other members with the + * {@code NestMembers} attribute (JVMS 4.7.29). + * A {@code class} file of version 54.0 or lower does not use these + * attributes. + * + * @return the nest host of this class or interface + * + * @throws SecurityException + * If the returned class is not the current class, and + * if a security manager, <i>s</i>, is present and the caller's + * class loader is not the same as or an ancestor of the class + * loader for the returned class and invocation of {@link + * SecurityManager#checkPackageAccess s.checkPackageAccess()} + * denies access to the package of the returned class + * @since 11 + * @jvms 4.7.28 and 4.7.29 NestHost and NestMembers attributes + * @jvms 5.4.4 Access Control + */ + @CallerSensitive + public Class<?> getNestHost() { + if (isPrimitive() || isArray()) { + return this; + } + Class<?> host; + try { + host = getNestHost0(); + } catch (LinkageError e) { + // if we couldn't load our nest-host then we + // act as-if we have no nest-host attribute + return this; + } + // if null then nest membership validation failed, so we + // act as-if we have no nest-host attribute + if (host == null || host == this) { + return this; + } + // returning a different class requires a security check + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + checkPackageAccess(sm, + ClassLoader.getClassLoader(Reflection.getCallerClass()), true); + } + return host; + } + + /** + * Determines if the given {@code Class} is a nestmate of the + * class or interface represented by this {@code Class} object. + * Two classes or interfaces are nestmates + * if they have the same {@linkplain #getNestHost() nest host}. + * + * @param c the class to check + * @return {@code true} if this class and {@code c} are members of + * the same nest; and {@code false} otherwise. + * + * @since 11 + */ + public boolean isNestmateOf(Class<?> c) { + if (this == c) { + return true; + } + if (isPrimitive() || isArray() || + c.isPrimitive() || c.isArray()) { + return false; + } + try { + return getNestHost0() == c.getNestHost0(); + } catch (LinkageError e) { + return false; + } + } + + private native Class<?>[] getNestMembers0(); + + /** + * Returns an array containing {@code Class} objects representing all the + * classes and interfaces that are members of the nest to which the class + * or interface represented by this {@code Class} object belongs. + * The {@linkplain #getNestHost() nest host} of that nest is the zeroth + * element of the array. Subsequent elements represent any classes or + * interfaces that are recorded by the nest host as being members of + * the nest; the order of such elements is unspecified. Duplicates are + * permitted. + * If the nest host of that nest does not enumerate any members, then the + * array has a single element containing {@code this}. + * + * <p>Each of the {@code Class} objects representing array types, + * primitive types, and {@code void} returns an array containing only + * {@code this}. + * + * <p>This method validates that, for each class or interface which is + * recorded as a member of the nest by the nest host, that class or + * interface records itself as a member of that same nest. Any exceptions + * that occur during this validation are rethrown by this method. + * + * @return an array of all classes and interfaces in the same nest as + * this class + * + * @throws LinkageError + * If there is any problem loading or validating a nest member or + * its nest host + * @throws SecurityException + * If any returned class is not the current class, and + * if a security manager, <i>s</i>, is present and the caller's + * class loader is not the same as or an ancestor of the class + * loader for that returned class and invocation of {@link + * SecurityManager#checkPackageAccess s.checkPackageAccess()} + * denies access to the package of that returned class + * + * @since 11 + * @see #getNestHost() + */ + @CallerSensitive + public Class<?>[] getNestMembers() { + if (isPrimitive() || isArray()) { + return new Class<?>[] { this }; + } + Class<?>[] members = getNestMembers0(); + // Can't actually enable this due to bootstrapping issues + // assert(members.length != 1 || members[0] == this); // expected invariant from VM + + if (members.length > 1) { + // If we return anything other than the current class we need + // a security check + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + checkPackageAccess(sm, + ClassLoader.getClassLoader(Reflection.getCallerClass()), true); + } + } + return members; + } } diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java --- a/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Sat Jun 23 01:32:41 2018 -0400 @@ -58,7 +58,8 @@ if (!member.isResolved()) throw new InternalError(); if (member.getDeclaringClass().isInterface() && - member.isMethod() && !member.isAbstract()) { + member.getReferenceKind() == REF_invokeInterface && + member.isMethod() && !member.isAbstract()) { // Check for corner case: invokeinterface of Object method MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind()); m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null); @@ -80,22 +81,28 @@ mtype = mtype.insertParameterTypes(0, refc); } if (!member.isField()) { + // refKind reflects the original type of lookup via findSpecial or + // findVirtual etc. switch (refKind) { case REF_invokeSpecial: { member = member.asSpecial(); - LambdaForm lform = preparedLambdaForm(member, callerClass); - Class<?> checkClass = refc; // Class to use for receiver type check - if (callerClass != null) { - checkClass = callerClass; // potentially strengthen to caller class + // if caller is an interface we need to adapt to get the + // receiver check inserted + if (callerClass == null) { + throw new InternalError("callerClass must not be null for REF_invokeSpecial"); } - return new Special(mtype, lform, member, checkClass); + LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface()); + return new Special(mtype, lform, member, callerClass); } case REF_invokeInterface: { - LambdaForm lform = preparedLambdaForm(member, callerClass); + // for interfaces we always need the receiver typecheck, + // so we always pass 'true' to ensure we adapt if needed + // to include the REF_invokeSpecial case + LambdaForm lform = preparedLambdaForm(member, true); return new Interface(mtype, lform, member, refc); } default: { - LambdaForm lform = preparedLambdaForm(member, callerClass); + LambdaForm lform = preparedLambdaForm(member); return new DirectMethodHandle(mtype, lform, member); } } @@ -165,11 +172,16 @@ * Cache and share this structure among all methods with * the same basicType and refKind. */ - private static LambdaForm preparedLambdaForm(MemberName m, Class<?> callerClass) { + private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecialIfc) { assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead MethodType mtype = m.getInvocationType().basicType(); assert(!m.isMethodHandleInvoke()) : m; int which; + // MemberName.getReferenceKind represents the JVM optimized form of the call + // as distinct from the "kind" passed to DMH.make which represents the original + // bytecode-equivalent request. Specifically private/final methods that use a direct + // call have getReferenceKind adapted to REF_invokeSpecial, even though the actual + // invocation mode may be invokevirtual or invokeinterface. switch (m.getReferenceKind()) { case REF_invokeVirtual: which = LF_INVVIRTUAL; break; case REF_invokeStatic: which = LF_INVSTATIC; break; @@ -183,7 +195,7 @@ preparedLambdaForm(mtype, which); which = LF_INVSTATIC_INIT; } - if (which == LF_INVSPECIAL && callerClass != null && callerClass.isInterface()) { + if (which == LF_INVSPECIAL && adaptToSpecialIfc) { which = LF_INVSPECIAL_IFC; } LambdaForm lform = preparedLambdaForm(mtype, which); @@ -195,7 +207,7 @@ } private static LambdaForm preparedLambdaForm(MemberName m) { - return preparedLambdaForm(m, null); + return preparedLambdaForm(m, false); } private static LambdaForm preparedLambdaForm(MethodType mtype, int which) { diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/java/lang/invoke/MethodHandle.java --- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -250,6 +250,9 @@ * can also be created. These do not perform virtual lookup based on * receiver type. Such a method handle simulates the effect of * an {@code invokespecial} instruction to the same method. + * A non-virtual method handle can also be created to simulate the effect + * of an {@code invokevirtual} or {@code invokeinterface} instruction on + * a private method (as applicable). * * <h1>Usage examples</h1> * Here are some examples of usage: diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/java/lang/invoke/MethodHandles.java --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Sat Jun 23 01:32:41 2018 -0400 @@ -469,15 +469,20 @@ * methods as if they were normal methods, but the JVM bytecode verifier rejects them. * A lookup of such an internal method will produce a {@code NoSuchMethodException}. * <p> - * In some cases, access between nested classes is obtained by the Java compiler by creating - * an wrapper method to access a private method of another class - * in the same top-level declaration. + * If the relationship between nested types is expressed directly through the + * {@code NestHost} and {@code NestMembers} attributes + * (see the Java Virtual Machine Specification, sections 4.7.28 and 4.7.29), + * then the associated {@code Lookup} object provides direct access to + * the lookup class and all of its nestmates + * (see {@link java.lang.Class#getNestHost Class.getNestHost}). + * Otherwise, access between nested classes is obtained by the Java compiler creating + * a wrapper method to access a private method of another class in the same nest. * For example, a nested class {@code C.D} * can access private members within other related classes such as * {@code C}, {@code C.D.E}, or {@code C.B}, * but the Java compiler may need to generate wrapper methods in * those related classes. In such cases, a {@code Lookup} object on - * {@code C.E} would be unable to those private members. + * {@code C.E} would be unable to access those private members. * A workaround for this limitation is the {@link Lookup#in Lookup.in} method, * which can transform a lookup on {@code C.E} into one on any of those other * classes, without special elevation of privilege. @@ -499,11 +504,12 @@ * <em>Discussion of private access:</em> * We say that a lookup has <em>private access</em> * if its {@linkplain #lookupModes lookup modes} - * include the possibility of accessing {@code private} members. + * include the possibility of accessing {@code private} members + * (which includes the private members of nestmates). * As documented in the relevant methods elsewhere, * only lookups with private access possess the following capabilities: * <ul style="font-size:smaller;"> - * <li>access private fields, methods, and constructors of the lookup class + * <li>access private fields, methods, and constructors of the lookup class and its nestmates * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods, * such as {@code Class.forName} * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions @@ -728,9 +734,7 @@ * <p> * A freshly-created lookup object * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has - * all possible bits set, except {@code UNCONDITIONAL}. The lookup can be used to - * access all members of the caller's class, all public types in the caller's module, - * and all public types in packages exported by other modules to the caller's module. + * all possible bits set, except {@code UNCONDITIONAL}. * A lookup object on a new lookup class * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object} * may have some mode bits set to zero. @@ -1106,8 +1110,9 @@ * The method and all its argument types must be accessible to the lookup object. * <p> * When called, the handle will treat the first argument as a receiver - * and dispatch on the receiver's type to determine which method + * and, for non-private methods, dispatch on the receiver's type to determine which method * implementation to enter. + * For private methods the named method in {@code refc} will be invoked on the receiver. * (The dispatching action is identical with that performed by an * {@code invokevirtual} or {@code invokeinterface} instruction.) * <p> @@ -1171,7 +1176,6 @@ * @throws NoSuchMethodException if the method does not exist * @throws IllegalAccessException if access checking fails, * or if the method is {@code static}, - * or if the method is {@code private} method of interface, * or if the method's variable arity modifier bit * is set and {@code asVarargsCollector} fails * @exception SecurityException if a security manager is present and it @@ -2225,17 +2229,13 @@ return "member is private to package"; } - private static final boolean ALLOW_NESTMATE_ACCESS = false; - private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException { int allowedModes = this.allowedModes; if (allowedModes == TRUSTED) return; if (!hasPrivateAccess() || (specialCaller != lookupClass() // ensure non-abstract methods in superinterfaces can be special-invoked - && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller)) - && !(ALLOW_NESTMATE_ACCESS && - VerifyAccess.isSamePackageMember(specialCaller, lookupClass())))) + && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller)))) throw new MemberName(specialCaller). makeAccessException("no private access for invokespecial", this); } @@ -2246,9 +2246,7 @@ if (!method.isProtected() || method.isStatic() || allowedModes == TRUSTED || method.getDeclaringClass() == lookupClass() - || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass()) - || (ALLOW_NESTMATE_ACCESS && - VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass()))) + || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())) return false; return true; } @@ -2288,6 +2286,7 @@ private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method, boolean checkSecurity, boolean doRestrict, Class<?> boundCallerClass) throws IllegalAccessException { + checkMethod(refKind, refc, method); // Optionally check with the security manager; this isn't needed for unreflect* calls. if (checkSecurity) @@ -2300,6 +2299,7 @@ refc != lookupClass().getSuperclass() && refc.isAssignableFrom(lookupClass())) { assert(!method.getName().equals("<init>")); // not this code path + // Per JVMS 6.5, desc. of invokespecial instruction: // If the method is in a superclass of the LC, // and if our original search was above LC.super, diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/java/lang/reflect/AccessibleObject.java --- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Sat Jun 23 01:32:41 2018 -0400 @@ -47,7 +47,7 @@ * in a manner that would normally be prohibited. * * <p> Java language access control prevents use of private members outside - * their class; package access members outside their package; protected members + * their top-level class; package access members outside their package; protected members * outside their package or subclasses; and public members outside their * module unless they are declared in an {@link Module#isExported(String,Module) * exported} package and the user {@link Module#canRead reads} their module. By diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/java/lang/reflect/Method.java --- a/src/java.base/share/classes/java/lang/reflect/Method.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/java/lang/reflect/Method.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -505,8 +505,8 @@ * * <p>If the underlying method is an instance method, it is invoked * using dynamic method lookup as documented in The Java Language - * Specification, Second Edition, section 15.12.4.4; in particular, - * overriding based on the runtime type of the target object will occur. + * Specification, section 15.12.4.4; in particular, + * overriding based on the runtime type of the target object may occur. * * <p>If the underlying method is static, the class that declared * the method is initialized if it has not already been initialized. diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/jdk/internal/org/objectweb/asm/Attribute.java --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Attribute.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Attribute.java Sat Jun 23 01:32:41 2018 -0400 @@ -58,6 +58,8 @@ */ package jdk.internal.org.objectweb.asm; +import java.util.Arrays; + /** * A non standard class, field, method or code attribute. * @@ -281,4 +283,72 @@ attr = attr.next; } } + + //The stuff below is temporary - once proper support for nestmate attribute has been added, it can be safely removed. + //see also changes in ClassReader.accept. + + public static class NestMembers extends Attribute { + public NestMembers() { + super("NestMembers"); + } + + byte[] bytes; + String[] classes; + + @Override + protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) { + int offset = off; + NestMembers a = new NestMembers(); + int size = cr.readShort(off); + a.classes = new String[size]; + off += 2; + for (int i = 0; i < size ; i++) { + a.classes[i] = cr.readClass(off, buf); + off += 2; + } + a.bytes = Arrays.copyOfRange(cr.b, offset, offset + len); + return a; + } + + @Override + protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) { + ByteVector v = new ByteVector(bytes.length); + v.putShort(classes.length); + for (String s : classes) { + v.putShort(cw.newClass(s)); + } + return v; + } + } + + public static class NestHost extends Attribute { + + byte[] bytes; + String clazz; + + public NestHost() { + super("NestHost"); + } + + @Override + protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) { + int offset = off; + NestHost a = new NestHost(); + a.clazz = cr.readClass(off, buf); + a.bytes = Arrays.copyOfRange(cr.b, offset, offset + len); + return a; + } + + @Override + protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) { + ByteVector v = new ByteVector(bytes.length); + v.putShort(cw.newClass(clazz)); + return v; + } + } + + static final Attribute[] DEFAULT_ATTRIBUTE_PROTOS = new Attribute[] { + new NestMembers(), + new NestHost() + }; } diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java --- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Sat Jun 23 01:32:41 2018 -0400 @@ -530,7 +530,7 @@ * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}. */ public void accept(final ClassVisitor classVisitor, final int flags) { - accept(classVisitor, new Attribute[0], flags); + accept(classVisitor, Attribute.DEFAULT_ATTRIBUTE_PROTOS, flags); } /** diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/jdk/internal/reflect/MethodAccessorGenerator.java --- a/src/java.base/share/classes/jdk/internal/reflect/MethodAccessorGenerator.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/jdk/internal/reflect/MethodAccessorGenerator.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -629,14 +629,10 @@ typeSizeInStackSlots(returnType)); } else { if (isInterface()) { - if (isPrivate()) { - cb.opc_invokespecial(targetMethodRef, count, 0); - } else { - cb.opc_invokeinterface(targetMethodRef, - count, - count, - typeSizeInStackSlots(returnType)); - } + cb.opc_invokeinterface(targetMethodRef, + count, + count, + typeSizeInStackSlots(returnType)); } else { cb.opc_invokevirtual(targetMethodRef, count, diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/jdk/internal/reflect/Reflection.java --- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -143,6 +143,15 @@ return true; } + // Check for nestmate access if member is private + if (Modifier.isPrivate(modifiers)) { + // Note: targetClass may be outside the nest, but that is okay + // as long as memberClass is in the nest. + if (areNestMates(currentClass, memberClass)) { + return true; + } + } + boolean successSoFar = false; if (Modifier.isProtected(modifiers)) { @@ -351,4 +360,12 @@ return new IllegalAccessException(msg); } + + /** + * Returns true if {@code currentClass} and {@code memberClass} + * are nestmates - that is, if they have the same nesthost as + * determined by the VM. + */ + public static native boolean areNestMates(Class<?> currentClass, + Class<?> memberClass); } diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/classes/sun/invoke/util/VerifyAccess.java --- a/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -44,7 +44,6 @@ private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE; private static final int PROTECTED_OR_PACKAGE_ALLOWED = (PACKAGE_ALLOWED|PROTECTED); private static final int ALL_ACCESS_MODES = (PUBLIC|PRIVATE|PROTECTED|PACKAGE_ONLY); - private static final boolean ALLOW_NESTMATE_ACCESS = false; /** * Evaluate the JVM linkage rules for access to the given method @@ -62,23 +61,29 @@ * the defining class should be passed for both arguments ({@code defc == refc}). * <h3>JVM Specification, 5.4.4 "Access Control"</h3> * A field or method R is accessible to a class or interface D if - * and only if any of the following conditions is true:<ul> - * <li>R is public. + * and only if any of the following is true: + * <ul> + * <li>R is public.</li> * <li>R is protected and is declared in a class C, and D is either - * a subclass of C or C itself. Furthermore, if R is not - * static, then the symbolic reference to R must contain a - * symbolic reference to a class T, such that T is either a - * subclass of D, a superclass of D or D itself. - * <li>R is either protected or has default access (that is, - * neither public nor protected nor private), and is declared - * by a class in the same runtime package as D. - * <li>R is private and is declared in D. + * a subclass of C or C itself. Furthermore, if R is not static, + * then the symbolic reference to R must contain a symbolic + * reference to a class T, such that T is either a subclass of D, + * a superclass of D, or D itself. + * <p>During verification, it was also required that, even if T is + * a superclass of D, the target reference of a protected instance + * field access or method invocation must be an instance of D or a + * subclass of D (4.10.1.8).</p></li> + * <li>R is either protected or has default access (that is, neither + * public nor protected nor private), and is declared by a class + * in the same run-time package as D.</li> + * <li>R is private and is declared in D by a class or interface + * belonging to the same nest as D.</li> * </ul> - * This discussion of access control omits a related restriction - * on the target of a protected field access or method invocation - * (the target must be of class D or a subtype of D). That - * requirement is checked as part of the verification process - * (5.4.1); it is not part of link-time access control. + * If a referenced field or method is not accessible, access checking + * throws an IllegalAccessError. If an exception is thrown while + * attempting to determine the nest host of a class or interface, + * access checking fails for the same reason. + * * @param refc the class used in the symbolic reference to the proposed member * @param defc the class in which the proposed member is actually defined * @param mods modifier flags for the proposed member @@ -98,9 +103,10 @@ return false; } // Usually refc and defc are the same, but verify defc also in case they differ. - if (defc == lookupClass && + if (defc == lookupClass && (allowedModes & PRIVATE) != 0) - return true; // easy check; all self-access is OK + return true; // easy check; all self-access is OK with a private lookup + switch (mods & ALL_ACCESS_MODES) { case PUBLIC: return true; // already checked above @@ -126,10 +132,13 @@ return ((allowedModes & PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)); case PRIVATE: - // Loosened rules for privates follows access rules for inner classes. - return (ALLOW_NESTMATE_ACCESS && - (allowedModes & PRIVATE) != 0 && - isSamePackageMember(defc, lookupClass)); + // Rules for privates follows access rules for nestmates. + boolean canAccess = ((allowedModes & PRIVATE) != 0 && + Reflection.areNestMates(defc, lookupClass)); + // for private methods the selected method equals the + // resolved method - so refc == defc + assert (canAccess && refc == defc) || !canAccess; + return canAccess; default: throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods)); } diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/native/libjava/Class.c --- a/src/java.base/share/native/libjava/Class.c Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/native/libjava/Class.c Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -65,15 +65,17 @@ {"getDeclaredMethods0","(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods}, {"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors}, {"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain}, - {"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses}, + {"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses}, {"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass}, {"getSimpleBinaryName0", "()" STR, (void *)&JVM_GetSimpleBinaryName}, {"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature}, - {"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations}, + {"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations}, {"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool}, - {"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus}, + {"desiredAssertionStatus0","("CLS")Z", (void *)&JVM_DesiredAssertionStatus}, {"getEnclosingMethod0", "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo}, {"getRawTypeAnnotations", "()" BA, (void *)&JVM_GetClassTypeAnnotations}, + {"getNestHost0", "()" CLS, (void *)&JVM_GetNestHost}, + {"getNestMembers0", "()[" CLS, (void *)&JVM_GetNestMembers}, }; #undef OBJ diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.base/share/native/libjava/Reflection.c --- a/src/java.base/share/native/libjava/Reflection.c Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.base/share/native/libjava/Reflection.c Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -38,3 +38,9 @@ { return JVM_GetClassAccessFlags(env, cls); } + +JNIEXPORT jboolean JNICALL +Java_jdk_internal_reflect_Reflection_areNestMates(JNIEnv *env, jclass unused, jclass current, jclass member) +{ + return JVM_AreNestMates(env, current, member); +} diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java --- a/src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -219,10 +219,14 @@ * Instances of the retransformed class are not affected. * * <P> - * The retransformation may change method bodies, the constant pool and attributes. + * The retransformation may change method bodies, the constant pool and + * attributes (unless explicitly prohibited). * The retransformation must not add, remove or rename fields or methods, change the - * signatures of methods, or change inheritance. These restrictions maybe be - * lifted in future versions. The class file bytes are not checked, verified and installed + * signatures of methods, or change inheritance. + * The retransformation must not change the <code>NestHost</code> or + * <code>NestMembers</code> attributes. + * These restrictions may be lifted in future versions. + * The class file bytes are not checked, verified and installed * until after the transformations have been applied, if the resultant bytes are in * error this method will throw an exception. * @@ -306,10 +310,14 @@ * Instances of the redefined class are not affected. * * <P> - * The redefinition may change method bodies, the constant pool and attributes. + * The redefinition may change method bodies, the constant pool and attributes + * (unless explicitly prohibited). * The redefinition must not add, remove or rename fields or methods, change the - * signatures of methods, or change inheritance. These restrictions maybe be - * lifted in future versions. The class file bytes are not checked, verified and installed + * signatures of methods, or change inheritance. + * The redefinition must not change the <code>NestHost</code> or + * <code>NestMembers</code> attributes. + * These restrictions may be lifted in future versions. + * The class file bytes are not checked, verified and installed * until after the transformations have been applied, if the resultant bytes are in * error this method will throw an exception. * diff -r 0828a0f6676b -r 2f2af62dfac7 src/java.instrument/share/native/libinstrument/JavaExceptions.c --- a/src/java.instrument/share/native/libinstrument/JavaExceptions.c Fri Jun 22 17:49:21 2018 -0700 +++ b/src/java.instrument/share/native/libinstrument/JavaExceptions.c Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -214,6 +214,11 @@ message = "class redefinition failed: attempted to change the class modifiers"; break; + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED: + throwableClassName = "java/lang/UnsupportedOperationException"; + message = "class redefinition failed: attempted to change the class NestHost or NestMembers attribute"; + break; + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED: throwableClassName = "java/lang/UnsupportedOperationException"; message = "class redefinition failed: attempted to change method modifiers"; diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Sat Jun 23 01:32:41 2018 -0400 @@ -94,6 +94,7 @@ private final Name dollarCloseResource; private final Types types; private final boolean debugLower; + private final boolean disableProtectedAccessors; // experimental private final PkgInfo pkginfoOpt; protected Lower(Context context) { @@ -122,6 +123,7 @@ Options options = Options.instance(context); debugLower = options.isSet("debuglower"); pkginfoOpt = PkgInfo.get(options); + disableProtectedAccessors = options.isSet("disableProtectedAccessors"); } /** The currently enclosing class. @@ -1031,6 +1033,9 @@ /** Do we need an access method to reference private symbol? */ boolean needsPrivateAccess(Symbol sym) { + if (target.hasNestmateAccess()) { + return false; + } if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) { return false; } else if (sym.name == names.init && sym.owner.isLocal()) { @@ -1045,6 +1050,7 @@ /** Do we need an access method to reference symbol in other package? */ boolean needsProtectedAccess(Symbol sym, JCTree tree) { + if (disableProtectedAccessors) return false; if ((sym.flags() & PROTECTED) == 0 || sym.owner.owner == currentClass.owner || // fast special case sym.packge() == currentClass.packge()) diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Sat Jun 23 01:32:41 2018 -0400 @@ -31,6 +31,7 @@ import java.util.Set; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.stream.Collectors; import javax.tools.JavaFileManager; import javax.tools.FileObject; @@ -1106,6 +1107,56 @@ endAttr(alenIdx); } + /** + * Write NestMembers attribute (if needed) + */ + int writeNestMembersIfNeeded(ClassSymbol csym) { + ListBuffer<Symbol> nested = new ListBuffer<>(); + listNested(csym, nested); + Set<Symbol> nestedUnique = new LinkedHashSet<>(nested); + if (csym.owner.kind == PCK && !nestedUnique.isEmpty()) { + int alenIdx = writeAttr(names.NestMembers); + databuf.appendChar(nestedUnique.size()); + for (Symbol s : nestedUnique) { + databuf.appendChar(pool.put(s)); + } + endAttr(alenIdx); + return 1; + } + return 0; + } + + /** + * Write NestHost attribute (if needed) + */ + int writeNestHostIfNeeded(ClassSymbol csym) { + if (csym.owner.kind != PCK) { + int alenIdx = writeAttr(names.NestHost); + databuf.appendChar(pool.put(csym.outermostClass())); + endAttr(alenIdx); + return 1; + } + return 0; + } + + private void listNested(Symbol sym, ListBuffer<Symbol> seen) { + if (sym.kind != TYP) return; + ClassSymbol csym = (ClassSymbol)sym; + if (csym.owner.kind != PCK) { + seen.add(csym); + } + if (csym.members() != null) { + for (Symbol s : sym.members().getSymbols()) { + listNested(s, seen); + } + } + if (csym.trans_local != null) { + for (Symbol s : csym.trans_local) { + listNested(s, seen); + } + } + } + /** Write "bootstrapMethods" attribute. */ void writeBootstrapMethods() { @@ -1835,6 +1886,13 @@ } poolbuf.appendChar(target.majorVersion); + if (c.owner.kind != MDL) { + if (target.hasNestmateAccess()) { + acount += writeNestMembersIfNeeded(c); + acount += writeNestHostIfNeeded(c); + } + } + writePool(c.pool); if (innerClasses != null) { diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -126,6 +126,7 @@ genCrt = options.isSet(XJCOV); debugCode = options.isSet("debug.code"); allowBetterNullChecks = target.hasObjects(); + disableVirtualizedPrivateInvoke = options.isSet("disableVirtualizedPrivateInvoke"); pool = new Pool(types); // ignore cldc because we cannot have both stackmap formats @@ -140,6 +141,7 @@ private final boolean genCrt; private final boolean debugCode; private final boolean allowBetterNullChecks; + private boolean disableVirtualizedPrivateInvoke; /** Code buffer, set by genMethod. */ @@ -2064,10 +2066,17 @@ } else { items.makeThisItem().load(); sym = binaryQualifier(sym, env.enclClass.type); - result = items.makeMemberItem(sym, (sym.flags() & PRIVATE) != 0); + result = items.makeMemberItem(sym, nonVirtualForPrivateAccess(sym)); } } + //where + private boolean nonVirtualForPrivateAccess(Symbol sym) { + boolean useVirtual = target.hasVirtualPrivateInvoke() && + !disableVirtualizedPrivateInvoke; + return !useVirtual && ((sym.flags() & PRIVATE) != 0); + } + public void visitSelect(JCFieldAccess tree) { Symbol sym = tree.sym; @@ -2124,7 +2133,7 @@ } else { result = items. makeMemberItem(sym, - (sym.flags() & PRIVATE) != 0 || + nonVirtualForPrivateAccess(sym) || selectSuper || accessSuper); } } diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java Sat Jun 23 01:32:41 2018 -0400 @@ -160,4 +160,17 @@ public String multiReleaseValue() { return Integer.toString(this.ordinal() - Target.JDK1_1.ordinal() + 1); } + + /** Does the target VM support nestmate access? + */ + public boolean hasNestmateAccess() { + return compareTo(JDK1_11) >= 0; + } + + /** Does the target VM support virtual private invocations? + */ + public boolean hasVirtualPrivateInvoke() { + return compareTo(JDK1_11) >= 0; + } + } diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -152,6 +152,8 @@ public final Name MethodParameters; public final Name Module; public final Name ModuleResolution; + public final Name NestHost; + public final Name NestMembers; public final Name RuntimeInvisibleAnnotations; public final Name RuntimeInvisibleParameterAnnotations; public final Name RuntimeInvisibleTypeAnnotations; @@ -315,6 +317,8 @@ MethodParameters = fromString("MethodParameters"); Module = fromString("Module"); ModuleResolution = fromString("ModuleResolution"); + NestHost = fromString("NestHost"); + NestMembers = fromString("NestMembers"); RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations"); RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations"); RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations"); diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdeps/share/classes/com/sun/tools/classfile/Attribute.java --- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Attribute.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Attribute.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -58,6 +58,8 @@ public static final String ModulePackages = "ModulePackages"; public static final String ModuleResolution = "ModuleResolution"; public static final String ModuleTarget = "ModuleTarget"; + public static final String NestHost = "NestHost"; + public static final String NestMembers = "NestMembers"; public static final String RuntimeVisibleAnnotations = "RuntimeVisibleAnnotations"; public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations"; public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations"; @@ -130,6 +132,8 @@ standardAttributes.put(ModulePackages, ModulePackages_attribute.class); standardAttributes.put(ModuleResolution, ModuleResolution_attribute.class); standardAttributes.put(ModuleTarget, ModuleTarget_attribute.class); + standardAttributes.put(NestHost, NestHost_attribute.class); + standardAttributes.put(NestMembers, NestMembers_attribute.class); standardAttributes.put(RuntimeInvisibleAnnotations, RuntimeInvisibleAnnotations_attribute.class); standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class); standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class); @@ -193,6 +197,8 @@ R visitModulePackages(ModulePackages_attribute attr, P p); R visitModuleResolution(ModuleResolution_attribute attr, P p); R visitModuleTarget(ModuleTarget_attribute attr, P p); + R visitNestHost(NestHost_attribute attr, P p); + R visitNestMembers(NestMembers_attribute attr, P p); R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p); R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p); R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p); diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java --- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -529,6 +529,12 @@ } @Override + public Void visitNestHost(NestHost_attribute attr, ClassOutputStream out) { + out.writeShort(attr.top_index); + return null; + } + + @Override public Void visitMethodParameters(MethodParameters_attribute attr, ClassOutputStream out) { out.writeByte(attr.method_parameter_table.length); for (MethodParameters_attribute.Entry e : attr.method_parameter_table) { @@ -627,6 +633,15 @@ } @Override + public Void visitNestMembers(NestMembers_attribute attr, ClassOutputStream out) { + out.writeShort(attr.members_indexes.length); + for (int i : attr.members_indexes) { + out.writeShort(i); + } + return null; + } + + @Override public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, ClassOutputStream out) { annotationWriter.write(attr.annotations, out); return null; diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdeps/share/classes/com/sun/tools/classfile/NestHost_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/NestHost_attribute.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,63 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.classfile; + +import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; + +import java.io.IOException; + +/** + * <p><b>This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice.</b> + */ +public class NestHost_attribute extends Attribute { + NestHost_attribute(ClassReader cr, int name_index, int length) throws IOException { + super(name_index, length); + top_index = cr.readUnsignedShort(); + } + + public NestHost_attribute(ConstantPool constant_pool, int signature_index) + throws ConstantPoolException { + this(constant_pool.getUTF8Index(Attribute.Signature), signature_index); + } + + public NestHost_attribute(int name_index, int top_index) { + super(name_index, 2); + this.top_index = top_index; + } + + public CONSTANT_Class_info getNestTop(ConstantPool constant_pool) throws ConstantPoolException { + return constant_pool.getClassInfo(top_index); + } + + public <R, D> R accept(Visitor<R, D> visitor, D data) { + return visitor.visitNestHost(this, data); + } + + public final int top_index; +} diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdeps/share/classes/com/sun/tools/classfile/NestMembers_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/NestMembers_attribute.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,70 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.classfile; + +import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; + +import java.io.IOException; +import java.util.stream.IntStream; + +/** + * <p><b>This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice.</b> + */ +public class NestMembers_attribute extends Attribute { + NestMembers_attribute(ClassReader cr, int name_index, int length) throws IOException { + super(name_index, length); + int len = cr.readUnsignedShort(); + members_indexes = new int[len]; + for (int i = 0 ; i < len ; i++) { + members_indexes[i] = cr.readUnsignedShort(); + } + } + + public NestMembers_attribute(int name_index, int[] members_indexes) { + super(name_index, 2); + this.members_indexes = members_indexes; + } + + public CONSTANT_Class_info[] getChildren(ConstantPool constant_pool) throws ConstantPoolException { + return IntStream.of(members_indexes) + .mapToObj(i -> { + try { + return constant_pool.getClassInfo(i); + } catch (ConstantPoolException ex) { + throw new AssertionError(ex); + } + }).toArray(CONSTANT_Class_info[]::new); + } + + public <R, D> R accept(Visitor<R, D> visitor, D data) { + return visitor.visitNestMembers(this, data); + } + + public final int[] members_indexes; +} diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -35,6 +35,7 @@ import com.sun.tools.classfile.Code_attribute; import com.sun.tools.classfile.CompilationID_attribute; import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; import com.sun.tools.classfile.ConstantPoolException; import com.sun.tools.classfile.ConstantValue_attribute; import com.sun.tools.classfile.DefaultAttribute; @@ -53,6 +54,8 @@ import com.sun.tools.classfile.ModulePackages_attribute; import com.sun.tools.classfile.ModuleResolution_attribute; import com.sun.tools.classfile.ModuleTarget_attribute; +import com.sun.tools.classfile.NestHost_attribute; +import com.sun.tools.classfile.NestMembers_attribute; import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute; import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute; import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; @@ -397,6 +400,14 @@ return null; } + @Override + public Void visitNestHost(NestHost_attribute attr, Void aVoid) { + print("NestHost: "); + constantWriter.write(attr.top_index); + println(); + return null; + } + private String getJavaClassName(ModuleMainClass_attribute a) { try { return getJavaName(a.getMainClassName(constant_pool)); @@ -687,6 +698,22 @@ } @Override + public Void visitNestMembers(NestMembers_attribute attr, Void aVoid) { + println("NestMembers:"); + indent(+1); + try { + CONSTANT_Class_info[] children = attr.getChildren(constant_pool); + for (int i = 0; i < attr.members_indexes.length; i++) { + println(constantWriter.stringValue(children[i])); + } + indent(-1); + } catch (ConstantPoolException ex) { + throw new AssertionError(ex); + } + return null; + } + + @Override public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) { println("RuntimeVisibleAnnotations:"); indent(+1); diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachine.java --- a/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachine.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachine.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -219,10 +219,11 @@ * this exception * <UL> * <LI>changing the schema (the fields) - * <LI>changing the hierarchy (subclasses, interfaces) + * <LI>changing the hierarchy (superclasses, interfaces) * <LI>deleting a method * <LI>changing class modifiers * <LI>changing method modifiers + * <LI>changing the {@code NestHost} or {@code NestMembers} class attributes * </UL> * </UL> * @@ -595,8 +596,9 @@ boolean canAddMethod(); /** - * Determines if the target VM supports unrestricted - * changes when performing class redefinition. + * Determines if the target VM supports + * changes when performing class redefinition that are + * otherwise restricted by {@link #redefineClasses}. * @see #redefineClasses * * @return <code>true</code> if the feature is supported, diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java --- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -395,6 +395,9 @@ case JDWP.Error.METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED : throw new UnsupportedOperationException( "changes to method modifiers not implemented"); + case JDWP.Error.CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED : + throw new UnsupportedOperationException( + "changes to class attribute not implemented"); case JDWP.Error.NAMES_DONT_MATCH : throw new NoClassDefFoundError( "class names do not match"); diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java --- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -52,7 +52,7 @@ private final ThreadGroup mainGroupForJDI; private ResourceBundle messages = null; private int vmSequenceNumber = 0; - private static final int majorVersion = 9; + private static final int majorVersion = 11; private static final int minorVersion = 0; private static final Object lock = new Object(); diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c --- a/src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -35,7 +35,7 @@ #include "FrameID.h" static char *versionName = "Java Debug Wire Protocol (Reference Implementation)"; -static int majorVersion = 9; /* JDWP major version */ +static int majorVersion = 11; /* JDWP major version */ static int minorVersion = 0; /* JDWP minor version */ static jboolean diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdwp.agent/share/native/libjdwp/error_messages.c --- a/src/jdk.jdwp.agent/share/native/libjdwp/error_messages.c Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdwp.agent/share/native/libjdwp/error_messages.c Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -285,6 +285,7 @@ CASE_RETURN_JDWP_ERROR_TEXT(NAMES_DONT_MATCH) CASE_RETURN_JDWP_ERROR_TEXT(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED) CASE_RETURN_JDWP_ERROR_TEXT(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED) + CASE_RETURN_JDWP_ERROR_TEXT(CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED) CASE_RETURN_JDWP_ERROR_TEXT(NOT_IMPLEMENTED) CASE_RETURN_JDWP_ERROR_TEXT(NULL_POINTER) CASE_RETURN_JDWP_ERROR_TEXT(ABSENT_INFORMATION) diff -r 0828a0f6676b -r 2f2af62dfac7 src/jdk.jdwp.agent/share/native/libjdwp/util.c --- a/src/jdk.jdwp.agent/share/native/libjdwp/util.c Fri Jun 22 17:49:21 2018 -0700 +++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.c Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -1888,6 +1888,8 @@ return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED; case JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED): return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED; + case JDWP_ERROR(CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED): + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; case JDWP_ERROR(NOT_IMPLEMENTED): return JVMTI_ERROR_NOT_AVAILABLE; case JDWP_ERROR(NULL_POINTER): @@ -2220,6 +2222,8 @@ return JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED); case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED: return JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED); + case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED: + return JDWP_ERROR(CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED); case AGENT_ERROR_NOT_CURRENT_FRAME: return JDWP_ERROR(NOT_CURRENT_FRAME); case AGENT_ERROR_INVALID_TAG: diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java --- a/test/hotspot/jtreg/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -23,8 +23,8 @@ /** * @test - * @bug 8025260 8016839 - * @summary Ensure that AbstractMethodError and IllegalAccessError are thrown appropriately, not NullPointerException + * @bug 8025260 8016839 8046171 + * @summary Ensure that correct exceptions are thrown, not NullPointerException * @modules java.base/jdk.internal.org.objectweb.asm * @library / . * @@ -34,6 +34,13 @@ * @run main/othervm -Xcomp compiler.jsr292.methodHandleExceptions.TestAMEnotNPE */ +// Since this test was written the specification for interface method selection has been +// revised (JEP 181 - Nestmates) so that private methods are never selected, as they never +// override any inherited method. So where a private method was previously selected +// and then resulted in IllegalAccessError, the private method is skipped and the invocation +// will either succeed or fail based on what other implementations are found in the inheritance +// hierarchy. This is explained for each test below. + package compiler.jsr292.methodHandleExceptions; import p.Dok; @@ -91,43 +98,41 @@ } } - try { - System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.F, p.F.m FINAL"); - tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/F"), - "p.D extends p.F (p.F implements p.I, FINAL public m), private m", - IllegalAccessError.class, "pD_ext_pF"); - // We'll take either a VerifyError (pre 2013-11-30) - // or an IllegalAccessError (post 2013-11-22) - } catch (VerifyError ve) { - System.out.println("Saw expected VerifyError " + ve); - } + System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.F, p.F.m FINAL"); + System.out.println(" - should invoke p.F.m as private p.D.m is skipped for selection"); + tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/F"), + "p.D extends p.F (p.F implements p.I, FINAL public m), private m", + null /* should succeed */, "pD_ext_pF"); System.out.println(); System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.E"); + System.out.println(" - should invoke p.E.m as private p.D.m is skipped for selection"); tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/E"), - "p.D extends p.E (p.E implements p.I, public m), private m", - IllegalAccessError.class, "pD_ext_pE"); + "p.D extends p.E (p.E implements p.I, public m), private m", + null /* should succeed */, "pD_ext_pE"); System.out.println("TRYING p.D.m ABSTRACT interface-invoked as p.I.m"); tryAndCheckThrown(lt, bytesForD(), - "D extends abstract C, no m", - AbstractMethodError.class, "pD_ext_pC"); + "D extends abstract C, no m", + AbstractMethodError.class, "pD_ext_pC"); System.out.println("TRYING q.D.m PACKAGE interface-invoked as p.I.m"); tryAndCheckThrown(lt, "q.D", bytesForDsomeAccess("q/D", 0), - "q.D implements p.I, protected m", IllegalAccessError.class, - "qD_m_pp_imp_pI"); + "q.D implements p.I, protected m", + IllegalAccessError.class, "qD_m_pp_imp_pI"); // Note jar file name is used in the plural-arg case. System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m"); + System.out.println(" - should invoke p.I.m as private p.D.m is skipped for selection"); tryAndCheckThrown(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE), - "p.D implements p.I, private m", - IllegalAccessError.class, "pD_m_pri_imp_pI"); + "p.D implements p.I, private m", + null /* should succeed */, "pD_m_pri_imp_pI"); // Plural-arg test. System.out.println("TRYING p.D.m PRIVATE MANY ARG interface-invoked as p.I.m"); + System.out.println(" - should invoke p.I.m as private p.D.m is skipped for selection"); tryAndCheckThrownMany(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE), - "p.D implements p.I, private m", IllegalAccessError.class); + "p.D implements p.I, private m", null /* should succeed */); if (lt.size() > 0) { System.out.flush(); diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -39,6 +39,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; public class ResolvedJavaTypeResolveConcreteMethodTest { public final MetaAccessProvider metaAccess; @@ -117,8 +118,9 @@ ResolvedJavaType c = getType(C.class); ResolvedJavaMethod priv = getMethod(a, "priv"); - assertNull(a.resolveConcreteMethod(priv, c)); - assertNull(b.resolveConcreteMethod(priv, c)); + // nestmates have access to private methods + assertNotNull(a.resolveConcreteMethod(priv, c)); + assertNotNull(b.resolveConcreteMethod(priv, c)); } @Test diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -39,6 +39,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; public class ResolvedJavaTypeResolveMethodTest { public final MetaAccessProvider metaAccess; @@ -117,8 +118,9 @@ ResolvedJavaType c = getType(C.class); ResolvedJavaMethod priv = getMethod(a, "priv"); - assertNull(a.resolveMethod(priv, c)); - assertNull(b.resolveMethod(priv, c)); + // nestmates have access to private methods + assertNotNull(a.resolveMethod(priv, c)); + assertNotNull(b.resolveMethod(priv, c)); } @Test diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/NestmatesJNI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/NestmatesJNI.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,54 @@ +/* + * 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. + */ + +/** + * Utility class for invoking methods and constructors and accessing fields + * via JNI. + */ +public class NestmatesJNI { + + static { + System.loadLibrary("NestmatesJNI"); + } + + public static native void callVoidVoid(Object target, String definingClassName, String methodName, boolean virtual); + + public static native String callStringVoid(Object target, String definingClassName, String methodName, boolean virtual); + + public static native void callStaticVoidVoid(String definingClassName, String methodName); + + public static Object newInstance(String definingClassName, String sig, Object outerThis) { + return newInstance0(definingClassName, "<init>", sig, outerThis); + } + + private static native Object newInstance0(String definingClassName, String method_name, String sig, Object outerThis); + + public static native int getIntField(Object target, String definingClassName, String fieldName); + + public static native void setIntField(Object target, String definingClassName, String fieldName, int newVal); + + public static native int getStaticIntField(String definingClassName, String fieldName); + + public static native void setStaticIntField(String definingClassName, String fieldName, int newVal); + +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/BadNestHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/BadNestHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Source: NestmateAttributeHolder.java + +public class NestmateAttributeHolder { + public static class TwoNestHost { + } +} +*/ + +// NestHost attribute does not refer to a class + +class NestmateAttributeHolder$BadNestHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "NestmateAttributeHolder.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "NestmateAttributeHolder$BadNestHost"; // #13 + Utf8 "BadNestHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "NestmateAttributeHolder"; // #17 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 2; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x000A; // not a class index + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 9; + } + } // end InnerClasses + } // Attributes +} // end class NestmateAttributeHolder$BadNestHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/BadNestHostLength.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/BadNestHostLength.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,111 @@ +/* + * 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. + */ + +/* Source: NestmateAttributeHolder.java + +public class NestmateAttributeHolder { + public static class BadNestHostLength { + } +} +*/ + +// Declare NestHost attribute as variable-length > 2 +class NestmateAttributeHolder$BadNestHostLength { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "NestmateAttributeHolder.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "NestmateAttributeHolder$BadNestHostLength"; // #13 + Utf8 "BadNestHostLength"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "NestmateAttributeHolder"; // #17 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 2; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + [] { + #11 #11 #11 #11; + } + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 9; + } + } // end InnerClasses + } // Attributes +} // end class NestmateAttributeHolder$BadNestHostLength diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/BadNestMembersEntry.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/BadNestMembersEntry.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Source: NestmateAttributeHolder.java + +public class NestmateAttributeHolder { + public static class TwoNestHost { + } +} +*/ + +// NestMembers attribute refers to non-class entry + +class BadNestMembersEntry { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #14; // #1 + class #15; // #2 + class #16; // #3 + class #17; // #4 + Utf8 "TwoNestHost"; // #5 + Utf8 "InnerClasses"; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "BadNestMembersEntry.java"; // #12 + Utf8 "NestMembers"; // #13 + NameAndType #7 #8; // #14 + Utf8 "BadNestMembersEntry"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "BadNestMembersEntry$TwoNestHost"; // #17 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 1; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestMembers + 0x00010009; // not a class index + } // end NestMembers + ; + Attr(#6) { // InnerClasses + [] { // InnerClasses + #4 #2 #5 9; + } + } // end InnerClasses + } // Attributes +} // end class BadNestMembersEntry diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/BadNestMembersLength.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/BadNestMembersLength.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Source: NestmateAttributeHolder.java + +public class NestmateAttributeHolder { + public static class TwoNestHost { + } +} +*/ + +// NestMembers attribute has wrong count for number of nestmates + +class BadNestMembersLength { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #14; // #1 + class #15; // #2 + class #16; // #3 + class #17; // #4 + Utf8 "TwoNestHost"; // #5 + Utf8 "InnerClasses"; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "BadNestMembersLength.java"; // #12 + Utf8 "NestMembers"; // #13 + NameAndType #7 #8; // #14 + Utf8 "BadNestMembersLength"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "BadNestMembersLength$TwoNestHost"; // #17 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 1; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestMembers + 0x00000004; // bad length + } // end NestMembers + ; + Attr(#6) { // InnerClasses + [] { // InnerClasses + #4 #2 #5 9; + } + } // end InnerClasses + } // Attributes +} // end class BadNestMembersLength diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Source: NestmateAttributeHolder.java + +public class NestmateAttributeHolder { + public static class TwoNestHost { + } +} +*/ + +// Add NestHost attribute to nest-host class - conflicting attributes + +class ConflictingAttributesInNestHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #14; // #1 + class #15; // #2 + class #16; // #3 + class #17; // #4 + Utf8 "TwoNestHost"; // #5 + Utf8 "InnerClasses"; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "ConflictingAttributesInNestHost.java"; // #12 + Utf8 "NestMembers"; // #13 + NameAndType #7 #8; // #14 + Utf8 "ConflictingAttributesInNestHost"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "ConflictingAttributesInNestHost$TwoNestHost"; // #17 + Utf8 "NestHost"; // #18 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 1; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestMembers + 0x00010004; + } // end NestMembers + ; + // conflict - can't be a member of a nest and have nest members + Attr(#18) { // NestHost + 0x0003; // #3 is Object + } // end NestHost + ; + Attr(#6) { // InnerClasses + [] { // InnerClasses + #4 #2 #5 9; + } + } // end InnerClasses + } // Attributes +} // end class ConflictingAttributesInNestHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestMember.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/ConflictingAttributesInNestMember.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Source: NestmateAttributeHolder.java + +public class NestmateAttributeHolder { + public static class TwoNestHost { + } +} +*/ + +class NestmateAttributeHolder$ConflictingAttributesInNestMember { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "NestmateAttributeHolder.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "NestmateAttributeHolder$ConflictingAttributesInNestMember"; // #13 + Utf8 "ConflictingAttributesInNestMember"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "NestmateAttributeHolder"; // #17 + Utf8 "NestMembers"; // #18 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 2; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x000B; + } // end NestHost + ; + // conflict: can't have nest members when you are a member of a nest + Attr(#18) { // NestMembers + 0x00010004; + } // end NestMembers + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 9; + } + } // end InnerClasses + } // Attributes +} // end class NestmateAttributeHolder$ConflictingAttributesInNestMember diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/TestFinalMethodOverride.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/TestFinalMethodOverride.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test nestmate checks are no longer used when check_final_method_override is executed during parsing + * @run main TestFinalMethodOverride + */ + +// The check_final_method_override function in ClassfileParser uses an +// accessability check to see if the subclass method overrides a same-named +// superclass method. This would result in a nestmate access check if the +// super class method is private, which in turn could lead to classloading +// and possibly exceptions and cause havoc in the classfile parsing process. +// To fix that we added a check for whether the super class method is private, +// and if so, we skip the override check as by definition you can't override +// a private method. +// +// This test simply sets up the case where a public subclass method has the +// same signature as a private superclass method - the case we now skip when +// doing check_final_method_override. The test should trivially complete +// normally. + +public class TestFinalMethodOverride { + + public static class Super { + private final void theMethod() {} + } + + public static class Inner extends Super { + // define our own theMethod + public void theMethod() {} + } + + public static void main(String[] args) { + Inner i = new Inner(); + } +} + diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/TestNestmateAttributes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/TestNestmateAttributes.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017, 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 + * @bug 8046171 + * @summary Test incorrect use of Nestmate related attributes + * @compile TwoNestHost.jcod + * TwoNestMembers.jcod + * ConflictingAttributesInNestHost.jcod + * ConflictingAttributesInNestMember.jcod + * BadNestMembersLength.jcod + * BadNestMembersEntry.jcod + * BadNestHost.jcod + * BadNestHostLength.jcod + * @run main TestNestmateAttributes + */ + +public class TestNestmateAttributes { + public static void main(String args[]) throws Throwable { + String[] badClasses = new String[] { + "NestmateAttributeHolder$TwoNestHost", + "NestmateAttributeHolder", + "ConflictingAttributesInNestHost", + "NestmateAttributeHolder$ConflictingAttributesInNestMember", + "BadNestMembersLength", + "BadNestMembersEntry", + "NestmateAttributeHolder$BadNestHost", + "NestmateAttributeHolder$BadNestHostLength", + }; + + String[] messages = new String[] { + "Multiple NestHost attributes in class file", + "Multiple NestMembers attributes in class file", + "Conflicting NestMembers and NestHost attributes", + "Conflicting NestHost and NestMembers attributes", + "Wrong NestMembers attribute length", + "Nest member class_info_index 9 has bad constant type", + "Nest-host class_info_index 10 has bad constant type", + "Wrong NestHost attribute length", + }; + + for (int i = 0; i < badClasses.length; i++ ) { + try { + Class c = Class.forName(badClasses[i]); + throw new Error("Missing ClassFormatError: " + messages[i]); + } + catch (ClassFormatError expected) { + if (!expected.getMessage().contains(messages[i])) + throw new Error("Wrong ClassFormatError message: \"" + + expected.getMessage() + "\" does not contain \"" + + messages[i] + "\""); + System.out.println("OK - got expected exception: " + expected); + } + } + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/TwoNestHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/TwoNestHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Source: NestmateAttributeHolder.java + +public class NestmateAttributeHolder { + public static class TwoNestHost { + } +} +*/ + +// Add second NestHost attribute - should fail parsing +class NestmateAttributeHolder$TwoNestHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "NestmateAttributeHolder.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "NestmateAttributeHolder$TwoNestHost"; // #13 + Utf8 "TwoNestHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "NestmateAttributeHolder"; // #17 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 2; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x000B; + } // end NestHost + ; + Attr(#10) { // NestHost + 0x000B; + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 9; + } + } // end InnerClasses + } // Attributes +} // end class NestmateAttributeHolder$TwoNestHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/classFileParsing/TwoNestMembers.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/classFileParsing/TwoNestMembers.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Source: NestmateAttributeHolder.java + +public class NestmateAttributeHolder { + public static class TwoNestHost { + } +} +*/ + +// Add second NestMembers attribute - should fail parsing + +class NestmateAttributeHolder { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #14; // #1 + class #15; // #2 + class #16; // #3 + class #17; // #4 + Utf8 "TwoNestHost"; // #5 + Utf8 "InnerClasses"; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "NestmateAttributeHolder.java"; // #12 + Utf8 "NestMembers"; // #13 + NameAndType #7 #8; // #14 + Utf8 "NestmateAttributeHolder"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "NestmateAttributeHolder$TwoNestHost"; // #17 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 1; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestMembers + 0x00010004; + } // end NestMembers + ; + Attr(#13) { // NestMembers + 0x00010004; + } // end NestMembers + ; + Attr(#6) { // InnerClasses + [] { // InnerClasses + #4 #2 #5 9; + } + } // end InnerClasses + } // Attributes +} // end class NestmateAttributeHolder diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/legacy/TestPrivateLookup.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/legacy/TestPrivateLookup.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,108 @@ +/* + * 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 + * @bug 8046171 + * @summary Test that private Lookup works for both nestmate-enabled classes + * and legacy classes + * @compile TestPrivateLookup.java + * @run main TestPrivateLookup + * @compile -source 10 -target 10 TestPrivateLookup.java + * @run main TestPrivateLookup noNestmates + */ + +// Need the explicit first @compile above so that jtreg forces recompilation +// with latest version. Otherwise compile-on-demand sees the JDK 10 version +// and assumes it is up to date and then runs the test using that version - +// which fails. + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +public class TestPrivateLookup { + + static boolean compiledForNestmates; + + static class C { + static class D { + private void m() { } + } + + static void test() throws Throwable { + MethodType M_T = MethodType.methodType(void.class); + // Direct lookup from C + Lookup l = lookup(); + try { + MethodHandle mh = l.findVirtual(D.class, "m", M_T); + if (compiledForNestmates) { + System.out.println("Lookup of D.m from C succeeded as expected with nestmates"); + } + else { + throw new Error("Unexpected success when not compiled for nestmates!"); + } + } + catch (IllegalAccessException iae) { + if (!compiledForNestmates) { + System.out.println("Lookup of D.m from C failed as expected without nestmates"); + } + else { + throw new Error("Unexpected failure with nestmates", iae); + } + } + // switch lookup class to D + l = l.in(D.class); + try { + MethodHandle mh = l.findVirtual(D.class, "m", M_T); + System.out.println("Lookup of D.m from D succeeded as expected" + + " with" + (compiledForNestmates ? "" : "out") + + " nestmates"); + } + catch (IllegalAccessException iae) { + throw new Error("Lookup of D.m from D failed", iae); + } + } + } + + public static void main(String[] args) throws Throwable { + + // If there's no nesthost attribute A.getNestHost() == A + compiledForNestmates = C.D.class.getNestHost() == TestPrivateLookup.class; + // sanity check + boolean expectingNestmates = args.length == 0; + + if (compiledForNestmates && !expectingNestmates) { + throw new Error("Test is being run incorrectly: " + + "nestmates are being used but not expected"); + } + if (expectingNestmates && !compiledForNestmates) { + throw new Error("Test is being run incorrectly: " + + "nestmates are expected but not being used"); + } + System.out.println("Testing with" + (expectingNestmates ? "" : "out") + + " nestmates"); + + C.test(); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/libNestmatesJNI.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/libNestmatesJNI.c Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,241 @@ +/* + * 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. + */ + +#include <jni.h> + +// boolean flag for static versus non-static +#define STATIC 1 +#define NON_STATIC 0 + +// Helper methods to get class/method/field IDs + +static void getClassID(JNIEnv *env, + jstring defining_class_name, + jclass* clazz) { + const char* name = (*env)->GetStringUTFChars(env, defining_class_name, NULL); + if (name != NULL) { + *clazz = (*env)->FindClass(env, name); + (*env)->ReleaseStringUTFChars(env, defining_class_name, name); + } +} + +static void getClassAndMethodID(JNIEnv *env, + int is_static, + jstring defining_class_name, + jstring method_name, + const char* sig, + jmethodID* m_id, jclass* clazz) { + getClassID(env, defining_class_name, clazz); + if (*clazz != NULL) { + const char* name = (*env)->GetStringUTFChars(env, method_name, NULL); + if (name != NULL) { + if (is_static) { + *m_id = (*env)->GetStaticMethodID(env, *clazz, name, sig); + } else { + *m_id = (*env)->GetMethodID(env, *clazz, name, sig); + } + (*env)->ReleaseStringUTFChars(env, method_name, name); + } + } +} + +static void getClassAndFieldID(JNIEnv *env, + int is_static, + jstring defining_class_name, + jstring field_name, + const char* sig, + jfieldID* m_id, jclass* clazz) { + getClassID(env, defining_class_name, clazz); + if (*clazz != NULL) { + const char* name = (*env)->GetStringUTFChars(env, field_name, NULL); + if (name != NULL) { + if (is_static) { + *m_id = (*env)->GetStaticFieldID(env, *clazz, name, sig); + } else { + *m_id = (*env)->GetFieldID(env, *clazz, name, sig); + } + (*env)->ReleaseStringUTFChars(env, field_name, name); + } + } +} + +JNIEXPORT void JNICALL +Java_NestmatesJNI_callVoidVoid(JNIEnv *env, jclass unused, + jobject target, + jstring defining_class_name, + jstring method_name, + jboolean virtual) { + + // Lookup "void method_name()" in defining_class_name, and if it exists + // call target.method_name() using a virtual or non-virtual invocation + + jmethodID m_id = NULL; + jclass clazz = NULL; + getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name, + "()V", &m_id, &clazz); + if (m_id != NULL && clazz != NULL) { + if (!virtual) { + (*env)->CallNonvirtualVoidMethod(env, target, clazz, m_id); + } else { + (*env)->CallVoidMethod(env, target, m_id); + } + } +} + +JNIEXPORT jobject JNICALL +Java_NestmatesJNI_callStringVoid(JNIEnv *env, jclass unused, + jobject target, + jstring defining_class_name, + jstring method_name, + jboolean virtual) { + + // Lookup "String method_name()" in defining_class_name, and if it exists + // call target.method_name() using a virtual or non-virtual invocation + + jmethodID m_id = NULL; + jclass clazz = NULL; + getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name, + "()Ljava/lang/String;", &m_id, &clazz); + if (m_id != NULL && clazz != NULL) { + if (!virtual) { + return (*env)->CallNonvirtualObjectMethod(env, target, clazz, m_id); + } else { + return (*env)->CallObjectMethod(env, target, m_id); + } + } + return NULL; +} + +JNIEXPORT jobject JNICALL +Java_NestmatesJNI_newInstance0(JNIEnv *env, jclass unused, + jstring defining_class_name, + jstring method_name, + jstring sig, + jobject outerThis) { + + // Lookup the no-user-arg constructor in defining_class_name using sig, + // and use it to create an instance of the class, and return it. For + // inner classes we need an outerThis reference to pass to the constructor. + + jmethodID m_id = NULL; + jclass clazz = NULL; + const char* _sig = (*env)->GetStringUTFChars(env, sig, NULL); + getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name, + _sig, &m_id, &clazz); + (*env)->ReleaseStringUTFChars(env, sig, _sig); + if (m_id != NULL && clazz != NULL) { + return (*env)->NewObject(env, clazz, m_id, outerThis); + } + return NULL; +} + +JNIEXPORT void JNICALL +Java_NestmatesJNI_callStaticVoidVoid(JNIEnv *env, jclass unused, + jstring defining_class_name, + jstring method_name) { + + // Lookup "static void method_name()" in defining_class_name, and if it exists + // invoke it. + + jmethodID m_id = NULL; + jclass clazz = NULL; + getClassAndMethodID(env, STATIC, defining_class_name, method_name, + "()V", &m_id, &clazz); + if (m_id != NULL && clazz != NULL) { + (*env)->CallStaticVoidMethod(env, clazz, m_id); + } +} + +JNIEXPORT jint JNICALL +Java_NestmatesJNI_getIntField(JNIEnv *env, jclass unused, + jobject target, + jstring defining_class_name, + jstring field_name) { + + // Lookup field field_name in defining_class_name, and if it exists + // return its value. + + jfieldID f_id = NULL; + jclass clazz = NULL; + getClassAndFieldID(env, NON_STATIC, defining_class_name, field_name, + "I", &f_id, &clazz); + if (f_id != NULL && clazz != NULL) { + return (*env)->GetIntField(env, target, f_id); + } + return -1; +} + +JNIEXPORT void JNICALL +Java_NestmatesJNI_setIntField(JNIEnv *env, jclass unused, + jobject target, + jstring defining_class_name, + jstring field_name, + jint newVal) { + + // Lookup field field_name in defining_class_name, and if it exists + // set it to newVal. + + jfieldID f_id = NULL; + jclass clazz = NULL; + getClassAndFieldID(env, NON_STATIC, defining_class_name, field_name, + "I", &f_id, &clazz); + if (f_id != NULL && clazz != NULL) { + (*env)->SetIntField(env, target, f_id, newVal); + } +} + +JNIEXPORT jint JNICALL +Java_NestmatesJNI_getStaticIntField(JNIEnv *env, jclass unused, + jstring defining_class_name, + jstring field_name) { + + // Lookup field field_name in defining_class_name, and if it exists + // return its value. + + jfieldID f_id = NULL; + jclass clazz = NULL; + getClassAndFieldID(env, STATIC, defining_class_name, field_name, + "I", &f_id, &clazz); + if (f_id != NULL && clazz != NULL) { + return (*env)->GetStaticIntField(env, clazz, f_id); + } + return -1; +} + +JNIEXPORT void JNICALL +Java_NestmatesJNI_setStaticIntField(JNIEnv *env, jclass unused, + jstring defining_class_name, + jstring field_name, + jint newVal) { + + // Lookup field field_name in defining_class_name, and if it exists + // set it to newVal. + + jfieldID f_id = NULL; + jclass clazz = NULL; + getClassAndFieldID(env, STATIC, defining_class_name, field_name, + "I", &f_id, &clazz); + if (f_id != NULL && clazz != NULL) { + (*env)->SetStaticIntField(env, clazz, f_id, newVal); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/CallerMissingHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/CallerMissingHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to non-existent class + +class TestNestmateMembership$CallerMissingHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Field #38 #39; // #1 + String #40; // #2 + Method #41 #42; // #3 + Method #9 #43; // #4 + Method #11 #43; // #5 + Method #16 #44; // #6 + String #45; // #7 + Field #15 #46; // #8 + class #47; // #9 + Method #9 #44; // #10 + class #50; // #11 + Method #11 #44; // #12 + Field #9 #52; // #13 + Field #11 #52; // #14 + class #53; // #15 + class #55; // #16 + Utf8 "msg"; // #17 + Utf8 "Ljava/lang/String;"; // #18 + Utf8 "f"; // #19 + Utf8 "I"; // #20 + Utf8 "m"; // #21 + Utf8 "()V"; // #22 + Utf8 "Code"; // #23 + Utf8 "LineNumberTable"; // #24 + Utf8 "invokeTarget"; // #25 + Utf8 "invokeTargetMissingHost"; // #26 + Utf8 "<init>"; // #27 + Utf8 "newTarget"; // #28 + Utf8 "newTargetMissingHost"; // #29 + Utf8 "getFieldTarget"; // #30 + Utf8 "getFieldTargetMissingHost"; // #31 + Utf8 "putFieldTarget"; // #32 + Utf8 "putFieldTargetMissingHost"; // #33 + Utf8 "SourceFile"; // #34 + Utf8 "TestNestmateMembership.java"; // #35 + Utf8 "NestHost"; // #36 + class #56; // #37 + class #57; // #38 + NameAndType #58 #59; // #39 + Utf8 "CallerMissingHost.m() - java version"; // #40 + class #60; // #41 + NameAndType #61 #62; // #42 + NameAndType #21 #22; // #43 + NameAndType #27 #22; // #44 + Utf8 "NoCallerMissingHost"; // #45 + NameAndType #17 #18; // #46 + Utf8 "TestNestmateMembership$Target"; // #47 + Utf8 "Target"; // #48 + Utf8 "InnerClasses"; // #49 + Utf8 "TestNestmateMembership$TargetMissingHost"; // #50 + Utf8 "TargetMissingHost"; // #51 + NameAndType #19 #20; // #52 + Utf8 "TestNestmateMembership$CallerMissingHost"; // #53 + Utf8 "CallerMissingHost"; // #54 + Utf8 "java/lang/Object"; // #55 + Utf8 "TestNestmateMembership"; // #56 + Utf8 "java/lang/System"; // #57 + Utf8 "out"; // #58 + Utf8 "Ljava/io/PrintStream;"; // #59 + Utf8 "java/io/PrintStream"; // #60 + Utf8 "println"; // #61 + Utf8 "(Ljava/lang/String;)V"; // #62 + class #45; // added - #63 + } // Constant Pool + + 0x0020; // access + #15;// this_cpx + #16;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0000; // access + #17; // name_cpx + #18; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #19; // name_cpx + #20; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x000A; // access + #21; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200011202B60003; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 209; + 8 210; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #25; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80004B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 212; + 3 213; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #26; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80005B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 215; + 3 216; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #27; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB700062A1207B5; + 0x0008B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 220; + 4 204; + 10 220; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #28; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000959B7000A4B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 223; + 8 224; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #29; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000B59B7000C4B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 226; + 8 227; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #30; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000D3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 234; + 4 235; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #31; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000E3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 237; + 4 238; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #32; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000DB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 240; + 5 241; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #33; // name_cpx + #22; // sig_cpx + [] { // Attributes + Attr(#23) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000EB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // LineNumberTable + 0 243; + 5 244; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#34) { // SourceFile + #35; + } // end SourceFile + ; + Attr(#36) { // NestHost + 0x003F; // modified - #63 + } // end NestHost + ; + Attr(#49) { // InnerClasses + [] { // InnerClasses + #9 #37 #48 8; + #11 #37 #51 8; + #15 #37 #54 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$CallerMissingHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/CallerNoHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/CallerNoHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute deleted + +class TestNestmateMembership$CallerNoHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Field #34 #35; // #1 + String #36; // #2 + Method #37 #38; // #3 + Method #7 #39; // #4 + Method #9 #39; // #5 + Method #14 #40; // #6 + class #41; // #7 + Method #7 #40; // #8 + class #44; // #9 + Method #9 #40; // #10 + Field #7 #46; // #11 + Field #9 #46; // #12 + class #47; // #13 + class #49; // #14 + Utf8 "f"; // #15 + Utf8 "I"; // #16 + Utf8 "m"; // #17 + Utf8 "()V"; // #18 + Utf8 "Code"; // #19 + Utf8 "LineNumberTable"; // #20 + Utf8 "invokeTarget"; // #21 + Utf8 "invokeTargetNoHost"; // #22 + Utf8 "<init>"; // #23 + Utf8 "newTarget"; // #24 + Utf8 "newTargetNoHost"; // #25 + Utf8 "getFieldTarget"; // #26 + Utf8 "getFieldTargetNoHost"; // #27 + Utf8 "putFieldTarget"; // #28 + Utf8 "putFieldTargetNoHost"; // #29 + Utf8 "SourceFile"; // #30 + Utf8 "TestNestmateMembership.java"; // #31 + Utf8 "NestHost"; // #32 + class #50; // #33 + class #51; // #34 + NameAndType #52 #53; // #35 + Utf8 "CallerNoHost.m() - java version"; // #36 + class #54; // #37 + NameAndType #55 #56; // #38 + NameAndType #17 #18; // #39 + NameAndType #23 #18; // #40 + Utf8 "TestNestmateMembership$Target"; // #41 + Utf8 "Target"; // #42 + Utf8 "InnerClasses"; // #43 + Utf8 "TestNestmateMembership$TargetNoHost"; // #44 + Utf8 "TargetNoHost"; // #45 + NameAndType #15 #16; // #46 + Utf8 "TestNestmateMembership$CallerNoHost"; // #47 + Utf8 "CallerNoHost"; // #48 + Utf8 "java/lang/Object"; // #49 + Utf8 "TestNestmateMembership"; // #50 + Utf8 "java/lang/System"; // #51 + Utf8 "out"; // #52 + Utf8 "Ljava/io/PrintStream;"; // #53 + Utf8 "java/io/PrintStream"; // #54 + Utf8 "println"; // #55 + Utf8 "(Ljava/lang/String;)V"; // #56 + } // Constant Pool + + 0x0020; // access + #13;// this_cpx + #14;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x000A; // access + #15; // name_cpx + #16; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x000A; // access + #17; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200011202B60003; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 163; + 8 164; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #21; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80004B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 166; + 3 167; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #22; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80005B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 169; + 3 170; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #23; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70006B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 174; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #24; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000759B700084B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 177; + 8 178; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #25; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000959B7000A4B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 180; + 8 181; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #26; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000B3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 188; + 4 189; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #27; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000C3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 191; + 4 192; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #28; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 195; + 5 196; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #29; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000CB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 198; + 5 199; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#30) { // SourceFile + #31; + } // end SourceFile + ; + Attr(#43) { // InnerClasses + [] { // InnerClasses + #7 #33 #42 8; + #9 #33 #45 8; + #13 #33 #48 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$CallerNoHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/CallerNotInstanceHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/CallerNotInstanceHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to non-instance class + +class TestNestmateMembership$CallerNotInstanceHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Field #36 #37; // #1 + String #38; // #2 + Method #39 #40; // #3 + Method #7 #41; // #4 + Method #9 #41; // #5 + Method #14 #42; // #6 + class #43; // #7 + Method #7 #42; // #8 + class #46; // #9 + Method #9 #42; // #10 + Field #7 #48; // #11 + Field #9 #48; // #12 + class #49; // #13 + class #51; // #14 + Utf8 "oa"; // #15 + Utf8 "[LInvalidNestHost;"; // #16 + Utf8 "f"; // #17 + Utf8 "I"; // #18 + Utf8 "m"; // #19 + Utf8 "()V"; // #20 + Utf8 "Code"; // #21 + Utf8 "LineNumberTable"; // #22 + Utf8 "invokeTarget"; // #23 + Utf8 "invokeTargetNotInstanceHost"; // #24 + Utf8 "<init>"; // #25 + Utf8 "newTarget"; // #26 + Utf8 "newTargetNotInstanceHost"; // #27 + Utf8 "getFieldTarget"; // #28 + Utf8 "getFieldTargetNotInstanceHost"; // #29 + Utf8 "putFieldTarget"; // #30 + Utf8 "putFieldTargetNotInstanceHost"; // #31 + Utf8 "SourceFile"; // #32 + Utf8 "TestNestmateMembership.java"; // #33 + Utf8 "NestHost"; // #34 + class #52; // #35 + class #53; // #36 + NameAndType #54 #55; // #37 + Utf8 "CallerNotInstanceHost.m() - java version"; // #38 + class #56; // #39 + NameAndType #57 #58; // #40 + NameAndType #19 #20; // #41 + NameAndType #25 #20; // #42 + Utf8 "TestNestmateMembership$Target"; // #43 + Utf8 "Target"; // #44 + Utf8 "InnerClasses"; // #45 + Utf8 "TestNestmateMembership$TargetNotInstanceHost"; // #46 + Utf8 "TargetNotInstanceHost"; // #47 + NameAndType #17 #18; // #48 + Utf8 "TestNestmateMembership$CallerNotInstanceHost"; // #49 + Utf8 "CallerNotInstanceHost"; // #50 + Utf8 "java/lang/Object"; // #51 + Utf8 "TestNestmateMembership"; // #52 + Utf8 "java/lang/System"; // #53 + Utf8 "out"; // #54 + Utf8 "Ljava/io/PrintStream;"; // #55 + Utf8 "java/io/PrintStream"; // #56 + Utf8 "println"; // #57 + Utf8 "(Ljava/lang/String;)V"; // #58 + class #16; // Added - #59 + } // Constant Pool + + 0x0020; // access + #13;// this_cpx + #14;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0000; // access + #15; // name_cpx + #16; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #17; // name_cpx + #18; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x000A; // access + #19; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200011202B60003; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 254; + 8 255; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #23; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80004B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 257; + 3 258; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #24; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80005B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 260; + 3 261; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #25; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70006B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 265; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #26; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000759B700084B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 268; + 8 269; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #27; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000959B7000A4B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 271; + 8 272; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #28; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000B3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 279; + 4 280; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #29; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000C3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 282; + 4 283; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #30; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 285; + 5 286; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #31; // name_cpx + #20; // sig_cpx + [] { // Attributes + Attr(#21) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000CB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#22) { // LineNumberTable + [] { // LineNumberTable + 0 288; + 5 289; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#32) { // SourceFile + #33; + } // end SourceFile + ; + Attr(#34) { // NestHost + 0x003B; // modified #59 + } // end NestHost + ; + Attr(#45) { // InnerClasses + [] { // InnerClasses + #7 #35 #44 8; + #9 #35 #47 8; + #13 #35 #50 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$CallerNotInstanceHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/CallerNotOurHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/CallerNotOurHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to class with no nest + +class TestNestmateMembership$CallerNotOurHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Field #34 #35; // #1 + String #36; // #2 + Method #37 #38; // #3 + Method #7 #39; // #4 + Method #9 #39; // #5 + Method #14 #40; // #6 + class #41; // #7 + Method #7 #40; // #8 + class #44; // #9 + Method #9 #40; // #10 + Field #7 #46; // #11 + Field #9 #46; // #12 + class #47; // #13 + class #49; // #14 + Utf8 "f"; // #15 + Utf8 "I"; // #16 + Utf8 "m"; // #17 + Utf8 "()V"; // #18 + Utf8 "Code"; // #19 + Utf8 "LineNumberTable"; // #20 + Utf8 "invokeTarget"; // #21 + Utf8 "invokeTargetNotOurHost"; // #22 + Utf8 "<init>"; // #23 + Utf8 "newTarget"; // #24 + Utf8 "newTargetNotOurHost"; // #25 + Utf8 "getFieldTarget"; // #26 + Utf8 "getFieldTargetNotOurHost"; // #27 + Utf8 "putFieldTarget"; // #28 + Utf8 "putFieldTargetNotOurHost"; // #29 + Utf8 "SourceFile"; // #30 + Utf8 "TestNestmateMembership.java"; // #31 + Utf8 "NestHost"; // #32 + class #50; // #33 + class #51; // #34 + NameAndType #52 #53; // #35 + Utf8 "CallerNotOurHost.m() - java version"; // #36 + class #54; // #37 + NameAndType #55 #56; // #38 + NameAndType #17 #18; // #39 + NameAndType #23 #18; // #40 + Utf8 "TestNestmateMembership$Target"; // #41 + Utf8 "Target"; // #42 + Utf8 "InnerClasses"; // #43 + Utf8 "TestNestmateMembership$TargetNotOurHost"; // #44 + Utf8 "TargetNotOurHost"; // #45 + NameAndType #15 #16; // #46 + Utf8 "TestNestmateMembership$CallerNotOurHost"; // #47 + Utf8 "CallerNotOurHost"; // #48 + Utf8 "java/lang/Object"; // #49 + Utf8 "TestNestmateMembership"; // #50 + Utf8 "java/lang/System"; // #51 + Utf8 "out"; // #52 + Utf8 "Ljava/io/PrintStream;"; // #53 + Utf8 "java/io/PrintStream"; // #54 + Utf8 "println"; // #55 + Utf8 "(Ljava/lang/String;)V"; // #56 + // Added + Utf8 "InvalidNestHost"; // #57 + class #57; // #58 + } // Constant Pool + + 0x0020; // access + #13;// this_cpx + #14;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x000A; // access + #15; // name_cpx + #16; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x000A; // access + #17; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200011202B60003; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 297; + 8 298; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #21; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80004B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 300; + 3 301; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #22; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80005B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 303; + 3 304; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #23; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70006B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 308; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #24; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000759B700084B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 311; + 8 312; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #25; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000959B7000A4B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 314; + 8 315; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #26; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000B3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 322; + 4 323; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #27; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000C3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 325; + 4 326; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #28; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 328; + 5 329; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #29; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000CB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 331; + 5 332; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#30) { // SourceFile + #31; + } // end SourceFile + ; + Attr(#32) { // NestHost + 0x003A; // modified - #58 + } // end NestHost + ; + Attr(#43) { // InnerClasses + [] { // InnerClasses + #7 #33 #42 8; + #9 #33 #45 8; + #13 #33 #48 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$CallerNotOurHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/CallerSelfHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/CallerSelfHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,378 @@ +/* + * 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. + */ + +// NestHost attribute refers to current class + +class TestNestmateMembership$CallerSelfHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Field #34 #35; // #1 + String #36; // #2 + Method #37 #38; // #3 + Method #7 #39; // #4 + Method #9 #39; // #5 + Method #14 #40; // #6 + class #41; // #7 + Method #7 #40; // #8 + class #44; // #9 + Method #9 #40; // #10 + Field #7 #46; // #11 + Field #9 #46; // #12 + class #47; // #13 + class #49; // #14 + Utf8 "f"; // #15 + Utf8 "I"; // #16 + Utf8 "m"; // #17 + Utf8 "()V"; // #18 + Utf8 "Code"; // #19 + Utf8 "LineNumberTable"; // #20 + Utf8 "invokeTarget"; // #21 + Utf8 "invokeTargetSelfHost"; // #22 + Utf8 "<init>"; // #23 + Utf8 "newTarget"; // #24 + Utf8 "newTargetSelfHost"; // #25 + Utf8 "getFieldTarget"; // #26 + Utf8 "getFieldTargetSelfHost"; // #27 + Utf8 "putFieldTarget"; // #28 + Utf8 "putFieldTargetSelfHost"; // #29 + Utf8 "SourceFile"; // #30 + Utf8 "TestNestmateMembership.java"; // #31 + Utf8 "NestHost"; // #32 + class #50; // #33 + class #51; // #34 + NameAndType #52 #53; // #35 + Utf8 "CallerSelfHost.m() - java version"; // #36 + class #54; // #37 + NameAndType #55 #56; // #38 + NameAndType #17 #18; // #39 + NameAndType #23 #18; // #40 + Utf8 "TestNestmateMembership$Target"; // #41 + Utf8 "Target"; // #42 + Utf8 "InnerClasses"; // #43 + Utf8 "TestNestmateMembership$TargetSelfHost"; // #44 + Utf8 "TargetSelfHost"; // #45 + NameAndType #15 #16; // #46 + Utf8 "TestNestmateMembership$CallerSelfHost"; // #47 + Utf8 "CallerSelfHost"; // #48 + Utf8 "java/lang/Object"; // #49 + Utf8 "TestNestmateMembership"; // #50 + Utf8 "java/lang/System"; // #51 + Utf8 "out"; // #52 + Utf8 "Ljava/io/PrintStream;"; // #53 + Utf8 "java/io/PrintStream"; // #54 + Utf8 "println"; // #55 + Utf8 "(Ljava/lang/String;)V"; // #56 + } // Constant Pool + + 0x0020; // access + #13;// this_cpx + #14;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x000A; // access + #15; // name_cpx + #16; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x000A; // access + #17; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200011202B60003; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 297; + 8 298; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #21; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80004B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 300; + 3 301; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #22; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80005B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 303; + 3 304; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #23; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70006B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 308; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #24; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000759B700084B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 311; + 8 312; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #25; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000959B7000A4B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 314; + 8 315; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #26; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000B3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 322; + 4 323; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #27; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB2000C3BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 325; + 4 326; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #28; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 328; + 5 329; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #29; // name_cpx + #18; // sig_cpx + [] { // Attributes + Attr(#19) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB3000CB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // LineNumberTable + 0 331; + 5 332; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#30) { // SourceFile + #31; + } // end SourceFile + ; + Attr(#32) { // NestHost + 0x000D; // modified - #13 + } // end NestHost + ; + Attr(#43) { // InnerClasses + [] { // InnerClasses + #7 #33 #42 8; + #9 #33 #45 8; + #13 #33 #48 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$CallerSelfHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/InvalidNestHost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/InvalidNestHost.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,29 @@ +/* + * 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. + */ + +/* Empty class to use as an invalid nest-host class, in the same package as + * the test classes. + */ +public class InvalidNestHost { +} + diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHost.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package P1; + +/* + * This is used to produce a jcod file in which we modify the + * NestMembers attribute to claim that P2.PackagedNestHost.Member + * is a member of our nest. + */ +public class PackagedNestHost { + public static class Member { + // jcod file will change these to private + public Member() {} + public static int f; + public static void m() { + System.out.println("You should never see this!"); + } + } + + // Entry points for main test. + // These should fail at runtime as members will now be private + // and the nestmate access check should fail due to being in a + // different package. + + public static void doInvoke() { + P2.PackagedNestHost2.Member.m(); + } + + public static void doConstruct() { + Object o = new P2.PackagedNestHost2.Member(); + } + + public static void doGetField() { + int x = P2.PackagedNestHost2.Member.f; + } + + public static void doPutField() { + P2.PackagedNestHost2.Member.f = 42; + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestMembers attribute is modified to contain P2.PackagedNestHost2.Member + +class P1/PackagedNestHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #7 #22; // #1 + Method #3 #23; // #2 + class #25; // #3 + Method #3 #22; // #4 + Field #3 #26; // #5 + class #27; // #6 + class #28; // #7 + class #29; // #8 + Utf8 "Member"; // #9 + Utf8 "InnerClasses"; // #10 + Utf8 "<init>"; // #11 + Utf8 "()V"; // #12 + Utf8 "Code"; // #13 + Utf8 "LineNumberTable"; // #14 + Utf8 "doInvoke"; // #15 + Utf8 "doConstruct"; // #16 + Utf8 "doGetField"; // #17 + Utf8 "doPutField"; // #18 + Utf8 "SourceFile"; // #19 + Utf8 "PackagedNestHost.java"; // #20 + Utf8 "NestMembers"; // #21 + NameAndType #11 #12; // #22 + NameAndType #30 #12; // #23 + class #31; // #24 + Utf8 "P2/PackagedNestHost2$Member"; // #25 + NameAndType #32 #33; // #26 + Utf8 "P1/PackagedNestHost"; // #27 + Utf8 "java/lang/Object"; // #28 + Utf8 "P1/PackagedNestHost$Member"; // #29 + Utf8 "m"; // #30 + Utf8 "P2/PackagedNestHost2"; // #31 + Utf8 "f"; // #32 + Utf8 "I"; // #33 + } // Constant Pool + + 0x0021; // access + #6;// this_cpx + #7;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#14) { // LineNumberTable + [] { // LineNumberTable + 0 31; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #15; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80002B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#14) { // LineNumberTable + [] { // LineNumberTable + 0 47; + 3 48; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #16; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000359B700044B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#14) { // LineNumberTable + [] { // LineNumberTable + 0 51; + 8 52; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #17; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB200053BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#14) { // LineNumberTable + [] { // LineNumberTable + 0 55; + 4 56; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #18; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB30005B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#14) { // LineNumberTable + [] { // LineNumberTable + 0 59; + 5 60; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#19) { // SourceFile + #20; + } // end SourceFile + ; + Attr(#21) { // NestMembers + 0x00010003; // modified - #3 + } // end NestMembers + ; + Attr(#10) { // InnerClasses + [] { // InnerClasses + #8 #6 #9 9; + #3 #24 #9 9; + } + } // end InnerClasses + } // Attributes +} // end class P1/PackagedNestHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHost2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHost2.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package P2; + +/* + * This is used to produce a jcod file in which we modify the + * NestHost attribute to claim that P2.PackagedNestHost.Member + * is a member of the nest of P1.PackagedNestHost. + */ +public class PackagedNestHost2 { + public static class Member { + // jcod file will change these to private + public Member() {} + public static int f; + public static void m() { + System.out.println("You should never see this!"); + } + + // Entry points for main test. + // These should fail at runtime as members will now be private + // and our nest-host won't resolve as it's in a different package. + + public static void doInvoke() { + P1.PackagedNestHost.Member.m(); + } + + public static void doConstruct() { + Object o = new P1.PackagedNestHost.Member(); + } + + public static void doGetField() { + int x = P1.PackagedNestHost.Member.f; + } + + public static void doPutField() { + P1.PackagedNestHost.Member.f = 42; + } + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHost2Member.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHost2Member.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute is modified to contain P1.PackagedNestHost +// Required members are declared private + +class P2/PackagedNestHost2$Member { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #10 #26; // #1 + Field #27 #28; // #2 + String #29; // #3 + Method #30 #31; // #4 + Method #6 #32; // #5 + class #34; // #6 + Method #6 #26; // #7 + Field #6 #37; // #8 + class #38; // #9 + class #39; // #10 + Utf8 "f"; // #11 + Utf8 "I"; // #12 + Utf8 "<init>"; // #13 + Utf8 "()V"; // #14 + Utf8 "Code"; // #15 + Utf8 "LineNumberTable"; // #16 + Utf8 "m"; // #17 + Utf8 "doInvoke"; // #18 + Utf8 "doConstruct"; // #19 + Utf8 "doGetField"; // #20 + Utf8 "doPutField"; // #21 + Utf8 "SourceFile"; // #22 + Utf8 "PackagedNestHost2.java"; // #23 + Utf8 "NestHost"; // #24 + class #40; // #25 + NameAndType #13 #14; // #26 + class #41; // #27 + NameAndType #42 #43; // #28 + Utf8 "You should never see this!"; // #29 + class #44; // #30 + NameAndType #45 #46; // #31 + NameAndType #17 #14; // #32 + class #47; // #33 + Utf8 "P1/PackagedNestHost$Member"; // #34 + Utf8 "Member"; // #35 + Utf8 "InnerClasses"; // #36 + NameAndType #11 #12; // #37 + Utf8 "P2/PackagedNestHost2$Member"; // #38 + Utf8 "java/lang/Object"; // #39 + Utf8 "P2/PackagedNestHost2"; // #40 + Utf8 "java/lang/System"; // #41 + Utf8 "out"; // #42 + Utf8 "Ljava/io/PrintStream;"; // #43 + Utf8 "java/io/PrintStream"; // #44 + Utf8 "println"; // #45 + Utf8 "(Ljava/lang/String;)V"; // #46 + Utf8 "P1/PackagedNestHost"; // #47 + } // Constant Pool + + 0x0021; // access + #9;// this_cpx + #10;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x000A; // access - modified + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0002; // access - modified + #13; // name_cpx + #14; // sig_cpx + [] { // Attributes + Attr(#15) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // LineNumberTable + 0 34; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access - modified + #17; // name_cpx + #14; // sig_cpx + [] { // Attributes + Attr(#15) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // LineNumberTable + 0 37; + 8 38; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #18; // name_cpx + #14; // sig_cpx + [] { // Attributes + Attr(#15) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80005B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // LineNumberTable + 0 45; + 3 46; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #19; // name_cpx + #14; // sig_cpx + [] { // Attributes + Attr(#15) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xBB000659B700074B; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // LineNumberTable + 0 49; + 8 50; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #20; // name_cpx + #14; // sig_cpx + [] { // Attributes + Attr(#15) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0xB200083BB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // LineNumberTable + 0 53; + 4 54; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #21; // name_cpx + #14; // sig_cpx + [] { // Attributes + Attr(#15) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0x102AB30008B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // LineNumberTable + 0 57; + 5 58; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#22) { // SourceFile + #23; + } // end SourceFile + ; + Attr(#24) { // NestHost + 0x0021; // modified - #33 + } // end NestHost + ; + Attr(#36) { // InnerClasses + [] { // InnerClasses + #6 #33 #35 9; + #9 #25 #35 9; + } + } // end InnerClasses + } // Attributes +} // end class P2/PackagedNestHost2$Member diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHostMember.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/PackagedNestHostMember.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017, 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. + */ + +// all members are declared private + +class P1/PackagedNestHost$Member { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #18; // #1 + Field #19 #20; // #2 + String #21; // #3 + Method #22 #23; // #4 + class #24; // #5 + class #27; // #6 + Utf8 "f"; // #7 + Utf8 "I"; // #8 + Utf8 "<init>"; // #9 + Utf8 "()V"; // #10 + Utf8 "Code"; // #11 + Utf8 "LineNumberTable"; // #12 + Utf8 "m"; // #13 + Utf8 "SourceFile"; // #14 + Utf8 "PackagedNestHost.java"; // #15 + Utf8 "NestHost"; // #16 + class #28; // #17 + NameAndType #9 #10; // #18 + class #29; // #19 + NameAndType #30 #31; // #20 + Utf8 "You should never see this!"; // #21 + class #32; // #22 + NameAndType #33 #34; // #23 + Utf8 "P1/PackagedNestHost$Member"; // #24 + Utf8 "Member"; // #25 + Utf8 "InnerClasses"; // #26 + Utf8 "java/lang/Object"; // #27 + Utf8 "P1/PackagedNestHost"; // #28 + Utf8 "java/lang/System"; // #29 + Utf8 "out"; // #30 + Utf8 "Ljava/io/PrintStream;"; // #31 + Utf8 "java/io/PrintStream"; // #32 + Utf8 "println"; // #33 + Utf8 "(Ljava/lang/String;)V"; // #34 + } // Constant Pool + + 0x0021; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x000A; // access - modified + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0002; // access - modified + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 34; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access - modified + #13; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 37; + 8 38; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#14) { // SourceFile + #15; + } // end SourceFile + ; + Attr(#16) { // NestHost + 0x0011; + } // end NestHost + ; + Attr(#26) { // InnerClasses + [] { // InnerClasses + #5 #17 #25 9; + } + } // end InnerClasses + } // Attributes +} // end class P1/PackagedNestHost$Member diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/TargetMissingHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/TargetMissingHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to non-existent class + +class TestNestmateMembership$TargetMissingHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #8 #22; // #1 + String #23; // #2 + Field #7 #24; // #3 + Field #25 #26; // #4 + String #27; // #5 + Method #28 #29; // #6 + class #30; // #7 + class #33; // #8 + Utf8 "msg"; // #9 + Utf8 "Ljava/lang/String;"; // #10 + Utf8 "f"; // #11 + Utf8 "I"; // #12 + Utf8 "<init>"; // #13 + Utf8 "()V"; // #14 + Utf8 "Code"; // #15 + Utf8 "LineNumberTable"; // #16 + Utf8 "m"; // #17 + Utf8 "SourceFile"; // #18 + Utf8 "TestNestmateMembership.java"; // #19 + Utf8 "NestHost"; // #20 + class #34; // #21 + NameAndType #13 #14; // #22 + Utf8 "NoTargetMissingHost"; // #23 + NameAndType #9 #10; // #24 + class #35; // #25 + NameAndType #36 #37; // #26 + Utf8 "TargetMissingHost.m() - java version"; // #27 + class #38; // #28 + NameAndType #39 #40; // #29 + Utf8 "TestNestmateMembership$TargetMissingHost"; // #30 + Utf8 "TargetMissingHost"; // #31 + Utf8 "InnerClasses"; // #32 + Utf8 "java/lang/Object"; // #33 + Utf8 "TestNestmateMembership"; // #34 + Utf8 "java/lang/System"; // #35 + Utf8 "out"; // #36 + Utf8 "Ljava/io/PrintStream;"; // #37 + Utf8 "java/io/PrintStream"; // #38 + Utf8 "println"; // #39 + Utf8 "(Ljava/lang/String;)V"; // #40 + class #23; // #41 - added + } // Constant Pool + + 0x0020; // access + #7;// this_cpx + #8;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0000; // access + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0002; // access + #13; // name_cpx + #14; // sig_cpx + [] { // Attributes + Attr(#15) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB700012A1202B5; + 0x0003B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // LineNumberTable + 0 354; + 4 353; + 10 354; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #17; // name_cpx + #14; // sig_cpx + [] { // Attributes + Attr(#15) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200041205B60006; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // LineNumberTable + 0 357; + 8 358; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#18) { // SourceFile + #19; + } // end SourceFile + ; + Attr(#20) { // NestHost + 0x0029; // modified #41 + } // end NestHost + ; + Attr(#32) { // InnerClasses + [] { // InnerClasses + #7 #21 #31 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$TargetMissingHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/TargetNoHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/TargetNoHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute deleted + +class TestNestmateMembership$TargetNoHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #18; // #1 + Field #19 #20; // #2 + String #21; // #3 + Method #22 #23; // #4 + class #24; // #5 + class #27; // #6 + Utf8 "f"; // #7 + Utf8 "I"; // #8 + Utf8 "<init>"; // #9 + Utf8 "()V"; // #10 + Utf8 "Code"; // #11 + Utf8 "LineNumberTable"; // #12 + Utf8 "m"; // #13 + Utf8 "SourceFile"; // #14 + Utf8 "TestNestmateMembership.java"; // #15 + Utf8 "NestHost"; // #16 + class #28; // #17 + NameAndType #9 #10; // #18 + class #29; // #19 + NameAndType #30 #31; // #20 + Utf8 "TargetNoHost.m() - java version"; // #21 + class #32; // #22 + NameAndType #33 #34; // #23 + Utf8 "TestNestmateMembership$TargetNoHost"; // #24 + Utf8 "TargetNoHost"; // #25 + Utf8 "InnerClasses"; // #26 + Utf8 "java/lang/Object"; // #27 + Utf8 "TestNestmateMembership"; // #28 + Utf8 "java/lang/System"; // #29 + Utf8 "out"; // #30 + Utf8 "Ljava/io/PrintStream;"; // #31 + Utf8 "java/io/PrintStream"; // #32 + Utf8 "println"; // #33 + Utf8 "(Ljava/lang/String;)V"; // #34 + } // Constant Pool + + 0x0020; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x000A; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0002; // access + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 345; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #13; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 348; + 8 349; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#14) { // SourceFile + #15; + } // end SourceFile + ; + Attr(#26) { // InnerClasses + [] { // InnerClasses + #5 #17 #25 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$TargetNoHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/TargetNotInstanceHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/TargetNotInstanceHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to non-instance class + +class TestNestmateMembership$TargetNotInstanceHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #20; // #1 + Field #21 #22; // #2 + String #23; // #3 + Method #24 #25; // #4 + class #26; // #5 + class #29; // #6 + Utf8 "oa"; // #7 + Utf8 "[LInvalidNestHost;"; // #8 - modified + Utf8 "f"; // #9 + Utf8 "I"; // #10 + Utf8 "<init>"; // #11 + Utf8 "()V"; // #12 + Utf8 "Code"; // #13 + Utf8 "LineNumberTable"; // #14 + Utf8 "m"; // #15 + Utf8 "SourceFile"; // #16 + Utf8 "TestNestmateMembership.java"; // #17 + Utf8 "NestHost"; // #18 + class #30; // #19 + NameAndType #11 #12; // #20 + class #31; // #21 + NameAndType #32 #33; // #22 + Utf8 "TargetNotInstanceHost.m() - java version"; // #23 + class #34; // #24 + NameAndType #35 #36; // #25 + Utf8 "TestNestmateMembership$TargetNotInstanceHost"; // #26 + Utf8 "TargetNotInstanceHost"; // #27 + Utf8 "InnerClasses"; // #28 + Utf8 "java/lang/Object"; // #29 + Utf8 "TestNestmateMembership"; // #30 + Utf8 "java/lang/System"; // #31 + Utf8 "out"; // #32 + Utf8 "Ljava/io/PrintStream;"; // #33 + Utf8 "java/io/PrintStream"; // #34 + Utf8 "println"; // #35 + Utf8 "(Ljava/lang/String;)V"; // #36 + class #8; // #37 added + } // Constant Pool + + 0x0020; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0000; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0002; // access + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#14) { // LineNumberTable + [] { // LineNumberTable + 0 363; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #15; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#13) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#14) { // LineNumberTable + [] { // LineNumberTable + 0 366; + 8 367; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#16) { // SourceFile + #17; + } // end SourceFile + ; + Attr(#18) { // NestHost + 0x0025; // modified - #37 + } // end NestHost + ; + Attr(#28) { // InnerClasses + [] { // InnerClasses + #5 #19 #27 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$TargetNotInstanceHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/TargetNotOurHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/TargetNotOurHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to class with no nest + +class TestNestmateMembership$TargetNotOurHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #18; // #1 + Field #19 #20; // #2 + String #21; // #3 + Method #22 #23; // #4 + class #24; // #5 + class #27; // #6 + Utf8 "f"; // #7 + Utf8 "I"; // #8 + Utf8 "<init>"; // #9 + Utf8 "()V"; // #10 + Utf8 "Code"; // #11 + Utf8 "LineNumberTable"; // #12 + Utf8 "m"; // #13 + Utf8 "SourceFile"; // #14 + Utf8 "TestNestmateMembership.java"; // #15 + Utf8 "NestHost"; // #16 + class #28; // #17 + NameAndType #9 #10; // #18 + class #29; // #19 + NameAndType #30 #31; // #20 + Utf8 "TargetNotOurHost.m() - java version"; // #21 + class #32; // #22 + NameAndType #33 #34; // #23 + Utf8 "TestNestmateMembership$TargetNotOurHost"; // #24 + Utf8 "TargetNotOurHost"; // #25 + Utf8 "InnerClasses"; // #26 + Utf8 "java/lang/Object"; // #27 + Utf8 "TestNestmateMembership"; // #28 + Utf8 "java/lang/System"; // #29 + Utf8 "out"; // #30 + Utf8 "Ljava/io/PrintStream;"; // #31 + Utf8 "java/io/PrintStream"; // #32 + Utf8 "println"; // #33 + Utf8 "(Ljava/lang/String;)V"; // #34 + // Added + Utf8 "InvalidNestHost"; // #35 + class #35; // #36 + } // Constant Pool + + 0x0020; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x000A; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0002; // access + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 371; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #13; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 374; + 8 375; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#14) { // SourceFile + #15; + } // end SourceFile + ; + Attr(#16) { // NestHost + 0x0024; // modified - #36 + } // end NestHost + ; + Attr(#26) { // InnerClasses + [] { // InnerClasses + #5 #17 #25 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$TargetNotOurHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/TargetSelfHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/TargetSelfHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,154 @@ +/* + * 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. + */ + +// NestHost attribute refers to current class + +class TestNestmateMembership$TargetSelfHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #18; // #1 + Field #19 #20; // #2 + String #21; // #3 + Method #22 #23; // #4 + class #24; // #5 + class #27; // #6 + Utf8 "f"; // #7 + Utf8 "I"; // #8 + Utf8 "<init>"; // #9 + Utf8 "()V"; // #10 + Utf8 "Code"; // #11 + Utf8 "LineNumberTable"; // #12 + Utf8 "m"; // #13 + Utf8 "SourceFile"; // #14 + Utf8 "TestNestmateMembership.java"; // #15 + Utf8 "NestHost"; // #16 + class #28; // #17 + NameAndType #9 #10; // #18 + class #29; // #19 + NameAndType #30 #31; // #20 + Utf8 "TargetSelfHost.m() - java version"; // #21 + class #32; // #22 + NameAndType #33 #34; // #23 + Utf8 "TestNestmateMembership$TargetSelfHost"; // #24 + Utf8 "TargetSelfHost"; // #25 + Utf8 "InnerClasses"; // #26 + Utf8 "java/lang/Object"; // #27 + Utf8 "TestNestmateMembership"; // #28 + Utf8 "java/lang/System"; // #29 + Utf8 "out"; // #30 + Utf8 "Ljava/io/PrintStream;"; // #31 + Utf8 "java/io/PrintStream"; // #32 + Utf8 "println"; // #33 + Utf8 "(Ljava/lang/String;)V"; // #34 + // Added + class #24; // #35 + } // Constant Pool + + 0x0020; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x000A; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0002; // access + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 371; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access + #13; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 374; + 8 375; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#14) { // SourceFile + #15; + } // end SourceFile + ; + Attr(#16) { // NestHost + 0x0023; // modified - #35 + } // end NestHost + ; + Attr(#26) { // InnerClasses + [] { // InnerClasses + #5 #17 #25 8; + } + } // end InnerClasses + } // Attributes +} // end class TestNestmateMembership$TargetSelfHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/membership/TestNestmateMembership.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/membership/TestNestmateMembership.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,1776 @@ +/* + * Copyright (c) 2017, 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 + * @bug 8046171 + * @summary Test the various rules for nest members and nest-hosts by + * triggering nestmate access checks on all possible paths + * @compile TestNestmateMembership.java + * PackagedNestHost.java + * PackagedNestHost2.java + * InvalidNestHost.java + * + * @compile TargetNoHost.jcod + * CallerNoHost.jcod + * TargetSelfHost.jcod + * CallerSelfHost.jcod + * TargetMissingHost.jcod + * CallerMissingHost.jcod + * TargetNotInstanceHost.jcod + * CallerNotInstanceHost.jcod + * TargetNotOurHost.jcod + * CallerNotOurHost.jcod + * PackagedNestHost.jcod + * PackagedNestHost2Member.jcod + * PackagedNestHostMember.jcod + * + * @run main/othervm TestNestmateMembership method + * @run main/othervm TestNestmateMembership constructor + * @run main/othervm TestNestmateMembership getField + * @run main/othervm TestNestmateMembership putField + * @run main/othervm -Xcomp TestNestmateMembership getField + */ + +// We test all the "illegal" relationships between a nest member and its nest-host +// except for the case where the name of the nest-member matches the name listed +// in the nest-host, but resolves to a different class. There doesn't seem to +// be a way to construct that scenario. +// For each nested class below there is a corresponding .jcod file which breaks one +// of the rules regarding nest membership. For the package related tests we have +// additional PackageNestHost*.java sources.[1] +// +// Note that all the .java files must be compiled in the same step, while all +// .jcod files must be compiled in a later step. + +// We test all the different nestmate access check paths: method invocation, constructor +// invocations, field get and field put. The test is invoked four times with each using +// a different test mode. Plus an extra Xcomp run for field access to hit ciField path. +// +// As access checking requires resolution and validation of the nest-host of +// both the caller class and the target class, we must check that all +// combinations of good/bad caller/target are checked for each of the +// possible errors: +// - no nest-host attribute +// - nest-host refers to self +// - nest-host class can not be found +// - nest-host class is not an instance class (but is in same package) +// - class is not a member of nest-host's nest (but is in same package) +// - class and nest-host are in different packages +// +// To provide coverage for reflection and MethodHandle paths through +// JVM_AreNestmates, we add reflection/MH accesses to a subset of the tests. +// We only need to test one case (for Caller.xxx) as all cases use the same path; further +// we don't need to test all failure cases, as all exceptions are equivalent in that regard, +// but for good measure we test the four basic error situations (eliding the different +// package test for simplicity). +// +// [1] In earlier versions the package-test was the final check done in nest membership +// validation, so we needed actual test classes in different packages that claimed +// membership. The final spec requires the package test to be done first, so it can +// be trivially tested by using Object as the nest-host. But we leave the explicit +// package tests as they are, and adjust the other tests so that a "bad host" is +// always in the same package. + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +public class TestNestmateMembership { + + static final MethodType VOID_T = MethodType.methodType(void.class); + + static class Caller { + + private Caller() {} + + private static void m() { + System.out.println("Caller.m()"); + } + + // direct static method invocations + + public static void invokeTarget() { + Target.m(); + } + public static void invokeTargetNoHost() { + TargetNoHost.m(); + } + public static void invokeTargetSelfHost() { + TargetSelfHost.m(); + } + public static void invokeTargetMissingHost() { + TargetMissingHost.m(); + } + public static void invokeTargetNotInstanceHost() { + TargetNotInstanceHost.m(); + } + public static void invokeTargetNotOurHost() { + TargetNotOurHost.m(); + } + + // reflective static method invocations + + public static void invokeTargetNoHostReflectively() throws Throwable { + TargetNoHost.class.getDeclaredMethod("m", new Class<?>[0]).invoke(null, new Object[0]); + } + public static void invokeTargetSelfHostReflectively() throws Throwable { + TargetSelfHost.class.getDeclaredMethod("m", new Class<?>[0]).invoke(null, new Object[0]); + } + public static void invokeTargetMissingHostReflectively() throws Throwable { + TargetMissingHost.class.getDeclaredMethod("m", new Class<?>[0]).invoke(null, new Object[0]); + } + public static void invokeTargetNotInstanceHostReflectively() throws Throwable { + TargetNotInstanceHost.class.getDeclaredMethod("m", new Class<?>[0]).invoke(null, new Object[0]); + } + public static void invokeTargetNotOurHostReflectively() throws Throwable { + TargetNotOurHost.class.getDeclaredMethod("m", new Class<?>[0]).invoke(null, new Object[0]); + } + + // MethodHandle static method lookup (no invoke as the lookup should fail) + + public static void invokeTargetNoHostMH() throws Throwable { + MethodHandle mh = lookup().findStatic(TargetNoHost.class, "m", VOID_T); + } + public static void invokeTargetSelfHostMH() throws Throwable { + MethodHandle mh = lookup().findStatic(TargetSelfHost.class, "m", VOID_T); + } + public static void invokeTargetMissingHostMH() throws Throwable { + MethodHandle mh = lookup().findStatic(TargetMissingHost.class, "m", VOID_T); + } + public static void invokeTargetNotInstanceHostMH() throws Throwable { + MethodHandle mh = lookup().findStatic(TargetNotInstanceHost.class, "m", VOID_T); + } + public static void invokeTargetNotOurHostMH() throws Throwable { + MethodHandle mh = lookup().findStatic(TargetNotOurHost.class, "m", VOID_T); + } + + + // direct constructor invocations + + public static void newTarget() { + Object o = new Target(); + } + public static void newTargetNoHost() { + Object o = new TargetNoHost(); + } + public static void newTargetSelfHost() { + Object o = new TargetSelfHost(); + } + public static void newTargetMissingHost() { + Object o = new TargetMissingHost(); + } + public static void newTargetNotInstanceHost() { + Object o = new TargetNotInstanceHost(); + } + public static void newTargetNotOurHost() { + Object o = new TargetNotOurHost(); + } + + // reflective constructor invocations + + public static void newTargetNoHostReflectively() throws Throwable { + Object o = TargetNoHost.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + public static void newTargetSelfHostReflectively() throws Throwable { + Object o = TargetSelfHost.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + public static void newTargetMissingHostReflectively() throws Throwable { + Object o = TargetMissingHost.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + public static void newTargetNotInstanceHostReflectively() throws Throwable { + Object o = TargetNotInstanceHost.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + public static void newTargetNotOurHostReflectively() throws Throwable { + Object o = TargetNotOurHost.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + + // MethodHandle constructor lookup (no invoke as the lookup should fail) + + public static void newTargetNoHostMH() throws Throwable { + MethodHandle mh = lookup().findConstructor(TargetNoHost.class, VOID_T); + } + public static void newTargetSelfHostMH() throws Throwable { + MethodHandle mh = lookup().findConstructor(TargetSelfHost.class, VOID_T); + } + public static void newTargetMissingHostMH() throws Throwable { + MethodHandle mh = lookup().findConstructor(TargetMissingHost.class, VOID_T); + } + public static void newTargetNotInstanceHostMH() throws Throwable { + MethodHandle mh = lookup().findConstructor(TargetNotInstanceHost.class, VOID_T); + } + public static void newTargetNotOurHostMH() throws Throwable { + MethodHandle mh = lookup().findConstructor(TargetNotOurHost.class, VOID_T); + } + + private static int f; + + // direct field accesses + + public static void getFieldTarget() { + int x = Target.f; + } + public static void getFieldTargetNoHost() { + int x = TargetNoHost.f; + } + public static void getFieldTargetSelfHost() { + int x = TargetSelfHost.f; + } + public static void getFieldTargetMissingHost() { + int x = TargetMissingHost.f; + } + public static void getFieldTargetNotInstanceHost() { + int x = TargetNotInstanceHost.f; + } + public static void getFieldTargetNotOurHost() { + int x = TargetNotOurHost.f; + } + + public static void putFieldTarget() { + Target.f = 42; + } + public static void putFieldTargetNoHost() { + TargetNoHost.f = 42; + } + public static void putFieldTargetSelfHost() { + TargetSelfHost.f = 42; + } + public static void putFieldTargetMissingHost() { + TargetMissingHost.f = 42; + } + public static void putFieldTargetNotInstanceHost() { + TargetNotInstanceHost.f = 42; + } + public static void putFieldTargetNotOurHost() { + TargetNotOurHost.f = 42; + } + + // reflective field accesses + + public static void getFieldTargetNoHostReflectively() throws Throwable { + int x = TargetNoHost.class.getDeclaredField("f").getInt(null); + } + public static void getFieldTargetSelfHostReflectively() throws Throwable { + int x = TargetSelfHost.class.getDeclaredField("f").getInt(null); + } + public static void getFieldTargetMissingHostReflectively() throws Throwable { + int x = TargetMissingHost.class.getDeclaredField("f").getInt(null); + } + public static void getFieldTargetNotInstanceHostReflectively() throws Throwable { + int x = TargetNotInstanceHost.class.getDeclaredField("f").getInt(null); + } + public static void getFieldTargetNotOurHostReflectively() throws Throwable { + int x = TargetNotOurHost.class.getDeclaredField("f").getInt(null); + } + + public static void putFieldTargetNoHostReflectively() throws Throwable { + TargetNoHost.class.getDeclaredField("f").setInt(null, 42); + } + public static void putFieldTargetSelfHostReflectively() throws Throwable { + TargetSelfHost.class.getDeclaredField("f").setInt(null, 42); + } + public static void putFieldTargetMissingHostReflectively() throws Throwable { + TargetMissingHost.class.getDeclaredField("f").setInt(null, 42); + } + public static void putFieldTargetNotInstanceHostReflectively() throws Throwable { + TargetNotInstanceHost.class.getDeclaredField("f").setInt(null, 42); + } + public static void putFieldTargetNotOurHostReflectively() throws Throwable { + TargetNotOurHost.class.getDeclaredField("f").setInt(null, 42); + } + + // MethodHandle field lookup (no access as the lookup will fail) + + public static void getFieldTargetNoHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticGetter(TargetNoHost.class, "f", int.class); + } + public static void getFieldTargetSelfHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticGetter(TargetSelfHost.class, "f", int.class); + } + public static void getFieldTargetMissingHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticGetter(TargetMissingHost.class, "f", int.class); + } + public static void getFieldTargetNotInstanceHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticGetter(TargetNotInstanceHost.class, "f", int.class); + } + public static void getFieldTargetNotOurHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticGetter(TargetNotOurHost.class, "f", int.class); + } + + public static void putFieldTargetNoHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticSetter(TargetNoHost.class, "f", int.class); + } + public static void putFieldTargetSelfHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticSetter(TargetSelfHost.class, "f", int.class); + } + public static void putFieldTargetMissingHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticSetter(TargetMissingHost.class, "f", int.class); + } + public static void putFieldTargetNotInstanceHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticSetter(TargetNotInstanceHost.class, "f", int.class); + } + public static void putFieldTargetNotOurHostMH() throws Throwable { + MethodHandle mh = lookup().findStaticSetter(TargetNotOurHost.class, "f", int.class); + } + + } + + static class CallerNoHost { + + // method invocations + + private static void m() { + System.out.println("CallerNoHost.m() - java version"); + } + public static void invokeTarget() { + Target.m(); + } + public static void invokeTargetNoHost() { + TargetNoHost.m(); + } + + // constructor invocations + + private CallerNoHost() {} + + public static void newTarget() { + Object o = new Target(); + } + public static void newTargetNoHost() { + Object o = new TargetNoHost(); + } + + // field accesses + + private static int f; + + public static void getFieldTarget() { + int x = Target.f; + } + public static void getFieldTargetNoHost() { + int x = TargetNoHost.f; + } + + public static void putFieldTarget() { + Target.f = 42; + } + public static void putFieldTargetNoHost() { + TargetNoHost.f = 42; + } + + } + + static class CallerSelfHost { + + // method invocations + + private static void m() { + System.out.println("CallerSelfHost.m() - java version"); + } + public static void invokeTarget() { + Target.m(); + } + public static void invokeTargetSelfHost() { + TargetSelfHost.m(); + } + + // constructor invocations + + private CallerSelfHost() {} + + public static void newTarget() { + Object o = new Target(); + } + public static void newTargetSelfHost() { + Object o = new TargetSelfHost(); + } + + // field accesses + + private static int f; + + public static void getFieldTarget() { + int x = Target.f; + } + public static void getFieldTargetSelfHost() { + int x = TargetSelfHost.f; + } + + public static void putFieldTarget() { + Target.f = 42; + } + public static void putFieldTargetSelfHost() { + TargetSelfHost.f = 42; + } + + } + + static class CallerMissingHost { + String msg = "NoCallerMissingHost"; // for cp entry + + // method invocations + + private static void m() { + System.out.println("CallerMissingHost.m() - java version"); + } + public static void invokeTarget() { + Target.m(); + } + public static void invokeTargetMissingHost() { + TargetMissingHost.m(); + } + + // constructor invocations + + private CallerMissingHost() {} + + public static void newTarget() { + Object o = new Target(); + } + public static void newTargetMissingHost() { + Object o = new TargetMissingHost(); + } + + // field accesses + + private static int f; + + public static void getFieldTarget() { + int x = Target.f; + } + public static void getFieldTargetMissingHost() { + int x = TargetMissingHost.f; + } + public static void putFieldTarget() { + Target.f = 42; + } + public static void putFieldTargetMissingHost() { + TargetMissingHost.f = 42; + } + + } + + static class CallerNotInstanceHost { + Object[] oa; // create CP entry to use in jcod change + + // method invocations + + private static void m() { + System.out.println("CallerNotInstanceHost.m() - java version"); + } + public static void invokeTarget() { + Target.m(); + } + public static void invokeTargetNotInstanceHost() { + TargetNotInstanceHost.m(); + } + + // constructor invocations + + private CallerNotInstanceHost() {} + + public static void newTarget() { + Object o = new Target(); + } + public static void newTargetNotInstanceHost() { + Object o = new TargetNotInstanceHost(); + } + + // field accesses + + private static int f; + + public static void getFieldTarget() { + int x = Target.f; + } + public static void getFieldTargetNotInstanceHost() { + int x = TargetNotInstanceHost.f; + } + public static void putFieldTarget() { + Target.f = 42; + } + public static void putFieldTargetNotInstanceHost() { + TargetNotInstanceHost.f = 42; + } + } + + static class CallerNotOurHost { + + // method invocations + + private static void m() { + System.out.println("CallerNotOurHost.m() - java version"); + } + public static void invokeTarget() { + Target.m(); + } + public static void invokeTargetNotOurHost() { + TargetNotOurHost.m(); + } + + // constructor invocations + + private CallerNotOurHost() {} + + public static void newTarget() { + Object o = new Target(); + } + public static void newTargetNotOurHost() { + Object o = new TargetNotOurHost(); + } + + // field accesses + + private static int f; + + public static void getFieldTarget() { + int x = Target.f; + } + public static void getFieldTargetNotOurHost() { + int x = TargetNotOurHost.f; + } + public static void putFieldTarget() { + Target.f = 42; + } + public static void putFieldTargetNotOurHost() { + TargetNotOurHost.f = 42; + } + + } + + static class Target { + private Target() {} + private static int f; + private static void m() { + System.out.println("Target.m()"); + } + } + + static class TargetNoHost { + private TargetNoHost() {} + private static int f; + private static void m() { + System.out.println("TargetNoHost.m() - java version"); + } + } + + static class TargetSelfHost { + private TargetSelfHost() {} + private static int f; + private static void m() { + System.out.println("TargetSelfHost.m() - java version"); + } + } + + static class TargetMissingHost { + String msg = "NoTargetMissingHost"; // for cp entry + private TargetMissingHost() {} + private static int f; + private static void m() { + System.out.println("TargetMissingHost.m() - java version"); + } + } + + static class TargetNotInstanceHost { + Object[] oa; // create CP entry to use in jcod change + private TargetNotInstanceHost() {} + private static int f; + private static void m() { + System.out.println("TargetNotInstanceHost.m() - java version"); + } + } + + static class TargetNotOurHost { + private TargetNotOurHost() {} + private static int f; + private static void m() { + System.out.println("TargetNotOurHost.m() - java version"); + } + } + + public static void main(String[] args) throws Throwable { + if (args.length < 1) { + throw new Error("Test mode argument must be one of: method, constructor, getField or putField"); + } + switch(args[0]) { + case "method": + System.out.println("TESTING METHOD INVOCATIONS:"); + test_GoodInvoke(); + test_NoHostInvoke(); + test_SelfHostInvoke(); + test_MissingHostInvoke(); + test_NotInstanceHostInvoke(); + test_NotOurHostInvoke(); + test_WrongPackageHostInvoke(); + break; + case "constructor": + System.out.println("TESTING CONSTRUCTOR INVOCATIONS:"); + test_GoodConstruct(); + test_NoHostConstruct(); + test_SelfHostConstruct(); + test_MissingHostConstruct(); + test_NotInstanceHostConstruct(); + test_NotOurHostConstruct(); + test_WrongPackageHostConstruct(); + break; + case "getField": + System.out.println("TESTING GETFIELD INVOCATIONS:"); + test_GoodGetField(); + test_NoHostGetField(); + test_SelfHostGetField(); + test_MissingHostGetField(); + test_NotInstanceHostGetField(); + test_NotOurHostGetField(); + test_WrongPackageHostGetField(); + break; + case "putField": + System.out.println("TESTING PUTFIELD INVOCATIONS:"); + test_GoodPutField(); + test_NoHostPutField(); + test_SelfHostPutField(); + test_MissingHostPutField(); + test_NotInstanceHostPutField(); + test_NotOurHostPutField(); + test_WrongPackageHostPutField(); + break; + default: + throw new Error("Uknown mode: " + args[0] + + ". Must be one of: method, constructor, getField or putField"); + } + } + + static void test_GoodInvoke(){ + try { + Caller.invokeTarget(); + } + catch (Exception e) { + throw new Error("Unexpected exception on good invocation " + e); + } + } + + static void test_NoHostInvoke() throws Throwable { + System.out.println("Testing for missing nest-host attribute"); + String msg = "tried to access method " + + "TestNestmateMembership$TargetNoHost.m()V from class " + + "TestNestmateMembership$Caller"; + try { + Caller.invokeTargetNoHost(); + throw new Error("Missing IllegalAccessError: " + msg); + } + catch (IllegalAccessError expected) { + check_expected(expected, msg); + } + msg = "TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNoHost with modifiers \"private static\""; + try { + Caller.invokeTargetNoHostReflectively(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + msg = "no such method: TestNestmateMembership$TargetNoHost.m()void/invokeStatic"; + try { + Caller.invokeTargetNoHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "tried to access method TestNestmateMembership$Target.m()V" + + " from class TestNestmateMembership$CallerNoHost"; + try { + CallerNoHost.invokeTarget(); + throw new Error("Missing IllegalAccessError: " + msg); + } + catch (IllegalAccessError expected) { + check_expected(expected, msg); + } + msg = "tried to access method TestNestmateMembership$TargetNoHost.m()V" + + " from class TestNestmateMembership$CallerNoHost"; + try { + CallerNoHost.invokeTargetNoHost(); + throw new Error("Missing IllegalAccessError: " + msg); + } + catch (IllegalAccessError expected) { + check_expected(expected, msg); + } + } + + static void test_SelfHostInvoke() throws Throwable { + System.out.println("Testing for class that lists itself as nest-host"); + String msg = "Type TestNestmateMembership$TargetSelfHost is not a nest member" + + " of TestNestmateMembership$TargetSelfHost: current type is not listed as a nest member"; + try { + Caller.invokeTargetSelfHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.invokeTargetSelfHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "no such method: TestNestmateMembership$TargetSelfHost.m()void/invokeStatic"; + try { + Caller.invokeTargetSelfHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerSelfHost is not a nest member" + + " of TestNestmateMembership$CallerSelfHost: current type is not listed as a nest member"; + try { + CallerSelfHost.invokeTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerSelfHost is not a nest member" + + " of TestNestmateMembership$CallerSelfHost: current type is not listed as a nest member"; + try { + CallerSelfHost.invokeTargetSelfHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_MissingHostInvoke() throws Throwable { + System.out.println("Testing for nest-host class that does not exist"); + String msg = "Unable to load nest-host class (NoTargetMissingHost) of " + + "TestNestmateMembership$TargetMissingHost"; + String cause_msg = "NoTargetMissingHost"; + try { + Caller.invokeTargetMissingHost(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + try { + Caller.invokeTargetMissingHostReflectively(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + msg = "no such method: TestNestmateMembership$TargetMissingHost.m()void/invokeStatic"; + try { + Caller.invokeTargetMissingHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + msg = "no such method: TestNestmateMembership$TargetMissingHost.m()void/invokeStatic"; + try { + Caller.invokeTargetMissingHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "Unable to load nest-host class (NoCallerMissingHost) of " + + "TestNestmateMembership$CallerMissingHost"; + cause_msg = "NoCallerMissingHost"; + try { + CallerMissingHost.invokeTarget(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + msg = "Unable to load nest-host class (NoCallerMissingHost) of "+ + "TestNestmateMembership$CallerMissingHost"; + cause_msg = "NoCallerMissingHost"; + try { + CallerMissingHost.invokeTargetMissingHost(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + } + + static void test_NotInstanceHostInvoke() throws Throwable { + System.out.println("Testing for nest-host class that is not an instance class"); + String msg = "Type TestNestmateMembership$TargetNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + Caller.invokeTargetNotInstanceHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.invokeTargetNotInstanceHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "no such method: TestNestmateMembership$TargetNotInstanceHost.m()void/invokeStatic"; + try { + Caller.invokeTargetNotInstanceHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + CallerNotInstanceHost.invokeTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + CallerNotInstanceHost.invokeTargetNotInstanceHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_NotOurHostInvoke() throws Throwable { + System.out.println("Testing for nest-host class that does not list us in its nest"); + String msg = "Type TestNestmateMembership$TargetNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + Caller.invokeTargetNotOurHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.invokeTargetNotOurHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "no such method: TestNestmateMembership$TargetNotOurHost.m()void/invokeStatic"; + try { + Caller.invokeTargetNotOurHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + CallerNotOurHost.invokeTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + CallerNotOurHost.invokeTargetNotOurHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_WrongPackageHostInvoke() { + System.out.println("Testing for nest-host and nest-member in different packages"); + String msg = "Type P2.PackagedNestHost2$Member is not a nest member of " + + "P1.PackagedNestHost: types are in different packages"; + try { + P1.PackagedNestHost.doInvoke(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + P2.PackagedNestHost2.Member.doInvoke(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + // constructor tests + + static void test_GoodConstruct(){ + try { + Caller.newTarget(); + } + catch (Exception e) { + throw new Error("Unexpected exception on good construction: " + e); + } + } + + static void test_NoHostConstruct() throws Throwable { + System.out.println("Testing for missing nest-host attribute"); + String msg = "tried to access method TestNestmateMembership$TargetNoHost.<init>()V" + + " from class TestNestmateMembership$Caller"; + try { + Caller.newTargetNoHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNoHost with modifiers \"private\""; + try { + Caller.newTargetNoHostReflectively(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + msg = "no such constructor: TestNestmateMembership$TargetNoHost.<init>()void/newInvokeSpecial"; + try { + Caller.newTargetNoHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "tried to access method TestNestmateMembership$Target.<init>()V" + + " from class TestNestmateMembership$CallerNoHost"; + try { + CallerNoHost.newTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "tried to access method TestNestmateMembership$TargetNoHost.<init>()V" + + " from class TestNestmateMembership$CallerNoHost"; + try { + CallerNoHost.newTargetNoHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_SelfHostConstruct() throws Throwable { + System.out.println("Testing for class that lists itself as nest-host"); + String msg = "Type TestNestmateMembership$TargetSelfHost is not a nest member" + + " of TestNestmateMembership$TargetSelfHost: current type is not listed as a nest member"; + try { + Caller.newTargetSelfHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.newTargetSelfHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "no such constructor: TestNestmateMembership$TargetSelfHost.<init>()void/newInvokeSpecial"; + try { + Caller.newTargetSelfHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerSelfHost is not a nest member" + + " of TestNestmateMembership$CallerSelfHost: current type is not listed as a nest member"; + try { + CallerSelfHost.newTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerSelfHost is not a nest member" + + " of TestNestmateMembership$CallerSelfHost: current type is not listed as a nest member"; + try { + CallerSelfHost.newTargetSelfHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_MissingHostConstruct() throws Throwable { + System.out.println("Testing for nest-host class that does not exist"); + String msg = "Unable to load nest-host class (NoTargetMissingHost) of " + + "TestNestmateMembership$TargetMissingHost"; + String cause_msg = "NoTargetMissingHost"; + try { + Caller.newTargetMissingHost(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + try { + Caller.newTargetMissingHostReflectively(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + msg = "no such constructor: TestNestmateMembership$TargetMissingHost.<init>()void/newInvokeSpecial"; + try { + Caller.newTargetMissingHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "Unable to load nest-host class (NoCallerMissingHost) of " + + "TestNestmateMembership$CallerMissingHost"; + cause_msg = "NoCallerMissingHost"; + try { + CallerMissingHost.newTarget(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + msg = "Unable to load nest-host class (NoCallerMissingHost) of "+ + "TestNestmateMembership$CallerMissingHost"; + cause_msg = "NoCallerMissingHost"; + try { + CallerMissingHost.newTargetMissingHost(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + } + + static void test_NotInstanceHostConstruct() throws Throwable { + System.out.println("Testing for nest-host class that is not an instance class"); + String msg = "Type TestNestmateMembership$TargetNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + Caller.newTargetNotInstanceHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.newTargetNotInstanceHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "no such constructor: TestNestmateMembership$TargetNotInstanceHost.<init>()void/newInvokeSpecial"; + try { + Caller.newTargetNotInstanceHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + CallerNotInstanceHost.newTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + CallerNotInstanceHost.newTargetNotInstanceHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_NotOurHostConstruct() throws Throwable { + System.out.println("Testing for nest-host class that does not list us in its nest"); + String msg = "Type TestNestmateMembership$TargetNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + Caller.newTargetNotOurHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.newTargetNotOurHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "no such constructor: TestNestmateMembership$TargetNotOurHost.<init>()void/newInvokeSpecial"; + try { + Caller.newTargetNotOurHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + CallerNotOurHost.newTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + CallerNotOurHost.newTargetNotOurHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_WrongPackageHostConstruct() { + System.out.println("Testing for nest-host and nest-member in different packages"); + String msg = "Type P2.PackagedNestHost2$Member is not a nest member of " + + "P1.PackagedNestHost: types are in different packages"; + try { + P1.PackagedNestHost.doConstruct(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + P2.PackagedNestHost2.Member.doConstruct(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + // field tests + + static void test_GoodGetField(){ + try { + Caller.getFieldTarget(); + } + catch (Exception e) { + throw new Error("Unexpected exception on good field access: " + e); + } + } + + static void test_NoHostGetField() throws Throwable { + System.out.println("Testing for missing nest-host attribute"); + String msg = "tried to access field TestNestmateMembership$TargetNoHost.f" + + " from class TestNestmateMembership$Caller"; + try { + Caller.getFieldTargetNoHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNoHost with modifiers \"private static\""; + try { + Caller.getFieldTargetNoHostReflectively(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + msg = "member is private: TestNestmateMembership$TargetNoHost.f/int/getStatic"; + try { + Caller.getFieldTargetNoHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "tried to access field TestNestmateMembership$Target.f" + + " from class TestNestmateMembership$CallerNoHost"; + try { + CallerNoHost.getFieldTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "tried to access field TestNestmateMembership$TargetNoHost.f" + + " from class TestNestmateMembership$CallerNoHost"; + try { + CallerNoHost.getFieldTargetNoHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_SelfHostGetField() throws Throwable { + System.out.println("Testing for class that lists itself as nest-host"); + String msg = "Type TestNestmateMembership$TargetSelfHost is not a nest member" + + " of TestNestmateMembership$TargetSelfHost: current type is not listed as a nest member"; + try { + Caller.getFieldTargetSelfHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.getFieldTargetSelfHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.getFieldTargetSelfHostMH(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerSelfHost is not a nest member" + + " of TestNestmateMembership$CallerSelfHost: current type is not listed as a nest member"; + try { + CallerSelfHost.getFieldTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerSelfHost is not a nest member" + + " of TestNestmateMembership$CallerSelfHost: current type is not listed as a nest member"; + try { + CallerSelfHost.getFieldTargetSelfHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_MissingHostGetField() throws Throwable { + System.out.println("Testing for nest-host class that does not exist"); + String msg = "Unable to load nest-host class (NoTargetMissingHost) of " + + "TestNestmateMembership$TargetMissingHost"; + String cause_msg = "NoTargetMissingHost"; + try { + Caller.getFieldTargetMissingHost(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + try { + Caller.getFieldTargetMissingHostReflectively(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + try { + Caller.getFieldTargetMissingHostMH(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + + msg = "Unable to load nest-host class (NoCallerMissingHost) of " + + "TestNestmateMembership$CallerMissingHost"; + cause_msg = "NoCallerMissingHost"; + try { + CallerMissingHost.getFieldTarget(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + msg = "Unable to load nest-host class (NoCallerMissingHost) of "+ + "TestNestmateMembership$CallerMissingHost"; + cause_msg = "NoCallerMissingHost"; + try { + CallerMissingHost.getFieldTargetMissingHost(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + } + + static void test_NotInstanceHostGetField() throws Throwable { + System.out.println("Testing for nest-host class that is not an instance class"); + String msg = "Type TestNestmateMembership$TargetNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + Caller.getFieldTargetNotInstanceHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.getFieldTargetNotInstanceHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.getFieldTargetNotInstanceHostMH(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + CallerNotInstanceHost.getFieldTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + CallerNotInstanceHost.getFieldTargetNotInstanceHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_NotOurHostGetField() throws Throwable { + System.out.println("Testing for nest-host class that does not list us in its nest"); + String msg = "Type TestNestmateMembership$TargetNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + Caller.getFieldTargetNotOurHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.getFieldTargetNotOurHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.getFieldTargetNotOurHostMH(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + CallerNotOurHost.getFieldTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + CallerNotOurHost.getFieldTargetNotOurHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_WrongPackageHostGetField() { + System.out.println("Testing for nest-host and nest-member in different packages"); + String msg = "Type P2.PackagedNestHost2$Member is not a nest member of " + + "P1.PackagedNestHost: types are in different packages"; + try { + P1.PackagedNestHost.doGetField(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + P2.PackagedNestHost2.Member.doGetField(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_GoodPutField(){ + try { + Caller.putFieldTarget(); + } + catch (Exception e) { + throw new Error("Unexpected exception on good field access: " + e); + } + } + + static void test_NoHostPutField() throws Throwable { + System.out.println("Testing for missing nest-host attribute"); + String msg = "tried to access field TestNestmateMembership$TargetNoHost.f" + + " from class TestNestmateMembership$Caller"; + try { + Caller.putFieldTargetNoHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNoHost with modifiers \"private static\""; + try { + Caller.putFieldTargetNoHostReflectively(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + msg = "member is private: TestNestmateMembership$TargetNoHost.f/int/putStatic"; + try { + Caller.putFieldTargetNoHostMH(); + throw new Error("Missing IllegalAccessException: " + msg); + } + catch (IllegalAccessException expected) { + check_expected(expected, msg); + } + + msg = "tried to access field TestNestmateMembership$Target.f" + + " from class TestNestmateMembership$CallerNoHost"; + try { + CallerNoHost.putFieldTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "tried to access field TestNestmateMembership$TargetNoHost.f" + + " from class TestNestmateMembership$CallerNoHost"; + try { + CallerNoHost.putFieldTargetNoHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_SelfHostPutField() throws Throwable { + System.out.println("Testing for class that lists itself as nest-host"); + String msg = "Type TestNestmateMembership$TargetSelfHost is not a nest member" + + " of TestNestmateMembership$TargetSelfHost: current type is not listed as a nest member"; + try { + Caller.putFieldTargetSelfHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.putFieldTargetSelfHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.putFieldTargetSelfHostMH(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerSelfHost is not a nest member" + + " of TestNestmateMembership$CallerSelfHost: current type is not listed as a nest member"; + try { + CallerSelfHost.putFieldTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerSelfHost is not a nest member" + + " of TestNestmateMembership$CallerSelfHost: current type is not listed as a nest member"; + try { + CallerSelfHost.putFieldTargetSelfHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_MissingHostPutField() throws Throwable { + System.out.println("Testing for nest-host class that does not exist"); + String msg = "Unable to load nest-host class (NoTargetMissingHost) of " + + "TestNestmateMembership$TargetMissingHost"; + String cause_msg = "NoTargetMissingHost"; + try { + Caller.putFieldTargetMissingHost(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + try { + Caller.putFieldTargetMissingHostReflectively(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + try { + Caller.putFieldTargetMissingHostMH(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + + msg = "Unable to load nest-host class (NoCallerMissingHost) of " + + "TestNestmateMembership$CallerMissingHost"; + cause_msg = "NoCallerMissingHost"; + try { + CallerMissingHost.putFieldTarget(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + msg = "Unable to load nest-host class (NoCallerMissingHost) of "+ + "TestNestmateMembership$CallerMissingHost"; + cause_msg = "NoCallerMissingHost"; + try { + CallerMissingHost.putFieldTargetMissingHost(); + throw new Error("Missing NoClassDefFoundError: " + msg); + } + catch (NoClassDefFoundError expected) { + check_expected(expected, msg, cause_msg); + } + } + + static void test_NotInstanceHostPutField() throws Throwable { + System.out.println("Testing for nest-host class that is not an instance class"); + String msg = "Type TestNestmateMembership$TargetNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + Caller.putFieldTargetNotInstanceHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.putFieldTargetNotInstanceHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.putFieldTargetNotInstanceHostMH(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + CallerNotInstanceHost.putFieldTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ + "nest member of [LInvalidNestHost;: current type is not listed as a nest member"; + try { + CallerNotInstanceHost.putFieldTargetNotInstanceHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_NotOurHostPutField() throws Throwable { + System.out.println("Testing for nest-host class that does not list us in its nest"); + String msg = "Type TestNestmateMembership$TargetNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + Caller.putFieldTargetNotOurHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.putFieldTargetNotOurHostReflectively(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + Caller.putFieldTargetNotOurHostMH(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + + msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + CallerNotOurHost.putFieldTarget(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + + " of InvalidNestHost: current type is not listed as a nest member"; + try { + CallerNotOurHost.putFieldTargetNotOurHost(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + static void test_WrongPackageHostPutField() { + System.out.println("Testing for nest-host and nest-member in different packages"); + String msg = "Type P2.PackagedNestHost2$Member is not a nest member of " + + "P1.PackagedNestHost: types are in different packages"; + try { + P1.PackagedNestHost.doPutField(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + try { + P2.PackagedNestHost2.Member.doPutField(); + throw new Error("Missing IncompatibleClassChangeError: " + msg); + } + catch (IncompatibleClassChangeError expected) { + check_expected(expected, msg); + } + } + + // utilities + + static void check_expected(Throwable expected, String msg) { + if (!expected.getMessage().contains(msg)) { + throw new Error("Wrong " + expected.getClass().getSimpleName() +": \"" + + expected.getMessage() + "\" does not contain \"" + + msg + "\""); + } + System.out.println("OK - got expected exception: " + expected); + } + + static void check_expected(Throwable expected, String msg, String cause_msg) { + if (!expected.getMessage().contains(msg)) { + throw new Error("Wrong " + expected.getClass().getSimpleName() +": \"" + + expected.getMessage() + "\" does not contain \"" + + msg + "\""); + } + Throwable cause = expected.getCause(); + if (cause instanceof NoClassDefFoundError) { + if (!cause.getMessage().contains(cause_msg)) { + throw new Error(expected.getClass().getSimpleName() + + " has wrong cause " + cause.getClass().getSimpleName() +": \"" + + cause.getMessage() + "\" does not contain \"" + + cause_msg + "\""); + } + } + else throw new Error(expected.getClass().getSimpleName() + + " has wrong cause " + cause.getClass().getSimpleName()); + + System.out.println("OK - got expected exception: " + expected + + " with cause " + cause); + } + +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/PA_I.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/PA_I.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,140 @@ + +// rename m -> bad_m; real_m -> m + +class TestInterfaceMethodSelection$PA_I { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #5 #18; // #1 + String #19; // #2 + String #20; // #3 + class #21; // #4 + class #24; // #5 + class #25; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "m"; // #11 MODIFIED + Utf8 "()Ljava/lang/String;"; // #12 + Utf8 "bad_m"; // #13 MODIFIED + Utf8 "SourceFile"; // #14 + Utf8 "TestInterfaceMethodSelection.java"; // #15 + Utf8 "NestHost"; // #16 + class #27; // #17 + NameAndType #7 #8; // #18 + Utf8 "PA_I::m"; // #19 + Utf8 "Should not see this"; // #20 + Utf8 "TestInterfaceMethodSelection$PA_I"; // #21 + Utf8 "PA_I"; // #22 + Utf8 "InnerClasses"; // #23 + Utf8 "java/lang/Object"; // #24 + Utf8 "TestInterfaceMethodSelection$I"; // #25 + Utf8 "I"; // #26 + Utf8 "TestInterfaceMethodSelection"; // #27 + } // Constant Pool + + 0x0020; // access + #4;// this_cpx + #5;// super_cpx + + [] { // Interfaces + #6; + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 113; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #11; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 114; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0001; // access + #13; // name_cpx + #12; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1203B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 115; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#14) { // SourceFile + #15; + } // end SourceFile + ; + Attr(#16) { // NestHost + 0x0011; + } // end NestHost + ; + Attr(#23) { // InnerClasses + [] { // InnerClasses + #4 #17 #22 8; + #6 #17 #26 1544; + } + } // end InnerClasses + } // Attributes +} // end class TestInterfaceMethodSelection$PA_I diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/PB_A.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/PB_A.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,132 @@ +/* + * 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. + */ + +// m() is declared private + +class TestMethodSelection$PB_A { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #15; // #1 + String #16; // #2 + class #17; // #3 + class #20; // #4 + Utf8 "<init>"; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "LineNumberTable"; // #8 + Utf8 "m"; // #9 + Utf8 "()Ljava/lang/String;"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "TestMethodSelection.java"; // #12 + Utf8 "NestHost"; // #13 + class #22; // #14 + NameAndType #5 #6; // #15 + Utf8 "PB_A::m"; // #16 + Utf8 "TestMethodSelection$PB_A"; // #17 + Utf8 "PB_A"; // #18 + Utf8 "InnerClasses"; // #19 + Utf8 "TestMethodSelection$A"; // #20 + Utf8 "A"; // #21 + Utf8 "TestMethodSelection"; // #22 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 119; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access - modified + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 120; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestHost + 0x000E; + } // end NestHost + ; + Attr(#19) { // InnerClasses + [] { // InnerClasses + #3 #14 #18 9; + #4 #14 #21 9; + } + } // end InnerClasses + } // Attributes +} // end class TestMethodSelection$PB_A diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/PB_A_I.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/PB_A_I.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,109 @@ +// m() is declared private + +class TestInterfaceMethodSelection$PB_A_I { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #15; // #1 + String #16; // #2 + class #17; // #3 + class #20; // #4 + Utf8 "<init>"; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "LineNumberTable"; // #8 + Utf8 "m"; // #9 + Utf8 "()Ljava/lang/String;"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "TestInterfaceMethodSelection.java"; // #12 + Utf8 "NestHost"; // #13 + class #22; // #14 + NameAndType #5 #6; // #15 + Utf8 "PB_A_I::m"; // #16 + Utf8 "TestInterfaceMethodSelection$PB_A_I"; // #17 + Utf8 "PB_A_I"; // #18 + Utf8 "InnerClasses"; // #19 + Utf8 "TestInterfaceMethodSelection$A_I"; // #20 + Utf8 "A_I"; // #21 + Utf8 "TestInterfaceMethodSelection"; // #22 + } // Constant Pool + + 0x0020; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 125; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access - modified + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 126; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestHost + 0x000E; + } // end NestHost + ; + Attr(#19) { // InnerClasses + [] { // InnerClasses + #3 #14 #18 8; + #4 #14 #21 8; + } + } // end InnerClasses + } // Attributes +} // end class TestInterfaceMethodSelection$PB_A_I diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/PB_A_PI.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/PB_A_PI.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,108 @@ +// m() is declared private + +class TestInterfaceMethodSelection$PB_A_PI { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #15; // #1 + String #16; // #2 + class #17; // #3 + class #19; // #4 + Utf8 "<init>"; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "LineNumberTable"; // #8 + Utf8 "m"; // #9 + Utf8 "()Ljava/lang/String;"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "TestInterfaceMethodSelection.java"; // #12 + Utf8 "NestHost"; // #13 + class #21; // #14 + NameAndType #5 #6; // #15 + Utf8 "PB_A_PI"; // #16 + Utf8 "TestInterfaceMethodSelection$PB_A_PI"; // #17 + Utf8 "InnerClasses"; // #18 + Utf8 "TestInterfaceMethodSelection$A_PI"; // #19 + Utf8 "A_PI"; // #20 + Utf8 "TestInterfaceMethodSelection"; // #21 + } // Constant Pool + + 0x0020; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 140; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access - modified + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 141; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestHost + 0x000E; + } // end NestHost + ; + Attr(#18) { // InnerClasses + [] { // InnerClasses + #3 #14 #16 8; + #4 #14 #20 8; + } + } // end InnerClasses + } // Attributes +} // end class TestInterfaceMethodSelection$PB_A_PI diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/PB_PA_I.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/PB_PA_I.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,135 @@ +// rename m -> bad_m; real_m -> m + +class TestInterfaceMethodSelection$PB_PA_I { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #5 #17; // #1 + String #18; // #2 + String #19; // #3 + class #20; // #4 + class #22; // #5 + Utf8 "<init>"; // #6 + Utf8 "()V"; // #7 + Utf8 "Code"; // #8 + Utf8 "LineNumberTable"; // #9 + Utf8 "bad_m"; // #10 - modified + Utf8 "()Ljava/lang/String;"; // #11 + Utf8 "m"; // #12 - modified + Utf8 "SourceFile"; // #13 + Utf8 "TestInterfaceMethodSelection.java"; // #14 + Utf8 "NestHost"; // #15 + class #24; // #16 + NameAndType #6 #7; // #17 + Utf8 "Should not see this"; // #18 + Utf8 "PB_PA_I"; // #19 + Utf8 "TestInterfaceMethodSelection$PB_PA_I"; // #20 + Utf8 "InnerClasses"; // #21 + Utf8 "TestInterfaceMethodSelection$PA_I"; // #22 + Utf8 "PA_I"; // #23 + Utf8 "TestInterfaceMethodSelection"; // #24 + } // Constant Pool + + 0x0020; // access + #4;// this_cpx + #5;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #6; // name_cpx + #7; // sig_cpx + [] { // Attributes + Attr(#8) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#9) { // LineNumberTable + [] { // LineNumberTable + 0 132; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0001; // access + #10; // name_cpx + #11; // sig_cpx + [] { // Attributes + Attr(#8) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#9) { // LineNumberTable + [] { // LineNumberTable + 0 133; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #12; // name_cpx + #11; // sig_cpx + [] { // Attributes + Attr(#8) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1203B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#9) { // LineNumberTable + [] { // LineNumberTable + 0 134; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#13) { // SourceFile + #14; + } // end SourceFile + ; + Attr(#15) { // NestHost + 0x0010; + } // end NestHost + ; + Attr(#21) { // InnerClasses + [] { // InnerClasses + #4 #16 #19 8; + #5 #16 #23 8; + } + } // end InnerClasses + } // Attributes +} // end class TestInterfaceMethodSelection$PB_PA_I diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/PC_B_A.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/PC_B_A.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,132 @@ +/* + * 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. + */ + +// m() is declared private + +class TestMethodSelection$PC_B_A { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #15; // #1 + String #16; // #2 + class #17; // #3 + class #20; // #4 + Utf8 "<init>"; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "LineNumberTable"; // #8 + Utf8 "m"; // #9 + Utf8 "()Ljava/lang/String;"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "TestMethodSelection.java"; // #12 + Utf8 "NestHost"; // #13 + class #22; // #14 + NameAndType #5 #6; // #15 + Utf8 "PC_B_A::m"; // #16 + Utf8 "TestMethodSelection$PC_B_A"; // #17 + Utf8 "PC_B_A"; // #18 + Utf8 "InnerClasses"; // #19 + Utf8 "TestMethodSelection$B_A"; // #20 + Utf8 "B_A"; // #21 + Utf8 "TestMethodSelection"; // #22 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 130; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access - modified + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 131; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestHost + 0x000E; + } // end NestHost + ; + Attr(#19) { // InnerClasses + [] { // InnerClasses + #3 #14 #18 9; + #4 #14 #21 9; + } + } // end InnerClasses + } // Attributes +} // end class TestMethodSelection$PC_B_A diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/PC_B_PA.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/PC_B_PA.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,132 @@ +/* + * 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. + */ + +// m() is declared private + +class TestMethodSelection$PC_B_PA { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #15; // #1 + String #16; // #2 + class #17; // #3 + class #20; // #4 + Utf8 "<init>"; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "LineNumberTable"; // #8 + Utf8 "m"; // #9 + Utf8 "()Ljava/lang/String;"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "TestMethodSelection.java"; // #12 + Utf8 "NestHost"; // #13 + class #22; // #14 + NameAndType #5 #6; // #15 + Utf8 "PC_B_PA::m"; // #16 + Utf8 "TestMethodSelection$PC_B_PA"; // #17 + Utf8 "PC_B_PA"; // #18 + Utf8 "InnerClasses"; // #19 + Utf8 "TestMethodSelection$B_PA"; // #20 + Utf8 "B_PA"; // #21 + Utf8 "TestMethodSelection"; // #22 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 144; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access - modified + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 145; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestHost + 0x000E; + } // end NestHost + ; + Attr(#19) { // InnerClasses + [] { // InnerClasses + #3 #14 #18 9; + #4 #14 #21 9; + } + } // end InnerClasses + } // Attributes +} // end class TestMethodSelection$PC_B_PA diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/PC_PB_A.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/PC_PB_A.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,132 @@ +/* + * 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. + */ + +// m() is declared private + +class TestMethodSelection$PC_PB_A { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #15; // #1 + String #16; // #2 + class #17; // #3 + class #20; // #4 + Utf8 "<init>"; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "LineNumberTable"; // #8 + Utf8 "m"; // #9 + Utf8 "()Ljava/lang/String;"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "TestMethodSelection.java"; // #12 + Utf8 "NestHost"; // #13 + class #22; // #14 + NameAndType #5 #6; // #15 + Utf8 "PC_PB_A::m"; // #16 + Utf8 "TestMethodSelection$PC_PB_A"; // #17 + Utf8 "PC_PB_A"; // #18 + Utf8 "InnerClasses"; // #19 + Utf8 "TestMethodSelection$PB_A"; // #20 + Utf8 "PB_A"; // #21 + Utf8 "TestMethodSelection"; // #22 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 137; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access - modified + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 138; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestHost + 0x000E; + } // end NestHost + ; + Attr(#19) { // InnerClasses + [] { // InnerClasses + #3 #14 #18 9; + #4 #14 #21 9; + } + } // end InnerClasses + } // Attributes +} // end class TestMethodSelection$PC_PB_A diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/TestInterfaceMethodSelection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/TestInterfaceMethodSelection.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,289 @@ +/* + * 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 + * @bug 8046171 + * @summary Test interface method selection process for private/public nestmate invocation + * @compile TestInterfaceMethodSelection.java + * @compile PA_I.jcod \ + * PB_A_I.jcod \ + * PB_A_PI.jcod \ + * PB_PA_I.jcod + * @run main TestInterfaceMethodSelection + * @run main/othervm -Dsun.reflect.noInflation=true TestInterfaceMethodSelection + */ + +// The first run will use NativeMethodAccessor and due to the limited number +// of calls we will not reach the inflation threshold. +// The second run disables inflation so we will use the GeneratedMethodAccessor +// instead. In this way both sets of Reflection classes are tested. + +/* +We are setting up a basic test structure as follows: + +interface I { + ?? String m() [ return "I::m"; // private case] +} +class A implements I { + ?? String m() { return "A::m"; } +} +class B extends A { + ?? String m() { return "B::m"; } +} + +where the access modifier of m() is either public or private in all combinations. +The only cases of interest here are private and non-private, so we use public for +the non-private case. Obviously for an interface, only the private case defines +a method body for m() - we're not testing default methods here (but they would be +invoked in the cases where we get AME). + +We then have a test function: + +void test(I target, String expected) { + check(target.m() == expected); +} + +where the call to target.m() is expressed as an invokeinterface I::m on target. We +then pass either an A instance or a B instance and check the expected method +is invoked. In all cases the resolved method is I::m, so we are effectively +testing the method selection rules. We are not testing resolution here. + +The expected behaviour is as follows (where P means m() is private and - means +m() is public). + +Target I.m A.m B.m Result Reason +------------------------------------------ + A P P n/a I.m [1] + A P - n/a I.m [1] + A - P n/a AME [2] + A - - n/a A.m [3] + B P P P I.m [1] + B P P - I.m [1] + B P - P I.m [1] + B P - - I.m [1] + B - P P AME [2] + B - P - B.m [3] + B - - P A.m [4] + B - - - B.m [3] + +[1] Resolved method is private => selected method == resolved method +[2] private A.m/B.m doesn't override abstract public I.m => AbstractMethodError +[3] Normal overriding: most specific method selected +[4] private B.m doesn't override public A.m/I.m so is ignored => A.m selected + +To allow us to do this in source code we encode the inheritance hierarchy in the +class name, and we use plain I (for example) when m() is public and PI when m() +is private. So class B_A_I defines a public m() and inherits public m() from +both A and I. While PB_PA_PI defines a private m() and also has private m() +defined in its superclass PA and implemented interface PI. + +For cases where the subclass makes a public method private we can't write this +directly in Java source code so we have to have jcod versions that change +the access modifier to private, but we also need to switch between having a +method implementation or not, so add fake_m() and then rename in the jcod file. +The affected cases are: + +- PA_I +- PB_A_I +- PB_PA_I +- PB_A_PI + +We test direct invocation from Java source, MethodHandle invocation and core +reflection invocation. For MH and reflection we look for the method in "I" to +maintain the same resolution process as in the direct case. +*/ + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +import java.lang.reflect.InvocationTargetException; + +public class TestInterfaceMethodSelection { + + static final MethodType M_T = MethodType.methodType(String.class); + + static interface I { + public String m(); + } + static interface PI { + private String m() { return "PI::m"; } + } + + static class A_I implements I { + public String m() { return "A_I::m"; } + } + static class A_PI implements PI { + public String m() { return "A_PI::m"; } + } + // jcod version will edit method names + static class PA_I implements I { + private String real_m() { return "PA_I::m"; } + public String m() { return "Should not see this"; } + } + static class PA_PI implements PI { + private String m() { return "PA_PI::m"; } + } + + static class B_A_I extends A_I { + public String m() { return "B_A_I::m"; } + } + // jcod version will rewrite this to have private m() + static class PB_A_I extends A_I { + public String m() { return "PB_A_I::m"; } + } + static class B_PA_I extends PA_I { + public String m() { return "B_PA_I::m"; } + } + // jcod version will edit method names + static class PB_PA_I extends PA_I { + public String m() { return "Should not see this"; } + private String real_m() { return "PB_PA_I"; } + } + static class B_A_PI extends A_PI { + public String m() { return "B_A_PI::m"; } + } + // jcod version will rewrite this to have private m() + static class PB_A_PI extends A_PI { + public String m() { return "PB_A_PI"; } + } + static class B_PA_PI extends PA_PI { + public String m() { return "B_PA_PI::m"; } + } + static class PB_PA_PI extends PA_PI { + private String m() { return "PB_PA_PI::m"; } + } + + // Need a test function for each of the "I" interfaces + + static void doInvoke(I target, String expected) throws Throwable { + // Direct + check(target.m(), expected); + // MethodHandle + MethodHandle mh = lookup().findVirtual(I.class, "m", M_T); + check((String)mh.invoke(target), expected); + // Reflection + check((String)I.class.getDeclaredMethod("m", new Class<?>[0]). + invoke(target, new Object[0]), expected); + } + static void doInvoke(PI target, String expected) throws Throwable { + // Direct + check(target.m(), expected); + // MethodHandle + MethodHandle mh = lookup().findVirtual(PI.class, "m", M_T); + check((String)mh.invoke(target), expected); + // Reflection + check((String)PI.class.getDeclaredMethod("m", new Class<?>[0]). + invoke(target, new Object[0]), expected); + } + + static void badInvoke(I target) { + badDirectInvoke(target); + badMHInvoke(target); + badReflectInvoke(target); + } + + static void badDirectInvoke(I target) { + try { + target.m(); + throw new Error("Unexpected success directly invoking " + + target.getClass().getSimpleName() + + ".m() - expected AbstractMethodError"); + } + catch (AbstractMethodError expected) { + } + catch (Throwable t) { + throw new Error("Unexpected exception directly invoking " + + target.getClass().getSimpleName() + + ".m() - expected AbstractMethodError got: " + t); + } + } + + static void badMHInvoke(I target) { + try { + lookup().findVirtual(I.class, "m", M_T).invoke(target); + throw new Error("Unexpected success for MH invoke of" + + target.getClass().getSimpleName() + + ".m() - expected AbstractMethodError"); + } + catch (AbstractMethodError expected) { + } + catch (Throwable t) { + throw new Error("Unexpected exception for MH invoke of " + + target.getClass().getSimpleName() + + ".m() - expected AbstractMethodError got: " + t); + } + } + + static void badReflectInvoke(I target) { + try { + I.class.getDeclaredMethod("m", new Class<?>[0]). + invoke(target, new Object[0]); + throw new Error("Unexpected success for Method invoke of" + + target.getClass().getSimpleName() + + ".m() - expected AbstractMethodError"); + } + catch (InvocationTargetException expected) { + Throwable t = expected.getCause(); + if (!(t instanceof AbstractMethodError)) { + throw new Error("Unexpected exception for Method invoke of " + + target.getClass().getSimpleName() + + ".m() - expected AbstractMethodError got: " + t); + + } + } + catch (Throwable t) { + throw new Error("Unexpected exception for Method invoke of " + + target.getClass().getSimpleName() + + ".m() - expected AbstractMethodError got: " + t); + } + } + + static void check(String actual, String expected) { + if (!actual.equals(expected)) { + throw new Error("Selection error: expected " + expected + + " but got " + actual); + } + } + + public static void main(String[] args) throws Throwable { + // First pass a suitable "A" instance + doInvoke(new PA_PI(), "PI::m"); + doInvoke(new A_PI(), "PI::m"); + badInvoke(new PA_I()); + doInvoke(new A_I(), "A_I::m"); + // Now a "B" instance + doInvoke(new PB_PA_PI(), "PI::m"); + doInvoke(new B_PA_PI(), "PI::m"); + doInvoke(new PB_A_PI(), "PI::m"); + doInvoke(new B_A_PI(), "PI::m"); + badInvoke(new PB_PA_I()); + doInvoke(new B_PA_I(), "B_PA_I::m"); + doInvoke(new PB_A_I(), "A_I::m"); + doInvoke(new B_A_I(), "B_A_I::m"); + } +} + + + + diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/methodSelection/TestMethodSelection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/methodSelection/TestMethodSelection.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,242 @@ +/* + * 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 + * @bug 8046171 + * @summary Test method selection process for private/public nestmate invocation + * @compile TestMethodSelection.java + * @compile PB_A.jcod \ + * PC_B_A.jcod \ + * PC_B_PA.jcod \ + * PC_PB_A.jcod + * @run main/othervm TestMethodSelection + * @run main/othervm -Dsun.reflect.noInflation=true TestMethodSelection + */ + +// The first run will use NativeMethodAccessor and due to the limited number +// of calls we will not reach the inflation threshold. +// The second run disables inflation so we will use the GeneratedMethodAccessor +// instead. In this way both sets of Reflection classes are tested. + +/* +We are setting up a basic test structure as follows: + +class A { + ?? String m() { return "A::m"; } +} +class B extends A { + ?? String m() { return "B::m"; } +} +class C extends B { + ?? String m() { return "C::m"; } +} + +where the access modifier of m() is either public or private in all combinations. +The only cases of interest here are private and non-private, so we use public for +the non-private case. + +We then have a test function: + +void test(B target, String expected) { + check(target.m() == expected); +} + +where the call to target.m() is expressed as an invokevirtual B::m on target. We +then pass either a B instance or a C instance and check that the expected method +is invoked. In all cases the resolved method is B::m, so we are effectively +testing the method selection rules. We are not testing resolution here. + +The expected behaviour is as follows (where P means m() is private and - means +m() is public). + +Target A.m B.m C.m Result Reason +------------------------------------------ + B P P n/a B.m [1] + B P - n/a B.m [2] + B - P n/a B.m [1] + B - - n/a B.m [2] + C P P P B.m [1] + C P P - B.m [1] + C P - P B.m [3] + C P - - C.m [2] + c - P P B.m [1] + C - P - B.m [1] + C - - P B.m [3] + C - - - C.m [2] + +[1] Resolved method is private => selected method == resolved method +[2] target-type.m() can override B.m => selected method == target-type.m() +[3] private C.m does not override resolved public method B.m, but + C has a superclass B, with B.m that (trivially) overrides resolved B.m + => selected method = B.m + +To allow us to do this in source code we encode the inheritance hierarchy in the +class name, and we use plain A (for example) when m() is public and PA when m() +is private. So class C_B_A defines a public m() and inherits public m() from +both B and A. While PC_PB_PA defines a private m() and also has private m() +defined in its superclasses PB and PA. + +For cases where the subclass makes a public method private we can't write this +directly in Java source code so we have to have jcod versions that change +the access modifier to private. This occurs for: + +- PC_B_A +- PB_A +- PC_B_PA +- PC_PB_A + +We test direct invocation from Java source, MethodHandle invocation and core +reflection invocation. For MH and reflection we look for the method in "B" to +maintain the same resolution process as in the direct case. +*/ + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +import java.lang.reflect.InvocationTargetException; + +public class TestMethodSelection { + + static final MethodType M_T = MethodType.methodType(String.class); + + static class A { + public String m() { return "A::m"; } + } + static class PA { + private String m() { return "PA::m"; } + } + + static class B_A extends A { + public String m() { return "B_A::m"; } + } + static class B_PA extends PA { + public String m() { return "B_PA::m"; } + } + // jcod version will rewrite this to have private m() + static class PB_A extends A { + public String m() { return "PB_A::m"; } + } + static class PB_PA extends PA { + private String m() { return "PB_PA::m"; } + } + + static class C_B_A extends B_A { + public String m() { return "C_B_A::m"; } + } + // jcod version will rewrite this to have private m() + static class PC_B_A extends B_A { + public String m() { return "PC_B_A"; } + } + static class C_PB_A extends PB_A { + public String m() { return "C_PB_A::m"; } + } + // jcod version will rewrite this to have private m() + static class PC_PB_A extends PB_A { + public String m() { return "PC_PB_A"; } + } + static class C_B_PA extends B_PA { + public String m() { return "C_B_PA::m"; } + } + // jcod version will rewrite this to have private m() + static class PC_B_PA extends B_PA { + public String m() { return "PC_B_PA"; } + } + static class C_PB_PA extends PB_PA { + public String m() { return "C_PB_PA::m"; } + } + static class PC_PB_PA extends PB_PA { + private String m() { return "PC_PB_PA::m"; } + } + + // Need a test function for each of the "B" classes + + static void doInvoke(B_A target, String expected) throws Throwable { + // Direct + check(target.m(), expected); + // MethodHandle + MethodHandle mh = lookup().findVirtual(B_A.class, "m", M_T); + check((String)mh.invoke(target), expected); + // Reflection + check((String)B_A.class.getDeclaredMethod("m", new Class<?>[0]). + invoke(target, new Object[0]), expected); + } + static void doInvoke(B_PA target, String expected) throws Throwable { + // Direct + check(target.m(), expected); + // MethodHandle + MethodHandle mh = lookup().findVirtual(B_PA.class, "m", M_T); + check((String)mh.invoke(target), expected); + // Reflection + check((String)B_PA.class.getDeclaredMethod("m", new Class<?>[0]). + invoke(target, new Object[0]), expected); + } + static void doInvoke(PB_A target, String expected) throws Throwable { + // Direct + check(target.m(), expected); + // MethodHandle + MethodHandle mh = lookup().findVirtual(PB_A.class, "m", M_T); + check((String)mh.invoke(target), expected); + // Reflection + check((String)PB_A.class.getDeclaredMethod("m", new Class<?>[0]). + invoke(target, new Object[0]), expected); + } + static void doInvoke(PB_PA target, String expected) throws Throwable { + // Direct + check(target.m(), expected); + // MethodHandle + MethodHandle mh = lookup().findVirtual(PB_PA.class, "m", M_T); + check((String)mh.invoke(target), expected); + // Reflection + check((String)PB_PA.class.getDeclaredMethod("m", new Class<?>[0]). + invoke(target, new Object[0]), expected); + } + + static void check(String actual, String expected) { + if (!actual.equals(expected)) { + throw new Error("Selection error: expected " + expected + + " but got " + actual); + } + } + + public static void main(String[] args) throws Throwable { + // First pass a suitable "B" instance + doInvoke(new PB_PA(), "PB_PA::m"); + doInvoke(new B_PA(), "B_PA::m"); + doInvoke(new PB_A(), "PB_A::m"); + doInvoke(new B_A(), "B_A::m"); + // Now a "C" instance + doInvoke(new PC_PB_PA(), "PB_PA::m"); + doInvoke(new C_PB_PA(), "PB_PA::m"); + doInvoke(new PC_B_PA(), "B_PA::m"); + doInvoke(new C_B_PA(), "C_B_PA::m"); + doInvoke(new PC_PB_A(), "PB_A::m"); + doInvoke(new C_PB_A(), "PB_A::m"); + doInvoke(new PC_B_A(), "B_A::m"); + doInvoke(new C_B_A(), "C_B_A::m"); + } +} + + + + diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateConstructors/ExternalSub.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateConstructors/ExternalSub.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Generated from: ExternalSub.java + + Super constructor call is changed from the public NestedA(int) + constructor to the private NestedA() constructor. +*/ + +class ExternalSub { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #10; // #1 + class #11; // #2 + class #13; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "TestConstructorHierarchy.java"; // #9 + NameAndType #4 #5; // #10 - modified #16 to #5 + Utf8 "ExternalSub"; // #11 + class #17; // #12 + Utf8 "TestConstructorHierarchy$NestedA"; // #13 + Utf8 "NestedA"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "(I)V"; // #16 + Utf8 "TestConstructorHierarchy"; // #17 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001 // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack - modified from 2 + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 84; +// 5 85; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #3 #12 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class ExternalSub diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateConstructors/ExternalSuper.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateConstructors/ExternalSuper.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* Generated from: ExternalSuper.java + + Constructor access level is changed to private. +*/ + +class ExternalSuper { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #10; // #1 + class #11; // #2 + class #12; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "TestConstructorHierarchy.java"; // #9 + NameAndType #4 #5; // #10 + Utf8 "ExternalSuper"; // #11 + Utf8 "java/lang/Object"; // #12 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0002; // access - modified to private + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 78; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + } // Attributes +} // end class ExternalSuper diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestConstructorHierarchy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestConstructorHierarchy.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private constructors in the hierarchy that are + * outside the nest + * @compile TestConstructorHierarchy.java + * @compile ExternalSuper.jcod + * ExternalSub.jcod + * @run main TestConstructorHierarchy + */ + +public class TestConstructorHierarchy { + + static class NestedA extends ExternalSuper { + private NestedA() {} + protected NestedA(int i) {} // for compile-time only + } + + // Access to private members of classes outside the nest is + // not permitted. These tests should throw IllegalAccessError + // at runtime. To allow them to compile the classes below are + // defined with public members. We then replace those class files + // with jcod variants that make the member private again. + + public static void main(String[] args) throws Throwable { + try { + new ExternalSuper(); + throw new Error("Unexpected construction of ExternalSuper"); + } + catch (IllegalAccessError iae) { + if (iae.getMessage().contains("tried to access method ExternalSuper.<init>()V from class TestConstructorHierarchy")) { + System.out.println("Got expected exception constructing ExternalSuper: " + iae); + } + else throw new Error("Unexpected IllegalAccessError: " + iae); + } + try { + new NestedA(); + throw new Error("Unexpected construction of NestedA and supers"); + } + catch (IllegalAccessError iae) { + if (iae.getMessage().contains("tried to access method ExternalSuper.<init>()V from class TestConstructorHierarchy$NestedA")) { + System.out.println("Got expected exception constructing NestedA: " + iae); + } + else throw new Error("Unexpected IllegalAccessError: " + iae); + } + try { + new ExternalSub(); + throw new Error("Unexpected construction of ExternalSub"); + } + catch (IllegalAccessError iae) { + if (iae.getMessage().contains("tried to access method TestConstructorHierarchy$NestedA.<init>()V from class ExternalSub")) { + System.out.println("Got expected exception constructing ExternalSub: " + iae); + } + else throw new Error("Unexpected IllegalAccessError: " + iae); + } + } +} + +// Classes that are not part of the nest. +// Being non-public allows us to declare them in this file. +// The constructor is public to allow this file to compile, but +// the jcod files change it back to private. + +class ExternalSuper { + public ExternalSuper() { } +} + + +class ExternalSub extends TestConstructorHierarchy.NestedA { + public ExternalSub() { + super(0); // this is changed to super() in jcod file + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestInvokeSpecial.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestInvokeSpecial.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private constructors between nestmates and nest-host + * using different flavours of named nested types that will + * generate invokespecial for the calls. The -Xcomp run is a special + * regression test for a compiler assertion that would fire when + * "loading" a nest-host class. + * @run main TestInvokeSpecial + * @run main/othervm -Xcomp TestInvokeSpecial + */ + +public class TestInvokeSpecial { + + // All constructors are private to ensure nestmate access checks apply + + // All doConstruct methods are public so they don't involve invoke_special + + private TestInvokeSpecial() {} + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + default void doConstruct(TestInvokeSpecial o) { + Object obj = new TestInvokeSpecial(); + } + default void doConstruct(InnerNested o) { + Object obj = new TestInvokeSpecial().new InnerNested(); + } + default void doConstruct(StaticNested o) { + Object obj = new StaticNested(); + } + default void doConstruct(StaticIface o) { + Object obj = new StaticIface() {}; + } + } + + static class StaticNested { + + private StaticNested() {} + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + public void doConstruct(TestInvokeSpecial o) { + Object obj = new TestInvokeSpecial(); + } + public void doConstruct(InnerNested o) { + Object obj = new TestInvokeSpecial().new InnerNested(); + } + public void doConstruct(StaticNested o) { + Object obj = new StaticNested(); + } + public void doConstruct(StaticIface o) { + Object obj = new StaticIface() {}; + } + } + + class InnerNested { + + private InnerNested() {} + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + public void doConstruct(TestInvokeSpecial o) { + Object obj = new TestInvokeSpecial(); + } + public void doConstruct(InnerNested o) { + Object obj = new TestInvokeSpecial().new InnerNested(); + } + public void doConstruct(StaticNested o) { + Object obj = new StaticNested(); + } + public void doConstruct(StaticIface o) { + Object obj = new StaticIface() {}; + } + } + + public static void main(String[] args) { + // These initial constructions test nest-host access + TestInvokeSpecial o = new TestInvokeSpecial(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + s.doConstruct(o); + s.doConstruct(i); + s.doConstruct(s); + s.doConstruct(intf); + + i.doConstruct(o); + i.doConstruct(i); + i.doConstruct(s); + i.doConstruct(intf); + + intf.doConstruct(o); + intf.doConstruct(i); + intf.doConstruct(s); + intf.doConstruct(intf); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestJNI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestJNI.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,142 @@ +/* + * 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 + * @bug 8046171 + * @summary Test JNI access to private constructors between nestmates and nest-host + * using different flavours of named nested types using core reflection + * @compile ../NestmatesJNI.java + * @run main/othervm/native TestJNI + * @run main/othervm/native -Xcheck:jni TestJNI + */ +public class TestJNI { + + // Unlike reflection, the calling context is not relevant to JNI + // calls, but we keep the same structure as the reflection tests. + + + // All constructors are private to ensure nestmate access checks apply + + // All doConstruct methods are public so they don't involve nestmate access + + private TestJNI() {} + + // The various nestmates + + // Note: No constructor on interfaces so no StaticIface variants + + static interface StaticIface { + + // Methods that will access private constructors of nestmates. + + default void doConstruct(TestJNI o) throws Throwable { + Object obj = newInstance(o.getClass()); + } + default void doConstruct(TestJNI outerThis, InnerNested o) throws Throwable { + Object obj = newInstance(o.getClass(), outerThis); + } + default void doConstruct(StaticNested o) throws Throwable { + Object obj = newInstance(o.getClass()); + } + } + + static class StaticNested { + + private StaticNested() {} + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + public void doConstruct(TestJNI o) throws Throwable { + Object obj = newInstance(o.getClass()); + } + public void doConstruct(TestJNI outerThis, InnerNested o) throws Throwable { + Object obj = newInstance(o.getClass(), outerThis); + } + public void doConstruct(StaticNested o) throws Throwable { + Object obj = newInstance(o.getClass()); + } + } + + class InnerNested { + + private InnerNested() {} + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + public void doConstruct(TestJNI o) throws Throwable { + Object obj = newInstance(o.getClass()); + } + public void doConstruct(TestJNI outerThis, InnerNested o) throws Throwable { + Object obj = newInstance(o.getClass(), outerThis); + } + public void doConstruct(StaticNested o) throws Throwable { + Object obj = newInstance(o.getClass()); + } + } + + public static void main(String[] args) throws Throwable { + // These initial constructions test nest-host access to members + + TestJNI o = newInstance(TestJNI.class); + StaticNested s = (StaticNested) newInstance(StaticNested.class); + InnerNested i = (InnerNested) newInstance(InnerNested.class, o); + + // We need a StaticIface instance to call doConstruct on + StaticIface intf = new StaticIface() {}; + + s.doConstruct(o); + s.doConstruct(o, i); + s.doConstruct(s); + + i.doConstruct(o); + i.doConstruct(o, i); + i.doConstruct(s); + + intf.doConstruct(o); + intf.doConstruct(o, i); + intf.doConstruct(s); + } + + static <T> T newInstance(Class<T> klass) { + return newInstance(klass, null); + } + + static <T> T newInstance(Class<T> klass, Object outerThis) { + String sig = (outerThis == null) ? + "()V" : + "(L" + outerThis.getClass().getName() + ";)V"; + String definingClass = klass.getName(); + String desc = " Invocation of constructor " + definingClass + sig; + try { + T ret = (T) NestmatesJNI.newInstance(definingClass, sig, outerThis); + System.out.println(desc + " - passed"); + return ret; + } + catch (Throwable t) { + throw new Error(desc + ": Unexpected exception: " + t, t); + } + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestMethodHandles.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestMethodHandles.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private constructors between nestmates and nest-host + * using different flavours of named nested types using MethodHandles + * @run main TestMethodHandles + */ + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +public class TestMethodHandles { + + static final MethodType NOARG_T = MethodType.methodType(void.class); + static final MethodType INNER_T = MethodType.methodType(void.class, TestMethodHandles.class); + + // All constructors are private to ensure nestmate access checks apply + + // All doConstruct methods are public so they don't involve invoke_special + + private TestMethodHandles() {} + + // The various nestmates + + // Note: No constructor on interfaces so no StaticIface variants + + static interface StaticIface { + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + default void doConstruct(TestMethodHandles o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(TestMethodHandles.class, NOARG_T); + TestMethodHandles obj = (TestMethodHandles) mh.invoke(); + obj = (TestMethodHandles) mh.invokeExact(); + } + default void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(InnerNested.class, INNER_T); + InnerNested obj = (InnerNested) mh.invoke(outer); + obj = (InnerNested) mh.invokeExact(outer); + } + default void doConstruct(StaticNested o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(StaticNested.class, NOARG_T); + StaticNested obj = (StaticNested) mh.invoke(); + obj = (StaticNested) mh.invokeExact(); + } + } + + static class StaticNested { + + private StaticNested() {} + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + public void doConstruct(TestMethodHandles o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(TestMethodHandles.class, NOARG_T); + TestMethodHandles obj = (TestMethodHandles) mh.invoke(); + obj = (TestMethodHandles) mh.invokeExact(); + } + public void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(InnerNested.class, INNER_T); + InnerNested obj = (InnerNested) mh.invoke(outer); + obj = (InnerNested) mh.invokeExact(outer); + } + public void doConstruct(StaticNested o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(StaticNested.class, NOARG_T); + StaticNested obj = (StaticNested) mh.invoke(); + obj = (StaticNested) mh.invokeExact(); + } + } + + class InnerNested { + + private InnerNested() {} + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + public void doConstruct(TestMethodHandles o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(TestMethodHandles.class, NOARG_T); + TestMethodHandles obj = (TestMethodHandles) mh.invoke(); + obj = (TestMethodHandles) mh.invokeExact(); + } + public void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(InnerNested.class, INNER_T); + InnerNested obj = (InnerNested) mh.invoke(outer); + obj = (InnerNested) mh.invokeExact(outer); + } + public void doConstruct(StaticNested o) throws Throwable { + MethodHandle mh = + lookup().findConstructor(StaticNested.class, NOARG_T); + StaticNested obj = (StaticNested) mh.invoke(); + obj = (StaticNested) mh.invokeExact(); + } + } + + public static void main(String[] args) throws Throwable { + // These initial constructions test nest-host access + MethodHandle mh = + lookup().findConstructor(TestMethodHandles.class, NOARG_T); + TestMethodHandles o = (TestMethodHandles) mh.invoke(); + o = (TestMethodHandles) mh.invokeExact(); + + mh = lookup().findConstructor(StaticNested.class, NOARG_T); + StaticNested s = (StaticNested) mh.invoke(); + s = (StaticNested) mh.invokeExact(); + + mh = lookup().findConstructor(InnerNested.class, INNER_T); + InnerNested i = (InnerNested) mh.invoke(o); + i = (InnerNested) mh.invokeExact(o); + + StaticIface intf = new StaticIface() {}; + + s.doConstruct(o); + s.doConstruct(o, i); + s.doConstruct(s); + + i.doConstruct(o); + i.doConstruct(o, i); + i.doConstruct(s); + + intf.doConstruct(o); + intf.doConstruct(o, i); + intf.doConstruct(s); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestReflection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateConstructors/TestReflection.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private constructors between nestmates and nest-host + * using different flavours of named nested types using core reflection + * @run main TestReflection + * @run main/othervm -Dsun.reflect.noInflation=true TestReflection + */ + +// The first run will use NativeConstructorAccessor and due to the limited +// number of calls we will not reach the inflation threshold. +// The second run disables inflation so we will use the +// GeneratedConstructorAccessor instead. +// In this way both sets of Reflection classes are tested. + +public class TestReflection { + + // All constructors are private to ensure nestmate access checks apply + + // All doConstruct methods are public so they don't involve invoke_special + + private TestReflection() {} + + // The various nestmates + + // Note: No constructor on interfaces so no StaticIface variants + + static interface StaticIface { + + // Methods that will access private constructors of nestmates. + + default void doConstruct(TestReflection o) throws Throwable { + Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + default void doConstruct(TestReflection tr, InnerNested o) throws Throwable { + Object obj = InnerNested.class.getDeclaredConstructor(new Class<?>[] {TestReflection.class}).newInstance(new Object[] { tr }); + } + default void doConstruct(StaticNested o) throws Throwable { + Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + } + + static class StaticNested { + + private StaticNested() {} + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + public void doConstruct(TestReflection o) throws Throwable { + Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + public void doConstruct(TestReflection tr, InnerNested o) throws Throwable { + Object obj = InnerNested.class.getDeclaredConstructor(new Class<?>[] {TestReflection.class}).newInstance(new Object[] { tr }); + } + public void doConstruct(StaticNested o) throws Throwable { + Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + } + + class InnerNested { + + private InnerNested() {} + + // Methods that will access private constructors of nestmates. + // The arg is a dummy for overloading purposes + + public void doConstruct(TestReflection o) throws Throwable { + Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + public void doConstruct(TestReflection tr, InnerNested o) throws Throwable { + Object obj = InnerNested.class.getDeclaredConstructor(new Class<?>[] {TestReflection.class}).newInstance(new Object[] { tr }); + } + public void doConstruct(StaticNested o) throws Throwable { + Object obj = o.getClass().getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + } + } + + public static void main(String[] args) throws Throwable { + // These initial constructions test nest-host access + TestReflection o = TestReflection.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + StaticNested s = StaticNested.class.getDeclaredConstructor(new Class<?>[0]).newInstance(new Object[0]); + InnerNested i = InnerNested.class.getDeclaredConstructor(new Class<?>[] {TestReflection.class}).newInstance(new Object[] { o }); + + StaticIface intf = new StaticIface() {}; + + s.doConstruct(o); + s.doConstruct(o, i); + s.doConstruct(s); + + i.doConstruct(o); + i.doConstruct(o, i); + i.doConstruct(s); + + intf.doConstruct(o); + intf.doConstruct(o, i); + intf.doConstruct(s); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateFields/TestJNI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateFields/TestJNI.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,156 @@ +/* + * 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 + * @bug 8046171 + * @summary Test JNI access to private fields between nestmates and nest-host + * using different flavours of named nested types + * @compile ../NestmatesJNI.java + * @run main/othervm/native TestJNI + * @run main/othervm/native -Xcheck:jni TestJNI + */ +public class TestJNI { + + // Private field of nest-host for nestmates to access + private int priv_field; + + static final String FIELD = "priv_field"; + + // public constructor so we aren't relying on private access + public TestJNI() {} + + // Methods that will access private fields of nestmates + + // NOTE: No StaticIface variants as interfaces can't have instance fields + + void access_priv(TestJNI o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + void access_priv(InnerNested o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + void access_priv(StaticNested o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private fields of nestmates + + default void access_priv(TestJNI o) { + int priv_field = getAndInc(o, o.getClass(), FIELD); + } + default void access_priv(InnerNested o) { + int priv_field = getAndInc(o, o.getClass(), FIELD); + } + default void access_priv(StaticNested o) { + int priv_field = getAndInc(o, o.getClass(), FIELD); + } + } + + static class StaticNested { + + private int priv_field; + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private fields of nestmates + + void access_priv(TestJNI o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + void access_priv(InnerNested o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + void access_priv(StaticNested o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + } + + class InnerNested { + + private int priv_field; + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestJNI o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + void access_priv(InnerNested o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + void access_priv(StaticNested o) { + this.priv_field = getAndInc(o, o.getClass(), FIELD); + } + } + + public static void main(String[] args) { + TestJNI o = new TestJNI(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestJNI()); + o.access_priv(i); + o.access_priv(s); + + s.access_priv(o); + s.access_priv(i); + s.access_priv(new StaticNested()); + + i.access_priv(o); + i.access_priv(o.new InnerNested()); + i.access_priv(s); + + intf.access_priv(o); + intf.access_priv(i); + intf.access_priv(s); + } + + static int getAndInc(Object target, Class<?> klass, String field) { + String definingClass = klass.getName(); + String desc = "Access to field " + + definingClass + "." + field + " on instance of class " + + target.getClass().getName(); + int first, second; + try { + first = NestmatesJNI.getIntField(target, definingClass, field); + NestmatesJNI.setIntField(target, definingClass, field, (first + 1)); + second = NestmatesJNI.getIntField(target, definingClass, field); + } + catch (Throwable t) { + throw new Error(desc + ": Unexpected exception: " + t, t); + } + if (second != first + 1) { + throw new Error(desc + ": wrong field values: first=" + first + + ", second=" + second + " (should equal first+1)"); + } + System.out.println(desc + " - passed"); + return first; + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateFields/TestMethodHandles.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateFields/TestMethodHandles.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private fields between nestmates and nest-host + * using different flavours of named nested types using MethodHandles + * @run main TestMethodHandles + */ + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; + +public class TestMethodHandles { + + // Private field of nest-host for nestmates to access + private int priv_field; + + // public constructor so we aren't relying on private access + public TestMethodHandles() {} + + // Methods that will access private fields of nestmates + + // NOTE: No StaticIface variants as interfaces can't have instance fields + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, new StaticNested()); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, new StaticNested()); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + void access_priv(InnerNested o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private fields of nestmates + + default void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + int priv_field = (int) mh.invoke(o); + priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + default void access_priv(InnerNested o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + int priv_field = (int) mh.invoke(o); + priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + default void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + int priv_field = (int) mh.invoke(o); + priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + } + + static class StaticNested { + + private int priv_field; + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private fields of nestmates + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + void access_priv(InnerNested o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, new TestMethodHandles()); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, new TestMethodHandles()); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + } + + class InnerNested { + + private int priv_field; + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + void access_priv(InnerNested o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, new StaticNested()); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, new StaticNested()); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findGetter(o.getClass(), "priv_field", int.class); + this.priv_field = (int) mh.invoke(o); + this.priv_field = (int) mh.invokeExact(o); + checkBadInvokeG(mh, this); // wrong nestmate + checkBadInvokeG(mh, mh); // completely wrong type + + mh = lookup().findSetter(o.getClass(), "priv_field", int.class); + mh.invoke(o, 2); + mh.invokeExact(o, 3); + checkBadInvokeS(mh, this); // wrong nestmate + checkBadInvokeS(mh, mh); // completely wrong type + } + } + + static void checkBadInvokeG(MethodHandle mh, Object o) throws Throwable { + try { + int x = (int) mh.invoke(o); + throw new Error("Invoke on MethodHandle " + mh + " with receiver " + + o + "should have failed with ClassCastException!"); + } + catch (ClassCastException expected) { + System.out.println("invoke got expected exception: " + expected); + } + } + + static void checkBadInvokeS(MethodHandle mh, Object o) throws Throwable { + try { + mh.invoke(o, 42); + throw new Error("Invoke on MethodHandle " + mh + " with receiver " + + o + "should have failed with ClassCastException!"); + } + catch (ClassCastException expected) { + System.out.println("invoke got expected exception: " + expected); + } + } + + public static void main(String[] args) throws Throwable { + TestMethodHandles o = new TestMethodHandles(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestMethodHandles()); + o.access_priv(i); + o.access_priv(s); + + s.access_priv(o); + s.access_priv(i); + s.access_priv(new StaticNested()); + + i.access_priv(o); + i.access_priv(o.new InnerNested()); + i.access_priv(s); + + intf.access_priv(o); + intf.access_priv(i); + intf.access_priv(s); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateFields/TestPrivateField.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateFields/TestPrivateField.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private fields between nestmates and nest-host + * using different flavours of named nested types + * @run main TestPrivateField + */ + +public class TestPrivateField { + + // Private field of nest-host for nestmates to access + private int priv_field; + + // public constructor so we aren't relying on private access + public TestPrivateField() {} + + // Methods that will access private fields of nestmates + + // NOTE: No StaticIface variants as interfaces can't have instance fields + + void access_priv(TestPrivateField o) { + this.priv_field = o.priv_field++; + } + void access_priv(InnerNested o) { + this.priv_field = o.priv_field++; + } + void access_priv(StaticNested o) { + this.priv_field = o.priv_field++; + } + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private fields of nestmates + + default void access_priv(TestPrivateField o) { + int priv_field = o.priv_field++; + } + default void access_priv(InnerNested o) { + int priv_field = o.priv_field++; + } + default void access_priv(StaticNested o) { + int priv_field = o.priv_field++; + } + } + + static class StaticNested { + + private int priv_field; + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private fields of nestmates + + void access_priv(TestPrivateField o) { + this.priv_field = o.priv_field++; + } + void access_priv(InnerNested o) { + this.priv_field = o.priv_field++; + } + void access_priv(StaticNested o) { + this.priv_field = o.priv_field++; + } + } + + class InnerNested { + + private int priv_field; + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestPrivateField o) { + this.priv_field = o.priv_field++; + } + void access_priv(InnerNested o) { + this.priv_field = o.priv_field++; + } + void access_priv(StaticNested o) { + this.priv_field = o.priv_field++; + } + } + + public static void main(String[] args) { + TestPrivateField o = new TestPrivateField(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestPrivateField()); + o.access_priv(i); + o.access_priv(s); + + s.access_priv(o); + s.access_priv(i); + s.access_priv(new StaticNested()); + + i.access_priv(o); + i.access_priv(o.new InnerNested()); + i.access_priv(s); + + intf.access_priv(o); + intf.access_priv(i); + intf.access_priv(s); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateFields/TestReflection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateFields/TestReflection.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private fields between nestmates and nest-host + * using different flavours of named nested types using core reflection + * @run main TestReflection + */ + +import java.lang.reflect.Field; + +public class TestReflection { + + // Private field of nest-host for nestmates to access + private int priv_field; + + // public constructor so we aren't relying on private access + public TestReflection() {} + + // Methods that will access private fields of nestmates + + // NOTE: No StaticIface variants as interfaces can't have instance fields + + void access_priv(TestReflection o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + void access_priv(InnerNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + void access_priv(StaticNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private fields of nestmates + + default void access_priv(TestReflection o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + int priv_field = f.getInt(o); + f.setInt(o, 2); + } + default void access_priv(InnerNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + int priv_field = f.getInt(o); + f.setInt(o, 2); + } + default void access_priv(StaticNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + int priv_field = f.getInt(o); + f.setInt(o, 2); + } + } + + static class StaticNested { + + private int priv_field; + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private fields of nestmates + + void access_priv(TestReflection o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + void access_priv(InnerNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + void access_priv(StaticNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + } + + class InnerNested { + + private int priv_field; + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestReflection o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + void access_priv(InnerNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + void access_priv(StaticNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + this.priv_field = f.getInt(o); + f.setInt(o, 2); + } + } + + public static void main(String[] args) throws Throwable { + TestReflection o = new TestReflection(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestReflection()); + o.access_priv(i); + o.access_priv(s); + + s.access_priv(o); + s.access_priv(i); + s.access_priv(new StaticNested()); + + i.access_priv(o); + i.access_priv(o.new InnerNested()); + i.access_priv(s); + + intf.access_priv(o); + intf.access_priv(i); + intf.access_priv(s); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/ExternalSub.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/ExternalSub.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2017, 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. + */ + +// Generated from the source in TestInvokeHierarchy.java +// with priv_invoke access modifier changed to private + +class ExternalSub { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + class #17; // #2 + String #18; // #3 + class #20; // #4 + Utf8 "ID"; // #5 + Utf8 "Ljava/lang/String;"; // #6 + Utf8 "ConstantValue"; // #7 + Utf8 "<init>"; // #8 + Utf8 "()V"; // #9 + Utf8 "Code"; // #10 + Utf8 "LineNumberTable"; // #11 + Utf8 "priv_invoke"; // #12 + Utf8 "()Ljava/lang/String;"; // #13 + Utf8 "SourceFile"; // #14 + Utf8 "TestInvokeHierarchy.java"; // #15 + NameAndType #8 #9; // #16 + Utf8 "ExternalSub"; // #17 + Utf8 "ExternalSub::priv_invoke"; // #18 + class #23; // #19 + Utf8 "TestInvokeHierarchy$NestedC"; // #20 + Utf8 "NestedC"; // #21 + Utf8 "InnerClasses"; // #22 + Utf8 "TestInvokeHierarchy"; // #23 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0018; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // ConstantValue + #3; + } // end ConstantValue + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0000; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 129; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access - private + #12; // name_cpx + #13; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1203B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 132; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#14) { // SourceFile + #15; + } // end SourceFile + ; + Attr(#22) { // InnerClasses + [] { // InnerClasses + #4 #19 #21 8; + } + } // end InnerClasses + } // Attributes +} // end class ExternalSub diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/ExternalSuper.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/ExternalSuper.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017, 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. + */ + +// Generated from the source in TestInvokeHierarchy.java +// with priv_invoke access modifier changed to private + +class ExternalSuper { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + class #17; // #2 + String #18; // #3 + class #19; // #4 + Utf8 "ID"; // #5 + Utf8 "Ljava/lang/String;"; // #6 + Utf8 "ConstantValue"; // #7 + Utf8 "<init>"; // #8 + Utf8 "()V"; // #9 + Utf8 "Code"; // #10 + Utf8 "LineNumberTable"; // #11 + Utf8 "priv_invoke_s"; // #12 + Utf8 "()Ljava/lang/String;"; // #13 + Utf8 "SourceFile"; // #14 + Utf8 "TestInvokeHierarchy.java"; // #15 + NameAndType #8 #9; // #16 + Utf8 "ExternalSuper"; // #17 + Utf8 "ExternalSuper::priv_invoke_s"; // #18 + Utf8 "java/lang/Object"; // #19 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0018; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // ConstantValue + #3; + } // end ConstantValue + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0000; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 119; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access - private + #12; // name_cpx + #13; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1203B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 124; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#14) { // SourceFile + #15; + } // end SourceFile + } // Attributes +} // end class ExternalSuper diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/MissingMethod.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/MissingMethod.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2017, 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. + */ + +// Generated from the source in TestInvokeErrors.java +// with priv_invoke renamed to not_priv_invoke so it isn't found + +class TestInvokeErrors$MissingMethod { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #16; // #1 + Field #17 #18; // #2 + String #19; // #3 + Method #20 #21; // #4 + class #22; // #5 + class #25; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "not_priv_invoke"; // #11 - renamed + Utf8 "SourceFile"; // #12 + Utf8 "TestInvokeErrors.java"; // #13 + Utf8 "NestHost"; // #14 + class #26; // #15 + NameAndType #7 #8; // #16 + class #27; // #17 + NameAndType #28 #29; // #18 + Utf8 "MissingMethod::priv_invoke"; // #19 + class #30; // #20 + NameAndType #31 #32; // #21 + Utf8 "TestInvokeErrors$MissingMethod"; // #22 + Utf8 "MissingMethod"; // #23 + Utf8 "InnerClasses"; // #24 + Utf8 "java/lang/Object"; // #25 + Utf8 "TestInvokeErrors"; // #26 + Utf8 "java/lang/System"; // #27 + Utf8 "out"; // #28 + Utf8 "Ljava/io/PrintStream;"; // #29 + Utf8 "java/io/PrintStream"; // #30 + Utf8 "println"; // #31 + Utf8 "(Ljava/lang/String;)V"; // #32 + } // Constant Pool + + 0x0020; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 35; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #11; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 38; + 8 39; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#12) { // SourceFile + #13; + } // end SourceFile + ; + Attr(#14) { // NestHost + 0x000F; + } // end NestHost + ; + Attr(#24) { // InnerClasses + [] { // InnerClasses + #5 #15 #23 8; + } + } // end InnerClasses + } // Attributes +} // end class TestInvokeErrors$MissingMethod diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/MissingMethodWithSuper.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/MissingMethodWithSuper.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2017, 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. + */ + +// Generated from the source in TestInvokeErrors.java +// with priv_invoke renamed to not_priv_invoke so it isn't found + +class TestInvokeErrors$MissingMethodWithSuper { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #16; // #1 + Field #17 #18; // #2 + String #19; // #3 + Method #20 #21; // #4 + class #22; // #5 + class #25; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "not_priv_invoke"; // #11 - rename + Utf8 "SourceFile"; // #12 + Utf8 "TestInvokeErrors.java"; // #13 + Utf8 "NestHost"; // #14 + class #27; // #15 + NameAndType #7 #8; // #16 + class #28; // #17 + NameAndType #29 #30; // #18 + Utf8 "MissingMethodWithSuper::priv_invoke"; // #19 + class #31; // #20 + NameAndType #32 #33; // #21 + Utf8 "TestInvokeErrors$MissingMethodWithSuper"; // #22 + Utf8 "MissingMethodWithSuper"; // #23 + Utf8 "InnerClasses"; // #24 + Utf8 "TestInvokeErrors$Nested"; // #25 + Utf8 "Nested"; // #26 + Utf8 "TestInvokeErrors"; // #27 + Utf8 "java/lang/System"; // #28 + Utf8 "out"; // #29 + Utf8 "Ljava/io/PrintStream;"; // #30 + Utf8 "java/io/PrintStream"; // #31 + Utf8 "println"; // #32 + Utf8 "(Ljava/lang/String;)V"; // #33 + } // Constant Pool + + 0x0020; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 49; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #11; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 52; + 8 53; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#12) { // SourceFile + #13; + } // end SourceFile + ; + Attr(#14) { // NestHost + 0x000F; + } // end NestHost + ; + Attr(#24) { // InnerClasses + [] { // InnerClasses + #5 #15 #23 8; + #6 #15 #26 8; + } + } // end InnerClasses + } // Attributes +} // end class TestInvokeErrors$MissingMethodWithSuper diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/MissingNestHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/MissingNestHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2017, 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. + */ + +// Generated from the source in TestInvokeErrors.java +// with NestHost referring to non-existent class: NoSuchClass + +class TestInvokeErrors$MissingNestHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #16; // #1 + Field #17 #18; // #2 + String #19; // #3 + Method #20 #21; // #4 + class #22; // #5 + class #25; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "priv_invoke"; // #11 + Utf8 "SourceFile"; // #12 + Utf8 "TestInvokeErrors.java"; // #13 + Utf8 "NestHost"; // #14 + class #26; // #15 + NameAndType #7 #8; // #16 + class #27; // #17 + NameAndType #28 #29; // #18 + Utf8 "MissingNestHost::priv_invoke"; // #19 + class #30; // #20 + NameAndType #31 #32; // #21 + Utf8 "TestInvokeErrors$MissingNestHost"; // #22 + Utf8 "MissingNestHost"; // #23 + Utf8 "InnerClasses"; // #24 + Utf8 "java/lang/Object"; // #25 + Utf8 "TestInvokeErrors"; // #26 + Utf8 "java/lang/System"; // #27 + Utf8 "out"; // #28 + Utf8 "Ljava/io/PrintStream;"; // #29 + Utf8 "java/io/PrintStream"; // #30 + Utf8 "println"; // #31 + Utf8 "(Ljava/lang/String;)V"; // #32 + Utf8 "NoSuchClass"; // #33 - added + class #33; // #34 - added + } // Constant Pool + + 0x0020; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 57; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0002; // access + #11; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 60; + 8 61; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#12) { // SourceFile + #13; + } // end SourceFile + ; + Attr(#14) { // NestHost + 0x0022; // Modified: class #34 -> NoSuchClass + } // end NestHost + ; + Attr(#24) { // InnerClasses + [] { // InnerClasses + #5 #15 #23 8; + } + } // end InnerClasses + } // Attributes +} // end class TestInvokeErrors$MissingNestHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestInvoke.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestInvoke.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private methods between nestmates and nest-host + * using different flavours of named nested types + * @run main TestInvoke + */ + +public class TestInvoke { + + // Private method of nest-host for nestmates to access + private void priv_invoke() { + System.out.println("TestInvoke::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public TestInvoke() {} + + // Methods that will access private methods of nestmates + + void access_priv(TestInvoke o) { + o.priv_invoke(); + } + void access_priv(InnerNested o) { + o.priv_invoke(); + } + void access_priv(StaticNested o) { + o.priv_invoke(); + } + void access_priv(StaticIface o) { + o.priv_invoke(); + } + + // The various nestmates + + static interface StaticIface { + + private void priv_invoke() { + System.out.println("StaticIface::priv_invoke"); + } + + // Methods that will access private methods of nestmates + + default void access_priv(TestInvoke o) { + o.priv_invoke(); + } + default void access_priv(InnerNested o) { + o.priv_invoke(); + } + default void access_priv(StaticNested o) { + o.priv_invoke(); + } + default void access_priv(StaticIface o) { + o.priv_invoke(); + } + } + + static class StaticNested { + + private void priv_invoke() { + System.out.println("StaticNested::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private methods of nestmates + + void access_priv(TestInvoke o) { + o.priv_invoke(); + } + void access_priv(InnerNested o) { + o.priv_invoke(); + } + void access_priv(StaticNested o) { + o.priv_invoke(); + } + void access_priv(StaticIface o) { + o.priv_invoke(); + } + } + + class InnerNested { + + private void priv_invoke() { + System.out.println("InnerNested::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv() { + TestInvoke.this.priv_invoke(); // check this$0 access + } + void access_priv(TestInvoke o) { + o.priv_invoke(); + } + void access_priv(InnerNested o) { + o.priv_invoke(); + } + void access_priv(StaticNested o) { + o.priv_invoke(); + } + void access_priv(StaticIface o) { + o.priv_invoke(); + } + } + + public static void main(String[] args) { + TestInvoke o = new TestInvoke(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestInvoke()); + o.access_priv(i); + o.access_priv(s); + o.access_priv(intf); + + s.access_priv(o); + s.access_priv(i); + s.access_priv(new StaticNested()); + s.access_priv(intf); + + i.access_priv(); + i.access_priv(o); + i.access_priv(o.new InnerNested()); + i.access_priv(s); + i.access_priv(intf); + + intf.access_priv(o); + intf.access_priv(i); + intf.access_priv(s); + intf.access_priv(new StaticIface(){}); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestInvokeErrors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestInvokeErrors.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Setup nestmate calls to private methods then use + * modified jcod classes to introduce errors. Test with + * and without verification enabled + * @compile TestInvokeErrors.java + * @compile MissingMethod.jcod + * MissingMethodWithSuper.jcod + * MissingNestHost.jcod + * @run main TestInvokeErrors true + * @run main/othervm -Xverify:none TestInvokeErrors false + */ + +public class TestInvokeErrors { + + static class Nested { + private void priv_invoke() { + System.out.println("Nested::priv_invoke"); + } + } + + static class MissingMethod { + // jcod version will rename this method to not_priv_invoke + private void priv_invoke() { + System.out.println("MissingMethod::priv_invoke"); + } + } + + static class MissingMethodWithSuper extends Nested { + // jcod version will rename this method to not_priv_invoke + private void priv_invoke() { + System.out.println("MissingMethodWithSuper::priv_invoke"); + } + } + + static class MissingNestHost { + // jcod version will change NestHost to a non-existent class + private void priv_invoke() { + System.out.println("MissingNestHost::priv_invoke"); + } + } + + // Helper class adds a level of indirection to avoid the main class + // failing verification if these tests are written directly in main. + // That can only happen if using invokespecial for nestmate invocation. + static class Helper { + static void doTest() { + try { + MissingNestHost m = new MissingNestHost(); + m.priv_invoke(); + throw new Error("Unexpected success invoking MissingNestHost.priv_invoke"); + } + catch (NoClassDefFoundError ncdfe) { + System.out.println("Got expected exception:" + ncdfe); + } + } + } + + public static void main(String[] args) throws Throwable { + // some errors change depending on whether they are caught by the + // verifier first + boolean verifying = Boolean.parseBoolean(args[0]); + System.out.println("Verification is " + + (verifying ? "enabled" : "disabled")); + + try { + MissingMethod m = new MissingMethod(); + m.priv_invoke(); + throw new Error("Unexpected success invoking MissingMethod.priv_invoke"); + } + catch (NoSuchMethodError nsme) { + System.out.println("Got expected exception:" + nsme); + } + + try { + MissingMethodWithSuper m = new MissingMethodWithSuper(); + m.priv_invoke(); + throw new Error("Unexpected success invoking MissingMethodWithSuper.priv_invoke"); + } + catch (NoSuchMethodError nsme) { + System.out.println("Got expected exception:" + nsme); + } + + // Verification of Helper will trigger the nestmate access check failure + try { + Helper.doTest(); + } + catch (NoClassDefFoundError ncdfe) { + if (verifying) + System.out.println("Got expected exception:" + ncdfe); + else + throw new Error("Unexpected error loading Helper class with verification disabled"); + } + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestInvokeHierarchy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestInvokeHierarchy.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private methods between nestmates where there + * is an inheritance hierarchy and we invoke private methods that + * exist in specific classes in the hierarchy. + * @compile TestInvokeHierarchy.java + * @compile ExternalSuper.jcod ExternalSub.jcod + * @run main TestInvokeHierarchy + */ + +public class TestInvokeHierarchy { + + static class NestedA extends ExternalSuper { + static final String ID = "NestedA::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + verifyEquals(a.priv_invoke(), NestedA.ID); + } + } + + static class NestedB extends NestedA { + static final String ID = "NestedB::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + verifyEquals(a.priv_invoke(), NestedA.ID); + } + } + + static class NestedC extends NestedB { + static final String ID = "NestedC::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + verifyEquals(a.priv_invoke(), NestedA.ID); + } + } + + static void checkA(NestedA a) throws Throwable { + verifyEquals(a.priv_invoke(), NestedA.ID); + } + + static void checkB(NestedB b) throws Throwable { + verifyEquals(b.priv_invoke(), NestedB.ID); + } + + static void checkC(NestedC c) throws Throwable { + verifyEquals(c.priv_invoke(), NestedC.ID); + } + + + // Access to private members of classes outside the nest is + // not permitted. These tests should throw IllegalAccessError + // at runtime. To allow them to compile the classes below are + // defined with public members. We then replace those class files + // with jcod variants that make the member private again. + + static void checkExternalSuper(ExternalSuper s) throws Throwable { + try { + String str = s.priv_invoke_s(); + throw new Error("Unexpected access to ExternalSuper.priv_invoke_s"); + } + catch (IllegalAccessError iae) { + System.out.println("Got expected exception accessing ExternalSuper.priv_invoke_s:" + iae); + } + } + + static void checkExternalSub(ExternalSub s) throws Throwable { + try { + String str = s.priv_invoke(); + throw new Error("Unexpected access to ExternalSub.priv_invoke"); + } + catch (IllegalAccessError iae) { + System.out.println("Got expected exception accessing ExternalSub.priv_invoke:" + iae); + } + } + + static void verifyEquals(String actual, String expected) { + if (!actual.equals(expected)) { + throw new Error("Expected " + expected + " but got " + actual); + } + System.out.println("Check passed for " + expected); + } + + public static void main(String[] args) throws Throwable { + NestedA a = new NestedA(); + NestedB b = new NestedB(); + NestedC c = new NestedC(); + ExternalSub sub = new ExternalSub(); + ExternalSuper sup = new ExternalSuper(); + + checkExternalSuper(sup); + checkExternalSuper(a); + checkExternalSuper(b); + checkExternalSuper(c); + checkExternalSuper(sub); + + checkA(a); + checkA(b); + checkA(c); + checkA(sub); + + NestedA.checkA(a); + NestedA.checkA(b); + NestedA.checkA(c); + NestedA.checkA(sub); + + NestedB.checkA(a); + NestedB.checkA(b); + NestedB.checkA(c); + NestedB.checkA(sub); + + NestedC.checkA(a); + NestedC.checkA(b); + NestedC.checkA(c); + NestedC.checkA(sub); + + checkB(b); + checkB(c); + checkB(sub); + + checkC(c); + checkC(sub); + + checkExternalSub(sub); + } +} + +// Classes that are not part of the nest. +// Being non-public allows us to declare them in this file. +// The priv_invoke* member is public to allow this file to compile, but +// the jcod files change it back to private. + +class ExternalSuper { + static final String ID = "ExternalSuper::priv_invoke_s"; + // Can't call this priv_invoke as subclasses make it less accessible + // which is not allowed. + public String priv_invoke_s() { + return ID; + } +} + + +class ExternalSub extends TestInvokeHierarchy.NestedC { + static final String ID = "ExternalSub::priv_invoke"; + public String priv_invoke() { + return ID; + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestJNI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestJNI.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,197 @@ +/* + * 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 + * @bug 8046171 + * @summary Test JNI access to private methods between nestmates and nest-host + * using different flavours of named nested types + * @compile ../NestmatesJNI.java + * @run main/othervm/native TestJNI + * @run main/othervm/native -Xcheck:jni TestJNI + */ +public class TestJNI { + + // Unlike reflection, the calling context is not relevant to JNI + // calls, but we keep the same structure as the reflection tests. + + static final String METHOD = "priv_invoke"; + + // Private method of nest-host for nestmates to access + private void priv_invoke() { + System.out.println("TestJNI::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public TestJNI() {} + + // Methods that will access private methods of nestmates + + void access_priv(TestJNI o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(InnerNested o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(StaticNested o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(StaticIface o) { + // Can't use o.getClass() as the method is not in that class + doCall(o, StaticIface.class, METHOD, true); + doCall(o, StaticIface.class, METHOD, false); + } + + // The various nestmates + + static interface StaticIface { + + private void priv_invoke() { + System.out.println("StaticIface::priv_invoke"); + } + + // Methods that will access private methods of nestmates + + default void access_priv(TestJNI o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + default void access_priv(InnerNested o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + default void access_priv(StaticNested o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + default void access_priv(StaticIface o) { + // Can't use o.getClass() as the method is not in that class + doCall(o, StaticIface.class, METHOD, true); + doCall(o, StaticIface.class, METHOD, false); + } + } + + static class StaticNested { + + private void priv_invoke() { + System.out.println("StaticNested::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private methods of nestmates + + void access_priv(TestJNI o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(InnerNested o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(StaticNested o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(StaticIface o) { + // Can't use o.getClass() as the method is not in that class + doCall(o, StaticIface.class, METHOD, true); + doCall(o, StaticIface.class, METHOD, false); + } + } + + class InnerNested { + + private void priv_invoke() { + System.out.println("InnerNested::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestJNI o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(InnerNested o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(StaticNested o) { + doCall(o, o.getClass(), METHOD, true); + doCall(o, o.getClass(), METHOD, false); + } + void access_priv(StaticIface o) { + // Can't use o.getClass() as the method is not in that class + doCall(o, StaticIface.class, METHOD, true); + doCall(o, StaticIface.class, METHOD, false); + } + } + + public static void main(String[] args) { + TestJNI o = new TestJNI(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestJNI()); + o.access_priv(i); + o.access_priv(s); + o.access_priv(intf); + + s.access_priv(o); + s.access_priv(i); + s.access_priv(new StaticNested()); + s.access_priv(intf); + + i.access_priv(o); + i.access_priv(o.new InnerNested()); + i.access_priv(s); + i.access_priv(intf); + + intf.access_priv(o); + intf.access_priv(i); + intf.access_priv(s); + intf.access_priv(new StaticIface(){}); + } + + + static void doCall(Object target, Class<?> klass, String method, + boolean virtual) { + String definingClass = klass.getName(); + String desc = (virtual ? "Virtual" : "Nonvirtual") + " Invocation of " + + definingClass + "." + method + " on instance of class " + + target.getClass().getName(); + try { + NestmatesJNI.callVoidVoid(target, definingClass, method, virtual); + System.out.println(desc + " - passed"); + } + catch (Throwable t) { + throw new Error(desc + ": Unexpected exception: " + t, t); + } + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestJNIHierarchy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestJNIHierarchy.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,237 @@ +/* + * 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 + * @bug 8046171 + * @summary Test access to private methods between nestmates where there + * is an inheritance hierarchy and we invoke private methods that + * exist in specific classes in the hierarchy. + * @compile ../NestmatesJNI.java + * @run main/othervm/native TestJNIHierarchy + * @run main/othervm/native -Xcheck:jni TestJNIHierarchy + */ + +public class TestJNIHierarchy { + + // Unlike reflection, the calling context is not relevant to JNI + // calls, but we keep the same structure as the reflection tests. + + static final String METHOD = "priv_invoke"; + + static class NestedA extends ExternalSuper { + static final String ID = "NestedA::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) { + String res = NestmatesJNI.callStringVoid(a, + NestedA.class.getName(), + METHOD, + true); + verifyEquals(res, NestedA.ID); + res = NestmatesJNI.callStringVoid(a, + NestedA.class.getName(), + METHOD, + false); + verifyEquals(res, NestedA.ID); + } + } + + static class NestedB extends NestedA { + static final String ID = "NestedB::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) { + String res = NestmatesJNI.callStringVoid(a, + NestedA.class.getName(), + METHOD, + true); + verifyEquals(res, NestedA.ID); + + res = NestmatesJNI.callStringVoid(a, + NestedA.class.getName(), + METHOD, + false); + verifyEquals(res, NestedA.ID); + } + } + + static class NestedC extends NestedB { + static final String ID = "NestedC::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) { + String res = NestmatesJNI.callStringVoid(a, + NestedA.class.getName(), + METHOD, + true); + verifyEquals(res, NestedA.ID); + } + } + + static void checkA(NestedA a) { + String res = NestmatesJNI.callStringVoid(a, + NestedA.class.getName(), + METHOD, + true); + verifyEquals(res, NestedA.ID); + + res = NestmatesJNI.callStringVoid(a, + NestedA.class.getName(), + METHOD, + false); + verifyEquals(res, NestedA.ID); + } + + static void checkB(NestedB b) { + String res = NestmatesJNI.callStringVoid(b, + NestedB.class.getName(), + METHOD, + true); + verifyEquals(res, NestedB.ID); + + res = NestmatesJNI.callStringVoid(b, + NestedB.class.getName(), + METHOD, + false); + verifyEquals(res, NestedB.ID); + + } + + static void checkC(NestedC c) { + String res = NestmatesJNI.callStringVoid(c, + NestedC.class.getName(), + METHOD, + true); + verifyEquals(res, NestedC.ID); + + res = NestmatesJNI.callStringVoid(c, + NestedC.class.getName(), + METHOD, + false); + verifyEquals(res, NestedC.ID); + } + + + // Access to private members of classes outside the nest is + // not permitted in general, but JNI ignores all access checks. + + static void checkExternalSuper(ExternalSuper s) { + String res = NestmatesJNI.callStringVoid(s, + ExternalSuper.class.getName(), + METHOD, + true); + verifyEquals(res, ExternalSuper.ID); + + res = NestmatesJNI.callStringVoid(s, + ExternalSuper.class.getName(), + METHOD, + false); + verifyEquals(res, ExternalSuper.ID); + } + + static void checkExternalSub(ExternalSub s) { + String res = NestmatesJNI.callStringVoid(s, + ExternalSub.class.getName(), + METHOD, + true); + verifyEquals(res, ExternalSub.ID); + + res = NestmatesJNI.callStringVoid(s, + ExternalSub.class.getName(), + METHOD, + false); + verifyEquals(res, ExternalSub.ID); + } + + static void verifyEquals(String actual, String expected) { + if (!actual.equals(expected)) { + throw new Error("Expected " + expected + " but got " + actual); + } + System.out.println("Check passed for " + expected); + } + + public static void main(String[] args) { + NestedA a = new NestedA(); + NestedB b = new NestedB(); + NestedC c = new NestedC(); + ExternalSub sub = new ExternalSub(); + ExternalSuper sup = new ExternalSuper(); + + checkExternalSuper(sup); + checkExternalSuper(a); + checkExternalSuper(b); + checkExternalSuper(c); + checkExternalSuper(sub); + + checkA(a); + checkA(b); + checkA(c); + checkA(sub); + + NestedA.checkA(a); + NestedA.checkA(b); + NestedA.checkA(c); + NestedA.checkA(sub); + + NestedB.checkA(a); + NestedB.checkA(b); + NestedB.checkA(c); + NestedB.checkA(sub); + + NestedC.checkA(a); + NestedC.checkA(b); + NestedC.checkA(c); + NestedC.checkA(sub); + + checkB(b); + checkB(c); + checkB(sub); + + checkC(c); + checkC(sub); + + checkExternalSub(sub); + } +} + +// Classes that are not part of the nest. +// Being non-public allows us to declare them in this file. + +class ExternalSuper { + static final String ID = "ExternalSuper::priv_invoke"; + private String priv_invoke() { + return ID; + } +} + + +class ExternalSub extends TestJNIHierarchy.NestedC { + static final String ID = "ExternalSub::priv_invoke"; + private String priv_invoke() { + return ID; + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestMethodHandles.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestMethodHandles.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private methods between nestmates and nest-host + * using different flavours of named nested types using MethodHandles + * @run main TestMethodHandles + */ + + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +public class TestMethodHandles { + + static final MethodType M_T = MethodType.methodType(void.class); + + // Private method of nest-host for nestmates to access + private void priv_invoke() { + System.out.println("TestMethodHandles::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public TestMethodHandles() {} + + // Methods that will access private methods of nestmates + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + // findSpecial also works when this and o are the same class + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + } + void access_priv(InnerNested o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + void access_priv(StaticIface o) throws Throwable { + MethodHandle mh = lookup().findVirtual(StaticIface.class, "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + + // The various nestmates + + static interface StaticIface { + + private void priv_invoke() { + System.out.println("StaticIface::priv_invoke"); + } + + // Methods that will access private methods of nestmates + + default void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = + lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + default void access_priv(InnerNested o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + default void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + default void access_priv(StaticIface o) throws Throwable { + MethodHandle mh = lookup().findVirtual(StaticIface.class, "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + // findSpecial also works when this and o are the same interface + mh = lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, StaticIface.class); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + } + } + + static class StaticNested { + + private void priv_invoke() { + System.out.println("StaticNested::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private methods of nestmates + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + void access_priv(InnerNested o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new TestMethodHandles()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + // findSpecial also works when this and o are the same class + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new TestMethodHandles()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + } + void access_priv(StaticIface o) throws Throwable { + MethodHandle mh = lookup().findVirtual(StaticIface.class, "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + } + + class InnerNested { + + private void priv_invoke() { + System.out.println("InnerNested::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + void access_priv(InnerNested o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + // findSpecial also works when this and o are the same class + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + void access_priv(StaticIface o) throws Throwable { + MethodHandle mh = lookup().findVirtual(StaticIface.class, "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, this); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} + } + } + + static void checkBadInvoke(MethodHandle mh, Object o) throws Throwable { + try { + mh.invoke(o); + throw new Error("Invoke on MethodHandle " + mh + " with receiver " + + o + "should have failed with ClassCastException!"); + } + catch (ClassCastException expected) { + System.out.println("invoke got expected exception: " + expected); + } + } + + public static void main(String[] args) throws Throwable { + TestMethodHandles o = new TestMethodHandles(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestMethodHandles()); + o.access_priv(i); + o.access_priv(s); + o.access_priv(intf); + + s.access_priv(o); + s.access_priv(i); + s.access_priv(new StaticNested()); + s.access_priv(intf); + + i.access_priv(o); + i.access_priv(o.new InnerNested()); + i.access_priv(s); + i.access_priv(intf); + + intf.access_priv(o); + intf.access_priv(i); + intf.access_priv(s); + intf.access_priv(new StaticIface(){}); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestMethodHandlesHierarchy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestMethodHandlesHierarchy.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private methods between nestmates where there + * is an inheritance hierarchy and we invoke private methods that + * exist in specific classes in the hierarchy. + * @run main TestMethodHandlesHierarchy + */ + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +public class TestMethodHandlesHierarchy { + + static final MethodType M_T = MethodType.methodType(String.class); + + static class NestedA extends ExternalSuper { + static final String ID = "NestedA::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + MethodHandle mh = + lookup().findSpecial(NestedA.class, "priv_invoke", + M_T, NestedA.class); + verifyEquals((String)mh.invoke(a), NestedA.ID); + verifyEquals((String)mh.invokeExact(a), NestedA.ID); + + mh = lookup().findVirtual(NestedA.class, "priv_invoke", M_T); + verifyEquals((String)mh.invoke(a), NestedA.ID); + verifyEquals((String)mh.invokeExact(a), NestedA.ID); + } + } + + static class NestedB extends NestedA { + static final String ID = "NestedB::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + MethodHandle mh = + lookup().findVirtual(NestedA.class, "priv_invoke", M_T); + verifyEquals((String)mh.invoke(a), NestedA.ID); + verifyEquals((String)mh.invokeExact(a), NestedA.ID); + } + } + + static class NestedC extends NestedB { + static final String ID = "NestedC::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + MethodHandle mh = + lookup().findVirtual(NestedA.class, "priv_invoke", M_T); + verifyEquals((String)mh.invoke(a), NestedA.ID); + verifyEquals((String)mh.invokeExact(a), NestedA.ID); + } + } + + static void checkA(NestedA a) throws Throwable { + MethodHandle mh = + lookup().findVirtual(NestedA.class, "priv_invoke", M_T); + verifyEquals((String)mh.invoke(a), NestedA.ID); + verifyEquals((String)mh.invokeExact(a), NestedA.ID); + } + + static void checkB(NestedB b) throws Throwable { + MethodHandle mh = + lookup().findVirtual(NestedB.class, "priv_invoke", M_T); + verifyEquals((String)mh.invoke(b), NestedB.ID); + verifyEquals((String)mh.invokeExact(b), NestedB.ID); + } + + static void checkC(NestedC c) throws Throwable { + MethodHandle mh = + lookup().findVirtual(NestedC.class, "priv_invoke", M_T); + verifyEquals((String)mh.invoke(c), NestedC.ID); + verifyEquals((String)mh.invokeExact(c), NestedC.ID); + } + + + // Access to private members of classes outside the nest is + // not permitted. These tests should throw IllegalAccessException + // at runtime. + + static void checkExternalSuper(ExternalSuper s) throws Throwable { + try { + lookup().findVirtual(ExternalSuper.class, "priv_invoke", M_T); + throw new Error("Unexpected access to ExternalSuper.priv_invoke"); + } + catch (IllegalAccessException iae) { + System.out.println("Got expected exception accessing ExternalSuper.priv_invoke:" + iae); + } + } + + static void checkExternalSub(ExternalSub s) throws Throwable { + try { + lookup().findVirtual(ExternalSub.class, "priv_invoke", M_T); + throw new Error("Unexpected access to ExternalSub.priv_invoke"); + } + catch (IllegalAccessException iae) { + System.out.println("Got expected exception accessing ExternalSub.priv_invoke:" + iae); + } + } + + static void verifyEquals(String actual, String expected) { + if (!actual.equals(expected)) { + throw new Error("Expected " + expected + " but got " + actual); + } + System.out.println("Check passed for " + expected); + } + + public static void main(String[] args) throws Throwable { + NestedA a = new NestedA(); + NestedB b = new NestedB(); + NestedC c = new NestedC(); + ExternalSub sub = new ExternalSub(); + ExternalSuper sup = new ExternalSuper(); + + checkExternalSuper(sup); + checkExternalSuper(a); + checkExternalSuper(b); + checkExternalSuper(c); + checkExternalSuper(sub); + + checkA(a); + checkA(b); + checkA(c); + checkA(sub); + + NestedA.checkA(a); + NestedA.checkA(b); + NestedA.checkA(c); + NestedA.checkA(sub); + + NestedB.checkA(a); + NestedB.checkA(b); + NestedB.checkA(c); + NestedB.checkA(sub); + + NestedC.checkA(a); + NestedC.checkA(b); + NestedC.checkA(c); + NestedC.checkA(sub); + + checkB(b); + checkB(c); + checkB(sub); + + checkC(c); + checkC(sub); + + checkExternalSub(sub); + } +} + +// Classes that are not part of the nest. +// Being non-public allows us to declare them in this file. + +class ExternalSuper { + static final String ID = "ExternalSuper::priv_invoke"; + private String priv_invoke() { + return ID; + } +} + + +class ExternalSub extends TestMethodHandlesHierarchy.NestedC { + static final String ID = "ExternalSub::priv_invoke"; + private String priv_invoke() { + return ID; + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestReflection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestReflection.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private methods between nestmates and nest-host + * using different flavours of named nested types using core reflection + * @run main TestReflection + * @run main/othervm -Dsun.reflect.noInflation=true TestReflection + */ + +// The first run will use NativeMethodAccessor and due to the limited number +// of calls we will not reach the inflation threshold. +// The second run disables inflation so we will use the GeneratedMethodAccessor +// instead. In this way both sets of Reflection classes are tested. + +public class TestReflection { + + // Private method of nest-host for nestmates to access + private void priv_invoke() { + System.out.println("TestReflection::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public TestReflection() {} + + // Methods that will access private methods of nestmates + + void access_priv(TestReflection o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(InnerNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(StaticNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(StaticIface o) throws Throwable { + // Can't use o.getClass() as the method is not in that class + StaticIface.class.getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + + // The various nestmates + + static interface StaticIface { + + private void priv_invoke() { + System.out.println("StaticIface::priv_invoke"); + } + + // Methods that will access private methods of nestmates + + default void access_priv(TestReflection o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + default void access_priv(InnerNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + default void access_priv(StaticNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + default void access_priv(StaticIface o) throws Throwable { + // Can't use o.getClass() as the method is not in that class + StaticIface.class.getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + } + + static class StaticNested { + + private void priv_invoke() { + System.out.println("StaticNested::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private methods of nestmates + + void access_priv(TestReflection o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(InnerNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(StaticNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(StaticIface o) throws Throwable { + // Can't use o.getClass() as the method is not in that class + StaticIface.class.getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + } + + class InnerNested { + + private void priv_invoke() { + System.out.println("InnerNested::priv_invoke"); + } + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestReflection o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(InnerNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(StaticNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + void access_priv(StaticIface o) throws Throwable { + // Can't use o.getClass() as the method is not in that class + StaticIface.class.getDeclaredMethod("priv_invoke", new Class<?>[0]).invoke(o, new Object[0]); + } + } + + public static void main(String[] args) throws Throwable { + TestReflection o = new TestReflection(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestReflection()); + o.access_priv(i); + o.access_priv(s); + o.access_priv(intf); + + s.access_priv(o); + s.access_priv(i); + s.access_priv(new StaticNested()); + s.access_priv(intf); + + i.access_priv(o); + i.access_priv(o.new InnerNested()); + i.access_priv(s); + i.access_priv(intf); + + intf.access_priv(o); + intf.access_priv(i); + intf.access_priv(s); + intf.access_priv(new StaticIface(){}); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestReflectionHierarchy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestReflectionHierarchy.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private methods between nestmates where there + * is an inheritance hierarchy and we invoke private methods that + * exist in specific classes in the hierarchy. + * @run main TestReflectionHierarchy + * @run main/othervm -Dsun.reflect.noInflation=true TestReflectionHierarchy + */ + +// The first run will use NativeMethodAccessor and due to the limited number +// of calls we will not reach the inflation threshold. +// The second run disables inflation so we will use the GeneratedMethodAccessor +// instead. In this way both sets of Reflection classes are tested. + + +public class TestReflectionHierarchy { + + static class NestedA extends ExternalSuper { + static final String ID = "NestedA::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + verifyEquals((String)NestedA.class. + getDeclaredMethod("priv_invoke", + new Class<?>[0]). + invoke(a, new Object[0]), + NestedA.ID); + } + } + + static class NestedB extends NestedA { + static final String ID = "NestedB::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + verifyEquals((String)NestedA.class. + getDeclaredMethod("priv_invoke", + new Class<?>[0]). + invoke(a, new Object[0]), + NestedA.ID); + } + } + + static class NestedC extends NestedB { + static final String ID = "NestedC::priv_invoke"; + private String priv_invoke() { + return ID; + } + static void checkA(NestedA a) throws Throwable { + verifyEquals((String)NestedA.class. + getDeclaredMethod("priv_invoke", + new Class<?>[0]). + invoke(a, new Object[0]), + NestedA.ID); + } + } + + static void checkA(NestedA a) throws Throwable { + verifyEquals((String)NestedA.class. + getDeclaredMethod("priv_invoke", + new Class<?>[0]). + invoke(a, new Object[0]), + NestedA.ID); + } + + static void checkB(NestedB b) throws Throwable { + verifyEquals((String)NestedB.class. + getDeclaredMethod("priv_invoke", + new Class<?>[0]). + invoke(b, new Object[0]), + NestedB.ID); + } + + static void checkC(NestedC c) throws Throwable { + verifyEquals((String)NestedC.class. + getDeclaredMethod("priv_invoke", + new Class<?>[0]). + invoke(c, new Object[0]), + NestedC.ID); + } + + + // Access to private members of classes outside the nest is + // not permitted. These tests should throw IllegalAccessException + // at runtime. + + static void checkExternalSuper(ExternalSuper s) throws Throwable { + try { + ExternalSuper.class. + getDeclaredMethod("priv_invoke", new Class<?>[0]). + invoke(s, new Object[0]); + throw new Error("Unexpected access to ExternalSuper.priv_invoke"); + } + catch (IllegalAccessException iae) { + System.out.println("Got expected exception accessing ExternalSuper.priv_invoke:" + iae); + } + } + + static void checkExternalSub(ExternalSub s) throws Throwable { + try { + ExternalSub.class. + getDeclaredMethod("priv_invoke", new Class<?>[0]). + invoke(s, new Object[0]); + throw new Error("Unexpected access to ExternalSub.priv_invoke"); + } + catch (IllegalAccessException iae) { + System.out.println("Got expected exception accessing ExternalSub.priv_invoke:" + iae); + } + } + + static void verifyEquals(String actual, String expected) { + if (!actual.equals(expected)) { + throw new Error("Expected " + expected + " but got " + actual); + } + System.out.println("Check passed for " + expected); + } + + public static void main(String[] args) throws Throwable { + NestedA a = new NestedA(); + NestedB b = new NestedB(); + NestedC c = new NestedC(); + ExternalSub sub = new ExternalSub(); + ExternalSuper sup = new ExternalSuper(); + + checkExternalSuper(sup); + checkExternalSuper(a); + checkExternalSuper(b); + checkExternalSuper(c); + checkExternalSuper(sub); + + checkA(a); + checkA(b); + checkA(c); + checkA(sub); + + NestedA.checkA(a); + NestedA.checkA(b); + NestedA.checkA(c); + NestedA.checkA(sub); + + NestedB.checkA(a); + NestedB.checkA(b); + NestedB.checkA(c); + NestedB.checkA(sub); + + NestedC.checkA(a); + NestedC.checkA(b); + NestedC.checkA(c); + NestedC.checkA(sub); + + checkB(b); + checkB(c); + checkB(sub); + + checkC(c); + checkC(sub); + + checkExternalSub(sub); + } +} + +// Classes that are not part of the nest. +// Being non-public allows us to declare them in this file. + +class ExternalSuper { + static final String ID = "ExternalSuper::priv_invoke"; + private String priv_invoke() { + return ID; + } +} + + +class ExternalSub extends TestReflectionHierarchy.NestedC { + static final String ID = "ExternalSub::priv_invoke"; + private String priv_invoke() { + return ID; + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateStaticFields/TestJNI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateStaticFields/TestJNI.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,138 @@ +/* + * 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 + * @bug 8046171 + * @summary Test JNI access to private static fields between nestmates and nest-host + * using different flavours of named nested types + * @compile ../NestmatesJNI.java + * @run main/othervm/native TestJNI + * @run main/othervm/native -Xcheck:jni TestJNI + */ +public class TestJNI { + + // Private field of nest-host for nestmates to access + private static int priv_field; + + static final String FIELD = "priv_field"; + + // public constructor so we aren't relying on private access + public TestJNI() {} + + // Methods that will access private static fields of nestmates + + // NOTE: No InnerNested calls in this test because non-static nested types + // can't have static fields. Also no StaticIface calls as static interface + // fields must be public (and final) + + void access_priv(TestJNI o) { + priv_field = getAndInc(o.getClass(), FIELD); + } + void access_priv(StaticNested o) { + priv_field = getAndInc(o.getClass(), FIELD); + } + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private static fields of nestmates + + default void access_priv(TestJNI o) { + int priv_field = getAndInc(o.getClass(), FIELD); + } + default void access_priv(StaticNested o) { + int priv_field = getAndInc(o.getClass(), FIELD); + } + } + + static class StaticNested { + + private static int priv_field; + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private static fields of nestmates + + void access_priv(TestJNI o) { + priv_field = getAndInc(o.getClass(), FIELD); + } + void access_priv(StaticNested o) { + priv_field = getAndInc(o.getClass(), FIELD); + } + } + + class InnerNested { + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestJNI o) { + int priv_field = getAndInc(o.getClass(), FIELD); + } + void access_priv(StaticNested o) { + int priv_field = getAndInc(o.getClass(), FIELD); + } + } + + public static void main(String[] args) { + TestJNI o = new TestJNI(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestJNI()); + o.access_priv(s); + + s.access_priv(o); + s.access_priv(new StaticNested()); + + i.access_priv(o); + i.access_priv(s); + + intf.access_priv(o); + intf.access_priv(s); + } + + static int getAndInc(Class<?> klass, String field) { + String definingClass = klass.getName(); + String desc = "Access to static field " + definingClass + "." + field; + int first, second; + try { + first = NestmatesJNI.getStaticIntField(definingClass, field); + NestmatesJNI.setStaticIntField(definingClass, field, (first + 1)); + second = NestmatesJNI.getStaticIntField(definingClass, field); + } + catch (Throwable t) { + throw new Error(desc + ": Unexpected exception: " + t, t); + } + if (second != first + 1) { + throw new Error(desc + ": wrong field values: first=" + first + + ", second=" + second + " (should equal first+1)"); + } + System.out.println(desc + " - passed"); + return first; + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateStaticFields/TestMethodHandles.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateStaticFields/TestMethodHandles.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private static fields between nestmates and nest-host + * using different flavours of named nested types using MethodHandles + * @run main TestMethodHandles + */ + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; + +import java.lang.reflect.Field; + +public class TestMethodHandles { + + // private static field of nest-host for nestmates to access + private static int priv_field; + + // public constructor so we aren't relying on private access + public TestMethodHandles() {} + + // Methods that will access private static fields of nestmates + + // NOTE: No InnerNested calls in this test because non-static nested types + // can't have static fields. Also no StaticIface calls as static interface + // fields must be public (and final) + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class); + priv_field = (int) mh.invoke(); + priv_field = (int) mh.invokeExact(); + mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class); + mh.invoke(2); + mh.invokeExact(3); + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class); + priv_field = (int) mh.invoke(); + priv_field = (int) mh.invokeExact(); + mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class); + mh.invoke(2); + mh.invokeExact(3); + } + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private static fields of nestmates + + default void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class); + int priv_field = (int) mh.invoke(); + priv_field = (int) mh.invokeExact(); + mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class); + mh.invoke(2); + mh.invokeExact(3); + } + default void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class); + int priv_field = (int) mh.invoke(); + priv_field = (int) mh.invokeExact(); + mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class); + mh.invoke(2); + mh.invokeExact(3); + } + } + + static class StaticNested { + + private static int priv_field; + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private static fields of nestmates + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class); + priv_field = (int) mh.invoke(); + priv_field = (int) mh.invokeExact(); + mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class); + mh.invoke(2); + mh.invokeExact(3); + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class); + priv_field = (int) mh.invoke(); + priv_field = (int) mh.invokeExact(); + mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class); + mh.invoke(2); + mh.invokeExact(3); + } + } + + class InnerNested { + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class); + priv_field = (int) mh.invoke(); + priv_field = (int) mh.invokeExact(); + mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class); + mh.invoke(2); + mh.invokeExact(3); + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = lookup().findStaticGetter(o.getClass(), "priv_field", int.class); + priv_field = (int) mh.invoke(); + priv_field = (int) mh.invokeExact(); + mh = lookup().findStaticSetter(o.getClass(), "priv_field", int.class); + mh.invoke(2); + mh.invokeExact(3); + } + } + + public static void main(String[] args) throws Throwable { + TestMethodHandles o = new TestMethodHandles(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestMethodHandles()); + o.access_priv(s); + + s.access_priv(o); + s.access_priv(new StaticNested()); + + i.access_priv(o); + i.access_priv(s); + + intf.access_priv(o); + intf.access_priv(s); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateStaticFields/TestPrivateStaticField.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateStaticFields/TestPrivateStaticField.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private static fields between nestmates and nest-host + * using different flavours of named nested types + * @run main TestPrivateStaticField + */ + +public class TestPrivateStaticField { + + // Private static field of nest-host for nestmates to access + private static int priv_field; + + // public constructor so we aren't relying on private access + public TestPrivateStaticField() {} + + // Methods that will access private static fields of nestmates + // We use the arguments for overloading purposes and use the fact + // you can access a static field through an object reference for + // convenience. + + // NOTE: No InnerNested calls in this test because non-static nested types + // can't have static fields. Also no StaticIface calls as static interface + // fields must be public (and final) + + void access_priv(TestPrivateStaticField o) { + priv_field = o.priv_field++; + } + void access_priv(StaticNested o) { + priv_field = o.priv_field++; + } + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private static fields of nestmates + + default void access_priv(TestPrivateStaticField o) { + int priv_field = o.priv_field++; + } + default void access_priv(StaticNested o) { + int priv_field = o.priv_field++; + } + } + + static class StaticNested { + + private static int priv_field; + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private static fields of nestmates + + void access_priv(TestPrivateStaticField o) { + priv_field = o.priv_field++; + } + void access_priv(StaticNested o) { + priv_field = o.priv_field++; + } + } + + class InnerNested { + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestPrivateStaticField o) { + int priv_field = o.priv_field++; + } + void access_priv(StaticNested o) { + int priv_field = o.priv_field++; + } + } + + public static void main(String[] args) { + TestPrivateStaticField o = new TestPrivateStaticField(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestPrivateStaticField()); + o.access_priv(s); + + s.access_priv(o); + s.access_priv(new StaticNested()); + + i.access_priv(o); + i.access_priv(s); + + intf.access_priv(o); + intf.access_priv(s); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateStaticFields/TestReflection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateStaticFields/TestReflection.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private static fields between nestmates and nest-host + * using different flavours of named nested types using core reflection + * @run main TestReflection + */ + +import java.lang.reflect.Field; + +public class TestReflection { + + // private static field of nest-host for nestmates to access + private static int priv_field; + + // public constructor so we aren't relying on private access + public TestReflection() {} + + // Methods that will access private static fields of nestmates + + // NOTE: No InnerNested calls in this test because non-static nested types + // can't have static fields. Also no StaticIface calls as static interface + // fields must be public (and final) + + void access_priv(TestReflection o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + priv_field = f.getInt(null); + f.setInt(null, 2); + } + void access_priv(StaticNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + priv_field = f.getInt(null); + f.setInt(null, 2); + } + + // The various nestmates + + static interface StaticIface { + + // Methods that will access private static fields of nestmates + + default void access_priv(TestReflection o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + int priv_field = f.getInt(null); + f.setInt(null, 2); + } + default void access_priv(StaticNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + int priv_field = f.getInt(null); + f.setInt(null, 2); + } + } + + static class StaticNested { + + private static int priv_field; + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private static fields of nestmates + + void access_priv(TestReflection o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + priv_field = f.getInt(null); + f.setInt(null, 2); + } + void access_priv(StaticNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + priv_field = f.getInt(null); + f.setInt(null, 2); + } + } + + class InnerNested { + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestReflection o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + priv_field = f.getInt(null); + f.setInt(null, 2); + } + void access_priv(StaticNested o) throws Throwable { + Field f = o.getClass().getDeclaredField("priv_field"); + priv_field = f.getInt(null); + f.setInt(null, 2); + } + } + + public static void main(String[] args) throws Throwable { + TestReflection o = new TestReflection(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestReflection()); + o.access_priv(s); + + s.access_priv(o); + s.access_priv(new StaticNested()); + + i.access_priv(o); + i.access_priv(s); + + intf.access_priv(o); + intf.access_priv(s); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateStaticMethods/TestInvokeStatic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateStaticMethods/TestInvokeStatic.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private static methods between nestmates and nest-host + * using different flavours of named nested types + * @run main TestInvokeStatic + */ + +public class TestInvokeStatic { + + // Private static method of nest-host for nestmates to access + private static void priv_static_invoke() { + System.out.println("TestInvokeStatic::priv_static_invoke"); + } + + // public constructor so we aren't relying on private access + public TestInvokeStatic() {} + + // Methods that will access private static methods of nestmates + // We use the arguments for overloading purposes and use the fact + // you can invoke a static method through an object reference for + // convenience. Except for static interface methods of course. + + // NOTE: No InnerNested calls in this test because non-static nested types + // can't have static method + + void access_priv(TestInvokeStatic o) { + o.priv_static_invoke(); + } + void access_priv(StaticNested o) { + o.priv_static_invoke(); + } + void access_priv(StaticIface o) { + StaticIface.priv_static_invoke(); + } + + // The various nestmates + + static interface StaticIface { + + private static void priv_static_invoke() { + System.out.println("StaticIface::priv_static_invoke"); + } + + // Methods that will access private static methods of nestmates + + default void access_priv(TestInvokeStatic o) { + o.priv_static_invoke(); + } + default void access_priv(StaticNested o) { + o.priv_static_invoke(); + } + default void access_priv(StaticIface o) { + StaticIface.priv_static_invoke(); + } + } + + static class StaticNested { + + private static void priv_static_invoke() { + System.out.println("StaticNested::priv_static_invoke"); + } + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private static methods of nestmates + + void access_priv(TestInvokeStatic o) { + o.priv_static_invoke(); + } + void access_priv(StaticNested o) { + o.priv_static_invoke(); + } + void access_priv(StaticIface o) { + StaticIface.priv_static_invoke(); + } + } + + class InnerNested { + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestInvokeStatic o) { + o.priv_static_invoke(); + } + void access_priv(StaticNested o) { + o.priv_static_invoke(); + } + void access_priv(StaticIface o) { + StaticIface.priv_static_invoke(); + } + } + + public static void main(String[] args) { + TestInvokeStatic o = new TestInvokeStatic(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestInvokeStatic()); + o.access_priv(s); + o.access_priv(intf); + + s.access_priv(o); + s.access_priv(new StaticNested()); + s.access_priv(intf); + + i.access_priv(o); + i.access_priv(s); + i.access_priv(intf); + + intf.access_priv(o); + intf.access_priv(s); + intf.access_priv(new StaticIface(){}); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateStaticMethods/TestJNI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateStaticMethods/TestJNI.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,163 @@ +/* + * 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 + * @bug 8046171 + * @summary Test JNI access to private methods between nestmates and nest-host + * using different flavours of named nested types + * @compile ../NestmatesJNI.java + * @run main/othervm/native TestJNI + * @run main/othervm/native -Xcheck:jni TestJNI + */ +public class TestJNI { + + // Unlike reflection, the calling context is not relevant to JNI + // calls, but we keep the same structure as the reflection tests. + + // Private static method of nest-host for nestmates to access + private static void priv_static_invoke() { + System.out.println("TestJNI::priv_static_invoke"); + } + + static final String METHOD = "priv_static_invoke"; + + // public constructor so we aren't relying on private access + public TestJNI() {} + + // Methods that will access private static methods of nestmates + // We use the arguments for overloading purposes and use the fact + // you can invoke a static method through an object reference for + // convenience. Except for static interface methods of course. + + // NOTE: No InnerNested calls in this test because non-static nested types + // can't have static method + + void access_priv(TestJNI o) { + doCall(o.getClass(), METHOD); + } + void access_priv(StaticNested o) { + doCall(o.getClass(), METHOD); + } + void access_priv(StaticIface o) { + // Can't use o.getClass() as the method is not in that class + doCall(StaticIface.class, METHOD); + } + + // The various nestmates + + static interface StaticIface { + + private static void priv_static_invoke() { + System.out.println("StaticIface::priv_static_invoke"); + } + + // Methods that will access private static methods of nestmates + + default void access_priv(TestJNI o) { + doCall(o.getClass(), METHOD); + } + default void access_priv(StaticNested o) { + doCall(o.getClass(), METHOD); + } + default void access_priv(StaticIface o) { + // Can't use o.getClass() as the method is not in that class + doCall(StaticIface.class, METHOD); + } + } + + static class StaticNested { + + private static void priv_static_invoke() { + System.out.println("StaticNested::priv_static_invoke"); + } + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private static methods of nestmates + + void access_priv(TestJNI o) { + doCall(o.getClass(), METHOD); + } + void access_priv(StaticNested o) { + doCall(o.getClass(), METHOD); + } + void access_priv(StaticIface o) { + // Can't use o.getClass() as the method is not in that class + doCall(StaticIface.class, METHOD); + } + } + + class InnerNested { + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestJNI o) { + doCall(o.getClass(), METHOD); + } + void access_priv(StaticNested o) { + doCall(o.getClass(), METHOD); + } + void access_priv(StaticIface o) { + // Can't use o.getClass() as the method is not in that class + doCall(StaticIface.class, METHOD); + } + } + + public static void main(String[] args) { + TestJNI o = new TestJNI(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestJNI()); + o.access_priv(s); + o.access_priv(intf); + + s.access_priv(o); + s.access_priv(new StaticNested()); + s.access_priv(intf); + + i.access_priv(o); + i.access_priv(s); + i.access_priv(intf); + + intf.access_priv(o); + intf.access_priv(s); + intf.access_priv(new StaticIface(){}); + } + + static void doCall(Class<?> klass, String method) { + String definingClass = klass.getName(); + String desc = "Static invocation of " + definingClass + "." + method; + try { + NestmatesJNI.callStaticVoidVoid(definingClass, method); + System.out.println(desc + " - passed"); + } + catch (Throwable t) { + throw new Error(desc + ": Unexpected exception: " + t, t); + } + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateStaticMethods/TestMethodHandles.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateStaticMethods/TestMethodHandles.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private static methods between nestmates and nest-host + * using different flavours of named nested types using MethodHandles + * @run main TestMethodHandles + */ + + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +public class TestMethodHandles { + + static final MethodType INVOKE_T = MethodType.methodType(void.class); + + // Private static method of nest-host for nestmates to access + private static void priv_static_invoke() { + System.out.println("TestMethodHandles::priv_static_invoke"); + } + + // public constructor so we aren't relying on private access + public TestMethodHandles() {} + + // Methods that will access private static methods of nestmates + + // NOTE: No InnerNested calls in this test because non-static nested types + // can't have static methods + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = + lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = + lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + void access_priv(StaticIface o) throws Throwable { + MethodHandle mh = + lookup().findStatic(StaticIface.class, "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + + // The various nestmates + + static interface StaticIface { + + private static void priv_static_invoke() { + System.out.println("StaticIface::priv_static_invoke"); + } + + // Methods that will access private static methods of nestmates + + default void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = + lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + default void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = + lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + default void access_priv(StaticIface o) throws Throwable { + MethodHandle mh = + lookup().findStatic(StaticIface.class, "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + } + + static class StaticNested { + + private static void priv_static_invoke() { + System.out.println("StaticNested::priv_static_invoke"); + } + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private static methods of nestmates + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = + lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = + lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + void access_priv(StaticIface o) throws Throwable { + MethodHandle mh = + lookup().findStatic(StaticIface.class, "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + } + + class InnerNested { + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestMethodHandles o) throws Throwable { + MethodHandle mh = + lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + void access_priv(StaticNested o) throws Throwable { + MethodHandle mh = + lookup().findStatic(o.getClass(), "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + void access_priv(StaticIface o) throws Throwable { + MethodHandle mh = + lookup().findStatic(StaticIface.class, "priv_static_invoke", INVOKE_T); + mh.invoke(); + mh.invokeExact(); + } + } + + public static void main(String[] args) throws Throwable { + TestMethodHandles o = new TestMethodHandles(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestMethodHandles()); + o.access_priv(s); + o.access_priv(intf); + + s.access_priv(o); + s.access_priv(new StaticNested()); + s.access_priv(intf); + + i.access_priv(o); + i.access_priv(s); + i.access_priv(intf); + + intf.access_priv(o); + intf.access_priv(s); + intf.access_priv(new StaticIface(){}); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/Nestmates/privateStaticMethods/TestReflection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Nestmates/privateStaticMethods/TestReflection.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046171 + * @summary Test access to private static methods between nestmates and nest-host + * using different flavours of named nested types using core reflection + * @run main TestReflection + * @run main/othervm -Dsun.reflect.noInflation=true TestReflection + */ + +// The first run will use NativeMethodAccessor and due to the limited number +// of calls we will not reach the inflation threshold. +// The second run disables inflation so we will use the GeneratedMethodAccessor +// instead. In this way both sets of Reflection classes are tested. + + +public class TestReflection { + + // Private method of nest-host for nestmates to access + private static void priv_static_invoke() { + System.out.println("TestReflection::priv_static_invoke"); + } + + // public constructor so we aren't relying on private access + public TestReflection() {} + + // Methods that will access private static methods of nestmates + + // NOTE: No InnerNested calls in this test because non-static nested types + // can't have static methods + + void access_priv(TestReflection o) throws Throwable { + o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + void access_priv(StaticNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + void access_priv(StaticIface o) throws Throwable { + // Can't use o.getClass() as the method is not in that class + StaticIface.class.getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + + // The various nestmates + + static interface StaticIface { + + private static void priv_static_invoke() { + System.out.println("StaticIface::priv_static_invoke"); + } + + // Methods that will access private static methods of nestmates + + default void access_priv(TestReflection o) throws Throwable { + o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + default void access_priv(StaticNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + default void access_priv(StaticIface o) throws Throwable { + // Can't use o.getClass() as the method is not in that class + StaticIface.class.getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + } + + static class StaticNested { + + private static void priv_static_invoke() { + System.out.println("StaticNested::priv_static_invoke"); + } + + // public constructor so we aren't relying on private access + public StaticNested() {} + + // Methods that will access private static methods of nestmates + + void access_priv(TestReflection o) throws Throwable { + o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + void access_priv(StaticNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + void access_priv(StaticIface o) throws Throwable { + // Can't use o.getClass() as the method is not in that class + StaticIface.class.getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + } + + class InnerNested { + + // public constructor so we aren't relying on private access + public InnerNested() {} + + void access_priv(TestReflection o) throws Throwable { + o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + void access_priv(StaticNested o) throws Throwable { + o.getClass().getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + void access_priv(StaticIface o) throws Throwable { + // Can't use o.getClass() as the method is not in that class + StaticIface.class.getDeclaredMethod("priv_static_invoke", new Class<?>[0]).invoke(null, new Object[0]); + } + } + + public static void main(String[] args) throws Throwable { + TestReflection o = new TestReflection(); + StaticNested s = new StaticNested(); + InnerNested i = o.new InnerNested(); + StaticIface intf = new StaticIface() {}; + + o.access_priv(new TestReflection()); + o.access_priv(s); + o.access_priv(intf); + + s.access_priv(o); + s.access_priv(new StaticNested()); + s.access_priv(intf); + + i.access_priv(o); + i.access_priv(s); + i.access_priv(intf); + + intf.access_priv(o); + intf.access_priv(s); + intf.access_priv(new StaticIface(){}); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/RedefineTests/RedefineDoubleDelete.java --- a/test/hotspot/jtreg/runtime/RedefineTests/RedefineDoubleDelete.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineDoubleDelete.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8178870 + * @bug 8178870 8010319 * @summary Redefine class with CFLH twice to test deleting the cached_class_file * @library /test/lib * @modules java.base/jdk.internal.misc @@ -34,27 +34,30 @@ * @run main/othervm/native -Xlog:redefine+class+load+exceptions -agentlib:RedefineDoubleDelete -javaagent:redefineagent.jar RedefineDoubleDelete */ +// package access top-level class to avoid problem with RedefineClassHelper +// and nested types. + +// The ClassFileLoadHook for this class turns foo into faa and prints out faa. +class RedefineDoubleDelete_B { + int faa() { System.out.println("foo"); return 1; } +} + public class RedefineDoubleDelete { // Class gets a redefinition error because it adds a data member public static String newB = - "class RedefineDoubleDelete$B {" + + "class RedefineDoubleDelete_B {" + " int count1 = 0;" + "}"; public static String newerB = - "class RedefineDoubleDelete$B { " + + "class RedefineDoubleDelete_B { " + " int faa() { System.out.println(\"baa\"); return 2; }" + "}"; - // The ClassFileLoadHook for this class turns foo into faa and prints out faa. - static class B { - int faa() { System.out.println("foo"); return 1; } - } - public static void main(String args[]) throws Exception { - B b = new B(); + RedefineDoubleDelete_B b = new RedefineDoubleDelete_B(); int val = b.faa(); if (val != 1) { throw new RuntimeException("return value wrong " + val); @@ -62,12 +65,12 @@ // Redefine B twice to get cached_class_file in both B scratch classes try { - RedefineClassHelper.redefineClass(B.class, newB); + RedefineClassHelper.redefineClass(RedefineDoubleDelete_B.class, newB); } catch (java.lang.UnsupportedOperationException e) { // this is expected } try { - RedefineClassHelper.redefineClass(B.class, newB); + RedefineClassHelper.redefineClass(RedefineDoubleDelete_B.class, newB); } catch (java.lang.UnsupportedOperationException e) { // this is expected } @@ -76,7 +79,7 @@ System.gc(); // Redefine with a compatible class - RedefineClassHelper.redefineClass(B.class, newerB); + RedefineClassHelper.redefineClass(RedefineDoubleDelete_B.class, newerB); val = b.faa(); if (val != 2) { throw new RuntimeException("return value wrong " + val); diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/RedefineTests/RedefineFinalizer.java --- a/test/hotspot/jtreg/runtime/RedefineTests/RedefineFinalizer.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineFinalizer.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6904403 + * @bug 6904403 8010319 * @summary Don't assert if we redefine finalize method * @library /test/lib * @modules java.base/jdk.internal.misc @@ -41,27 +41,31 @@ * * when redefining finalizer method */ + + +// package access top-level class to avoid problem with RedefineClassHelper +// and nested types. +class RedefineFinalizer_B { + protected void finalize() { + // should be empty + } +} + public class RedefineFinalizer { public static String newB = - "class RedefineFinalizer$B {" + + "class RedefineFinalizer_B {" + " protected void finalize() { " + " System.out.println(\"Finalizer called\");" + " }" + "}"; public static void main(String[] args) throws Exception { - RedefineClassHelper.redefineClass(B.class, newB); + RedefineClassHelper.redefineClass(RedefineFinalizer_B.class, newB); A a = new A(); } - static class A extends B { - } - - static class B { - protected void finalize() { - // should be empty - } + static class A extends RedefineFinalizer_B { } } diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/RedefineTests/RedefineInterfaceCall.java --- a/test/hotspot/jtreg/runtime/RedefineTests/RedefineInterfaceCall.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineInterfaceCall.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8174962 + * @bug 8174962 8010319 * @summary Redefine class with interface method call * @library /test/lib * @modules java.base/jdk.internal.misc @@ -39,19 +39,21 @@ interface I1 { default int m() { return 0; } } interface I2 extends I1 {} -public class RedefineInterfaceCall { +// package access top-level class to avoid problem with RedefineClassHelper +// and nested types. +class RedefineInterfaceCall_C implements I2 { + public int test(I2 i) { + return i.m(); // invokeinterface cpCacheEntry + } +} - public static class C implements I2 { - public int test(I2 i) { - return i.m(); // invokeinterface cpCacheEntry - } - } +public class RedefineInterfaceCall { static String newI1 = "interface I1 { default int m() { return 1; } }"; static String newC = - "public class RedefineInterfaceCall$C implements I2 { " + + "class RedefineInterfaceCall_C implements I2 { " + " public int test(I2 i) { " + " return i.m(); " + " } " + @@ -62,12 +64,12 @@ } public static void main(String[] args) throws Exception { - C c = new C(); + RedefineInterfaceCall_C c = new RedefineInterfaceCall_C(); assertEquals(test(c), 0); assertEquals(c.test(c), 0); - RedefineClassHelper.redefineClass(C.class, newC); + RedefineClassHelper.redefineClass(RedefineInterfaceCall_C.class, newC); assertEquals(c.test(c), 0); @@ -76,7 +78,7 @@ assertEquals(test(c), 1); assertEquals(c.test(c), 1); - RedefineClassHelper.redefineClass(C.class, newC); + RedefineClassHelper.redefineClass(RedefineInterfaceCall_C.class, newC); assertEquals(c.test(c), 1); } diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/RedefineTests/RedefineInterfaceMethods.java --- a/test/hotspot/jtreg/runtime/RedefineTests/RedefineInterfaceMethods.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineInterfaceMethods.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8081800 + * @bug 8081800 8010319 * @summary Redefine private and default interface methods * @library /test/lib * @modules java.base/jdk.internal.misc @@ -33,23 +33,27 @@ * @run main RedefineClassHelper * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class*=trace RedefineInterfaceMethods */ + +// package access top-level class to avoid problem with RedefineClassHelper +// and nested types. + +interface RedefineInterfaceMethods_B { + int ORIGINAL_RETURN = 1; + int NEW_RETURN = 2; + private int privateMethod() { + return ORIGINAL_RETURN; + } + public default int defaultMethod() { + return privateMethod(); + } +} + public class RedefineInterfaceMethods { static final int RET = -2; - static interface B { - int ORIGINAL_RETURN = 1; - int NEW_RETURN = 2; - private int privateMethod() { - return ORIGINAL_RETURN; - } - public default int defaultMethod() { - return privateMethod(); - } - } - public static String redefinedPrivateMethod = - "interface RedefineInterfaceMethods$B {" + + "interface RedefineInterfaceMethods_B {" + " int ORIGINAL_RETURN = 1;" + " int NEW_RETURN = 2;" + " private int privateMethod() {" + @@ -61,7 +65,7 @@ "}"; public static String redefinedDefaultMethod = - "interface RedefineInterfaceMethods$B {" + + "interface RedefineInterfaceMethods_B {" + " int ORIGINAL_RETURN = 1;" + " int NEW_RETURN = 2;" + " private int privateMethod() {" + @@ -72,7 +76,7 @@ " }" + "}"; - static class Impl implements B { + static class Impl implements RedefineInterfaceMethods_B { } @@ -81,20 +85,20 @@ Impl impl = new Impl(); int res = impl.defaultMethod(); - if (res != B.ORIGINAL_RETURN) + if (res != RedefineInterfaceMethods_B.ORIGINAL_RETURN) throw new Error("defaultMethod returned " + res + - " expected " + B.ORIGINAL_RETURN); + " expected " + RedefineInterfaceMethods_B.ORIGINAL_RETURN); - RedefineClassHelper.redefineClass(B.class, redefinedPrivateMethod); + RedefineClassHelper.redefineClass(RedefineInterfaceMethods_B.class, redefinedPrivateMethod); res = impl.defaultMethod(); - if (res != B.NEW_RETURN) + if (res != RedefineInterfaceMethods_B.NEW_RETURN) throw new Error("defaultMethod returned " + res + - " expected " + B.NEW_RETURN); + " expected " + RedefineInterfaceMethods_B.NEW_RETURN); System.gc(); - RedefineClassHelper.redefineClass(B.class, redefinedDefaultMethod); + RedefineClassHelper.redefineClass(RedefineInterfaceMethods_B.class, redefinedDefaultMethod); res = impl.defaultMethod(); if (res != RET) diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/RedefineTests/RedefinePreviousVersions.java --- a/test/hotspot/jtreg/runtime/RedefineTests/RedefinePreviousVersions.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefinePreviousVersions.java Sat Jun 23 01:32:41 2018 -0400 @@ -23,7 +23,7 @@ /* * @test - * @bug 8165246 + * @bug 8165246 8010319 * @summary Test has_previous_versions flag and processing during class unloading. * @requires vm.opt.final.ClassUnloading * @library /test/lib @@ -38,38 +38,43 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; +// package access top-level classes to avoid problem with RedefineClassHelper +// and nested types. + +class RedefinePreviousVersions_B { } + +class RedefinePreviousVersions_Running { + public static volatile boolean stop = false; + public static volatile boolean running = false; + static void localSleep() { + try { + Thread.sleep(10); // sleep for 10 ms + } catch(InterruptedException ie) { + } + } + + public static void infinite() { + running = true; + while (!stop) { localSleep(); } + } +} + + + public class RedefinePreviousVersions { public static String newB = - "class RedefinePreviousVersions$B {" + + "class RedefinePreviousVersions_B {" + "}"; - static class B { } - public static String newRunning = - "class RedefinePreviousVersions$Running {" + + "class RedefinePreviousVersions_Running {" + " public static volatile boolean stop = true;" + " public static volatile boolean running = true;" + " static void localSleep() { }" + " public static void infinite() { }" + "}"; - static class Running { - public static volatile boolean stop = false; - public static volatile boolean running = false; - static void localSleep() { - try{ - Thread.sleep(10); // sleep for 10 ms - } catch(InterruptedException ie) { - } - } - - public static void infinite() { - running = true; - while (!stop) { localSleep(); } - } - } - public static void main(String[] args) throws Exception { if (args.length > 0) { @@ -88,7 +93,7 @@ // Redefine a class and create some garbage // Since there are no methods running, the previous version is never added to the // previous_version_list and the flag _has_previous_versions should stay false - RedefineClassHelper.redefineClass(B.class, newB); + RedefineClassHelper.redefineClass(RedefinePreviousVersions_B.class, newB); for (int i = 0; i < 10 ; i++) { String s = new String("some garbage"); @@ -98,17 +103,17 @@ // Start a class that has a method running new Thread() { public void run() { - Running.infinite(); + RedefinePreviousVersions_Running.infinite(); } }.start(); - while (!Running.running) { + while (!RedefinePreviousVersions_Running.running) { Thread.sleep(10); // sleep for 10 ms } // Since a method of newRunning is running, this class should be added to the previous_version_list // of Running, and _has_previous_versions should return true at class unloading. - RedefineClassHelper.redefineClass(Running.class, newRunning); + RedefineClassHelper.redefineClass(RedefinePreviousVersions_Running.class, newRunning); for (int i = 0; i < 10 ; i++) { String s = new String("some garbage"); @@ -116,7 +121,7 @@ } // purge should clean everything up, except Xcomp it might not. - Running.stop = true; + RedefinePreviousVersions_Running.stop = true; for (int i = 0; i < 10 ; i++) { String s = new String("some garbage"); diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethods.java --- a/test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethods.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethods.java Sat Jun 23 01:32:41 2018 -0400 @@ -23,7 +23,7 @@ /* * @test - * @bug 8055008 8197901 + * @bug 8055008 8197901 8010319 * @summary Redefine EMCP and non-EMCP methods that are running in an infinite loop * @library /test/lib * @modules java.base/jdk.internal.misc @@ -34,10 +34,33 @@ * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace,all=trace:file=all.log RedefineRunningMethods */ // Test is executed with full trace logging redirected to a file to ensure there is no crash during logging anonymous classes - see JDK-8197901 + + +// package access top-level class to avoid problem with RedefineClassHelper +// and nested types. +class RedefineRunningMethods_B { + static int count1 = 0; + static int count2 = 0; + public static volatile boolean stop = false; + static void localSleep() { + try{ + Thread.currentThread().sleep(10);//sleep for 10 ms + } catch(InterruptedException ie) { + } + } + + public static void infinite() { + while (!stop) { count1++; localSleep(); } + } + public static void infinite_emcp() { + while (!stop) { count2++; localSleep(); } + } +} + public class RedefineRunningMethods { public static String newB = - "class RedefineRunningMethods$B {" + + "class RedefineRunningMethods_B {" + " static int count1 = 0;" + " static int count2 = 0;" + " public static volatile boolean stop = false;" + @@ -56,7 +79,7 @@ "}"; public static String evenNewerB = - "class RedefineRunningMethods$B {" + + "class RedefineRunningMethods_B {" + " static int count1 = 0;" + " static int count2 = 0;" + " public static volatile boolean stop = false;" + @@ -72,50 +95,31 @@ " }" + "}"; - static class B { - static int count1 = 0; - static int count2 = 0; - public static volatile boolean stop = false; - static void localSleep() { - try{ - Thread.currentThread().sleep(10);//sleep for 10 ms - } catch(InterruptedException ie) { - } - } - - public static void infinite() { - while (!stop) { count1++; localSleep(); } - } - public static void infinite_emcp() { - while (!stop) { count2++; localSleep(); } - } - } - public static void main(String[] args) throws Exception { new Thread() { public void run() { - B.infinite(); + RedefineRunningMethods_B.infinite(); } }.start(); new Thread() { public void run() { - B.infinite_emcp(); + RedefineRunningMethods_B.infinite_emcp(); } }.start(); - RedefineClassHelper.redefineClass(B.class, newB); + RedefineClassHelper.redefineClass(RedefineRunningMethods_B.class, newB); System.gc(); - B.infinite(); + RedefineRunningMethods_B.infinite(); // Start a thread with the second version of infinite_emcp running new Thread() { public void run() { - B.infinite_emcp(); + RedefineRunningMethods_B.infinite_emcp(); } }.start(); @@ -124,22 +128,22 @@ System.gc(); } - RedefineClassHelper.redefineClass(B.class, evenNewerB); + RedefineClassHelper.redefineClass(RedefineRunningMethods_B.class, evenNewerB); System.gc(); for (int i = 0; i < 20 ; i++) { - B.infinite(); + RedefineRunningMethods_B.infinite(); String s = new String("some garbage"); System.gc(); } - B.infinite_emcp(); + RedefineRunningMethods_B.infinite_emcp(); // purge should clean everything up. - B.stop = true; + RedefineRunningMethods_B.stop = true; for (int i = 0; i < 20 ; i++) { - B.infinite(); + RedefineRunningMethods_B.infinite(); String s = new String("some garbage"); System.gc(); } diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethodsWithBacktrace.java --- a/test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethodsWithBacktrace.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethodsWithBacktrace.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8087315 + * @bug 8087315 8010319 * @summary Get old method's stack trace elements after GC * @library /test/lib * @modules java.base/jdk.internal.misc @@ -36,16 +36,58 @@ import static jdk.test.lib.Asserts.*; +// package access top-level class to avoid problem with RedefineClassHelper +// and nested types. + +class RedefineRunningMethodsWithBacktrace_B { + static int count1 = 0; + static int count2 = 0; + public static volatile boolean stop = false; + static void localSleep() { + try { + Thread.sleep(10);//sleep for 10 ms + } catch(InterruptedException ie) { + } + } + + public static void infinite() { + while (!stop) { count1++; localSleep(); } + } + public static void throwable() { + // add some stuff to the original constant pool + String s1 = new String ("string1"); + String s2 = new String ("string2"); + String s3 = new String ("string3"); + String s4 = new String ("string4"); + String s5 = new String ("string5"); + String s6 = new String ("string6"); + String s7 = new String ("string7"); + String s8 = new String ("string8"); + String s9 = new String ("string9"); + String s10 = new String ("string10"); + String s11 = new String ("string11"); + String s12 = new String ("string12"); + String s13 = new String ("string13"); + String s14 = new String ("string14"); + String s15 = new String ("string15"); + String s16 = new String ("string16"); + String s17 = new String ("string17"); + String s18 = new String ("string18"); + String s19 = new String ("string19"); + throw new RuntimeException("throwable called"); + } +} + public class RedefineRunningMethodsWithBacktrace { public static String newB = - "class RedefineRunningMethodsWithBacktrace$B {" + + "class RedefineRunningMethodsWithBacktrace_B {" + " static int count1 = 0;" + " static int count2 = 0;" + " public static volatile boolean stop = false;" + " static void localSleep() { " + " try{ " + - " Thread.currentThread().sleep(10);" + + " Thread.sleep(10);" + " } catch(InterruptedException ie) { " + " } " + " } " + @@ -58,13 +100,13 @@ "}"; public static String evenNewerB = - "class RedefineRunningMethodsWithBacktrace$B {" + + "class RedefineRunningMethodsWithBacktrace_B {" + " static int count1 = 0;" + " static int count2 = 0;" + " public static volatile boolean stop = false;" + " static void localSleep() { " + " try{ " + - " Thread.currentThread().sleep(1);" + + " Thread.sleep(1);" + " } catch(InterruptedException ie) { " + " } " + " } " + @@ -74,45 +116,6 @@ " }" + "}"; - static class B { - static int count1 = 0; - static int count2 = 0; - public static volatile boolean stop = false; - static void localSleep() { - try { - Thread.currentThread().sleep(10);//sleep for 10 ms - } catch(InterruptedException ie) { - } - } - - public static void infinite() { - while (!stop) { count1++; localSleep(); } - } - public static void throwable() { - // add some stuff to the original constant pool - String s1 = new String ("string1"); - String s2 = new String ("string2"); - String s3 = new String ("string3"); - String s4 = new String ("string4"); - String s5 = new String ("string5"); - String s6 = new String ("string6"); - String s7 = new String ("string7"); - String s8 = new String ("string8"); - String s9 = new String ("string9"); - String s10 = new String ("string10"); - String s11 = new String ("string11"); - String s12 = new String ("string12"); - String s13 = new String ("string13"); - String s14 = new String ("string14"); - String s15 = new String ("string15"); - String s16 = new String ("string16"); - String s17 = new String ("string17"); - String s18 = new String ("string18"); - String s19 = new String ("string19"); - throw new RuntimeException("throwable called"); - } - } - private static void touchRedefinedMethodInBacktrace(Throwable throwable) { System.out.println("touchRedefinedMethodInBacktrace: "); throwable.printStackTrace(); // this actually crashes with the bug in @@ -133,7 +136,7 @@ private static Throwable getThrowableInB() { Throwable t = null; try { - B.throwable(); + RedefineRunningMethodsWithBacktrace_B.throwable(); } catch (Exception e) { t = e; // Don't print here because Throwable will cache the constructed stacktrace @@ -147,32 +150,32 @@ new Thread() { public void run() { - B.infinite(); + RedefineRunningMethodsWithBacktrace_B.infinite(); } }.start(); Throwable t1 = getThrowableInB(); - RedefineClassHelper.redefineClass(B.class, newB); + RedefineClassHelper.redefineClass(RedefineRunningMethodsWithBacktrace_B.class, newB); System.gc(); Throwable t2 = getThrowableInB(); - B.infinite(); + RedefineRunningMethodsWithBacktrace_B.infinite(); for (int i = 0; i < 20 ; i++) { String s = new String("some garbage"); System.gc(); } - RedefineClassHelper.redefineClass(B.class, evenNewerB); + RedefineClassHelper.redefineClass(RedefineRunningMethodsWithBacktrace_B.class, evenNewerB); System.gc(); Throwable t3 = getThrowableInB(); for (int i = 0; i < 20 ; i++) { - B.infinite(); + RedefineRunningMethodsWithBacktrace_B.infinite(); String s = new String("some garbage"); System.gc(); } @@ -182,10 +185,10 @@ touchRedefinedMethodInBacktrace(t3); // purge should clean everything up. - B.stop = true; + RedefineRunningMethodsWithBacktrace_B.stop = true; for (int i = 0; i < 20 ; i++) { - B.infinite(); + RedefineRunningMethodsWithBacktrace_B.infinite(); String s = new String("some garbage"); System.gc(); } diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/SelectionResolution/InvokeInterfaceICCE.java --- a/test/hotspot/jtreg/runtime/SelectionResolution/InvokeInterfaceICCE.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/SelectionResolution/InvokeInterfaceICCE.java Sat Jun 23 01:32:41 2018 -0400 @@ -154,20 +154,7 @@ Template.IfaceMethodrefNotEqualsExpected, Template.IgnoredAbstract, Template.AllCallsiteCases, - Template.IfaceMethodrefAmbiguousResolvedIsIface), - - /* Group 175: private method in interface */ - new TestGroup.Simple(initBuilder, - Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), - Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), - EnumSet.of(MethodData.Access.PRIVATE), - EnumSet.of(MethodData.Context.INSTANCE), - EnumSet.of(ClassData.Package.SAME)), - Template.OverrideAbstractExpectedIface, - Template.MethodrefEqualsExpected, - Template.IgnoredAbstract, - Template.CallsiteEqualsMethodref, - Template.IfaceMethodrefSelection) + Template.IfaceMethodrefAmbiguousResolvedIsIface) ); private InvokeInterfaceICCE() { diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/SelectionResolution/InvokeInterfaceSuccessTest.java --- a/test/hotspot/jtreg/runtime/SelectionResolution/InvokeInterfaceSuccessTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/SelectionResolution/InvokeInterfaceSuccessTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -136,6 +136,20 @@ Template.CallsiteUnrelatedToMethodref, Template.IfaceMethodrefSelection, Template.SelectionOverrideAbstract) + /* , + // Group 175: private method in interface [was ICCE case up to JDK 11] + // Can't get this to work for some reason. + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.IfaceMethodrefSelection) + */ ); private InvokeInterfaceSuccessTest() { diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/SelectionResolution/classes/selectionresolution/Template.java --- a/test/hotspot/jtreg/runtime/SelectionResolution/classes/selectionresolution/Template.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/SelectionResolution/classes/selectionresolution/Template.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -4394,6 +4394,15 @@ builder.objectref = C1; }); + // NOTE: The selection changes in JVMS 11 mean that private class methods + // are never selected to satisfy an interface method invocation, and so no + // IllegalAccessError is subsequently thrown. Because of this all the + // "private" cases below are commented out. At some point in the future + // these should be factored out and moved to a test that expects success + // but it is not that simple as the commented out cases result in 2600 + // testcases being excluded, but only ~150 failing cases were seen. Though + // it is not clear from the test if a single failure can result in further + // testcases being skipped. public static final Template IfaceMethodrefSelectionOverrideNonPublic = new Template("IfaceMethodrefSelection", /* Case 1: Objectref overrides. @@ -4401,22 +4410,22 @@ * I[](*) = mref * C[I](priv) = oref = expected */ - (final SelectionResolutionTestCase.Builder builder) -> { - final ClassData.Package pck = - builder.classdata.get(builder.methodref).packageId; - final ClassData oldexpected = - builder.classdata.get(builder.expected); - final MethodData meth = - new MethodData(MethodData.Access.PRIVATE, - MethodData.Context.INSTANCE); - final ClassData withDef = - new ClassData(pck, meth); - final int I = builder.methodref; - final int C = builder.addClass(withDef); - builder.hier.addInherit(C, I); - builder.objectref = C; - builder.expected = C; - }, + // (final SelectionResolutionTestCase.Builder builder) -> { + // final ClassData.Package pck = + // builder.classdata.get(builder.methodref).packageId; + // final ClassData oldexpected = + // builder.classdata.get(builder.expected); + // final MethodData meth = + // new MethodData(MethodData.Access.PRIVATE, + // MethodData.Context.INSTANCE); + // final ClassData withDef = + // new ClassData(pck, meth); + // final int I = builder.methodref; + // final int C = builder.addClass(withDef); + // builder.hier.addInherit(C, I); + // builder.objectref = C; + // builder.expected = C; + // }, /* Case 2: Objectref overrides. * * I[](*) = mref @@ -4466,27 +4475,27 @@ * C2[I2](priv) = expected, I1[I2]() * C1[I1,C2]() = oref */ - (final SelectionResolutionTestCase.Builder builder) -> { - final ClassData.Package pck = - builder.classdata.get(builder.expected).packageId; - final ClassData oldexpected = - builder.classdata.get(builder.expected); - final MethodData meth = - new MethodData(MethodData.Access.PRIVATE, - MethodData.Context.INSTANCE); - final ClassData withDef = - new ClassData(pck, meth); - final int I2 = builder.methodref; - final int I1 = builder.addInterface(emptyClass(pck)); - final int C2 = builder.addClass(withDef); - final int C1 = builder.addClass(emptyClass(pck)); - builder.hier.addInherit(C1, I1); - builder.hier.addInherit(C1, C2); - builder.hier.addInherit(I1, I2); - builder.hier.addInherit(C2, I2); - builder.objectref = C1; - builder.expected = C2; - }, + // (final SelectionResolutionTestCase.Builder builder) -> { + // final ClassData.Package pck = + // builder.classdata.get(builder.expected).packageId; + // final ClassData oldexpected = + // builder.classdata.get(builder.expected); + // final MethodData meth = + // new MethodData(MethodData.Access.PRIVATE, + // MethodData.Context.INSTANCE); + // final ClassData withDef = + // new ClassData(pck, meth); + // final int I2 = builder.methodref; + // final int I1 = builder.addInterface(emptyClass(pck)); + // final int C2 = builder.addClass(withDef); + // final int C1 = builder.addClass(emptyClass(pck)); + // builder.hier.addInherit(C1, I1); + // builder.hier.addInherit(C1, C2); + // builder.hier.addInherit(I1, I2); + // builder.hier.addInherit(C2, I2); + // builder.objectref = C1; + // builder.expected = C2; + // }, /* Case 5: Diamond, with superclass, expected at top, * class overriding with package private. * @@ -4549,24 +4558,24 @@ * C2[](priv) = expected, I1[](*) = mref * C1[I1,C2]() = oref */ - (final SelectionResolutionTestCase.Builder builder) -> { - final ClassData.Package pck = - builder.classdata.get(builder.expected).packageId; - final ClassData oldexpected = - builder.classdata.get(builder.expected); - final MethodData meth = - new MethodData(MethodData.Access.PRIVATE, - MethodData.Context.INSTANCE); - final ClassData withDef = - new ClassData(pck, meth); - final int I1 = builder.methodref; - final int C2 = builder.addClass(withDef); - final int C1 = builder.addClass(emptyClass(pck)); - builder.hier.addInherit(C1, I1); - builder.hier.addInherit(C1, C2); - builder.objectref = C1; - builder.expected = C2; - }, + // (final SelectionResolutionTestCase.Builder builder) -> { + // final ClassData.Package pck = + // builder.classdata.get(builder.expected).packageId; + // final ClassData oldexpected = + // builder.classdata.get(builder.expected); + // final MethodData meth = + // new MethodData(MethodData.Access.PRIVATE, + // MethodData.Context.INSTANCE); + // final ClassData withDef = + // new ClassData(pck, meth); + // final int I1 = builder.methodref; + // final int C2 = builder.addClass(withDef); + // final int C1 = builder.addClass(emptyClass(pck)); + // builder.hier.addInherit(C1, I1); + // builder.hier.addInherit(C1, C2); + // builder.objectref = C1; + // builder.expected = C2; + // }, /* Case 8: Y, with superclass, overlaping, expected * at top, class overrides * @@ -4622,26 +4631,26 @@ * C2[I2](priv) = expected, I1[](*) = mref * C1[I1,C2]() = oref */ - (final SelectionResolutionTestCase.Builder builder) -> { - final ClassData.Package pck = - builder.classdata.get(builder.expected).packageId; - final ClassData oldexpected = - builder.classdata.get(builder.expected); - final MethodData meth = - new MethodData(MethodData.Access.PRIVATE, - MethodData.Context.INSTANCE); - final ClassData withDef = - new ClassData(pck, meth); - final int I2 = builder.expected; - final int I1 = builder.methodref; - final int C2 = builder.addClass(withDef); - final int C1 = builder.addClass(emptyClass(pck)); - builder.hier.addInherit(C1, I1); - builder.hier.addInherit(C1, C2); - builder.hier.addInherit(C2, I2); - builder.objectref = C1; - builder.expected = C2; - }, + // (final SelectionResolutionTestCase.Builder builder) -> { + // final ClassData.Package pck = + // builder.classdata.get(builder.expected).packageId; + // final ClassData oldexpected = + // builder.classdata.get(builder.expected); + // final MethodData meth = + // new MethodData(MethodData.Access.PRIVATE, + // MethodData.Context.INSTANCE); + // final ClassData withDef = + // new ClassData(pck, meth); + // final int I2 = builder.expected; + // final int I1 = builder.methodref; + // final int C2 = builder.addClass(withDef); + // final int C1 = builder.addClass(emptyClass(pck)); + // builder.hier.addInherit(C1, I1); + // builder.hier.addInherit(C1, C2); + // builder.hier.addInherit(C2, I2); + // builder.objectref = C1; + // builder.expected = C2; + // }, /* Case 11: Diamond, with superclass, overlaping, expected * at top, class overrides * @@ -4702,25 +4711,25 @@ * C2[I](priv) = expected * C1[C2]() = oref */ - (final SelectionResolutionTestCase.Builder builder) -> { - final ClassData.Package pck = - builder.classdata.get(builder.expected).packageId; - final ClassData oldexpected = - builder.classdata.get(builder.expected); - final MethodData meth = - new MethodData(MethodData.Access.PRIVATE, - MethodData.Context.INSTANCE); - final ClassData withDef = - new ClassData(pck, meth); - final int I = builder.methodref; - final int C2 = builder.addClass(withDef); - final int C1 = builder.addClass(emptyClass(pck)); - builder.hier.addInherit(C1, I); - builder.hier.addInherit(C1, C2); - builder.hier.addInherit(C2, I); - builder.expected = C2; - builder.objectref = C1; - }, + // (final SelectionResolutionTestCase.Builder builder) -> { + // final ClassData.Package pck = + // builder.classdata.get(builder.expected).packageId; + // final ClassData oldexpected = + // builder.classdata.get(builder.expected); + // final MethodData meth = + // new MethodData(MethodData.Access.PRIVATE, + // MethodData.Context.INSTANCE); + // final ClassData withDef = + // new ClassData(pck, meth); + // final int I = builder.methodref; + // final int C2 = builder.addClass(withDef); + // final int C1 = builder.addClass(emptyClass(pck)); + // builder.hier.addInherit(C1, I); + // builder.hier.addInherit(C1, C2); + // builder.hier.addInherit(C2, I); + // builder.expected = C2; + // builder.objectref = C1; + // }, /* Case 14: Superclass overrides. * * I[](*) = mref diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineBasic.java --- a/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineBasic.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineBasic.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -24,10 +24,21 @@ import sun.hotspot.WhiteBox; +// package access top-level class to avoid problem with RedefineClassHelper +// and nested types. +class RedefineBasic_B { + public static void okToCallBeforeRedefine() { + System.out.println("okToCallBeforeRedefine"); + } + public static void okToCallAfterRedefine() { + throw new RuntimeException("okToCallAfterRedefine is called before redefinition, test failed"); + } +} + public class RedefineBasic { public static String newB = - " class RedefineBasic$B { " + + " class RedefineBasic_B { " + " public static void okToCallBeforeRedefine() { " + " throw new RuntimeException(\"newB: okToCallBeforeRedefine is " + " called after redefinition, test failed\"); }" + @@ -36,23 +47,14 @@ " } "; - static class B { - public static void okToCallBeforeRedefine() { - System.out.println("okToCallBeforeRedefine"); - } - public static void okToCallAfterRedefine() { - throw new RuntimeException( - "okToCallAfterRedefine is called before redefinition, test failed"); + + static class SubclassOfB extends RedefineBasic_B { + public static void testAfterRedefine() { + RedefineBasic_B.okToCallAfterRedefine(); } } - static class SubclassOfB extends B { - public static void testAfterRedefine() { - B.okToCallAfterRedefine(); - } - } - - class Subclass2OfB extends B { + class Subclass2OfB extends RedefineBasic_B { public void testAfterRedefine() { super.okToCallAfterRedefine(); } @@ -74,17 +76,17 @@ WhiteBox wb = WhiteBox.getWhiteBox(); verifyClassIsShared(wb, RedefineBasic.class); - verifyClassIsShared(wb, B.class); + verifyClassIsShared(wb, RedefineBasic_B.class); verifyClassIsShared(wb, SubclassOfB.class); verifyClassIsShared(wb, Subclass2OfB.class); // (1) Test case: verify that original B works as expected // and that redefined B is shared and works as expected, // with new behavior - B.okToCallBeforeRedefine(); - RedefineClassHelper.redefineClass(B.class, newB); - verifyClassIsShared(wb, B.class); - B.okToCallAfterRedefine(); + RedefineBasic_B.okToCallBeforeRedefine(); + RedefineClassHelper.redefineClass(RedefineBasic_B.class, newB); + verifyClassIsShared(wb, RedefineBasic_B.class); + RedefineBasic_B.okToCallAfterRedefine(); // Static subclass of the super: // 1. Make sure it is still shared diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineBasicTest.java --- a/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineBasicTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineBasicTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -43,7 +43,7 @@ public class RedefineBasicTest { public static String sharedClasses[] = { "RedefineBasic", - "RedefineBasic$B", + "RedefineBasic_B", "RedefineBasic$SubclassOfB", "RedefineBasic$Subclass2OfB", "RedefineClassHelper", diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineRunningMethods_Shared.java --- a/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineRunningMethods_Shared.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/runtime/appcds/redefineClass/RedefineRunningMethods_Shared.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -47,7 +47,7 @@ "RedefineRunningMethods$1", "RedefineRunningMethods$2", "RedefineRunningMethods$3", - "RedefineRunningMethods$B", + "RedefineRunningMethods_B", "RedefineClassHelper", "jdk/test/lib/compiler/InMemoryJavaCompiler", "jdk/test/lib/compiler/InMemoryJavaCompiler$FileManagerWrapper", diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/testlibrary_tests/RedefineClassTest.java --- a/test/hotspot/jtreg/testlibrary_tests/RedefineClassTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/testlibrary_tests/RedefineClassTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -38,19 +38,22 @@ /* * Proof of concept test for the test utility class RedefineClassHelper */ + +// package access top-level class to avoid problem with RedefineClassHelper +// and nested types. +class RedefineClassTest_A { + public int Method() { + return 1; + } +} + public class RedefineClassTest { - public static String newClass = "class RedefineClassTest$A { public int Method() { return 2; } }"; + public static String newClass = "class RedefineClassTest_A { public int Method() { return 2; } }"; public static void main(String[] args) throws Exception { - A a = new A(); + RedefineClassTest_A a = new RedefineClassTest_A(); assertTrue(a.Method() == 1); - RedefineClassHelper.redefineClass(A.class, newClass); + RedefineClassHelper.redefineClass(RedefineClassTest_A.class, newClass); assertTrue(a.Method() == 2); } - - static class A { - public int Method() { - return 1; - } - } } diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/vmTestbase/nsk/stress/except/except004.java --- a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except004.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except004.java Sat Jun 23 01:32:41 2018 -0400 @@ -211,15 +211,15 @@ Object integerValue = new Integer(0); Object doubleValue = new Double(0); Object trash = null; - Field abraPrivateField; Field abraIntegerField; Field abraBooleanField; + Field extPrivateField; try { - abraPrivateField = Abra.class.getDeclaredField("DONT_TOUCH_ME"); abraIntegerField = Abra.class.getDeclaredField("MAIN_CYR_NUMBER"); abraBooleanField = Abra.class.getDeclaredField("NOT_AN_INTEGER"); + extPrivateField = Ext.class.getDeclaredField("DONT_TOUCH_ME"); } catch (NoSuchFieldException nsfe) { - out.println("Test initialisation failed: field not found in class Abra"); + out.println("Test initialisation failed: field not found: " + nsfe.getMessage()); return 2; } @@ -369,7 +369,6 @@ // Check IllegalAccessException (positive): try { int junkIt = abraIntegerField.getInt(null); // legal - should pass -// int junkIt = abraPrivateField.getInt(null); // illegal - should fail if (TRACE_ON) log[messages++] = "Success: IllegalAccessException (positive)"; } catch (IllegalAccessException iae) { @@ -383,8 +382,7 @@ // Check IllegalAccessException (negative): try { -// int junkIt = abraIntegerField.getInt(null); // legal - should pass - int junkIt = abraPrivateField.getInt(null); // illegal - should fail + int junkIt = extPrivateField.getInt(null); // illegal - should fail log[messages++] = "Failure: IllegalAccessException (negative)"; exitCode = 2; // FAILED } catch (IllegalAccessException iae) { @@ -512,7 +510,7 @@ /** * This class should be used to check <code>CloneNotSupportedException</code>, - * <code>IllegalAccessException</code>, and <code>IllegalArgumentException</code>. + * and <code>IllegalArgumentException</code>. * The class extends <code>except004</code> in order that its (protected) * method <code>clone()</code> be available from <code>except004</code>. */ @@ -527,10 +525,6 @@ /** * Will try to incorrectly access to this field from outside this class. */ - private static final int DONT_TOUCH_ME = 666; - /** - * Will try to incorrectly access to this field from outside this class. - */ public static final int MAIN_CYR_NUMBER = 47; /** * Will try to get this field like <code>int<code> zero. @@ -551,3 +545,11 @@ } } } + +/* Package accessible class that has non-accessible private member */ +class Ext { + /** + * Will try to incorrectly access to this field from outside this class. + */ + private static final int DONT_TOUCH_ME = 666; +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/BasicTest.java --- a/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/BasicTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/BasicTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -81,7 +81,7 @@ expectedClass = IllegalArgumentException.class; } else if (factory.getExecutionMode().equals("INVOKE_WITH_ARGS")) { // Notes from JDK-8029926 which details reasons behind CCE. - // The code below demonstrates the use of a MethodHandle + // The code below demonstrates the use of a MethodHandle // of kind REF_invokeInterface pointing to method I.m. // Because 'invoke' is called, this MethodHandle is effectively // wrapped in the type adaptations necessary to accept a C @@ -157,38 +157,38 @@ } /* - * Default method override w/ non-public concrete method + * Default method override attempt w/ non-public concrete method. + * Private methods never override any other method. * - * interface I { void m() default {} } - * class C implements I { - * [private/package-private/protected] - * void m() {} + * interface I { int m() default { returns 1; } } + * class C/D/E implements I { + * [private/protected/package-private] + * int m() { returns 2;} * } * */ - @KnownFailure(modes = {INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY}) // NPE, instead of IAE public void testNonPublicOverride() { TestBuilder b = factory.getBuilder(); Interface I = b.intf("I") - .defaultMethod("m","()V").emptyBody().build() + .defaultMethod("m", "()I").returns(1).build() .build(); ConcreteClass C = b.clazz("C").implement(I) - .concreteMethod("m", "()V").private_().emptyBody().build() + .concreteMethod("m", "()I").private_().returns(2).build() .build(); ConcreteClass D = b.clazz("D").implement(I) - .concreteMethod("m", "()V").protected_().emptyBody().build() + .concreteMethod("m", "()I").protected_().returns(2).build() .build(); ConcreteClass E = b.clazz("E").implement(I) - .concreteMethod("m", "()V").package_private().emptyBody().build() + .concreteMethod("m", "()I").package_private().returns(2).build() .build(); - b.test().callSite(I, C, "m", "()V").throws_(IllegalAccessError.class).done() - .test().callSite(I, D, "m", "()V").throws_(IllegalAccessError.class).done() - .test().callSite(I, E, "m", "()V").throws_(IllegalAccessError.class).done() + b.test().callSite(I, C, "m", "()I").returns(1).done() + .test().callSite(I, D, "m", "()I").throws_(IllegalAccessError.class).done() + .test().callSite(I, E, "m", "()I").throws_(IllegalAccessError.class).done() .run(); } diff -r 0828a0f6676b -r 2f2af62dfac7 test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/PrivateMethodsTest.java --- a/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/PrivateMethodsTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/PrivateMethodsTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -48,11 +48,28 @@ // to even see an interface private method // Throw ICCE if method resolution returns interface private method + // Spec change JDK 11 - invokeinterface can be used for private interface + // methods and is now the preferred invocation bytecode - so no ICCE. + // Private methods are skipped during selection unless the resolved method + // is private. + // This change is not dependent on the classfile version. + + // Note on reflection testing: + // Reflection is only used for the initial callsite, which is not always + // the method of interest. For example where a default method m() calls + // the private interface method privateM(). It is the latter call we are + // really testing, but it is the call of the default method that occurs + // via reflection. + // In private cases reflection triggers a NoSuchMethodException instead of the + // expected IllegalAccessError. This indicates it is getDeclaredMethod() that is + // failing rather than the actual invoke(). Which in turn suggests the wrong class + // is being used, or that getMethod() is being used instead of getDeclaredMethod(). + /* * testPrivateInvokeVirtual * * interface I { - * default private int privateM() { return 1; } + * private int privateM() { return 1; } * default public int m() { return (I)this.privateM(); } // invokevirtual * } * class C implements I {} @@ -85,13 +102,13 @@ * testPrivateInvokeIntf * * interface I { - * default private int privateM() { return 1; } + * private int privateM() { return 1; } * default public int m() { return (I)this.privateM(); } // invokeinterface * } * class C implements I {} * - * TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError - * TEST: C o = new C(); o.m()I throws IncompatibleClassChangeError + * TEST: I o = new C(); o.m()I returns 1 + * TEST: C o = new C(); o.m()I returns 1 */ public void testPrivateInvokeIntf() { TestBuilder b = factory.getBuilder(); @@ -105,8 +122,8 @@ ConcreteClass C = b.clazz("C").implement(I).build(); - b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() - .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() + b.test().callSite(I, C, "m", "()I").returns(1).done() + .test().callSite(C, C, "m", "()I").returns(1).done() .run(); } @@ -115,13 +132,13 @@ * testPrivateInvokeStatic * * interface I { - * default private int privateM() { return 1; } + * private int privateM() { return 1; } * default public int m() { return I.privateM(); } // invokestatic * } * class C implements I {} * - * TEST: I o = new C(); o.m()I throws LinkageError - * TEST: C o = new C(); o.m()I throws LinkageError + * TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError + * TEST: C o = new C(); o.m()I throws IncompatibleClassChangeError */ public void testPrivateInvokeStatic() { TestBuilder b = factory.getBuilder(); @@ -135,8 +152,8 @@ ConcreteClass C = b.clazz("C").implement(I).build(); - b.test().callSite(I, C, "m", "()I").throws_(LinkageError.class).done() - .test().callSite(C, C, "m", "()I").throws_(LinkageError.class).done() + b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() + .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() .run(); } @@ -146,8 +163,8 @@ * testPrivateCallSameClass * * interface I { - * default private privateM()I { return 1; } - * default public int m() { return I.super.privateM(); } + * private privateM()I { return 1; } + * default public int m() { return I.super.privateM(); } // invokespecial * } * class C implements I {} * @@ -178,7 +195,7 @@ * Attempt to call from subinterface fails * interface I { - * default private privateM()I { return 1; } + * private privateM()I { return 1; } * } * J, K, L use invokespecial * interface J extends I { @@ -248,7 +265,7 @@ * Attempt to call from subclass fails * * interface I { - * default private privateM()I { return 1; } + * private privateM()I { return 1; } * } * class C implements I { * public int m() { return I.super.privateM(); } @@ -260,9 +277,9 @@ * public int m() { return C.super.privateM(); } * } * - * TEST: { C o = new C(); o.m()I throws LinkageError } - * TEST: { D o = new D(); o.m()I throws LinkageError } - * TEST: { E o = new E(); o.m()I throws NoSuchMethodError; } + * TEST: { C o = new C(); o.m()I throws IllegalAccessError (or VerifyError) } + * TEST: { D o = new D(); o.m()I throws VerifyError } + * TEST: { E o = new E(); o.m()I throws NoSuchMethodError (or VerifyError); } */ @NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading public void testPrivateCallImplClass() { @@ -289,16 +306,19 @@ .build(); Class eeExpectedClass; + Class ccExpectedClass; if (factory.getVer() >= 52) { eeExpectedClass = NoSuchMethodError.class; + ccExpectedClass = IllegalAccessError.class; } else { // The test gets a VerifyError in this case due to an // invokespecial IMR bytecode. This was not allowed // until class file version 52. (See 8030249.) eeExpectedClass = VerifyError.class; + ccExpectedClass = VerifyError.class; } - b.test().callSite(C, C, "m", "()I").throws_(LinkageError.class).done() - .test().callSite(D, D, "m", "()I").throws_(LinkageError.class).done() + b.test().callSite(C, C, "m", "()I").throws_(ccExpectedClass).done() + .test().callSite(D, D, "m", "()I").throws_(VerifyError.class).done() .test().callSite(E, E, "m", "()I").throws_(eeExpectedClass).done() .run(); @@ -308,18 +328,18 @@ // method overriding /* - * testPrivateDefault + * testPrivate * * interface I { - * default private int m() { return 1; } + * private int m() { return 1; } * } * class C implements I {} * * TEST: { I o = new C(); o.m()I throws IllegalAccessError; } * -mode reflect throws NoSuchMethodException - * TEST: { C o = new C(); o.m()I throws java/lang/NoSuchMethodError; } + * TEST: { C o = new C(); o.m()I throws NoSuchMethodError; } */ - public void testPrivateDefault() { + public void testPrivate() { TestBuilder b = factory.getBuilder(); Interface I = b.intf("I") @@ -343,10 +363,10 @@ } /* - * testPrivateDefaultVsConcrete + * testPrivateVsConcrete * * interface I { - * default private int m() { return 1; } + * private int m() { return 1; } * } * class C implements I { * public int m() { return 2; } @@ -356,7 +376,7 @@ * -mode reflect throws NoSuchMethodException * TEST: { C o = new C(); o.m()I == 2; } */ - public void testPrivateDefaultVsConcrete() { + public void testPrivateVsConcrete() { TestBuilder b = factory.getBuilder(); Interface I = b.intf("I") @@ -385,7 +405,7 @@ * testPublicOverridePrivate * * interface I { - * default private int m() { return 1; } + * private int m() { return 1; } * } * interface J extends I { * default public int m() { return 2; } @@ -433,7 +453,7 @@ * default public int m() { return 1; } * } * interface J extends I { - * default private int m() { return 2; } + * private int m() { return 2; } * } * class C implements J {} * @@ -441,14 +461,6 @@ * TEST: { J o = new C(); o.m()I == IllegalAccessError; } II J.m priv * TEST: { C o = new C(); o.m()I == 1; } */ - /* - - REFLECTION: - Test2_J_C_m : FAILED - nsk.share.TestFailure: Caught exception as expected, but its type is wrong: - expected: java.lang.IllegalAccessError; - actual: java.lang.NoSuchMethodException. - */ public void testPrivateOverrideDefault() { TestBuilder b = factory.getBuilder(); @@ -475,7 +487,7 @@ * testPrivateReabstract * * interface I { - * default private int m() { return 1; } + * private int m() { return 1; } * } * interface J extends I { * abstract public int m(); @@ -522,23 +534,14 @@ * abstract public int m(); * } * interface J extends I { - * default private int m() { return 1; } + * private int m() { return 1; } * } * class C implements J {} * * TEST: { I o = new C(); o.m()I throws AbstractMethodError } - * TEST: { J o = new C(); o.m()I throws IncompatibleClassChangeError } + * TEST: { J o = new C(); o.m()I throws IllegalAccessError } * TEST: { C o = new C(); o.m()I throws AbstractMethodError } */ - /* - REFLECTION: - Test1_I_C_m : FAILED - nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError - Test2_J_C_m : FAILED - nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError - Test3_C_C_m : FAILED - nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError - */ public void testPrivateOverrideAbstract() { TestBuilder b = factory.getBuilder(); @@ -553,24 +556,17 @@ ConcreteClass C = b.clazz("C").implement(J).build(); - Class expectedClass; - if (factory.getExecutionMode().equals("REFLECTION")) { - expectedClass = IllegalAccessException.class; - } else { - expectedClass = IncompatibleClassChangeError.class; - } - b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done() - .test().privateCallSite(J, C, "m", "()I").throws_(expectedClass).done() + .test().privateCallSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done() .test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done() .run(); } /* - * testPrivateInheritedDefault + * testPrivateInherited * * interface I { - * default private int m() { return 1; } + * private int m() { return 1; } * } * class B implements I {} * class C extends B {} @@ -580,7 +576,7 @@ * TEST: { B o = new C(); o.m()I throws NoSuchMethodError } * TEST: { C o = new C(); o.m()I throws NoSuchMethodError } */ - public void testPrivateInheritedDefault() { + public void testPrivateInherited() { TestBuilder b = factory.getBuilder(); Interface I = b.intf("I") @@ -607,10 +603,10 @@ } /* - * testPrivateDefaultVsConcreteInherited + * testPrivateVsConcreteInherited * * interface I { - * default private int m() { return 1; } + * private int m() { return 1; } * } * class B { * public int m() { return 2; } @@ -622,7 +618,7 @@ * TEST: { B o = new C(); o.m()I == 2; } * TEST: { C o = new C(); o.m()I == 2; } */ - public void testPrivateDefaultVsConcreteInherited() { + public void testPrivateVsConcreteInherited() { TestBuilder b = factory.getBuilder(); Interface I = b.intf("I") @@ -653,10 +649,10 @@ /* * testPrivateConflict * - * Conflicting default methods + * Conflicting methods * * interface I { - * default private int m() { return 1; } + * private int m() { return 1; } * } * interface J { * default public int m() { return 2; } diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/ProblemList-graal.txt --- a/test/jdk/ProblemList-graal.txt Fri Jun 22 17:49:21 2018 -0700 +++ b/test/jdk/ProblemList-graal.txt Sat Jun 23 01:32:41 2018 -0400 @@ -69,6 +69,8 @@ java/lang/Runtime/exec/LotsOfOutput.java 8196611 generic-all java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java 8196611 generic-all +java/lang/invoke/PrivateInterfaceCall.java 8202698 generic-all + # Next JFR tests fail with Graal. Assuming 8193210. jdk/jfr/event/compiler/TestCodeSweeper.java 8193210 generic-all jdk/jfr/event/compiler/TestCompilerInlining.java 8193210 generic-all diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/Host/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/Host/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,29 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "Host/Host.java";} + public int m() { + return 1; // original class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/Host/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/Host/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,29 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "Host/redef/Host.java";} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostA/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostA/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,30 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostA/Host.java";} + public static class A {} + public int m() { + return 1; // original class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostA/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostA/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,30 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostA/redef/Host.java"; } + public static class A {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostAB/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostAB/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostAB/Host.java";} + public static class A {} + public static class B {} + public int m() { + return 1; // original class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostAB/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostAB/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostAB/redef/Host.java"; } + public static class A {} + public static class B {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostABC/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostABC/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostABC/Host.java";} + public static class A {} + public static class B {} + public static class C {} + public int m() { + return 1; // original class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostABC/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostABC/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostABC/redef/Host.java"; } + public static class A {} + public static class B {} + public static class C {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostABCD/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostABCD/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,33 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostABCD/redef/Host.java"; } + public static class A {} + public static class B {} + public static class C {} + public static class D {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostABD/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostABD/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostABD/redef/Host.java"; } + public static class A {} + public static class B {} + public static class D {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostAC/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostAC/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostAC/redef/Host.java"; } + public static class A {} + public static class C {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostACB/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostACB/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostACB/redef/Host.java"; } + public static class A {} + public static class C {} + public static class B {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostB/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostB/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,30 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostB/redef/Host.java"; } + public static class B {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostBA/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostBA/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostBA/redef/Host.java"; } + public static class B {} + public static class A {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostBAC/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostBAC/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostBAC/redef/Host.java"; } + public static class B {} + public static class A {} + public static class C {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostBCA/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostBCA/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostBCA/redef/Host.java"; } + public static class B {} + public static class C {} + public static class A {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostCAB/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostCAB/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostCAB/redef/Host.java"; } + public static class C {} + public static class A {} + public static class B {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/HostCBA/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/HostCBA/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostCBA/redef/Host.java"; } + public static class C {} + public static class B {} + public static class A {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/NamedBuffer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/NamedBuffer.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; + +/* + * Copyright 2003 Wily Technology, Inc. + */ + +public class NamedBuffer +{ + private final String fName; + private final byte[] fBuffer; + + public + NamedBuffer( String name, + byte[] buffer) + { + fName = name; + fBuffer = buffer; + } + + public + NamedBuffer( String name, + InputStream stream) + throws IOException + { + this( name, + loadBufferFromStream(stream)); + } + + public String + getName() + { + return fName; + } + + public byte[] + getBuffer() + { + return fBuffer; + } + + public static byte[] + loadBufferFromStream(InputStream stream) + throws IOException + { + // hack for now, just assume the stream will fit in our reasonable size buffer. + // if not, panic + int bufferLimit = 200 * 1024; + byte[] readBuffer = new byte[bufferLimit]; + int actualSize = stream.read(readBuffer); + if ( actualSize >= bufferLimit ) + { + // if there might be more bytes, just surrender + throw new IOException("too big for buffer"); + } + + byte[] resultBuffer = new byte[actualSize]; + System.arraycopy( readBuffer, + 0, + resultBuffer, + 0, + actualSize); + return resultBuffer; + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/com/sun/jdi/RedefineNestmateAttr/TestNestmateAttr.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/TestNestmateAttr.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,582 @@ +/* + * 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 + * @bug 8046171 + * @summary Class redefinition must preclude changes to nest attributes + * @comment This is a copy of test/jdk/java/lang/instrument/RedefineNestmateAttr/ + * @comment modified for JDI + * @library /test/lib .. + * @modules java.compiler + * @run build TestScaffold VMConnection TargetListener TargetAdapter + * @compile NamedBuffer.java + * @compile Host/Host.java + * @run main/othervm TestNestmateAttr Host + * @compile HostA/Host.java + * @run main/othervm TestNestmateAttr HostA + * @compile HostAB/Host.java + * @run main/othervm TestNestmateAttr HostAB + * @compile HostABC/Host.java + * @run main/othervm TestNestmateAttr HostABC + */ + +/* Test Description + +The basic test class is called Host and we have variants that have zero or more +nested classes named A, B, C etc. Each variant of Host is defined in source +code in its own directory i.e. + +Host/Host.java defines zero nested classes +HostA/Host.java defines one nested class A +HostAB/Host.java defines two nested classes A and B (in that order) +etc. + +Each Host class has the form: + + public class Host { + public static String getID() { return "<directory name>/Host.java"; } + + < zero or more empty nested classes> + + public int m() { + return 1; // original class + } + } + +Under each directory is a directory "redef" with a modified version of the Host +class that changes the ID to e.g. Host/redef/Host.java, and the method m() +returns 2. This allows us to check we have the redefined class loaded. + +Using Host' to represent the redefined version we test redefinition +combinations as follows: + +Host: + Host -> Host' - succeeds m() returns 2 + Host -> HostA' - fails - added a nest member + +HostA: + HostA -> HostA' - succeeds m() returns 2 + HostA -> Host' - fails - removed a nest member + HostA -> HostAB' - fails - added a nest member + HostA -> HostB' - fails - replaced a nest member + +HostAB: + HostAB -> HostAB' - succeeds m() returns 2 + HostAB -> HostBA' - succeeds m() returns 2 + HostAB -> HostA' - fails - removed a nest member + HostAB -> HostABC' - fails - added a nest member + HostAB -> HostAC' - fails - replaced a nest member + +HostABC: + HostABC -> HostABC' - succeeds m() returns 2 + HostABC -> HostACB' - succeeds m() returns 2 + HostABC -> HostBAC' - succeeds m() returns 2 + HostABC -> HostBCA' - succeeds m() returns 2 + HostABC -> HostCAB' - succeeds m() returns 2 + HostABC -> HostCBA' - succeeds m() returns 2 + HostABC -> HostAB' - fails - removed a nest member + HostABC -> HostABCD' - fails - added a nest member + HostABC -> HostABD' - fails - replaced a nest member + +More than three nested classes doesn't add to the code coverage so +we stop here. + +Note that we always try to load the redefined version even when we expect it +to fail. + +We can only directly load one class Host per classloader, so to run all the +groups we either need to use new classloaders, or we reinvoke the test +requesting a different primary directory. We chose the latter using +multiple @run tags. So we proceed as follows: + + @compile Host/Host.java + @run TestNestmateAttr Host + @compile HostA/Host.java - replaces previous Host.class + @run TestNestmateAttr HostA + @compile HostAB/Host.java - replaces previous Host.class + @run TestNestmateAttr HostAB +etc. + +Within the test we directly compile redefined versions of the classes, +using CompilerUtil, and then read the .class file directly as a byte[]. + +Finally we test redefinition of the NestHost attribute - which is +conceptually simple, but in fact very tricky to do. We do that +when testing HostA so we can reuse the Host$A class. + +*/ + +import com.sun.jdi.*; +import com.sun.jdi.event.*; +import com.sun.jdi.request.*; + +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jdk.test.lib.ByteCodeLoader; +import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.compiler.InMemoryJavaCompiler; +import static jdk.test.lib.Asserts.assertTrue; + +/* For JDI the test is split across two VMs and so split into + two main classes. This is the class we will run under the debugger. + Package access so we can define in the same source file for ease of + reference. +*/ +class Target { + // We have to load all of the variants of the classes that we will + // attempt to redefine. This requires some in-memory compilation + // and use of additional classloaders. + public static void main(String[] args) throws Throwable { + String origin = args[0]; + System.out.println("Target: Testing original Host class from " + origin); + + // Make sure the Host class loaded directly is an original version + // and from the expected location + Host h = new Host(); + assertTrue(h.m() == 1); + assertTrue(Host.getID().startsWith(origin + "/")); + + // The rest of this setup is only needed for the case + // when we perform the checkNestHostChanges() test. + if (origin.equals("HostA")) { + String name = "Host$A"; + + // Have to do this reflectively as there is no Host$A + // when compiling the "Host/" case. + Class<?> nestedA = Class.forName(name); // triggers initialization + + // This is compiled as a top-level class: the $ in the name is not + // significant to the compiler. + String hostA = "public class " + name + " {}"; + byte[] bytes = InMemoryJavaCompiler.compile(name, hostA); + // And we have to load this into a new classloader + Class<?> topLevelHostA = ByteCodeLoader.load(name, bytes); + // The loaded class has not been linked (as per ClassLoader.resolveClass) + // and so will be filtered out by VirtualMachine.allClasses(). There are + // a number of ways to force linking - this is the simplest. + Object o = topLevelHostA.newInstance(); + + // sanity check + assertTrue(nestedA.getClassLoader() != topLevelHostA.getClassLoader()); + + } + + allowRedefine(); // debugger stops us here to attempt redefinitions + + System.out.println("Target executed okay"); + } + + public static void allowRedefine() { } +} + +public class TestNestmateAttr extends TestScaffold { + + static final String SRC = System.getProperty("test.src"); + static final String DEST = System.getProperty("test.classes"); + static final boolean VERBOSE = Boolean.getBoolean("verbose"); + + static String origin; + + // override this to correct a bug so arguments can be passed to + // the Target class + protected void startUp(String targetName) { + List<String> argList = new ArrayList<>(Arrays.asList(args)); + argList.add(0, targetName); // pre-pend so it becomes the first "app" arg + println("run args: " + argList); + connect((String[]) argList.toArray(args)); + waitForVMStart(); + } + + TestNestmateAttr (String[] args) { + super(args); + } + + public static void main(String[] args) throws Throwable { + origin = args[0]; + new TestNestmateAttr(args).startTests(); + } + + public void runTests() throws Exception { + // Get Target into debuggable state + BreakpointEvent bpe = startToMain("Target"); + EventRequestManager erm = vm().eventRequestManager(); + MethodEntryRequest mee = erm.createMethodEntryRequest(); + mee.addClassFilter("Target"); + mee.enable(); + + // Allow application to complete and shut down + listenUntilVMDisconnect(); + + if (getExceptionCaught()) { + throw new Exception("TestNestmateAttr: failed due to unexpected exception - check logs for details"); + } + else if (!testFailed) { + println("TestNestmateAttr: passed"); + } else { + throw new Exception("TestNestmateAttr: failure reported - check log for details"); + } + } + + // All the actual work is done from here once we see we've entered Target.allowRedefine() + public void methodEntered(MethodEntryEvent event) { + Method meth = event.location().method(); + + if (!meth.name().equals("allowRedefine")) { + return; + } + + System.out.println("TestNestmateAttr: Testing original Host class from " + origin); + + String[] badTransforms; // directories of bad classes + String[] goodTransforms; // directories of good classes + + boolean testNestHostChanges = false; + + switch (origin) { + case "Host": + badTransforms = new String[] { + "HostA" // add member + }; + goodTransforms = new String[] { + origin + }; + break; + + case "HostA": + badTransforms = new String[] { + "Host", // remove member + "HostAB", // add member + "HostB" // change member + }; + goodTransforms = new String[] { + origin + }; + testNestHostChanges = true; + break; + + case "HostAB": + badTransforms = new String[] { + "HostA", // remove member + "HostABC", // add member + "HostAC" // change member + }; + goodTransforms = new String[] { + origin, + "HostBA" // reorder members + }; + break; + + case "HostABC": + badTransforms = new String[] { + "HostAB", // remove member + "HostABCD", // add member + "HostABD" // change member + }; + goodTransforms = new String[] { + origin, + "HostACB", // reorder members + "HostBAC", // reorder members + "HostBCA", // reorder members + "HostCAB", // reorder members + "HostCBA" // reorder members + }; + break; + + default: throw new Error("Unknown test directory: " + origin); + } + + // Need to locate the type we will be trying to redefine in Target + findReferenceTypes(); + + try { + // Compile and check bad transformations + checkBadTransforms(_Host, badTransforms); + + // Compile and check good transformations + checkGoodTransforms(_Host, goodTransforms); + + if (testNestHostChanges) + checkNestHostChanges(); + } + catch (Throwable t) { + failure(t); + } + } + + // override to give exception details + protected void failure(Throwable t) { + super.failure(t.getMessage()); + t.printStackTrace(System.out); + } + + // These are references to the types in Target + // that we will be trying to redefine. + ReferenceType _Host; + ReferenceType _Host_A_nested; + ReferenceType _Host_A_topLevel; + + void findReferenceTypes() { + List<ReferenceType> classes = vm().allClasses(); + ClassLoaderReference cl = null; // track the main loader + ReferenceType a1 = null; + ReferenceType a2 = null; + for (ReferenceType c : classes) { + String name = c.name(); + if (name.equals("Host")) { + _Host = c; + cl = c.classLoader(); + } + else if (name.equals("Host$A")) { + if (a1 == null) { + a1 = c; + } else if (a2 == null) { + a2 = c; + } + else { + assertTrue(false); // Too many Host$A classes found! + } + } + } + assertTrue(_Host != null); + + // The rest of this setup is only needed for the case + // when we perform the checkNestHostChanges() test. + if (origin.equals("HostA")) { + assertTrue(a1 != null); + assertTrue(a2 != null); + + if (a1.classLoader() == cl) { + _Host_A_nested = a1; + assertTrue(a2.classLoader() != cl); + _Host_A_topLevel = a2; + } + else if (a2.classLoader() == cl) { + _Host_A_nested = a2; + assertTrue(a1.classLoader() != cl); + _Host_A_topLevel = a1; + } + else { + assertTrue(false); // Wrong classLoaders found + } + } + } + + void checkNestHostChanges() throws Throwable { + Map<ReferenceType, byte[]> map = new HashMap<>(); + + // case 1: remove NestHost attribute + // - try to redefine nested Host$A with a top-level + // class called Host$A + System.out.println("Trying bad retransform that removes the NestHost attribute"); + + String name = "Host$A"; + + // This is compiled as a top-level class: the $ in the name is not + // significant to the compiler. + String hostA = "public class " + name + " {}"; + byte[] bytes = InMemoryJavaCompiler.compile(name, hostA); + + map.put(_Host_A_nested, bytes); + + try { + vm().redefineClasses(map); + throw new Error("Retransformation to top-level class " + name + + " succeeded unexpectedly"); + } + catch (UnsupportedOperationException uoe) { + if (uoe.getMessage().contains("changes to class attribute not implemented")) { + System.out.println("Got expected exception " + uoe); + } + else throw new Error("Wrong UnsupportedOperationException", uoe); + } + + map.clear(); + + // case 2: add NestHost attribute + // - This is tricky because the class with no NestHost attribute + // has to have the name of a nested class! But we know how to + // do that as we already created a top-level Host$A. So now + // we try to replace with a really nested Host$A. + + System.out.println("Trying bad retransform that adds the NestHost attribute"); + + byte[] nestedBytes; + File clsfile = new File(DEST + "/" + name + ".class"); + if (VERBOSE) System.out.println("Reading bytes from " + clsfile); + try (FileInputStream str = new FileInputStream(clsfile)) { + nestedBytes = NamedBuffer.loadBufferFromStream(str); + } + + map.put(_Host_A_topLevel, nestedBytes); + + try { + vm().redefineClasses(map); + throw new Error("Retransformation to nested class " + name + + " succeeded unexpectedly"); + } + catch (UnsupportedOperationException uoe) { + if (uoe.getMessage().contains("changes to class attribute not implemented")) { + System.out.println("Got expected exception " + uoe); + } + else throw new Error("Wrong UnsupportedOperationException", uoe); + } + + map.clear(); + + // case 3: replace the NestHost attribute + // - the easiest way (perhaps only reasonable way) to do this + // is to search for the Utf8 entry used by the Constant_ClassRef, + // set in the NestHost attribute, and edit it to refer to a different + // name. We reuse nestedBytes from above. + + System.out.println("Trying bad retransform that changes the NestHost attribute"); + + int utf8Entry_length = 7; + boolean found = false; + for (int i = 0; i < nestedBytes.length - utf8Entry_length; i++) { + if (nestedBytes[i] == 1 && // utf8 tag + nestedBytes[i+1] == 0 && // msb of length + nestedBytes[i+2] == 4 && // lsb of length + nestedBytes[i+3] == (byte) 'H' && + nestedBytes[i+4] == (byte) 'o' && + nestedBytes[i+5] == (byte) 's' && + nestedBytes[i+6] == (byte) 't') { + + if (VERBOSE) System.out.println("Appear to have found Host utf8 entry starting at " + i); + + nestedBytes[i+3] = (byte) 'G'; + found = true; + break; + } + } + + if (!found) + throw new Error("Could not locate 'Host' name in byte array"); + + map.put(_Host_A_nested, nestedBytes); + + try { + vm().redefineClasses(map); + throw new Error("Retransformation to modified nested class" + + " succeeded unexpectedly"); + } + catch (UnsupportedOperationException uoe) { + if (uoe.getMessage().contains("changes to class attribute not implemented")) { + System.out.println("Got expected exception " + uoe); + } + else throw new Error("Wrong UnsupportedOperationException", uoe); + } + + } + + void checkGoodTransforms(ReferenceType c, String[] dirs) throws Throwable { + // To verify the redefinition actually took place we will invoke the + // Host.getID method and check the result. To do that we need to find the + // main thread in the target VM. We don't check that "(new Host()).m()" + // returns 2 due to the complexity of setting that up via JDI. + + ThreadReference main = null; + List<ThreadReference> threads = vm().allThreads(); + for (ThreadReference t : threads) { + if (t.name().equals("main")) { + main = t; + break; + } + } + + assertTrue(main != null); + + // Now find the method + Method getID = null; + List<Method> methods = _Host.methodsByName("getID"); + assertTrue(methods.size() == 1); + getID = methods.get(0); + + Map<ReferenceType, byte[]> map = new HashMap<>(); + for (String dir : dirs) { + dir += "/redef"; + System.out.println("Trying good retransform from " + dir); + byte[] buf = bytesForHostClass(dir); + map.put(c, buf); + vm().redefineClasses(map); + map.clear(); + // Test redefinition worked + Value v = ((ClassType)_Host).invokeMethod(main, getID, Collections.emptyList(), 0); + assertTrue(v instanceof StringReference); + String id = ((StringReference)v).value(); + if (VERBOSE) System.out.println("Redefined ID: " + id); + assertTrue(id.startsWith(dir)); + assertTrue(id.contains("/redef/")); + } + } + + void checkBadTransforms(ReferenceType c, String[] dirs) throws Throwable { + Map<ReferenceType, byte[]> map = new HashMap<>(); + for (String dir : dirs) { + dir += "/redef"; + System.out.println("Trying bad retransform from " + dir); + byte[] buf = bytesForHostClass(dir); + map.put(c, buf); + try { + vm().redefineClasses(map); + throw new Error("Retransformation from directory " + dir + + " succeeded unexpectedly"); + } + catch (UnsupportedOperationException uoe) { + if (uoe.getMessage().contains("changes to class attribute not implemented")) { + System.out.println("Got expected exception " + uoe); + } + else throw new Error("Wrong UnsupportedOperationException", uoe); + } + } + } + + static byte[] bytesForHostClass(String dir) throws Throwable { + compile("/" + dir); + File clsfile = new File(DEST + "/" + dir + "/Host.class"); + if (VERBOSE) System.out.println("Reading bytes from " + clsfile); + byte[] buf = null; + try (FileInputStream str = new FileInputStream(clsfile)) { + return buf = NamedBuffer.loadBufferFromStream(str); + } + } + + static void compile(String dir) throws Throwable { + File src = new File(SRC + dir); + File dst = new File(DEST + dir); + if (VERBOSE) System.out.println("Compiling from: " + src + "\n" + + " to: " + dst); + CompilerUtils.compile(src.toPath(), + dst.toPath(), + false /* don't recurse */, + new String[0]); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/Host/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/Host/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,29 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "Host/Host.java";} + public int m() { + return 1; // original class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/Host/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/Host/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,29 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "Host/redef/Host.java";} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostA/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostA/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,30 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostA/Host.java";} + public static class A {} + public int m() { + return 1; // original class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostA/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostA/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,30 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostA/redef/Host.java"; } + public static class A {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostAB/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostAB/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostAB/Host.java";} + public static class A {} + public static class B {} + public int m() { + return 1; // original class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostAB/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostAB/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostAB/redef/Host.java"; } + public static class A {} + public static class B {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostABC/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostABC/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostABC/Host.java";} + public static class A {} + public static class B {} + public static class C {} + public int m() { + return 1; // original class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostABC/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostABC/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostABC/redef/Host.java"; } + public static class A {} + public static class B {} + public static class C {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostABCD/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostABCD/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,33 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostABCD/redef/Host.java"; } + public static class A {} + public static class B {} + public static class C {} + public static class D {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostABD/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostABD/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostABD/redef/Host.java"; } + public static class A {} + public static class B {} + public static class D {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostAC/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostAC/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostAC/redef/Host.java"; } + public static class A {} + public static class C {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostACB/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostACB/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostACB/redef/Host.java"; } + public static class A {} + public static class C {} + public static class B {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostB/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostB/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,30 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostB/redef/Host.java"; } + public static class B {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostBA/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostBA/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostBA/redef/Host.java"; } + public static class B {} + public static class A {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostBAC/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostBAC/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostBAC/redef/Host.java"; } + public static class B {} + public static class A {} + public static class C {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostBCA/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostBCA/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostBCA/redef/Host.java"; } + public static class B {} + public static class C {} + public static class A {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostCAB/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostCAB/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostCAB/redef/Host.java"; } + public static class C {} + public static class A {} + public static class B {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/HostCBA/redef/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/HostCBA/redef/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,32 @@ +/* + * 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. + */ + +public class Host { + public static String getID() { return "HostCBA/redef/Host.java"; } + public static class C {} + public static class B {} + public static class A {} + public int m() { + return 2; // redefined class + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/instrument/RedefineNestmateAttr/TestNestmateAttr.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineNestmateAttr/TestNestmateAttr.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,376 @@ +/* + * 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 + * @bug 8046171 + * @summary Class redefinition must preclude changes to nest attributes + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @modules java.compiler + * java.instrument + * jdk.jartool/sun.tools.jar + * @compile ../NamedBuffer.java + * @run main RedefineClassHelper + * @compile Host/Host.java + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+nestmates=trace TestNestmateAttr Host + * @compile HostA/Host.java + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+nestmates=trace TestNestmateAttr HostA + * @compile HostAB/Host.java + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+nestmates=trace TestNestmateAttr HostAB + * @compile HostABC/Host.java + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+nestmates=trace TestNestmateAttr HostABC + */ + +/* Test Description + +The basic test class is call Host and we have variants that have zero or more +nested classes named A, B, C etc. Each variant of Host is defined in source +code in its own directory i.e. + +Host/Host.java defines zero nested classes +HostA/Host.java defines one nested class A +HostAB/Host.java defines two nested classes A and B (in that order) +etc. + +Each Host class has the form: + + public class Host { + public static String getID() { return "<directory name>/Host.java"; } + + < zero or more empty nested classes> + + public int m() { + return 1; // original class + } + } + +Under each directory is a directory "redef" with a modified version of the Host +class that changes the ID to e.g. Host/redef/Host.java, and the method m() +returns 2. This allows us to check we have the redefined class loaded. + +Using Host' to represent the redefined version we test redefinition +combinations as follows: + +Host: + Host -> Host' - succeeds m() returns 2 + Host -> HostA' - fails - added a nest member + +HostA: + HostA -> HostA' - succeeds m() returns 2 + HostA -> Host' - fails - removed a nest member + HostA -> HostAB' - fails - added a nest member + HostA -> HostB' - fails - replaced a nest member + +HostAB: + HostAB -> HostAB' - succeeds m() returns 2 + HostAB -> HostBA' - succeeds m() returns 2 + HostAB -> HostA' - fails - removed a nest member + HostAB -> HostABC' - fails - added a nest member + HostAB -> HostAC' - fails - replaced a nest member + +HostABC: + HostABC -> HostABC' - succeeds m() returns 2 + HostABC -> HostACB' - succeeds m() returns 2 + HostABC -> HostBAC' - succeeds m() returns 2 + HostABC -> HostBCA' - succeeds m() returns 2 + HostABC -> HostCAB' - succeeds m() returns 2 + HostABC -> HostCBA' - succeeds m() returns 2 + HostABC -> HostAB' - fails - removed a nest member + HostABC -> HostABCD' - fails - added a nest member + HostABC -> HostABD' - fails - replaced a nest member + +More than three nested classes doesn't add to the code coverage so +we stop here. + +Note that we always try to load the redefined version even when we expect it +to fail. + +We can only directly load one class Host per classloader, so to run all the +groups we either need to use new classloaders, or we reinvoke the test +requesting a different primary directory. We chose the latter using +multiple @run tags. So we preceed as follows: + + @compile Host/Host.java + @run TestNestmateAttr Host + @compile HostA/Host.java - replaces previous Host.class + @run TestNestmateAttr HostA + @compile HostAB/Host.java - replaces previous Host.class + @run TestNestmateAttr HostAB +etc. + +Within the test we directly compile redefined versions of the classes, +using CompilerUtil, and then read the .class file directly as a byte[] +to use with the RedefineClassHelper. + +Finally we test redefinition of the NestHost attribute - which is +conceptually simple, but in fact very tricky to do. We do that +when testing HostA so we can reuse the Host$A class. + +*/ + +import java.io.File; +import java.io.FileInputStream; +import jdk.test.lib.ByteCodeLoader; +import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.compiler.InMemoryJavaCompiler; +import static jdk.test.lib.Asserts.assertTrue; + +public class TestNestmateAttr { + + static final String SRC = System.getProperty("test.src"); + static final String DEST = System.getProperty("test.classes"); + static final boolean VERBOSE = Boolean.getBoolean("verbose"); + + public static void main(String[] args) throws Throwable { + String origin = args[0]; + System.out.println("Testing original Host class from " + origin); + + // Make sure the Host class loaded directly is an original version + // and from the expected location + Host h = new Host(); + assertTrue(h.m() == 1); + assertTrue(Host.getID().startsWith(origin + "/")); + + String[] badTransforms; // directories of bad classes + String[] goodTransforms; // directories of good classes + + boolean testNestHostChanges = false; + + switch (origin) { + case "Host": + badTransforms = new String[] { + "HostA" // add member + }; + goodTransforms = new String[] { + origin + }; + break; + + case "HostA": + badTransforms = new String[] { + "Host", // remove member + "HostAB", // add member + "HostB" // change member + }; + goodTransforms = new String[] { + origin + }; + testNestHostChanges = true; + break; + + case "HostAB": + badTransforms = new String[] { + "HostA", // remove member + "HostABC", // add member + "HostAC" // change member + }; + goodTransforms = new String[] { + origin, + "HostBA" // reorder members + }; + break; + + case "HostABC": + badTransforms = new String[] { + "HostAB", // remove member + "HostABCD", // add member + "HostABD" // change member + }; + goodTransforms = new String[] { + origin, + "HostACB", // reorder members + "HostBAC", // reorder members + "HostBCA", // reorder members + "HostCAB", // reorder members + "HostCBA" // reorder members + }; + break; + + default: throw new Error("Unknown test directory: " + origin); + } + + // Compile and check bad transformations + checkBadTransforms(Host.class, badTransforms); + + // Compile and check good transformations + checkGoodTransforms(Host.class, goodTransforms); + + if (testNestHostChanges) + checkNestHostChanges(); + } + + static void checkNestHostChanges() throws Throwable { + // case 1: remove NestHost attribute + // - try to redefine Host$A with a top-level + // class called Host$A + System.out.println("Trying bad retransform that removes the NestHost attribute"); + + String name = "Host$A"; + // This is compiled as a top-level class: the $ in the name is not + // significant to the compiler. + String hostA = "public class " + name + " {}"; + + // Have to do this reflectively as there is no Host$A + // when compiling the "Host/" case. + Class<?> nestedA = Class.forName(name); + + try { + RedefineClassHelper.redefineClass(nestedA, hostA); + throw new Error("Retransformation to top-level class " + name + + " succeeded unexpectedly"); + } + catch (UnsupportedOperationException uoe) { + if (uoe.getMessage().contains("attempted to change the class Nest")) { + System.out.println("Got expected exception " + uoe); + } + else throw new Error("Wrong UnsupportedOperationException", uoe); + } + + // case 2: add NestHost attribute + // - This is tricky because the class with no NestHost attribute + // has to have the name of a nested class! Plus we need the + // redefining class in bytecode form. + // - Use the InMemoryJavaCompiler plus ByteCodeLoader to load + // the top-level Host$A class + // - Try to redefine that class with a real nested Host$A + + System.out.println("Trying bad retransform that adds the NestHost attribute"); + byte[] bytes = InMemoryJavaCompiler.compile(name, hostA); + Class<?> topLevelHostA = ByteCodeLoader.load(name, bytes); + + byte[] nestedBytes; + File clsfile = new File(DEST + "/" + name + ".class"); + if (VERBOSE) System.out.println("Reading bytes from " + clsfile); + try (FileInputStream str = new FileInputStream(clsfile)) { + nestedBytes = NamedBuffer.loadBufferFromStream(str); + } + try { + RedefineClassHelper.redefineClass(topLevelHostA, nestedBytes); + throw new Error("Retransformation to nested class " + name + + " succeeded unexpectedly"); + } + catch (UnsupportedOperationException uoe) { + if (uoe.getMessage().contains("attempted to change the class Nest")) { + System.out.println("Got expected exception " + uoe); + } + else throw new Error("Wrong UnsupportedOperationException", uoe); + } + + // case 3: replace the NestHost attribute + // - the easiest way (perhaps only reasonable way) to do this + // is to search for the Utf8 entry used by the Constant_ClassRef, + // set in the NestHost attribute, and edit it to refer to a different + // name. + System.out.println("Trying bad retransform that changes the NestHost attribute"); + int utf8Entry_length = 7; + boolean found = false; + for (int i = 0; i < nestedBytes.length - utf8Entry_length; i++) { + if (nestedBytes[i] == 1 && // utf8 tag + nestedBytes[i+1] == 0 && // msb of length + nestedBytes[i+2] == 4 && // lsb of length + nestedBytes[i+3] == (byte) 'H' && + nestedBytes[i+4] == (byte) 'o' && + nestedBytes[i+5] == (byte) 's' && + nestedBytes[i+6] == (byte) 't') { + + if (VERBOSE) System.out.println("Appear to have found Host utf8 entry starting at " + i); + + nestedBytes[i+3] = (byte) 'G'; + found = true; + break; + } + } + + if (!found) + throw new Error("Could not locate 'Host' name in byte array"); + + try { + RedefineClassHelper.redefineClass(nestedA, nestedBytes); + throw new Error("Retransformation to modified nested class" + + " succeeded unexpectedly"); + } + catch (UnsupportedOperationException uoe) { + if (uoe.getMessage().contains("attempted to change the class Nest")) { + System.out.println("Got expected exception " + uoe); + } + else throw new Error("Wrong UnsupportedOperationException", uoe); + } + + } + + static void checkGoodTransforms(Class<?> c, String[] dirs) throws Throwable { + for (String dir : dirs) { + dir += "/redef"; + System.out.println("Trying good retransform from " + dir); + byte[] buf = bytesForHostClass(dir); + RedefineClassHelper.redefineClass(c, buf); + + // Test redefintion worked + Host h = new Host(); + assertTrue(h.m() == 2); + if (VERBOSE) System.out.println("Redefined ID: " + Host.getID()); + assertTrue(Host.getID().startsWith(dir)); + } + } + + static void checkBadTransforms(Class<?> c, String[] dirs) throws Throwable { + for (String dir : dirs) { + dir += "/redef"; + System.out.println("Trying bad retransform from " + dir); + byte[] buf = bytesForHostClass(dir); + try { + RedefineClassHelper.redefineClass(c, buf); + throw new Error("Retransformation from directory " + dir + + " succeeded unexpectedly"); + } + catch (UnsupportedOperationException uoe) { + if (uoe.getMessage().contains("attempted to change the class Nest")) { + System.out.println("Got expected exception " + uoe); + } + else throw new Error("Wrong UnsupportedOperationException", uoe); + } + } + } + + static byte[] bytesForHostClass(String dir) throws Throwable { + compile("/" + dir); + File clsfile = new File(DEST + "/" + dir + "/Host.class"); + if (VERBOSE) System.out.println("Reading bytes from " + clsfile); + byte[] buf = null; + try (FileInputStream str = new FileInputStream(clsfile)) { + return buf = NamedBuffer.loadBufferFromStream(str); + } + } + + static void compile(String dir) throws Throwable { + File src = new File(SRC + dir); + File dst = new File(DEST + dir); + if (VERBOSE) System.out.println("Compiling from: " + src + "\n" + + " to: " + dst); + CompilerUtils.compile(src.toPath(), + dst.toPath(), + false /* don't recurse */, + new String[0]); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/invoke/AccessControlTest.java --- a/test/jdk/java/lang/invoke/AccessControlTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/jdk/java/lang/invoke/AccessControlTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -241,8 +241,10 @@ LookupCase lc = this.in(c2); int m1 = lc.lookupModes(); int m2 = fixMods(m.getModifiers()); - // privacy is strictly enforced on lookups - if (c1 != c2) m1 &= ~PRIVATE; + // allow private lookup on nestmates. Otherwise, privacy is strictly enforced + if (c1 != c2 && ((m2 & PRIVATE) == 0 || !c1.isNestmateOf(c2))) { + m1 &= ~PRIVATE; + } // protected access is sometimes allowed if ((m2 & PROTECTED) != 0) { int prev = m2; @@ -252,7 +254,7 @@ m2 |= PUBLIC; // from a subclass, it acts like a public method also } if (verbosity >= 2) - System.out.println(this+" willAccess "+lc+" m1="+m1+" m2="+m2+" => "+((m2 & m1) != 0)); + System.out.format("%s willAccess %s m1=0x%h m2=0x%h => %s%n", this, lc, m1, m2, ((m2 & m1) != 0)); return (m2 & m1) != 0; } diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/invoke/FinalVirtualCallFromInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/invoke/FinalVirtualCallFromInterface.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,61 @@ +/* + * 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 + * @bug 8200167 8010319 + * @summary Regression test for a bug introduced in 8200167 and fixed in 8010319 + * @run main FinalVirtualCallFromInterface + */ + +import java.lang.invoke.*; + +/* + * Test that a MethodHandle for a final method, called from an interface, works correctly. + * With only 8200167 applied this fails with: + * Exception in thread "main" java.lang.InternalError: Should only be invoked on a subclass + * at + * java.base/java.lang.invoke.DirectMethodHandle.checkReceiver(DirectMethodHandle.java:441) + * + * The nestmate update under 8010319 fixes that bug. + */ +public class FinalVirtualCallFromInterface { + + static class Final { + public final void fm() {} + } + + static interface FinalUser { + static void test() throws Throwable { + MethodType mt = MethodType.methodType(void.class); + MethodHandle mh = MethodHandles.lookup().findVirtual(Final.class, "fm", mt); + Final f = new Final(); + mh.invokeExact(f); + mh.invoke(f); + } + } + + public static void main(String[] args) throws Throwable { + FinalUser.test(); + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/invoke/PrivateInterfaceCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/invoke/PrivateInterfaceCall.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,316 @@ +/* + * 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 + * @bug 8046171 + * @summary Test direct and MethodHandle access to private interface methods using invokeinterface semantics + * to ensure all receiver typechecks occur as required. + * @comment This complements SpecialInterfaceCall which tests invokespecial semantics. + * @compile PrivateInterfaceCall.java + * @compile PrivateInterfaceCallI4.jasm + * @run main/othervm -Xint PrivateInterfaceCall + * @run main/othervm -Xbatch -XX:+TieredCompilation -XX:TieredStopAtLevel=1 PrivateInterfaceCall + * @run main/othervm -Xbatch -XX:+TieredCompilation -XX:TieredStopAtLevel=2 PrivateInterfaceCall + * @run main/othervm -Xbatch -XX:+TieredCompilation -XX:TieredStopAtLevel=3 PrivateInterfaceCall + * @run main/othervm -Xbatch -XX:-TieredCompilation PrivateInterfaceCall + */ + +// This is an adaptation of SpecialInterfaceCall to only use private interface methods and with +// virtual invocation semantics. Because we don't have the same corner cases as for invokespecial +// there's no practical difference between the I3 and I2 cases here. But we do have to ensure the +// correct versions of the methods get executed. +// In addition we add tests that involve calls from nestmates - which also covers the distinction +// between the caller being a class and being an interface. + +import java.lang.invoke.*; + +public class PrivateInterfaceCall { + interface I1 { + private void priv_m() { throw new Error("Should not call this"); }; + } + interface I2 extends I1 { + private void priv_m() { }; + + static void invokeDirect(I2 i) { + i.priv_m(); // generates invokeinterface + } + static void invokeInterfaceMH(I2 i) throws Throwable { + // emulates behaviour of invokeDirect + mh_I2_priv_m_from_I2.invokeExact(i); + } + // special case of invoking an Object method via an interface + static void invokeInterfaceObjectMH(I2 i) throws Throwable { + // emulates invokeInterface of I2.toString on i, which resolves + // to Object.toString + String s = (String) mh_I2_toString_from_I2.invokeExact(i); + } + // special case of invoking a final Object method via an interface + static void invokeInterfaceObjectFinalMH(I2 i) throws Throwable { + // emulates invokeInterface of I1.getClass on i, which resolves + // to Object.getClass + Class<?> c = (Class<?>) mh_I2_getClass_from_I2.invokeExact(i); + } + + static void init() throws Throwable { + MethodType mt = MethodType.methodType(void.class); + MethodHandles.Lookup lookup = MethodHandles.lookup(); + mh_I2_priv_m_from_I2 = lookup.findVirtual(I2.class, "priv_m", mt); + + mt = MethodType.methodType(String.class); + mh_I2_toString_from_I2 = lookup.findVirtual(I2.class, "toString", mt); + + mt = MethodType.methodType(Class.class); + mh_I2_getClass_from_I2 = lookup.findVirtual(I2.class, "getClass", mt); + } + } + interface I3 extends I2 { + static void invokeInterfaceMH(I2 i) throws Throwable { + // emulates behaviour of I2.invokeDirect + mh_I2_priv_m_from_I3.invokeExact(i); + } + static void init() throws Throwable { + MethodType mt = MethodType.methodType(void.class); + mh_I2_priv_m_from_I3 = MethodHandles.lookup().findVirtual(I2.class, "priv_m", mt); + } + } + + // This interface acts like I2 but we define directInvoke* methods + // that we will rewrite the bytecode of to use invokeinterface + // (see PrivateInterfaceCallI4.jasm). + interface I4 extends I1 { + static void invokeDirect(I4 i) { + // invokeinterface I4.toString() + throw new Error("Class file for I4 is not overwritten"); + } + static void invokeDirectFinal(I4 i) { + // invokeinterface I4.getClass() - final method + throw new Error("Class file for I4 is not overwritten"); + } + } + + // check invocations from nestmates outside the + // inheritance hierarchy - and from a class not interface + static void invokeDirect(I2 i) { + i.priv_m(); // generates invokeinterface + } + static void invokeInterfaceMH(I2 i) throws Throwable { + mh_I2_priv_m_from_PIC.invokeExact(i); + } + + // Concrete classes + static class C2 implements I2 { } + static class C3 implements I3 { } + static class C4 implements I4 { } + + // Classes that don't implement I2/I3 but do have a + // priv_m method in their hierarchy + static class D1 implements I1 { } + static class E { + private void priv_m() { throw new Error("Should not call this"); } + } + + // This MH acts like the invocation in I2.invokeDirect with caller I2 + static MethodHandle mh_I2_priv_m_from_I2; + + // This MH acts like the invocation in I3.invokeDirect with caller I3 + static MethodHandle mh_I2_priv_m_from_I3; + + // This MH acts like the invocation in PrivateInterfaceCall.invokeDirect + // with caller PrivateInterfaceCall + static MethodHandle mh_I2_priv_m_from_PIC; + + // This MH acts likes an invokeinterface of I2.toString from I2 + static MethodHandle mh_I2_toString_from_I2; + + // This MH acts likes an invokeinterface of I2.getClass from I2 + static MethodHandle mh_I2_getClass_from_I2; + + static { + try { + MethodType mt = MethodType.methodType(void.class); + mh_I2_priv_m_from_PIC = MethodHandles.lookup().findVirtual(I2.class, "priv_m", mt); + I2.init(); + I3.init(); + } catch (Throwable e) { + throw new Error(e); + } + } + + static void runPositiveTests() { + shouldNotThrow(() -> PrivateInterfaceCall.invokeDirect(new C2())); + shouldNotThrow(() -> PrivateInterfaceCall.invokeDirect(new C3())); + shouldNotThrow(() -> PrivateInterfaceCall.invokeInterfaceMH(new C2())); + shouldNotThrow(() -> PrivateInterfaceCall.invokeInterfaceMH(new C3())); + + shouldNotThrow(() -> I2.invokeDirect(new C2())); + shouldNotThrow(() -> I2.invokeDirect(new C3())); + shouldNotThrow(() -> I2.invokeInterfaceMH(new C2())); + shouldNotThrow(() -> I2.invokeInterfaceMH(new C3())); + shouldNotThrow(() -> I2.invokeInterfaceObjectMH(new C2())); + shouldNotThrow(() -> I2.invokeInterfaceObjectMH(new C3())); + shouldNotThrow(() -> I2.invokeInterfaceObjectFinalMH(new C2())); + shouldNotThrow(() -> I2.invokeInterfaceObjectFinalMH(new C3())); + + // This looks odd but at runtime the only constraint is that the + // receiver is an I2. In contrast in the invokespecial case the + // receiver must be an I3. + shouldNotThrow(() -> I3.invokeInterfaceMH(unsafeCastI3(new C2()))); + shouldNotThrow(() -> I3.invokeInterfaceMH(new C3())); + + shouldNotThrow(() -> I4.invokeDirect(new C4())); + shouldNotThrow(() -> I4.invokeDirectFinal(new C4())); + } + + static void runNegativeTests() { + System.out.println("ICCE PrivateInterfaceCall.invokeDirect D1"); + shouldThrowICCE(() -> PrivateInterfaceCall.invokeDirect(unsafeCastI2(new D1()))); + System.out.println("ICCE PrivateInterfaceCall.invokeDirect E"); + shouldThrowICCE(() -> PrivateInterfaceCall.invokeDirect(unsafeCastI2(new E()))); + System.out.println("ICCE PrivateInterfaceCall.invokeInterfaceMH D1"); + shouldThrowICCE(() -> PrivateInterfaceCall.invokeInterfaceMH(unsafeCastI2(new D1()))); + System.out.println("ICCE PrivateInterfaceCall.invokeInterfaceMH E"); + shouldThrowICCE(() -> PrivateInterfaceCall.invokeInterfaceMH(unsafeCastI2(new E()))); + + + System.out.println("ICCE I2.invokeInterfaceMH D1"); + shouldThrowICCE(() -> I2.invokeInterfaceMH(unsafeCastI2(new D1()))); + System.out.println("ICCE I2.invokeInterfaceMH E"); + shouldThrowICCE(() -> I2.invokeInterfaceMH(unsafeCastI2(new E()))); + + System.out.println("ICCE I2.invokeInterfaceObjectFinalMH D1"); + shouldThrowICCE(() -> I2.invokeInterfaceObjectFinalMH(unsafeCastI2(new D1()))); + System.out.println("ICCE I2.invokeInterfaceObjectFinalMH E"); + shouldThrowICCE(() -> I2.invokeInterfaceObjectFinalMH(unsafeCastI2(new E()))); + + System.out.println("ICCE I3.invokeInterfaceMH D1"); + shouldThrowICCE(() -> I3.invokeInterfaceMH(unsafeCastI3(new D1()))); + System.out.println("ICCE I3.invokeInterfaceMH E"); + shouldThrowICCE(() -> I3.invokeInterfaceMH(unsafeCastI3(new E()))); + + System.out.println("ICCE I4.invokeDirect D1"); + shouldThrowICCE(() -> I4.invokeDirect(unsafeCastI4(new D1()))); + System.out.println("ICCE I4.invokeDirect E"); + shouldThrowICCE(() -> I4.invokeDirect(unsafeCastI4(new E()))); + } + + static void warmup() { + for (int i = 0; i < 20_000; i++) { + runPositiveTests(); + } + } + + public static void main(String[] args) throws Throwable { + System.out.println("UNRESOLVED:"); + runNegativeTests(); + runPositiveTests(); + + System.out.println("RESOLVED:"); + runNegativeTests(); + + System.out.println("WARMUP:"); + warmup(); + + System.out.println("COMPILED:"); + runNegativeTests(); + runPositiveTests(); + } + + static interface Test { + void run() throws Throwable; + } + + static void shouldThrowICCE(Test t) { + shouldThrow(IncompatibleClassChangeError.class, + "does not implement the requested interface", t); + } + + // Depending on whether the exception originates in the linkResolver, the interpreter + // or the compiler, the message can be different - which is unfortunate and could be + // fixed. So we allow the listed reason or else a null message. + static void shouldThrow(Class<?> expectedError, String reason, Test t) { + try { + t.run(); + } catch (Throwable e) { + // Don't accept subclasses as they can hide unexpected failure modes + if (expectedError == e.getClass()) { + String msg = e.getMessage(); + if ((msg != null && msg.contains(reason)) || msg == null) { + // passed + System.out.println("Threw expected: " + e); + return; + } + else { + throw new AssertionError("Wrong exception reason: expected '" + reason + + "', got '" + msg + "'", e); + } + } else { + String msg = String.format("Wrong exception thrown: expected=%s; thrown=%s", + expectedError.getName(), e.getClass().getName()); + throw new AssertionError(msg, e); + } + } + throw new AssertionError("No exception thrown: expected " + expectedError.getName()); + } + + static void shouldNotThrow(Test t) { + try { + t.run(); + // passed + } catch (Throwable e) { + throw new AssertionError("Exception was thrown: ", e); + } + } + + // Note: these unsafe casts are only possible for interface types + + static I2 unsafeCastI2(Object obj) { + try { + MethodHandle mh = MethodHandles.identity(Object.class); + mh = MethodHandles.explicitCastArguments(mh, mh.type().changeReturnType(I2.class)); + return (I2)mh.invokeExact((Object) obj); + } catch (Throwable e) { + throw new Error(e); + } + } + + static I3 unsafeCastI3(Object obj) { + try { + MethodHandle mh = MethodHandles.identity(Object.class); + mh = MethodHandles.explicitCastArguments(mh, mh.type().changeReturnType(I3.class)); + return (I3)mh.invokeExact((Object) obj); + } catch (Throwable e) { + throw new Error(e); + } + } + + static I4 unsafeCastI4(Object obj) { + try { + MethodHandle mh = MethodHandles.identity(Object.class); + mh = MethodHandles.explicitCastArguments(mh, mh.type().changeReturnType(I4.class)); + return (I4)mh.invokeExact((Object) obj); + } catch (Throwable e) { + throw new Error(e); + } + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/invoke/PrivateInterfaceCallI4.jasm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/invoke/PrivateInterfaceCallI4.jasm Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,49 @@ +/* + * 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. + */ + +// invokeDirect is modified to use invokeinterface instead of invokevirtual + +interface PrivateInterfaceCall$I4 implements PrivateInterfaceCall$I1 + version 55:0 +{ + public static Method invokeDirect:"(LPrivateInterfaceCall$I4;)V" + stack 1 locals 2 + { + aload_0; + invokeinterface InterfaceMethod PrivateInterfaceCall$I4.toString:"()Ljava/lang/String;", 1; + astore_1; + return; + } + + public static Method invokeDirectFinal:"(LPrivateInterfaceCall$I4;)V" + stack 1 locals 2 + { + aload_0; + invokeinterface InterfaceMethod PrivateInterfaceCall$I4.getClass:"()Ljava/lang/Class;", 1; + astore_1; + return; + } + static abstract interface InnerClass I4=class PrivateInterfaceCall$I4 of class PrivateInterfaceCall; + static abstract interface InnerClass I1=class PrivateInterfaceCall$I1 of class PrivateInterfaceCall; + +} // end Class PrivateInterfaceCall$I4 diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/invoke/SpecialInterfaceCall.java --- a/test/jdk/java/lang/invoke/SpecialInterfaceCall.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/jdk/java/lang/invoke/SpecialInterfaceCall.java Sat Jun 23 01:32:41 2018 -0400 @@ -23,9 +23,10 @@ /** * @test - * @bug 8200167 + * @bug 8200167 8010319 * @summary Test direct and MethodHandle access to interface methods using invokespecial semantics - * @compile SpecialInterfaceCall.java + * @comment This must be compiled so invokespecial is used + * @compile -XDdisableVirtualizedPrivateInvoke SpecialInterfaceCall.java * @compile SpecialInterfaceCallI4.jasm * @run main/othervm -Xint SpecialInterfaceCall * @run main/othervm -Xbatch -XX:+TieredCompilation -XX:TieredStopAtLevel=1 SpecialInterfaceCall diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/HostOfMemberMalformedHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/HostOfMemberMalformedHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to class with invalid class file format + +class HostOfMemberMalformedHost$MemberMalformedHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "Hosts.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "HostOfMemberMalformedHost$MemberMalformedHost"; // #13 + Utf8 "MemberMalformedHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "HostOfMemberMalformedHost"; // #17 + // added + Utf8 "MalformedHost"; // #18 + class #18; // #19 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 68; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x0013; // Modified #19 + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class HostOfMemberMalformedHost$MemberMalformedHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/HostOfMemberMissingHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/HostOfMemberMissingHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to non-existent class + +class HostOfMemberMissingHost$MemberMissingHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "Hosts.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "HostOfMemberMissingHost$MemberMissingHost"; // #13 + Utf8 "MemberMissingHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "HostOfMemberMissingHost"; // #17 + class #10; // #18 - added + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 60; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x0012; // modified + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class HostOfMemberMissingHost$MemberMissingHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/HostOfMemberNoHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/HostOfMemberNoHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute deleted + +class HostOfMemberNoHost$MemberNoHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "Hosts.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "HostOfMemberNoHost$MemberNoHost"; // #13 + Utf8 "MemberNoHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "HostOfMemberNoHost"; // #17 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 57; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class HostOfMemberNoHost$MemberNoHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/HostOfMemberNotInstanceHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/HostOfMemberNotInstanceHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to non-instance class + +class HostOfMemberNotInstanceHost$MemberNotInstanceHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #14; // #1 + class #15; // #2 + class #18; // #3 + Utf8 "oa"; // #4 + Utf8 "[LInvalidNestHost;"; // #5 + Utf8 "<init>"; // #6 + Utf8 "()V"; // #7 + Utf8 "Code"; // #8 + Utf8 "LineNumberTable"; // #9 + Utf8 "SourceFile"; // #10 + Utf8 "Hosts.java"; // #11 + Utf8 "NestHost"; // #12 + class #19; // #13 + NameAndType #6 #7; // #14 + Utf8 "HostOfMemberNotInstanceHost$MemberNotInstanceHost"; // #15 + Utf8 "MemberNotInstanceHost"; // #16 + Utf8 "InnerClasses"; // #17 + Utf8 "java/lang/Object"; // #18 + Utf8 "HostOfMemberNotInstanceHost"; // #19 + class #5; // #20 - added + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0000; // access + #6; // name_cpx + #7; // sig_cpx + [] { // Attributes + Attr(#8) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#9) { // LineNumberTable + [] { // LineNumberTable + 0 63; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#10) { // SourceFile + #11; + } // end SourceFile + ; + Attr(#12) { // NestHost + 0x0014; // Modified #20 + } // end NestHost + ; + Attr(#17) { // InnerClasses + [] { // InnerClasses + #2 #13 #16 8; + } + } // end InnerClasses + } // Attributes +} // end class HostOfMemberNotInstanceHost$MemberNotInstanceHost + diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/HostOfMemberNotOurHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/HostOfMemberNotOurHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to class with no nest + +class HostOfMemberNotOurHost$MemberNotOurHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "Hosts.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "HostOfMemberNotOurHost$MemberNotOurHost"; // #13 + Utf8 "MemberNotOurHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "HostOfMemberNotOurHost"; // #17 + // Added + Utf8 "InvalidNestHost"; // #18 + class #18; // #19 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 68; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x0013; // Modified #19 + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class HostOfMemberNotOurHost$MemberNotOurHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/HostWithDuplicateMembers.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/HostWithDuplicateMembers.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,107 @@ +/* + * 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. + */ + +// Modify NestMembers attribute to contain multiple duplicates + +class HostWithDuplicateMembers { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #16; // #1 + class #17; // #2 + class #18; // #3 + class #19; // #4 + Utf8 "Member2"; // #5 + Utf8 "InnerClasses"; // #6 + class #20; // #7 + Utf8 "Member1"; // #8 + Utf8 "<init>"; // #9 + Utf8 "()V"; // #10 + Utf8 "Code"; // #11 + Utf8 "LineNumberTable"; // #12 + Utf8 "SourceFile"; // #13 + Utf8 "Hosts.java"; // #14 + Utf8 "NestMembers"; // #15 + NameAndType #9 #10; // #16 + Utf8 "HostWithDuplicateMembers"; // #17 + Utf8 "java/lang/Object"; // #18 + Utf8 "HostWithDuplicateMembers$Member2"; // #19 + Utf8 "HostWithDuplicateMembers$Member1"; // #20 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #9; // name_cpx + #10; // sig_cpx + [] { // Attributes + Attr(#11) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#12) { // LineNumberTable + [] { // LineNumberTable + 0 60; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#13) { // SourceFile + #14; + } // end SourceFile + ; + Attr(#15) { // NestMembers + 0x0006000700040007; // modified + 0x000400070004; + } // end NestMembers + ; + Attr(#6) { // InnerClasses + [] { // InnerClasses + #4 #2 #5 1544; + #7 #2 #8 8; + } + } // end InnerClasses + } // Attributes +} // end class HostWithDuplicateMembers diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/HostWithSelfMember.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/HostWithSelfMember.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,102 @@ +/* + * 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. + */ + +// Modify NestMembers attribute to include reference to the currnet class + +class HostWithSelfMember { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #14; // #1 + class #15; // #2 + class #16; // #3 + class #17; // #4 + Utf8 "Member"; // #5 + Utf8 "InnerClasses"; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "SourceFile"; // #11 + Utf8 "Hosts.java"; // #12 + Utf8 "NestMembers"; // #13 + NameAndType #7 #8; // #14 + Utf8 "HostWithSelfMember"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "HostWithSelfMember$Member"; // #17 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 55; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#11) { // SourceFile + #12; + } // end SourceFile + ; + Attr(#13) { // NestMembers + 0x000200040002; // modified - added self + } // end NestMembers + ; + Attr(#6) { // InnerClasses + [] { // InnerClasses + #4 #2 #5 8; + } + } // end InnerClasses + } // Attributes +} // end class HostWithSelfMember diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/Hosts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/Hosts.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, 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. + */ + +// Non-public classes so we can keep them all in this one source file + +class HostOfMemberNoHost { + // Missing NestHost attribute + static class MemberNoHost {} +} + +class HostOfMemberMissingHost { + // Missing NestHost class + static class MemberMissingHost {} +} + +class HostOfMemberNotInstanceHost { + // Invalid NestHost class (not instance class) + static class MemberNotInstanceHost { + Object[] oa; // create CP entry to use in jcod change + } +} + +class HostOfMemberNotOurHost { + // Valid but different NestHost class + static class MemberNotOurHost {} +} + +class HostOfMemberMalformedHost { + // Malformed NestHost class + static class MemberMalformedHost {} +} + +// Host lists itself as a member along +// with real member. +class HostWithSelfMember { + static class Member {} +} + +// Host lists duplicate members. +class HostWithDuplicateMembers { + static class Member1 {} + static interface Member2 {} +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/InvalidNestHost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/InvalidNestHost.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,29 @@ +/* + * 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. + */ + +/* Empty class to use as an invalid nest-host class, in the same package as + * the test classes. + */ +public class InvalidNestHost { +} + diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/MalformedHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/MalformedHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017, 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. + */ + +// Invalid class file format + +class MalformedHost { + 0xDEADBEEF; // bad magic number + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "MemberMalformedHost"; // #14 + Utf8 "java/lang/Object"; // #16 + Utf8 "TestReflectionAPI"; // #17 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 68; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + } // Attributes +} // end class MalformedHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/MemberMalformedHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/MemberMalformedHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to class with invalid class file format + +class TestReflectionAPI$MemberMalformedHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "TestReflectionAPI.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "TestReflectionAPI$MemberMalformedHost"; // #13 + Utf8 "MemberMalformedHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "TestReflectionAPI"; // #17 + // added + Utf8 "MalformedHost"; // #18 + class #18; // #19 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 68; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x0013; // Modified #19 + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class TestReflectionAPI$MemberMalformedHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/MemberMissingHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/MemberMissingHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to non-existent class + +class TestReflectionAPI$MemberMissingHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "TestReflectionAPI.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "TestReflectionAPI$MemberMissingHost"; // #13 + Utf8 "MemberMissingHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "TestReflectionAPI"; // #17 + class #10; // #18 - added + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 60; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x0012; // modified + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class TestReflectionAPI$MemberMissingHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/MemberNoHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/MemberNoHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute deleted + +class TestReflectionAPI$MemberNoHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "TestReflectionAPI.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "TestReflectionAPI$MemberNoHost"; // #13 + Utf8 "MemberNoHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "TestReflectionAPI"; // #17 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 57; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class TestReflectionAPI$MemberNoHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/MemberNotInstanceHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/MemberNotInstanceHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to non-instance class + +class TestReflectionAPI$MemberNotInstanceHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #14; // #1 + class #15; // #2 + class #18; // #3 + Utf8 "oa"; // #4 + Utf8 "[LInvalidNestHost;"; // #5 + Utf8 "<init>"; // #6 + Utf8 "()V"; // #7 + Utf8 "Code"; // #8 + Utf8 "LineNumberTable"; // #9 + Utf8 "SourceFile"; // #10 + Utf8 "TestReflectionAPI.java"; // #11 + Utf8 "NestHost"; // #12 + class #19; // #13 + NameAndType #6 #7; // #14 + Utf8 "TestReflectionAPI$MemberNotInstanceHost"; // #15 + Utf8 "MemberNotInstanceHost"; // #16 + Utf8 "InnerClasses"; // #17 + Utf8 "java/lang/Object"; // #18 + Utf8 "TestReflectionAPI"; // #19 + class #5; // #20 - added + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0000; // access + #6; // name_cpx + #7; // sig_cpx + [] { // Attributes + Attr(#8) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#9) { // LineNumberTable + [] { // LineNumberTable + 0 63; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#10) { // SourceFile + #11; + } // end SourceFile + ; + Attr(#12) { // NestHost + 0x0014; // Modified #20 + } // end NestHost + ; + Attr(#17) { // InnerClasses + [] { // InnerClasses + #2 #13 #16 8; + } + } // end InnerClasses + } // Attributes +} // end class TestReflectionAPI$MemberNotInstanceHost + diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/MemberNotOurHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/MemberNotOurHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute refers to class with no nest + +class TestReflectionAPI$MemberNotOurHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #12; // #1 + class #13; // #2 + class #16; // #3 + Utf8 "<init>"; // #4 + Utf8 "()V"; // #5 + Utf8 "Code"; // #6 + Utf8 "LineNumberTable"; // #7 + Utf8 "SourceFile"; // #8 + Utf8 "TestReflectionAPI.java"; // #9 + Utf8 "NestHost"; // #10 + class #17; // #11 + NameAndType #4 #5; // #12 + Utf8 "TestReflectionAPI$MemberNotOurHost"; // #13 + Utf8 "MemberNotOurHost"; // #14 + Utf8 "InnerClasses"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "TestReflectionAPI"; // #17 + // Added + Utf8 "InvalidNestHost"; // #18 + class #18; // #19 + } // Constant Pool + + 0x0020; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#7) { // LineNumberTable + [] { // LineNumberTable + 0 68; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#8) { // SourceFile + #9; + } // end SourceFile + ; + Attr(#10) { // NestHost + 0x0013; // Modified #19 + } // end NestHost + ; + Attr(#15) { // InnerClasses + [] { // InnerClasses + #2 #11 #14 8; + } + } // end InnerClasses + } // Attributes +} // end class TestReflectionAPI$MemberNotOurHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/PackagedNestHost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/PackagedNestHost.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package P1; + +/* + * This is used to produce a jcod file in which we modify the + * NestMembers attribute to claim that P2.PackagedNestHost.Member + * is a member of our nest. + */ +public class PackagedNestHost { + public static class Member { } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/PackagedNestHost.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/PackagedNestHost.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestMembers attribute is modified to contain P2.PackagedNestHost2.Member + +class P1/PackagedNestHost { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #16; // #1 + Method #17 #18; // #2 + class #19; // #3 + class #20; // #4 + class #21; // #5 + Utf8 "Member"; // #6 + Utf8 "InnerClasses"; // #7 + Utf8 "<init>"; // #8 + Utf8 "()V"; // #9 + Utf8 "Code"; // #10 + Utf8 "LineNumberTable"; // #11 + Utf8 "doAccess"; // #12 + Utf8 "SourceFile"; // #13 + Utf8 "PackagedNestHost.java"; // #14 + Utf8 "NestMembers"; // #15 + NameAndType #8 #9; // #16 + class #23; // #17 + NameAndType #24 #9; // #18 + Utf8 "P1/PackagedNestHost"; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "P1/PackagedNestHost$Member"; // #21 + class #25; // #22 + Utf8 "P2/PackagedNestHost2$Member"; // #23 + Utf8 "m"; // #24 + Utf8 "P2/PackagedNestHost2"; // #25 + } // Constant Pool + + 0x0021; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 31; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #12; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80002B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 44; + 3 45; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#13) { // SourceFile + #14; + } // end SourceFile + ; + Attr(#15) { // NestMembers + 0x00010011; // modified - #17 + } // end NestMembers + ; + Attr(#7) { // InnerClasses + [] { // InnerClasses + #5 #3 #6 9; + #17 #22 #6 9; + } + } // end InnerClasses + } // Attributes +} // end class P1/PackagedNestHost diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/PackagedNestHost2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/PackagedNestHost2.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package P2; + +/* + * This is used to produce a jcod file in which we modify the + * NestHost attribute to claim that P2.PackagedNestHost.Member + * is a member of the nest of P1.PackagedNestHost. + */ +public class PackagedNestHost2 { + public static class Member { } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/PackagedNestHost2Member.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/PackagedNestHost2Member.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2017, 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. + */ + +// NestHost attribute is modified to contain P1.PackagedNestHost +// m() is declared private + +class P2/PackagedNestHost2$Member { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #7 #18; // #1 + Field #19 #20; // #2 + String #21; // #3 + Method #22 #23; // #4 + Method #24 #25; // #5 + class #26; // #6 + class #29; // #7 + Utf8 "<init>"; // #8 + Utf8 "()V"; // #9 + Utf8 "Code"; // #10 + Utf8 "LineNumberTable"; // #11 + Utf8 "m"; // #12 + Utf8 "doAccess"; // #13 + Utf8 "SourceFile"; // #14 + Utf8 "PackagedNestHost2.java"; // #15 + Utf8 "NestHost"; // #16 + class #30; // #17 + NameAndType #8 #9; // #18 + class #31; // #19 + NameAndType #32 #33; // #20 + Utf8 "You should never see this!"; // #21 + class #34; // #22 + NameAndType #35 #36; // #23 + class #38; // #24 + NameAndType #12 #9; // #25 + Utf8 "P2/PackagedNestHost2$Member"; // #26 + Utf8 "Member"; // #27 + Utf8 "InnerClasses"; // #28 + Utf8 "java/lang/Object"; // #29 + Utf8 "P2/PackagedNestHost2"; // #30 + Utf8 "java/lang/System"; // #31 + Utf8 "out"; // #32 + Utf8 "Ljava/io/PrintStream;"; // #33 + Utf8 "java/io/PrintStream"; // #34 + Utf8 "println"; // #35 + Utf8 "(Ljava/lang/String;)V"; // #36 + class #39; // #37 + Utf8 "P1/PackagedNestHost$Member"; // #38 + Utf8 "P1/PackagedNestHost"; // #39 + } // Constant Pool + + 0x0021; // access + #6;// this_cpx + #7;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 32; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access - modified + #12; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 35; + 8 36; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0009; // access + #13; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 0; // max_stack + 0; // max_locals + Bytes[]{ + 0xB80005B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 42; + 3 43; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#14) { // SourceFile + #15; + } // end SourceFile + ; + Attr(#16) { // NestHost + 0x0025; // modified - #37 + } // end NestHost + ; + Attr(#28) { // InnerClasses + [] { // InnerClasses + #6 #17 #27 9; + #24 #37 #27 9; + } + } // end InnerClasses + } // Attributes +} // end class P2/PackagedNestHost2$Member diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/PackagedNestHostMember.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/PackagedNestHostMember.jcod Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2017, 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. + */ + +// m() is declared private + +class P1/PackagedNestHost$Member { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #6 #16; // #1 + Field #17 #18; // #2 + String #19; // #3 + Method #20 #21; // #4 + class #22; // #5 + class #25; // #6 + Utf8 "<init>"; // #7 + Utf8 "()V"; // #8 + Utf8 "Code"; // #9 + Utf8 "LineNumberTable"; // #10 + Utf8 "m"; // #11 + Utf8 "SourceFile"; // #12 + Utf8 "PackagedNestHost.java"; // #13 + Utf8 "NestHost"; // #14 + class #26; // #15 + NameAndType #7 #8; // #16 + class #27; // #17 + NameAndType #28 #29; // #18 + Utf8 "You should never see this!"; // #19 + class #30; // #20 + NameAndType #31 #32; // #21 + Utf8 "P1/PackagedNestHost$Member"; // #22 + Utf8 "Member"; // #23 + Utf8 "InnerClasses"; // #24 + Utf8 "java/lang/Object"; // #25 + Utf8 "P1/PackagedNestHost"; // #26 + Utf8 "java/lang/System"; // #27 + Utf8 "out"; // #28 + Utf8 "Ljava/io/PrintStream;"; // #29 + Utf8 "java/io/PrintStream"; // #30 + Utf8 "println"; // #31 + Utf8 "(Ljava/lang/String;)V"; // #32 + } // Constant Pool + + 0x0021; // access + #5;// this_cpx + #6;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0001; // access + #7; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 32; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x000A; // access - modified + #11; // name_cpx + #8; // sig_cpx + [] { // Attributes + Attr(#9) { // Code + 2; // max_stack + 0; // max_locals + Bytes[]{ + 0xB200021203B60004; + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#10) { // LineNumberTable + [] { // LineNumberTable + 0 35; + 8 36; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#12) { // SourceFile + #13; + } // end SourceFile + ; + Attr(#14) { // NestHost + 0x000F; + } // end NestHost + ; + Attr(#24) { // InnerClasses + [] { // InnerClasses + #5 #15 #23 9; + } + } // end InnerClasses + } // Attributes +} // end class P1/PackagedNestHost$Member diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/SampleNest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/SampleNest.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017, 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. + */ + +import java.util.Arrays; +import java.util.List; +import java.util.LinkedList; + +// A sample nest for use with reflection API tests +public class SampleNest { + + // recursively gather all the named nested types + + static List<Class<?>> _nestedTypes = new LinkedList<>(); + + static void gather(Class<?> c) { + _nestedTypes.add(c); + for (Class<?> d : c.getDeclaredClasses()) { + gather(d); + } + } + + static { + gather(SampleNest.class); + SampleNest s = new SampleNest(); + } + + public static Class<?>[] nestedTypes() { + return _nestedTypes.toArray(new Class<?>[0]); + } + + // Define a nested type of each possible kind + + static class StaticClass { } + static interface StaticIface { } + class InnerClass { } + interface InnerIface { } + + // check multi-level nesting + + static class DeepNest1 { + static class DeepNest2 { + static class DeepNest3 { + } + } + } + + // local and anonymous classes aren't declared + // so they have to add themselves + public SampleNest() { + class LocalClass { } + _nestedTypes.add(LocalClass.class); + + Runnable r = new Runnable() { + public void run() { + // anonymous class + _nestedTypes.add(getClass()); + } + }; + r.run(); + } +} + diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/TestReflectionAPI.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/TestReflectionAPI.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2017, 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 + * @bug 8046171 + * @summary Test the new nestmate reflection API + * @compile TestReflectionAPI.java + * PackagedNestHost.java + * PackagedNestHost2.java + * SampleNest.java + * Hosts.java + * InvalidNestHost.java + * + * @compile MemberNoHost.jcod + * MemberMissingHost.jcod + * MemberNotInstanceHost.jcod + * MemberNotOurHost.jcod + * MemberMalformedHost.jcod + * MalformedHost.jcod + * PackagedNestHost.jcod + * PackagedNestHost2Member.jcod + * PackagedNestHostMember.jcod + * HostOfMemberNoHost.jcod + * HostOfMemberMissingHost.jcod + * HostOfMemberNotInstanceHost.jcod + * HostOfMemberNotOurHost.jcod + * HostOfMemberMalformedHost.jcod + * HostWithSelfMember.jcod + * HostWithDuplicateMembers.jcod + * + * @run main/othervm TestReflectionAPI + * @run main/othervm/java.security.policy=empty.policy TestReflectionAPI + */ + +// We need a nest member class that is invalid for each of the possible reasons, +// plus we need some external classes to test other failure modes. +// For each nested class below there is a corresponding .jcod file which breaks one +// of the rules regarding nest membership. For the package related tests we have +// additional PackageNestHost*.java sources. +// For testing getNestMembers we need an external host class that has a nested class +// which we can form a jcod file from such that we get all the expected failure modes. +// Note that all the .java files must be compiled in the same step, while all +// .jcod files must be compiled in a later step. + +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; + +public class TestReflectionAPI { + + // Valid nest member + static class Member {} + + // Missing NestHost attribute + static class MemberNoHost {} + + // Missing NestHost class + static class MemberMissingHost {} + + // Invalid NestHost class (not instance class) + static class MemberNotInstanceHost { + Object[] oa; // create CP entry to use in jcod change + } + + // Valid but different NestHost class + static class MemberNotOurHost {} + + // Malformed NestHost class + static class MemberMalformedHost {} + + public static void main(String[] args) throws Throwable { + // run tests twice so that failure reasons are + // seen to remain the same + for (int i = 0; i < 2; i++) { + test_getNestHost(); + test_isNestmateOf(); + test_getNestMembers(); + } + } + + static void test_getNestHost() { + Class<?> host = TestReflectionAPI.class; + + // sampling of "good" checks + + checkHost(host, host); + checkHost(Member.class, host); + Runnable r = new Runnable() { public void run() {}}; + checkHost(r.getClass(), host); + + // all the "bad" classes should report themselves as their + // own nest host - no exceptions should be thrown + Class<?>[] allClasses = host.getDeclaredClasses(); + for (Class<?> c : allClasses) { + if (c == Member.class) + continue; + checkHost(c, c); + } + checkHost(P1.PackagedNestHost.Member.class, + P1.PackagedNestHost.Member.class); + checkHost(P2.PackagedNestHost2.Member.class, + P2.PackagedNestHost2.Member.class); + + // test some 'special' classes + checkHost(int.class, int.class); // primitive + checkHost(Object[].class, Object[].class); // array + checkHost(Thread.State.class, Thread.class); // enum + checkHost(java.lang.annotation.Documented.class, // annotation + java.lang.annotation.Documented.class); + } + + static void test_isNestmateOf() { + Class<?> host = TestReflectionAPI.class; + checkNestmates(host, host, true); + checkNestmates(Member.class, host, true); + Runnable r = new Runnable() { public void run() {}}; + checkNestmates(r.getClass(), host, true); + + // all the "bad" classes should report themselves as their + // own nest host - no exceptions should be thrown - so not + // nestmates + Class<?>[] allClasses = host.getDeclaredClasses(); + for (Class<?> c : allClasses) { + if (c == Member.class) + continue; + checkNestmates(host, c, false); + } + + // 'special' classes + checkNestmates(int.class, int.class, true); // primitive + checkNestmates(int.class, long.class, false); // primitive + checkNestmates(Object[].class, Object[].class, true); // array + checkNestmates(Object[].class, int[].class, false); // array + checkNestmates(Thread.State.class, Thread.class, true); // enum + checkNestmates(java.lang.annotation.Documented.class, // annotation + java.lang.annotation.Documented.class, true); + } + + static void test_getNestMembers() { + // Sampling of "good" checks + Class<?>[] good = { Object.class, Object[].class, int.class}; + checkSingletonNests(good); + + // More thorough correctness check + checkNest(SampleNest.class, SampleNest.nestedTypes(), false); + + // Special cases - legal but not produced by javac + checkNest(HostWithSelfMember.class, + new Class<?>[] { HostWithSelfMember.class, + HostWithSelfMember.Member.class }, + true); + checkNest(HostWithDuplicateMembers.class, + new Class<?>[] { HostWithDuplicateMembers.class, + HostWithDuplicateMembers.Member1.class, + HostWithDuplicateMembers.Member2.class }, + true); + + // Hosts with "bad" members + Class<?>[] bad = { + HostOfMemberNoHost.class, + HostOfMemberMissingHost.class, + HostOfMemberNotOurHost.class, + HostOfMemberNotInstanceHost.class, + HostOfMemberMalformedHost.class, + }; + Class<?>[] exceptions = { + IncompatibleClassChangeError.class, + NoClassDefFoundError.class, + IncompatibleClassChangeError.class, + IncompatibleClassChangeError.class, + ClassFormatError.class, + }; + String[] messages = { + "Nest member HostOfMemberNoHost$MemberNoHost in HostOfMemberNoHost " + + "declares a different nest host of HostOfMemberNoHost$MemberNoHost", + "Unable to load nest-host class (NestHost) of " + + "HostOfMemberMissingHost$MemberMissingHost", + "Type HostOfMemberNotOurHost$MemberNotOurHost is not a nest member " + + "of InvalidNestHost: current type is not listed as a nest member", + "Type HostOfMemberNotInstanceHost$MemberNotInstanceHost is not a nest " + + "member of [LInvalidNestHost;: current type is not listed as a nest member", + "Incompatible magic value 3735928559 in class file MalformedHost", + }; + for (int i = 0; i < bad.length; i++) { + try { + bad[i].getNestMembers(); + throw new Error("getNestMembers() succeeded for class " + + bad[i].getName()); + } catch (LinkageError e) { + checkException(e, messages[i], exceptions[i]); + } + } + } + + static void checkException(Throwable actual, String msg, Class<?> expected) { + if (!actual.getClass().equals(expected)) + throw new Error("Unexpected exception: got " + actual.getClass().getName() + + " but expected " + expected.getName()); + if (!actual.getMessage().contains(msg)) + throw new Error("Wrong " + actual.getClass().getSimpleName() +": \"" + + actual.getMessage() + "\" does not contain \"" + + msg + "\""); + System.out.println("OK - got expected exception: " + actual); + } + + static void checkHost(Class<?> target, Class<?> expected) { + System.out.println("Checking nest host of " + target.getName()); + Class<?> host = target.getNestHost(); + if (host != expected) + throw new Error("Class " + target.getName() + + " has nest host " + host.getName() + + " but expected " + expected.getName()); + } + + static void checkNestmates(Class<?> a, Class<?> b, boolean mates) { + System.out.println("Checking if " + a.getName() + + " isNestmateOf " + b.getName()); + + if (a.isNestmateOf(b) != mates) + throw new Error("Class " + a.getName() + " is " + + (mates ? "not " : "") + + "a nestmate of " + b.getName() + " but should " + + (mates ? "" : "not ") + "be"); + } + + static Comparator<Class<?>> cmp = Comparator.comparing(Class::getName); + + static void checkNest(Class<?> host, Class<?>[] unsortedTypes, boolean expectDups) { + Class<?>[] members = host.getNestMembers(); + Arrays.sort(members, cmp); + Class<?>[] nestedTypes = unsortedTypes.clone(); + Arrays.sort(nestedTypes, cmp); + printMembers(host, members); + printDeclared(host, nestedTypes); + if (!Arrays.equals(members, nestedTypes)) { + if (!expectDups) { + throw new Error("Class " + host.getName() + " has different members " + + "compared to declared classes"); + } + else { + // get rid of duplicates + Class<?>[] memberSet = + Arrays.stream(members).sorted(cmp).distinct().toArray(Class<?>[]::new); + if (!Arrays.equals(memberSet, nestedTypes)) { + throw new Error("Class " + host.getName() + " has different members " + + "compared to declared classes, even after duplicate removal"); + } + } + } + // verify all the relationships that must hold for nest members + for (Class<?> a : members) { + checkHost(a, host); + checkNestmates(a, host, true); + Class<?>[] aMembers = a.getNestMembers(); + if (aMembers[0] != host) { + throw new Error("Class " + a.getName() + " getNestMembers()[0] = " + + aMembers[0].getName() + " not " + host.getName()); + + } + Arrays.sort(aMembers, cmp); + if (!Arrays.equals(members, aMembers)) { + throw new Error("Class " + a.getName() + " has different members " + + "compared to host " + host.getName()); + } + for (Class<?> b : members) { + checkNestmates(a, b, true); + } + } + } + + static void checkSingletonNests(Class<?>[] classes) { + for (Class<?> host : classes) { + Class<?>[] members = host.getNestMembers(); + if (members.length != 1) { + printMembers(host, members); + throw new Error("Class " + host.getName() + " lists " + members.length + + " members instead of 1 (itself)"); + } + if (members[0] != host) { + printMembers(host, members); + throw new Error("Class " + host.getName() + " lists " + + members[0].getName() + " as member instead of itself"); + } + } + } + + static void printMembers(Class<?> host, Class<?>[] members) { + System.out.println("Class " + host.getName() + " has members: "); + for (Class<?> c : members) { + System.out.println(" - " + c.getName()); + } + } + + static void printDeclared(Class<?> host, Class<?>[] declared) { + System.out.println("Class " + host.getName() + " has declared types: "); + for (Class<?> c : declared) { + System.out.println(" - " + c.getName()); + } + } + +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/TestSecurityManagerChecks.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/TestSecurityManagerChecks.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,110 @@ +/* + * 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 + * @bug 8046171 + * @summary Test that security checks occur for getNestHost/getNestMembers + * + * @library /test/lib + * @build TestSecurityManagerChecks testPkg.Host testPkg.Singleton + * @run driver ClassFileInstaller testPkg.Host testPkg.Host$Member testPkg.Singleton + * @run main/othervm -Xbootclasspath/a:. TestSecurityManagerChecks + */ + +// ClassFileInstaller copies the testPkg files into the "current" directory +// so we can add it to the bootclasspath. Then when we run the test the +// loader for the testPkg files is the bootloader but the loader for the +// test class is the system loader, hence a package access check will fail +// because the system loader is not the same as, nor a parent of, the bootloader. +import java.security.Security; + +public class TestSecurityManagerChecks { + + public static void main(String[] args) throws Throwable { + + // First get hold of the target classes before we enable security + Class<?> host = testPkg.Host.class; + Class<?> member = testPkg.Host.Member.class; + Class<?> memberArray = testPkg.Host.Member[].class; + Class<?> singleton = testPkg.Singleton.class; + + // Next add testPkg to the set of packages for which package-access + // permission is required + Security.setProperty("package.access", + Security.getProperty("package.access") + ",testPkg."); + + // Finally install a default security manager + SecurityManager sm = new SecurityManager(); + System.setSecurityManager(sm); + + // These cases all succeed + getNestHost(int.class); // primitive + getNestHost(int[].class); // primitive[] + getNestHost(host); // host class + getNestHost(memberArray); // NestedT[] + getNestHost(singleton); // Singleton nest + + getNestMembers(int.class); // primitive + getNestMembers(int[].class); // primitive[] + getNestMembers(memberArray); // NestedT[] + getNestMembers(singleton); // Singleton nest + + // these cases all fail + getNestHostThrows(member); // NestedT + + getNestMembersThrows(member); // NestedT + getNestMembersThrows(host); // host class + } + + static void getNestHost(Class<?> c) { + Class<?> host = c.getNestHost(); + System.out.println("OK - getNestHost succeeded for " + c.getName()); + } + + static void getNestHostThrows(Class<?> c) throws SecurityException { + try { + Class<?> host = c.getNestHost(); + throw new Error("getNestHost succeeded for " + c.getName()); + } catch (SecurityException e) { + System.out.println("OK - getNestHost for " + c.getName() + + " got expected exception: " + e); + } + } + + static void getNestMembers(Class<?> c) { + Class<?>[] members = c.getNestMembers(); + System.out.println("OK - getNestMembers succeeded for " + c.getName()); + } + + static void getNestMembersThrows(Class<?> c) throws SecurityException { + try { + Class<?>[] members = c.getNestMembers(); + throw new Error("getNestMembers succeeded for " + c.getName()); + } catch (SecurityException e) { + System.out.println("OK - getNestMembers for " + c.getName() + + " got expected exception: " + e); + } + } + +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/empty.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/empty.policy Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,5 @@ +// A deliberately empty policy file for use with jtreg. +// Setting othervm/java.security.policy=empty.policy +// causes jtreg to run under the default system policy +// and default security manager, with the addition of +// the permissions jtreg itself needs to run. diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/testPkg/Host.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/testPkg/Host.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,30 @@ +/* + * 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. + */ + +package testPkg; + +// Host class with single member +public class Host { + public static class Member { + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/java/lang/reflect/Nestmates/testPkg/Singleton.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/reflect/Nestmates/testPkg/Singleton.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,28 @@ +/* + * 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. + */ + +package testPkg; + +// Self-hosting singleton nest +public class Singleton { +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/jdk/lambda/vm/InterfaceAccessFlagsTest.java --- a/test/jdk/jdk/lambda/vm/InterfaceAccessFlagsTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/jdk/jdk/lambda/vm/InterfaceAccessFlagsTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -71,7 +71,8 @@ } } - @Test(groups = "vm_prototype") + /* excluded: 8187655 */ + @Test(enabled=false, groups = "vm_prototype") public void testPrivateMethodCall() { testMethodCallWithFlag(AccessFlag.PRIVATE); } diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/tools/pack200/BandIntegrity.java --- a/test/jdk/tools/pack200/BandIntegrity.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/jdk/tools/pack200/BandIntegrity.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,7 +22,7 @@ */ /* - * @test + * @test 8187645 * @summary test ensures the proper sequencing of bands, dump bands as well. * @compile -XDignore.symbol.file Utils.java BandIntegrity.java * @run main BandIntegrity diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/tools/pack200/pack200-verifier/make/build.xml --- a/test/jdk/tools/pack200/pack200-verifier/make/build.xml Fri Jun 22 17:49:21 2018 -0700 +++ b/test/jdk/tools/pack200/pack200-verifier/make/build.xml Sat Jun 23 01:32:41 2018 -0400 @@ -22,18 +22,18 @@ <target name="compile" depends="init"> <!-- Compile the java code from ${src} into ${build} --> <javac - source="1.8" + source="1.9" srcdir="${src}" destdir="${build}/classes" verbose="no" debug="on"> - <compilerarg value="--add-exports=jdk.jdeps/com.sun.tools.classfile"/> + <compilerarg line="--add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED"/> </javac> </target> <target name="doc" depends="init, compile"> <javadoc - source="1.8" + source="1.9" sourcepath="${src}" destdir="${api}" /> diff -r 0828a0f6676b -r 2f2af62dfac7 test/jdk/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java --- a/test/jdk/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/jdk/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -85,6 +85,8 @@ import com.sun.tools.classfile.ModuleResolution_attribute; import com.sun.tools.classfile.ModuleTarget_attribute; import com.sun.tools.classfile.ModulePackages_attribute; +import com.sun.tools.classfile.NestHost_attribute; +import com.sun.tools.classfile.NestMembers_attribute; import com.sun.tools.classfile.Opcode; import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute; import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute; @@ -1566,6 +1568,30 @@ p.add(e); return null; } + + @Override + public Element visitNestHost(NestHost_attribute attr, Element p) { + String aname = x.getCpString(attr.attribute_name_index); + String hname = x.getCpString(attr.top_index); + Element se = new Element(aname); + se.add(hname); + se.trimToSize(); + p.add(se); + return null; + } + + @Override + public Element visitNestMembers(NestMembers_attribute attr, Element p) { + Element ee = new Element(x.getCpString(attr.attribute_name_index)); + for (int idx : attr.members_indexes) { + Element n = new Element("Item"); + n.setAttr("class", x.getCpString(idx)); + ee.add(n); + } + ee.trimToSize(); + p.add(ee); + return null; + } } class StackMapVisitor implements StackMapTable_attribute.stack_map_frame.Visitor<Element, Void> { diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/jdk/jshell/ClassesTest.java --- a/test/langtools/jdk/jshell/ClassesTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/jdk/jshell/ClassesTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8145239 8129559 8080354 8189248 + * @bug 8145239 8129559 8080354 8189248 8010319 * @summary Tests for EvaluationState.classes * @build KullaTesting TestingInputStream ExpectedDiagnostic * @run testng ClassesTest @@ -308,7 +308,7 @@ public void testInnerClassesCrash() { Snippet a = classKey(assertEval("class A { class B extends A {} }")); Snippet a2 = classKey(assertEval("class A { interface I1 extends I2 {} interface I2 {} }", - ste(MAIN_SNIPPET, VALID, VALID, false, null), + ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); assertEval("class A { A a = new A() {}; }", ste(MAIN_SNIPPET, VALID, VALID, true, null), diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/jdk/jshell/ForwardReferenceTest.java --- a/test/langtools/jdk/jshell/ForwardReferenceTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/jdk/jshell/ForwardReferenceTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -22,7 +22,7 @@ */ /* - * @test 8173232 + * @test 8173232 8010319 * @summary Test of forward referencing of snippets. * @build KullaTesting TestingInputStream * @run testng ForwardReferenceTest @@ -315,7 +315,7 @@ Snippet f = methodKey(assertEval("void f() { class A {} g(); }", added(RECOVERABLE_DEFINED))); assertEval("void g() {}", added(VALID), - ste(f, RECOVERABLE_DEFINED, VALID, false, null)); + ste(f, RECOVERABLE_DEFINED, VALID, true, null)); assertEval("f();", ""); } } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/jdk/jshell/GetResourceTest.java --- a/test/langtools/jdk/jshell/GetResourceTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/jdk/jshell/GetResourceTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8179531 + * @bug 8179531 8010319 * @summary Check that ClassLoader.getResource works as expected in the JShell agent. * @modules jdk.jshell * @build KullaTesting TestingInputStream @@ -80,7 +80,7 @@ null, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, - ste(MAIN_SNIPPET, VALID, VALID, false, null), + ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(testMethod, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); assertEval("test()", "true"); } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/lib/annotations/annotations/classfile/ClassfileInspector.java --- a/test/langtools/lib/annotations/annotations/classfile/ClassfileInspector.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/lib/annotations/annotations/classfile/ClassfileInspector.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -1253,6 +1253,11 @@ } @Override + public Void visitNestHost(NestHost_attribute attr, T p) { + return null; + } + + @Override public Void visitMethodParameters(MethodParameters_attribute attr, T p) { return null; } @@ -1288,6 +1293,11 @@ } @Override + public Void visitNestMembers(NestMembers_attribute attr, T p) { + return null; + } + + @Override public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, T p) { return null; } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/6917288/GraphicalInstallerTest.java --- a/test/langtools/tools/javac/6917288/GraphicalInstallerTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/6917288/GraphicalInstallerTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -47,7 +47,6 @@ } check(classes, - "GraphicalInstaller$1.class", "GraphicalInstaller$1X$1.class", "GraphicalInstaller$1X.class", "GraphicalInstaller$BackgroundInstaller.class", diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/6917288/T6917288.java --- a/test/langtools/tools/javac/6917288/T6917288.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/6917288/T6917288.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -69,7 +69,14 @@ return; } - check(classesDir, "Test.class", "Test$Inner.class", "Test$1.class"); + switch (k) { + case ALWAYS: + case TRUE: + check(classesDir, "Test.class", "Test$Inner.class", "Test$1.class"); + break; + default: + check(classesDir, "Test.class", "Test$Inner.class"); + } } /** diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/7199823/InnerClassCannotBeVerified.java --- a/test/langtools/tools/javac/7199823/InnerClassCannotBeVerified.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/7199823/InnerClassCannotBeVerified.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -29,6 +29,7 @@ * @run main InnerClassCannotBeVerified */ +import java.nio.file.NoSuchFileException; import java.util.Arrays; import javax.tools.JavaFileObject; import java.net.URI; @@ -43,6 +44,17 @@ public class InnerClassCannotBeVerified { + enum CompilationKind { + PRE_NESTMATES("-source", "10", "-target", "10"), + POST_NESTMATES(); + + String[] opts; + + CompilationKind(String... opts) { + this.opts = opts; + } + } + private static final String errorMessage = "Compile error while compiling the following source:\n"; @@ -51,34 +63,49 @@ } void run() throws Exception { - JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - JavaSource source = new JavaSource(); - JavacTask ct = (JavacTask)comp.getTask(null, null, null, - null, null, Arrays.asList(source)); - try { - if (!ct.call()) { + for (CompilationKind ck : CompilationKind.values()) { + File file = new File("Test$1.class"); + if (file.exists()) { + file.delete(); + } + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + JavaSource source = new JavaSource(); + JavacTask ct = (JavacTask)comp.getTask(null, null, null, + Arrays.asList(ck.opts), null, Arrays.asList(source)); + try { + if (!ct.call()) { + throw new AssertionError(errorMessage + + source.getCharContent(true)); + } + } catch (Throwable ex) { throw new AssertionError(errorMessage + source.getCharContent(true)); } - } catch (Throwable ex) { - throw new AssertionError(errorMessage + - source.getCharContent(true)); + check(ck); } - check(); } - private void check() throws IOException, ConstantPoolException { - File file = new File("Test$1.class"); - ClassFile classFile = ClassFile.read(file); - boolean inheritsFromObject = - classFile.getSuperclassName().equals("java/lang/Object"); - boolean implementsNoInterface = classFile.interfaces.length == 0; - boolean noMethods = classFile.methods.length == 0; - if (!(inheritsFromObject && - implementsNoInterface && - noMethods)) { - throw new AssertionError("The inner classes reused as " + - "access constructor tag for this code must be empty"); + private void check(CompilationKind ck) throws IOException, ConstantPoolException { + try { + File file = new File("Test$1.class"); + ClassFile classFile = ClassFile.read(file); + if (ck == CompilationKind.POST_NESTMATES) { + throw new AssertionError("Unexpected constructor tag class!"); + } + boolean inheritsFromObject = + classFile.getSuperclassName().equals("java/lang/Object"); + boolean implementsNoInterface = classFile.interfaces.length == 0; + boolean noMethods = classFile.methods.length == 0; + if (!(inheritsFromObject && + implementsNoInterface && + noMethods)) { + throw new AssertionError("The inner classes reused as " + + "access constructor tag for this code must be empty"); + } + } catch (NoSuchFileException ex) { + if (ck == CompilationKind.PRE_NESTMATES) { + throw new AssertionError("Constructor tag class missing!"); + } } } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/MethodParameters/AttributeVisitor.java --- a/test/langtools/tools/javac/MethodParameters/AttributeVisitor.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/MethodParameters/AttributeVisitor.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -42,6 +42,7 @@ public R visitLineNumberTable(LineNumberTable_attribute attr, P p) { return null; } public R visitLocalVariableTable(LocalVariableTable_attribute attr, P p) { return null; } public R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p) { return null; } + public R visitNestHost(NestHost_attribute attr, P p) { return null; } public R visitMethodParameters(MethodParameters_attribute attr, P p) { return null; } public R visitModule(Module_attribute attr, P p) { return null; } public R visitModuleHashes(ModuleHashes_attribute attr, P p) { return null; } @@ -49,6 +50,7 @@ public R visitModulePackages(ModulePackages_attribute attr, P p) { return null; } public R visitModuleResolution(ModuleResolution_attribute attr, P p) { return null; } public R visitModuleTarget(ModuleTarget_attribute attr, P p) { return null; } + public R visitNestMembers(NestMembers_attribute attr, P p) { return null; } public R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p) { return null; } public R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p) { return null; } public R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p) { return null; } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -30,14 +30,30 @@ * jdk.compiler/com.sun.tools.javac.main * jdk.jdeps/com.sun.tools.classfile * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase - * @run main SyntheticClassTest + * @compile -source 10 -target 10 SyntheticClassTest.java + * @run main SyntheticClassTest true + * @clean SyntheticClassTest$1 + * @compile SyntheticClassTest.java + * @run main SyntheticClassTest false */ +import java.nio.file.NoSuchFileException; + public class SyntheticClassTest extends SourceFileTestBase { public static void main(String[] args) throws Exception { + boolean expectSynthetic = Boolean.parseBoolean(args[0]); new Inner(); - new SyntheticClassTest().test("SyntheticClassTest$1", "SyntheticClassTest.java"); + try { + new SyntheticClassTest().test("SyntheticClassTest$1", "SyntheticClassTest.java"); + if (!expectSynthetic) { + throw new AssertionError("Synthetic class should not have been emitted!"); + } + } catch (NoSuchFileException ex) { + if (expectSynthetic) { + throw new AssertionError("Synthetic class should have been emitted!"); + } + } } static class Inner { diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassConstructorsTest.java --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassConstructorsTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassConstructorsTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -31,7 +31,7 @@ * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult * @build AccessToPrivateInnerClassConstructorsTest SyntheticTestDriver ExpectedClass ExpectedClasses - * @run main SyntheticTestDriver AccessToPrivateInnerClassConstructorsTest 1 + * @run main SyntheticTestDriver AccessToPrivateInnerClassConstructorsTest 0 * @run main AccessToPrivateInnerClassConstructorsTest */ @@ -45,7 +45,7 @@ "<init>(AccessToPrivateInnerClassConstructorsTest, " + "AccessToPrivateInnerClassConstructorsTest$1)"}, expectedNumberOfSyntheticFields = 1, - expectedNumberOfSyntheticMethods = 2) + expectedNumberOfSyntheticMethods = 0) @ExpectedClass(className = "AccessToPrivateInnerClassConstructorsTest$1Local", expectedMethods = {"<init>(AccessToPrivateInnerClassConstructorsTest)"}, expectedNumberOfSyntheticFields = 1) diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassMembersTest.java --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassMembersTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassMembersTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -32,7 +32,7 @@ * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult * @build AccessToPrivateInnerClassMembersTest SyntheticTestDriver ExpectedClass ExpectedClasses - * @run main SyntheticTestDriver AccessToPrivateInnerClassMembersTest 1 + * @run main SyntheticTestDriver AccessToPrivateInnerClassMembersTest */ /** @@ -51,12 +51,10 @@ @ExpectedClass(className = "AccessToPrivateInnerClassMembersTest$Inner1", expectedMethods = {"<init>(AccessToPrivateInnerClassMembersTest)", "function()"}, expectedFields = "var", - expectedNumberOfSyntheticMethods = 4, expectedNumberOfSyntheticFields = 1) @ExpectedClass(className = "AccessToPrivateInnerClassMembersTest$Inner2", expectedMethods = {"function()", "staticFunction()", "<init>()"}, - expectedFields = {"staticVar", "var"}, - expectedNumberOfSyntheticMethods = 7) + expectedFields = {"staticVar", "var"}) public class AccessToPrivateInnerClassMembersTest { private class Inner1 { diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateSiblingsTest.java --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateSiblingsTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateSiblingsTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -32,7 +32,7 @@ * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build AccessToPrivateSiblingsTest SyntheticTestDriver ExpectedClass ExpectedClasses - * @run main SyntheticTestDriver AccessToPrivateSiblingsTest 1 + * @run main SyntheticTestDriver AccessToPrivateSiblingsTest */ /** @@ -50,19 +50,16 @@ @ExpectedClass(className = "AccessToPrivateSiblingsTest$Inner1", expectedMethods = {"function()", "<init>(AccessToPrivateSiblingsTest)"}, expectedFields = "var", - expectedNumberOfSyntheticMethods = 4, expectedNumberOfSyntheticFields = 1) @ExpectedClass(className = "AccessToPrivateSiblingsTest$Inner2", expectedMethods = "<init>(AccessToPrivateSiblingsTest)", expectedNumberOfSyntheticFields = 1) @ExpectedClass(className = "AccessToPrivateSiblingsTest$Inner3", expectedMethods = {"<init>()", "function()", "staticFunction()", "<clinit>()"}, - expectedFields = {"var", "staticVar"}, - expectedNumberOfSyntheticMethods = 4) + expectedFields = {"var", "staticVar"}) @ExpectedClass(className = "AccessToPrivateSiblingsTest$Inner4", expectedMethods = {"<init>()", "function()", "staticFunction()"}, - expectedFields = {"var", "staticVar"}, - expectedNumberOfSyntheticMethods = 4) + expectedFields = {"var", "staticVar"}) public class AccessToPrivateSiblingsTest { private class Inner1 { diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTest.java --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -33,7 +33,7 @@ * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build SyntheticTestDriver ExpectedClass ExpectedClasses * @compile -XDdeduplicateLambdas=false BridgeMethodsForLambdaTest.java - * @run main SyntheticTestDriver BridgeMethodsForLambdaTest 1 + * @run main SyntheticTestDriver BridgeMethodsForLambdaTest */ import java.util.Comparator; @@ -59,15 +59,14 @@ @ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner1", expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()", "run()"}, expectedFields = "lambda1", - expectedNumberOfSyntheticMethods = 4, + expectedNumberOfSyntheticMethods = 1, expectedNumberOfSyntheticFields = 1) @ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner2", expectedMethods = {"<init>()", "staticFunction()"}, expectedFields = "lambda1", - expectedNumberOfSyntheticMethods = 3) + expectedNumberOfSyntheticMethods = 1) @ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner3", expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()"}, - expectedNumberOfSyntheticMethods = 1, expectedNumberOfSyntheticFields = 1) @ExpectedClass(className = "BridgeMethodsForLambdaTest$Inner4", expectedMethods = {"<init>(BridgeMethodsForLambdaTest)", "function()"}, diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -31,21 +31,30 @@ * jdk.jdeps/com.sun.tools.classfile * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase - * @run main InnerClassesInInnerClassTest + * @run main InnerClassesInInnerClassTest true + * @run main InnerClassesInInnerClassTest false */ +import java.util.Arrays; import java.util.List; public class InnerClassesInInnerClassTest extends InnerClassesInInnerClassTestBase { + final boolean expectSyntheticClass; + + public InnerClassesInInnerClassTest(boolean expectSyntheticClass) { + this.expectSyntheticClass = expectSyntheticClass; + } + public static void main(String[] args) throws TestFailedException { - InnerClassesTestBase test = new InnerClassesInInnerClassTest(); + boolean expectSyntheticClass = Boolean.parseBoolean(args[0]); + InnerClassesTestBase test = new InnerClassesInInnerClassTest(expectSyntheticClass); test.test("InnerClassesSrc$Inner", "Inner", "1"); } @Override public void setProperties() { - setHasSyntheticClass(true); + setHasSyntheticClass(expectSyntheticClass); setOuterClassType(ClassType.CLASS); setInnerClassType(ClassType.CLASS); } @@ -62,4 +71,11 @@ return sources; } + + @Override + protected List<String> getCompileOptions() { + return !expectSyntheticClass ? + super.getCompileOptions() : + Arrays.asList("-source", "10", "-target", "10"); + } } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -31,13 +31,24 @@ * jdk.jdeps/com.sun.tools.classfile * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase - * @run main InnerClassesInInnerEnumTest + * @run main InnerClassesInInnerEnumTest true + * @run main InnerClassesInInnerEnumTest false */ +import java.util.Arrays; +import java.util.List; + public class InnerClassesInInnerEnumTest extends InnerClassesInInnerClassTestBase { + final boolean expectSyntheticClass; + + public InnerClassesInInnerEnumTest(boolean expectSyntheticClass) { + this.expectSyntheticClass = expectSyntheticClass; + } + public static void main(String[] args) throws TestFailedException { - InnerClassesTestBase test = new InnerClassesInInnerEnumTest(); + boolean expectSyntheticClass = Boolean.parseBoolean(args[0]); + InnerClassesTestBase test = new InnerClassesInInnerEnumTest(expectSyntheticClass); test.test("InnerClassesSrc$Inner", "Inner", "1"); } @@ -46,8 +57,15 @@ setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC); setOuterClassType(ClassType.ENUM); setInnerClassType(ClassType.CLASS); - setHasSyntheticClass(true); + setHasSyntheticClass(expectSyntheticClass); setPrefix("Inner {;"); setSuffix("}"); } + + @Override + protected List<String> getCompileOptions() { + return !expectSyntheticClass ? + super.getCompileOptions() : + Arrays.asList("-source", "10", "-target", "10"); + } } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -31,20 +31,29 @@ * jdk.jdeps/com.sun.tools.classfile * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesTestBase - * @run main InnerClassesTest + * @run main InnerClassesTest true + * @run main InnerClassesTest false */ +import java.util.Arrays; import java.util.List; public class InnerClassesTest extends InnerClassesTestBase { + final boolean expectSyntheticClass; + + public InnerClassesTest(boolean expectSyntheticClass) { + this.expectSyntheticClass = expectSyntheticClass; + } + public static void main(String[] args) throws TestFailedException { - new InnerClassesTest().test("InnerClassesSrc"); + boolean expectSyntheticClass = Boolean.parseBoolean(args[0]); + new InnerClassesTest(expectSyntheticClass).test("InnerClassesSrc"); } private List<TestCase> generateClasses() { setInnerClassType(ClassType.CLASS); - setHasSyntheticClass(true); + setHasSyntheticClass(expectSyntheticClass); return super.generateTestCases(); } @@ -82,4 +91,11 @@ sources.addAll(generateAnnotations()); return sources; } + + @Override + protected List<String> getCompileOptions() { + return !expectSyntheticClass ? + super.getCompileOptions() : + Arrays.asList("-source", "10", "-target", "10"); + } } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -199,7 +199,7 @@ printf("Testing :\n%s\n", test.getSource()); try { Map<String, Set<String>> class2Flags = test.getFlags(); - ClassFile cf = readClassFile(compile(test.getSource()) + ClassFile cf = readClassFile(compile(getCompileOptions(), test.getSource()) .getClasses().get(classToTest)); InnerClasses_attribute innerClasses = (InnerClasses_attribute) cf.getAttribute(Attribute.InnerClasses); @@ -324,6 +324,10 @@ return flags; } + protected List<String> getCompileOptions() { + return Collections.emptyList(); + } + private List<List<Modifier>> getAllCombinations(Modifier[] accessModifiers, Modifier[] otherModifiers) { List<List<Modifier>> list = new ArrayList<>(); for (Modifier access : accessModifiers) { diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/nativeHeaders/NativeHeaderTest.java --- a/test/langtools/tools/javac/nativeHeaders/NativeHeaderTest.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/nativeHeaders/NativeHeaderTest.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -122,7 +122,7 @@ // double check the synthetic class was generated checkEqual("generatedClasses", - createSet("C.class", "C$1.class", "C$Inner.class"), + createSet("C.class", "C$Inner.class"), createSet(classesDir.list())); } diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/nestmates/CheckNestmateAttrs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/nestmates/CheckNestmateAttrs.java Sat Jun 23 01:32:41 2018 -0400 @@ -0,0 +1,120 @@ +/* + * 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 + * @summary Smoke test for nestmate classfile support + * @run main CheckNestmateAttrs + * @modules + * jdk.compiler + * jdk.jdeps/com.sun.tools.javap + */ + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Paths; + +public class CheckNestmateAttrs { + + private void test() { } + + class Inner { + void m() { + class LocalInner { + void testInner() { + test(); + } + } + } + } + + static class Nested { + void s() { + class LocalNested { } + } + } + + public static void main(String[] args) { + new CheckNestmateAttrs().run(); + } + + void run() { + String [] params = new String [] { "-v", + Paths.get(System.getProperty("test.classes"), + "CheckNestmateAttrs.class").toString() }; + runCheck(params, new String [] { + "NestMembers:" + + " CheckNestmateAttrs$Nested" + + " CheckNestmateAttrs$Nested$1LocalNested" + + " CheckNestmateAttrs$Inner" + + " CheckNestmateAttrs$Inner$1LocalInner" + }); + + params = new String [] { "-v", + Paths.get(System.getProperty("test.classes"), + "CheckNestmateAttrs$Inner.class").toString() }; + + runCheck(params, new String [] { "NestHost: class CheckNestmateAttrs" }); + + params = new String [] { "-v", + Paths.get(System.getProperty("test.classes"), + "CheckNestmateAttrs$Nested.class").toString() }; + + runCheck(params, new String [] { "NestHost: class CheckNestmateAttrs" }); + + params = new String [] { "-v", + Paths.get(System.getProperty("test.classes"), + "CheckNestmateAttrs$Inner$1LocalInner.class").toString() }; + + runCheck(params, new String [] { + "NestHost: class CheckNestmateAttrs", + "0: aload_0", + "1: getfield #1 // Field this$1:LCheckNestmateAttrs$Inner;", + "4: getfield #3 // Field CheckNestmateAttrs$Inner.this$0:LCheckNestmateAttrs;", + "7: invokevirtual #4 // Method CheckNestmateAttrs.test:()V", + "10: return" + }); + + params = new String [] { "-v", + Paths.get(System.getProperty("test.classes"), + "CheckNestmateAttrs$Nested$1LocalNested.class").toString() }; + + runCheck(params, new String [] { "NestHost: class CheckNestmateAttrs" }); + } + + void runCheck(String [] params, String [] expectedOut) { + StringWriter s; + String out; + + try (PrintWriter pw = new PrintWriter(s = new StringWriter())) { + com.sun.tools.javap.Main.run(params, pw); + out = s.toString(); + } + for (String eo: expectedOut) { + if (!out.contains(eo)) { + System.out.println("Actual output: " + out); + throw new AssertionError("Missing output: " + eo); + } + } + } +} diff -r 0828a0f6676b -r 2f2af62dfac7 test/langtools/tools/javac/processing/model/completionfailure/NoAbortForBadClassFile.java --- a/test/langtools/tools/javac/processing/model/completionfailure/NoAbortForBadClassFile.java Fri Jun 22 17:49:21 2018 -0700 +++ b/test/langtools/tools/javac/processing/model/completionfailure/NoAbortForBadClassFile.java Sat Jun 23 01:32:41 2018 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -121,6 +121,7 @@ new toolbox.JavacTask(tb) .outdir(out) + .options("-source", "10", "-target", "10") .files(tb.findJavaFiles(src)) .run(Expect.SUCCESS) .writeAll()