Skip to content

Commit 95bf195

Browse files
David Holmesabuckley-jdkMaurizio MimadamoremlchungTobiHartmann
committed
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
1 parent 6e0bd36 commit 95bf195

259 files changed

Lines changed: 21350 additions & 886 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

make/data/jdwp/jdwp.spec

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ JDWP "Java(tm) Debug Wire Protocol"
395395
"Can the VM add methods when redefining "
396396
"classes?")
397397
(boolean canUnrestrictedlyRedefineClasses
398-
"Can the VM redefine classes"
399-
"in arbitrary ways?")
398+
"Can the VM redefine classes "
399+
"in ways that are normally restricted?")
400400
(boolean canPopFrames
401401
"Can the VM pop stack frames?")
402402
(boolean canUseInstanceFilters
@@ -460,12 +460,23 @@ JDWP "Java(tm) Debug Wire Protocol"
460460
"<a href=\"#JDWP_StackFrame_PopFrames\">PopFrames</a> command can be used "
461461
"to pop frames with obsolete methods."
462462
"<p>"
463+
"Unless the canUnrestrictedlyRedefineClasses capability is present the following "
464+
"redefinitions are restricted: "
465+
"<ul>"
466+
"<li>changing the schema (the fields)</li>"
467+
"<li>changing the hierarchy (superclasses, interfaces)</li>"
468+
"<li>deleting a method</li>"
469+
"<li>changing class modifiers</li>"
470+
"<li>changing method modifiers</li>"
471+
"<li>changing the <code>NestHost</code> or <code>NestMembers</code> class attributes</li>"
472+
"</ul>"
473+
"<p>"
463474
"Requires canRedefineClasses capability - see "
464475
"<a href=\"#JDWP_VirtualMachine_CapabilitiesNew\">CapabilitiesNew</a>. "
465476
"In addition to the canRedefineClasses capability, the target VM must "
466477
"have the canAddMethod capability to add methods when redefining classes, "
467-
"or the canUnrestrictedlyRedefineClasses to redefine classes in arbitrary "
468-
"ways."
478+
"or the canUnrestrictedlyRedefineClasses capability to redefine classes in ways "
479+
"that are normally restricted."
469480
(Out
470481
(Repeat classes "Number of reference types that follow."
471482
(Group ClassDef
@@ -496,6 +507,7 @@ JDWP "Java(tm) Debug Wire Protocol"
496507
(Error DELETE_METHOD_NOT_IMPLEMENTED)
497508
(Error CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED)
498509
(Error METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED)
510+
(Error CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED)
499511
(Error VM_DEAD)
500512
)
501513
)
@@ -3148,12 +3160,16 @@ JDWP "Java(tm) Debug Wire Protocol"
31483160
"different from the name in the old class object.")
31493161
(Constant CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED
31503162
=70 "The new class version has different modifiers and "
3151-
"and canUnrestrictedlyRedefineClasses is false.")
3163+
"canUnrestrictedlyRedefineClasses is false.")
31523164
(Constant METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED
31533165
=71 "A method in the new class version has "
31543166
"different modifiers "
31553167
"than its counterpart in the old class version and "
3156-
"and canUnrestrictedlyRedefineClasses is false.")
3168+
"canUnrestrictedlyRedefineClasses is false.")
3169+
(Constant CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED
3170+
=72 "The new class version has different NestHost or "
3171+
"NestMembers class attribute and "
3172+
"canUnrestrictedlyRedefineClasses is false.")
31573173
(Constant NOT_IMPLEMENTED =99 "The functionality is not implemented in "
31583174
"this virtual machine.")
31593175
(Constant NULL_POINTER =100 "Invalid pointer.")

make/hotspot/symbols/symbols-unix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#
2323

2424
JVM_ActiveProcessorCount
25+
JVM_AreNestMates
2526
JVM_ArrayCopy
2627
JVM_AssertionStatusDirectives
2728
JVM_BeforeHalt
@@ -118,6 +119,8 @@ JVM_GetMethodIxSignatureUTF
118119
JVM_GetMethodParameters
119120
JVM_GetMethodTypeAnnotations
120121
JVM_GetNanoTimeAdjustment
122+
JVM_GetNestHost
123+
JVM_GetNestMembers
121124
JVM_GetPrimitiveArrayElement
122125
JVM_GetProtectionDomain
123126
JVM_GetSimpleBinaryName

src/hotspot/cpu/aarch64/templateTable_aarch64.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3362,22 +3362,45 @@ void TemplateTable::invokeinterface(int byte_no) {
33623362
// r2: receiver
33633363
// r3: flags
33643364

3365+
// First check for Object case, then private interface method,
3366+
// then regular interface method.
3367+
33653368
// Special case of invokeinterface called for virtual method of
3366-
// java.lang.Object. See cpCacheOop.cpp for details.
3367-
// This code isn't produced by javac, but could be produced by
3368-
// another compliant java compiler.
3369-
Label notMethod;
3370-
__ tbz(r3, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod);
3369+
// java.lang.Object. See cpCache.cpp for details.
3370+
Label notObjectMethod;
3371+
__ tbz(r3, ConstantPoolCacheEntry::is_forced_virtual_shift, notObjectMethod);
33713372

33723373
invokevirtual_helper(rmethod, r2, r3);
3373-
__ bind(notMethod);
3374+
__ bind(notObjectMethod);
3375+
3376+
Label no_such_interface;
3377+
3378+
// Check for private method invocation - indicated by vfinal
3379+
Label notVFinal;
3380+
__ tbz(r3, ConstantPoolCacheEntry::is_vfinal_shift, notVFinal);
3381+
3382+
// Get receiver klass into r3 - also a null check
3383+
__ null_check(r2, oopDesc::klass_offset_in_bytes());
3384+
__ load_klass(r3, r2);
3385+
3386+
Label subtype;
3387+
__ check_klass_subtype(r3, r0, r4, subtype);
3388+
// If we get here the typecheck failed
3389+
__ b(no_such_interface);
3390+
__ bind(subtype);
3391+
3392+
__ profile_final_call(r0);
3393+
__ profile_arguments_type(r0, rmethod, r4, true);
3394+
__ jump_from_interpreted(rmethod, r0);
3395+
3396+
__ bind(notVFinal);
33743397

33753398
// Get receiver klass into r3 - also a null check
33763399
__ restore_locals();
33773400
__ null_check(r2, oopDesc::klass_offset_in_bytes());
33783401
__ load_klass(r3, r2);
33793402

3380-
Label no_such_interface, no_such_method;
3403+
Label no_such_method;
33813404

33823405
// Preserve method for throw_AbstractMethodErrorVerbose.
33833406
__ mov(r16, rmethod);

src/hotspot/cpu/arm/templateTable_arm.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4276,25 +4276,41 @@ void TemplateTable::invokeinterface(int byte_no) {
42764276
const Register Rinterf = R5_tmp;
42774277
const Register Rindex = R4_tmp;
42784278
const Register Rflags = R3_tmp;
4279-
const Register Rklass = R3_tmp;
4279+
const Register Rklass = R2_tmp; // Note! Same register with Rrecv
42804280

42814281
prepare_invoke(byte_no, Rinterf, Rmethod, Rrecv, Rflags);
42824282

4283-
// Special case of invokeinterface called for virtual method of
4284-
// java.lang.Object. See cpCacheOop.cpp for details.
4285-
// This code isn't produced by javac, but could be produced by
4286-
// another compliant java compiler.
4287-
Label notMethod;
4288-
__ tbz(Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod);
4283+
// First check for Object case, then private interface method,
4284+
// then regular interface method.
42894285

4286+
// Special case of invokeinterface called for virtual method of
4287+
// java.lang.Object. See cpCache.cpp for details.
4288+
Label notObjectMethod;
4289+
__ tbz(Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift, notObjectMethod);
42904290
invokevirtual_helper(Rmethod, Rrecv, Rflags);
4291-
__ bind(notMethod);
4291+
__ bind(notObjectMethod);
42924292

42934293
// Get receiver klass into Rklass - also a null check
42944294
__ load_klass(Rklass, Rrecv);
42954295

4296+
// Check for private method invocation - indicated by vfinal
42964297
Label no_such_interface;
42974298

4299+
Label notVFinal;
4300+
__ tbz(Rflags, ConstantPoolCacheEntry::is_vfinal_shift, notVFinal);
4301+
4302+
Label subtype;
4303+
__ check_klass_subtype(Rklass, Rinterf, R1_tmp, R3_tmp, noreg, subtype);
4304+
// If we get here the typecheck failed
4305+
__ b(no_such_interface);
4306+
__ bind(subtype);
4307+
4308+
// do the call
4309+
__ profile_final_call(R0_tmp);
4310+
__ jump_from_interpreted(Rmethod);
4311+
4312+
__ bind(notVFinal);
4313+
42984314
// Receiver subtype check against REFC.
42994315
__ lookup_interface_method(// inputs: rec. class, interface
43004316
Rklass, Rinterf, noreg,

src/hotspot/cpu/ppc/templateTable_ppc_64.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3583,14 +3583,46 @@ void TemplateTable::invokeinterface(int byte_no) {
35833583

35843584
prepare_invoke(byte_no, Rinterface_klass, Rret_addr, Rmethod, Rreceiver, Rflags, Rscratch1);
35853585

3586-
// Get receiver klass.
3586+
// First check for Object case, then private interface method,
3587+
// then regular interface method.
3588+
3589+
// Get receiver klass - this is also a null check
35873590
__ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2);
35883591
__ load_klass(Rrecv_klass, Rreceiver);
35893592

35903593
// Check corner case object method.
3591-
Label LobjectMethod, L_no_such_interface, Lthrow_ame;
3594+
// Special case of invokeinterface called for virtual method of
3595+
// java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
3596+
// The invokeinterface was rewritten to a invokevirtual, hence we have
3597+
// to handle this corner case.
3598+
3599+
Label LnotObjectMethod, Lthrow_ame;
35923600
__ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift);
3593-
__ btrue(CCR0, LobjectMethod);
3601+
__ bfalse(CCR0, LnotObjectMethod);
3602+
invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2);
3603+
__ bind(LnotObjectMethod);
3604+
3605+
// Check for private method invocation - indicated by vfinal
3606+
Label LnotVFinal, L_no_such_interface, L_subtype;
3607+
3608+
__ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
3609+
__ bfalse(CCR0, LnotVFinal);
3610+
3611+
__ check_klass_subtype(Rrecv_klass, Rinterface_klass, Rscratch1, Rscratch2, L_subtype);
3612+
// If we get here the typecheck failed
3613+
__ b(L_no_such_interface);
3614+
__ bind(L_subtype);
3615+
3616+
// do the call
3617+
3618+
Register Rscratch = Rflags; // Rflags is dead now.
3619+
3620+
__ profile_final_call(Rscratch1, Rscratch);
3621+
__ profile_arguments_type(Rindex, Rscratch, Rrecv_klass /* scratch */, true);
3622+
3623+
__ call_from_interpreter(Rindex, Rret_addr, Rscratch, Rrecv_klass /* scratch */);
3624+
3625+
__ bind(LnotVFinal);
35943626

35953627
__ lookup_interface_method(Rrecv_klass, Rinterface_klass, noreg, noreg, Rscratch1, Rscratch2,
35963628
L_no_such_interface, /*return_method=*/false);
@@ -3631,14 +3663,6 @@ void TemplateTable::invokeinterface(int byte_no) {
36313663
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose),
36323664
Rrecv_klass, Rinterface_klass);
36333665
DEBUG_ONLY( __ should_not_reach_here(); )
3634-
3635-
// Special case of invokeinterface called for virtual method of
3636-
// java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
3637-
// The invokeinterface was rewritten to a invokevirtual, hence we have
3638-
// to handle this corner case. This code isn't produced by javac, but could
3639-
// be produced by another compliant java compiler.
3640-
__ bind(LobjectMethod);
3641-
invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2);
36423666
}
36433667

36443668
void TemplateTable::invokedynamic(int byte_no) {

src/hotspot/cpu/s390/templateTable_s390.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3610,20 +3610,43 @@ void TemplateTable::invokeinterface(int byte_no) {
36103610

36113611
BLOCK_COMMENT("invokeinterface {");
36123612

3613-
prepare_invoke(byte_no, interface, method, // Get f1 klassOop, f2 itable index.
3613+
prepare_invoke(byte_no, interface, method, // Get f1 klassOop, f2 Method*.
36143614
receiver, flags);
36153615

36163616
// Z_R14 (== Z_bytecode) : return entry
36173617

3618+
// First check for Object case, then private interface method,
3619+
// then regular interface method.
3620+
36183621
// Special case of invokeinterface called for virtual method of
3619-
// java.lang.Object. See cpCacheOop.cpp for details.
3620-
// This code isn't produced by javac, but could be produced by
3621-
// another compliant java compiler.
3622-
NearLabel notMethod, no_such_interface, no_such_method;
3622+
// java.lang.Object. See cpCache.cpp for details.
3623+
NearLabel notObjectMethod, no_such_method;
36233624
__ testbit(flags, ConstantPoolCacheEntry::is_forced_virtual_shift);
3624-
__ z_brz(notMethod);
3625+
__ z_brz(notObjectMethod);
36253626
invokevirtual_helper(method, receiver, flags);
3626-
__ bind(notMethod);
3627+
__ bind(notObjectMethod);
3628+
3629+
// Check for private method invocation - indicated by vfinal
3630+
NearLabel notVFinal;
3631+
__ testbit(flags, ConstantPoolCacheEntry::is_vfinal_shift);
3632+
__ z_brz(notVFinal);
3633+
3634+
// Get receiver klass into klass - also a null check.
3635+
__ load_klass(klass, receiver);
3636+
3637+
NearLabel subtype, no_such_interface;
3638+
3639+
__ check_klass_subtype(klass, interface, Z_tmp_2, Z_tmp_3, subtype);
3640+
// If we get here the typecheck failed
3641+
__ z_bru(no_such_interface);
3642+
__ bind(subtype);
3643+
3644+
// do the call
3645+
__ profile_final_call(Z_tmp_2);
3646+
__ profile_arguments_type(Z_tmp_2, method, Z_ARG5, true);
3647+
__ jump_from_interpreted(method, Z_tmp_2);
3648+
3649+
__ bind(notVFinal);
36273650

36283651
// Get receiver klass into klass - also a null check.
36293652
__ restore_locals();

src/hotspot/cpu/sparc/templateTable_sparc.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3202,28 +3202,56 @@ void TemplateTable::invokeinterface(int byte_no) {
32023202

32033203
prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags);
32043204

3205-
// get receiver klass
3205+
// First check for Object case, then private interface method,
3206+
// then regular interface method.
3207+
3208+
// get receiver klass - this is also a null check
32063209
__ null_check(O0_recv, oopDesc::klass_offset_in_bytes());
32073210
__ load_klass(O0_recv, O2_Klass);
32083211

32093212
// Special case of invokeinterface called for virtual method of
3210-
// java.lang.Object. See cpCacheOop.cpp for details.
3211-
// This code isn't produced by javac, but could be produced by
3212-
// another compliant java compiler.
3213-
Label notMethod;
3213+
// java.lang.Object. See cpCache.cpp for details.
3214+
Label notObjectMethod;
32143215
__ set((1 << ConstantPoolCacheEntry::is_forced_virtual_shift), Rscratch);
32153216
__ btst(O1_flags, Rscratch);
3216-
__ br(Assembler::zero, false, Assembler::pt, notMethod);
3217+
__ br(Assembler::zero, false, Assembler::pt, notObjectMethod);
32173218
__ delayed()->nop();
32183219

32193220
invokeinterface_object_method(O2_Klass, Rinterface, Rret, O1_flags);
32203221

3221-
__ bind(notMethod);
3222-
3223-
Register Rtemp = O1_flags;
3222+
__ bind(notObjectMethod);
32243223

32253224
Label L_no_such_interface;
32263225

3226+
// Check for private method invocation - indicated by vfinal
3227+
Label notVFinal;
3228+
{
3229+
__ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), Rscratch);
3230+
__ btst(O1_flags, Rscratch);
3231+
__ br(Assembler::zero, false, Assembler::pt, notVFinal);
3232+
__ delayed()->nop();
3233+
3234+
Label subtype;
3235+
Register Rtemp = O1_flags;
3236+
__ check_klass_subtype(O2_Klass, Rinterface, Rscratch, Rtemp, subtype);
3237+
// If we get here the typecheck failed
3238+
__ ba(L_no_such_interface);
3239+
__ delayed()->nop();
3240+
__ bind(subtype);
3241+
3242+
// do the call
3243+
Register Rcall = Rinterface;
3244+
__ mov(Rmethod, G5_method);
3245+
assert_different_registers(Rcall, G5_method, Gargs, Rret);
3246+
3247+
__ profile_arguments_type(G5_method, Rcall, Gargs, true);
3248+
__ profile_final_call(Rscratch);
3249+
__ call_from_interpreter(Rcall, Gargs, Rret);
3250+
}
3251+
__ bind(notVFinal);
3252+
3253+
Register Rtemp = O1_flags;
3254+
32273255
// Receiver subtype check against REFC.
32283256
__ lookup_interface_method(// inputs: rec. class, interface, itable index
32293257
O2_Klass, Rinterface, noreg,

0 commit comments

Comments
 (0)