8010319: Implementation of JEP 181: Nest-Based Access Control

Co-authored-by: Alex Buckley <alex.buckley@oracle.com>
Co-authored-by: Maurizio Mimadamore <maurizio.mimadamore@oracle.com>
Co-authored-by: Mandy Chung <mandy.chung@oracle.com>
Co-authored-by: Tobias Hartmann <tobias.hartmann@oracle.com>
Co-authored-by: Vlaidmir Ivanov <vladimir.x.ivanov@oracle.com>
Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com>
Co-authored-by: Vladimir Kozlov <vladimir.kozlov@oracle.com>
Co-authored-by: John Rose <john.r.rose@oracle.com>
Co-authored-by: Daniel Smith <daniel.smith@oracle.com>
Co-authored-by: Serguei Spitsyn <serguei.spitsyn@oracle.com>
Co-authored-by: Kumar Srinivasan <kumardotsrinivasan@gmail.com>
Co-authored-by: Boris Ulasevich <boris.ulasevich@bell-sw.com>
Reviewed-by: alanb, psandoz, mchung, coleenp, acorn, mcimadamore, forax, jlahoda, sspitsyn, abuckley
This commit is contained in:
David Holmes 2018-06-23 01:32:41 -04:00
parent 6e0bd36f42
commit 95bf19563b
259 changed files with 21354 additions and 890 deletions
make
data/jdwp
hotspot/symbols
src
hotspot
java.base/share
java.instrument/share
classes/java/lang/instrument
native/libinstrument
jdk.compiler/share/classes/com/sun/tools/javac
jdk.jdeps/share/classes/com/sun/tools
jdk.jdi/share/classes/com/sun
jdk.jdwp.agent/share/native/libjdwp
test/hotspot/jtreg

@ -395,8 +395,8 @@ JDWP "Java(tm) Debug Wire Protocol"
"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 @@ JDWP "Java(tm) Debug Wire Protocol"
"<a href=\"#JDWP_StackFrame_PopFrames\">PopFrames</a> command can be used "
"to pop frames with obsolete methods."
"<p>"
"Unless the canUnrestrictedlyRedefineClasses capability is present the following "
"redefinitions are restricted: "
"<ul>"
"<li>changing the schema (the fields)</li>"
"<li>changing the hierarchy (superclasses, interfaces)</li>"
"<li>deleting a method</li>"
"<li>changing class modifiers</li>"
"<li>changing method modifiers</li>"
"<li>changing the <code>NestHost</code> or <code>NestMembers</code> class attributes</li>"
"</ul>"
"<p>"
"Requires canRedefineClasses capability - see "
"<a href=\"#JDWP_VirtualMachine_CapabilitiesNew\">CapabilitiesNew</a>. "
"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 @@ JDWP "Java(tm) Debug Wire Protocol"
(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 @@ JDWP "Java(tm) Debug Wire Protocol"
"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.")

@ -22,6 +22,7 @@
#
JVM_ActiveProcessorCount
JVM_AreNestMates
JVM_ArrayCopy
JVM_AssertionStatusDirectives
JVM_BeforeHalt
@ -118,6 +119,8 @@ JVM_GetMethodIxSignatureUTF
JVM_GetMethodParameters
JVM_GetMethodTypeAnnotations
JVM_GetNanoTimeAdjustment
JVM_GetNestHost
JVM_GetNestMembers
JVM_GetPrimitiveArrayElement
JVM_GetProtectionDomain
JVM_GetSimpleBinaryName

@ -3362,22 +3362,45 @@ void TemplateTable::invokeinterface(int byte_no) {
// 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);

@ -4276,25 +4276,41 @@ void TemplateTable::invokeinterface(int byte_no) {
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);
// 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);
// 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 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,

@ -3583,14 +3583,46 @@ void TemplateTable::invokeinterface(int byte_no) {
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 @@ void TemplateTable::invokeinterface(int byte_no) {
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) {

@ -3610,20 +3610,43 @@ void TemplateTable::invokeinterface(int byte_no) {
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();

@ -3202,28 +3202,56 @@ void TemplateTable::invokeinterface(int byte_no) {
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);
Register Rtemp = O1_flags;
__ 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;
// Receiver subtype check against REFC.
__ lookup_interface_method(// inputs: rec. class, interface, itable index
O2_Klass, Rinterface, noreg,

@ -3792,30 +3792,61 @@ void TemplateTable::invokeinterface(int byte_no) {
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 @@ void TemplateTable::invokeinterface(int byte_no) {
__ 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),

@ -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 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
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 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
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 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
// 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 @@ ciField::ciField(ciInstanceKlass* klass, int index) :
// 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;
}

@ -3148,7 +3148,6 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea
_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 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea
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<u2>* const nest_members = MetadataFactory::new_array<u2>(_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 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
// 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 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
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 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
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 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
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 @@ void ClassFileParser::apply_parsed_class_metadata(
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 @@ static void check_final_method_override(const InstanceKlass* this_klass, TRAPS)
}
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 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
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 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
_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 @@ void ClassFileParser::clear_class_metadata() {
_fields = NULL;
_methods = NULL;
_inner_classes = NULL;
_nest_members = NULL;
_local_interfaces = NULL;
_combined_annotations = NULL;
_annotations = _type_annotations = NULL;
@ -5868,6 +5960,10 @@ ClassFileParser::~ClassFileParser() {
MetadataFactory::free_array<u2>(_loader_data, _inner_classes);
}
if (_nest_members != NULL && _nest_members != Universe::the_empty_short_array()) {
MetadataFactory::free_array<u2>(_loader_data, _nest_members);
}
// Free interfaces
InstanceKlass::deallocate_interfaces(_loader_data, _super_klass,
_local_interfaces, _transitive_interfaces);

@ -97,6 +97,8 @@ class ClassFileParser {
Array<u2>* _fields;
Array<Method*>* _methods;
Array<u2>* _inner_classes;
Array<u2>* _nest_members;
u2 _nest_host;
Array<Klass*>* _local_interfaces;
Array<Klass*>* _transitive_interfaces;
Annotations* _combined_annotations;
@ -290,6 +292,10 @@ class ClassFileParser {
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,

@ -245,10 +245,6 @@ Klass* SystemDictionary::resolve_or_fail(Symbol* class_name,
// 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 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
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);

@ -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") \

@ -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 @@ class ClassHierarchyWalker {
} 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()) {

@ -522,6 +522,17 @@ JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnl
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

@ -387,12 +387,13 @@ Method* LinkResolver::lookup_method_in_klasses(const LinkInfo& link_info,
// 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 @@ void LinkResolver::check_method_accessability(Klass* ref_klass,
}
// 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 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
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 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
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 @@ methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info, B
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 ? "<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 @@ void LinkResolver::check_field_accessability(Klass* ref_klass,
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 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
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 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
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 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
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 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
// 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 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
// 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 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
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 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
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 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
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);
}
}

@ -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 @@ class LinkResolver: AllStatic {
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

@ -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) \

@ -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, \

@ -71,13 +71,14 @@ Klass* ArrayKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) co
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) :

@ -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 @@ class ArrayKlass: public Klass {
// 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<ArrayKlass*>(cast(const_cast<const Klass*>(k)));

@ -174,17 +174,37 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
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 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
// 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 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
// 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);

@ -145,6 +145,198 @@ static inline bool is_class_loader(const Symbol* class_name,
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 @@ InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& par
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 @@ InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind) :
_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 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
}
set_inner_classes(NULL);
if (nest_members() != NULL &&
nest_members() != Universe::the_empty_short_array() &&
!nest_members()->is_shared()) {
MetadataFactory::free_array<jushort>(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 @@ bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) {
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 @@ Method* InstanceKlass::find_method_impl(const Symbol* name,
// and skips over static methods
Method* InstanceKlass::find_instance_method(const Array<Method*>* 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 @@ Method* InstanceKlass::find_instance_method(const Array<Method*>* methods,
// 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 @@ int InstanceKlass::find_method_index(const Array<Method*>* methods,
// 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 @@ int InstanceKlass::find_method_by_name(const Array<Method*>* methods,
}
// 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 @@ Method* InstanceKlass::uncached_lookup_method(const Symbol* name,
signature,
overpass_local_mode,
find_static,
find_private);
private_mode);
if (method != NULL) {
return method;
}
@ -2044,6 +2248,8 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
}
}
}
it->push(&_nest_members);
}
void InstanceKlass::remove_unshareable_info() {
@ -2087,10 +2293,12 @@ void InstanceKlass::remove_unshareable_info() {
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 @@ void InstanceKlass::print_on(outputStream* st) const {
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 @@ void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
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();

@ -165,6 +165,19 @@ class InstanceKlass: public Klass {
// number_of_inner_classes * 4 + enclosing_method_attribute_size.
Array<jushort>* _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<jushort>* _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 @@ class InstanceKlass: public Klass {
Array<u2>* inner_classes() const { return _inner_classes; }
void set_inner_classes(Array<u2>* f) { _inner_classes = f; }
// nest members
Array<u2>* nest_members() const { return _nest_members; }
void set_nest_members(Array<u2>* 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 @@ class InstanceKlass: public Klass {
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<Method*>* 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 @@ class InstanceKlass: public Klass {
// 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)

@ -168,7 +168,9 @@ Klass* Klass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
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"

@ -467,7 +467,9 @@ protected:
// 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);

@ -1122,7 +1122,7 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
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; // <init> or <clinit>
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 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
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(),

@ -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 @@ void Parse::do_call() {
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.

@ -1892,6 +1892,98 @@ JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls))
}
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<u2>* 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 //////////////////////////////////////////////////////////

@ -358,7 +358,7 @@
]>
<specification label="JVM(TM) Tool Interface"
majorversion="9"
majorversion="11"
minorversion="0"
microversion="0">
<title subtitle="Version">
@ -7631,9 +7631,12 @@ class C2 extends C1 implements I2 {
<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 @@ class C2 extends C1 implements I2 {
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 @@ class C2 extends C1 implements I2 {
<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 @@ class C2 extends C1 implements I2 {
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 @@ myInit() {
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 @@ typedef void (JNICALL *jvmtiEventVMInit)
- 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>

@ -388,6 +388,40 @@ void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {
}
}
// 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 @@ void JvmtiClassFileReconstituter::write_class_attributes() {
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 @@ void JvmtiClassFileReconstituter::write_class_attributes() {
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

@ -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 @@ class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter {
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);

@ -370,6 +370,14 @@ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
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
}

@ -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 @@ typedef enum {
<xsl:apply-templates select="functionsection"/>
<xsl:call-template name="outro"/>
</xsl:template>
<xsl:template name="intro">
@ -114,6 +114,7 @@ enum {
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 @@ struct _jvmtiEnv {
</xsl:when>
<xsl:otherwise>
<xsl:text> RESERVED */
void *reserved</xsl:text>
void *reserved</xsl:text>
<xsl:value-of select="$index"/>
</xsl:otherwise>
</xsl:choose>

@ -683,6 +683,95 @@ void VM_RedefineClasses::finalize_operands_merge(const constantPoolHandle& merge
_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 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
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 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
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 @@ bool VM_RedefineClasses::rewrite_cp_refs(InstanceKlass* scratch_class,
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) {

@ -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 @@ class VM_RedefineClasses: public VM_Operation {
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);

@ -238,7 +238,12 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
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 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
} 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;

@ -650,26 +650,27 @@ char* Reflection::verify_class_access_msg(const Klass* current_class,
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 @@ bool Reflection::verify_field_access(const Klass* current_class,
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 @@ bool Reflection::verify_field_access(const Klass* current_class,
}
}
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) {

@ -90,12 +90,13 @@ class Reflection: public AllStatic {
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

@ -13,6 +13,8 @@ pack.code.attribute.CoverageTable = NH[PHHII]
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.

@ -82,9 +82,9 @@ import sun.reflect.annotation.*;
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 @@ import sun.reflect.misc.ReflectUtil;
* {@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 final class Class<T> implements java.io.Serializable,
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;
}
}

@ -58,7 +58,8 @@ class DirectMethodHandle extends MethodHandle {
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 @@ class DirectMethodHandle extends MethodHandle {
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 @@ class DirectMethodHandle extends MethodHandle {
* 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 @@ class DirectMethodHandle extends MethodHandle {
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 @@ class DirectMethodHandle extends MethodHandle {
}
private static LambdaForm preparedLambdaForm(MemberName m) {
return preparedLambdaForm(m, null);
return preparedLambdaForm(m, false);
}
private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {

@ -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 @@ import static java.lang.invoke.MethodHandleStatics.*;
* 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:

@ -469,15 +469,20 @@ public class MethodHandles {
* 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 @@ public class MethodHandles {
* <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 @@ public class MethodHandles {
* <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 @@ assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
* 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 @@ assertEquals("", (String) MH_newString.invokeExact());
* @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 mh1;
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 @@ return mh1;
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 @@ return mh1;
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 @@ return mh1;
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,

@ -47,7 +47,7 @@ import sun.security.util.SecurityConstants;
* 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

@ -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 @@ public final class Method extends Executable {
*
* <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.

@ -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 @@ public class Attribute {
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()
};
}

@ -530,7 +530,7 @@ public class ClassReader {
* , {@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);
}
/**

@ -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 @@ class MethodAccessorGenerator extends AccessorGenerator {
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,

@ -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 @@ public class Reflection {
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 @@ public class Reflection {
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);
}

@ -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 @@ public class VerifyAccess {
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 @@ public class VerifyAccess {
* 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 @@ public class VerifyAccess {
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 @@ public class VerifyAccess {
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));
}

@ -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 @@ static JNINativeMethod methods[] = {
{"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

@ -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 @@ Java_jdk_internal_reflect_Reflection_getClassAccessFlags(JNIEnv *env, jclass unu
{
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);
}

@ -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 @@ public interface Instrumentation {
* 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 @@ public interface Instrumentation {
* 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.
*

@ -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 @@ createThrowableFromJVMTIErrorCode(JNIEnv * jnienv, jvmtiError errorCode) {
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";

@ -94,6 +94,7 @@ public class Lower extends TreeTranslator {
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 @@ public class Lower extends TreeTranslator {
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 @@ public class Lower extends TreeTranslator {
/** 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 @@ public class Lower extends TreeTranslator {
/** 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())

@ -31,6 +31,7 @@ import java.util.Map;
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 @@ public class ClassWriter extends ClassFile {
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 @@ public class ClassWriter extends ClassFile {
}
poolbuf.appendChar(target.majorVersion);
if (c.owner.kind != MDL) {
if (target.hasNestmateAccess()) {
acount += writeNestMembersIfNeeded(c);
acount += writeNestHostIfNeeded(c);
}
}
writePool(c.pool);
if (innerClasses != null) {

@ -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 @@ public class Gen extends JCTree.Visitor {
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 @@ public class Gen extends JCTree.Visitor {
private final boolean genCrt;
private final boolean debugCode;
private final boolean allowBetterNullChecks;
private boolean disableVirtualizedPrivateInvoke;
/** Code buffer, set by genMethod.
*/
@ -2064,10 +2066,17 @@ public class Gen extends JCTree.Visitor {
} 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 @@ public class Gen extends JCTree.Visitor {
} else {
result = items.
makeMemberItem(sym,
(sym.flags() & PRIVATE) != 0 ||
nonVirtualForPrivateAccess(sym) ||
selectSuper || accessSuper);
}
}

@ -160,4 +160,17 @@ public enum Target {
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;
}
}

@ -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 class Names {
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 @@ public class Names {
MethodParameters = fromString("MethodParameters");
Module = fromString("Module");
ModuleResolution = fromString("ModuleResolution");
NestHost = fromString("NestHost");
NestMembers = fromString("NestMembers");
RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");

@ -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 abstract class Attribute {
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 @@ public abstract class Attribute {
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 @@ public abstract class Attribute {
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);

@ -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
@ -528,6 +528,12 @@ public class ClassWriter {
out.writeShort(entry.index);
}
@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);
@ -626,6 +632,15 @@ public class ClassWriter {
return null;
}
@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);

@ -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;
}

@ -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;
}

@ -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.CharacterRangeTable_attribute.Entry;
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.ModuleMainClass_attribute;
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 @@ public class AttributeWriter extends BasicWriter
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));
@ -686,6 +697,22 @@ public class AttributeWriter extends BasicWriter
}
}
@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:");

@ -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 @@ public interface VirtualMachine extends Mirror {
* 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 @@ public interface VirtualMachine extends Mirror {
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,

@ -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 @@ class VirtualMachineImpl extends MirrorImpl
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");

@ -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 @@ public class VirtualMachineManagerImpl implements VirtualMachineManagerService {
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();

@ -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

@ -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 @@ jdwpErrorText(jdwpError serror)
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)

@ -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 @@ map2jvmtiError(jdwpError error)
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 @@ map2jdwpError(jvmtiError error)
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:

@ -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 @@ public class TestAMEnotNPE {
}
}
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();

@ -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 org.junit.Test;
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 @@ public class ResolvedJavaTypeResolveConcreteMethodTest {
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

@ -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 org.junit.Test;
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 @@ public class ResolvedJavaTypeResolveMethodTest {
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

@ -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);
}

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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();
}
}

@ -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);
}
}
}
}

@ -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

@ -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

@ -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();
}
}

@ -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);
}
}

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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 {
}

@ -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;
}
}

@ -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

@ -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;
}
}
}

@ -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

@ -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

@ -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

@ -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

Some files were not shown because too many files have changed in this diff Show More