< prev index next >

src/hotspot/cpu/aarch64/templateTable_aarch64.cpp

Print this page
rev 49172 : 8197405: Improve messages of AbstractMethodErrors and IncompatibleClassChangeErrors.
Reviewed-by: coleenp, dholmes, mdoerr, njian


3423   // r2: receiver
3424   // r3: flags
3425 
3426   // Special case of invokeinterface called for virtual method of
3427   // java.lang.Object.  See cpCacheOop.cpp for details.
3428   // This code isn't produced by javac, but could be produced by
3429   // another compliant java compiler.
3430   Label notMethod;
3431   __ tbz(r3, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod);
3432 
3433   invokevirtual_helper(rmethod, r2, r3);
3434   __ bind(notMethod);
3435 
3436   // Get receiver klass into r3 - also a null check
3437   __ restore_locals();
3438   __ null_check(r2, oopDesc::klass_offset_in_bytes());
3439   __ load_klass(r3, r2);
3440 
3441   Label no_such_interface, no_such_method;
3442 


3443   // Receiver subtype check against REFC.
3444   // Superklass in r0. Subklass in r3. Blows rscratch2, r13
3445   __ lookup_interface_method(// inputs: rec. class, interface, itable index
3446                              r3, r0, noreg,
3447                              // outputs: scan temp. reg, scan temp. reg
3448                              rscratch2, r13,
3449                              no_such_interface,
3450                              /*return_method=*/false);
3451 
3452   // profile this call
3453   __ profile_virtual_call(r3, r13, r19);
3454 
3455   // Get declaring interface class from method, and itable index
3456   __ ldr(r0, Address(rmethod, Method::const_offset()));
3457   __ ldr(r0, Address(r0, ConstMethod::constants_offset()));
3458   __ ldr(r0, Address(r0, ConstantPool::pool_holder_offset_in_bytes()));
3459   __ ldrw(rmethod, Address(rmethod, Method::itable_index_offset()));
3460   __ subw(rmethod, rmethod, Method::itable_index_max);
3461   __ negw(rmethod, rmethod);
3462 


3463   __ lookup_interface_method(// inputs: rec. class, interface, itable index
3464                              r3, r0, rmethod,
3465                              // outputs: method, scan temp. reg
3466                              rmethod, r13,
3467                              no_such_interface);
3468 
3469   // rmethod,: methodOop to call
3470   // r2: receiver
3471   // Check for abstract method error
3472   // Note: This should be done more efficiently via a throw_abstract_method_error
3473   //       interpreter entry point and a conditional jump to it in case of a null
3474   //       method.
3475   __ cbz(rmethod, no_such_method);
3476 
3477   __ profile_arguments_type(r3, rmethod, r13, true);
3478 
3479   // do the call
3480   // r2: receiver
3481   // rmethod,: methodOop
3482   __ jump_from_interpreted(rmethod, r3);
3483   __ should_not_reach_here();
3484 
3485   // exception handling code follows...
3486   // note: must restore interpreter registers to canonical
3487   //       state for exception handling to work correctly!
3488 
3489   __ bind(no_such_method);
3490   // throw exception
3491   __ restore_bcp();      // bcp must be correct for exception handler   (was destroyed)
3492   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3493   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));

3494   // the call_VM checks for exception, so we should never return here.
3495   __ should_not_reach_here();
3496 
3497   __ bind(no_such_interface);
3498   // throw exception
3499   __ restore_bcp();      // bcp must be correct for exception handler   (was destroyed)
3500   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)

3501   __ call_VM(noreg, CAST_FROM_FN_PTR(address,
3502                    InterpreterRuntime::throw_IncompatibleClassChangeError));
3503   // the call_VM checks for exception, so we should never return here.
3504   __ should_not_reach_here();
3505   return;
3506 }
3507 
3508 void TemplateTable::invokehandle(int byte_no) {
3509   transition(vtos, vtos);
3510   assert(byte_no == f1_byte, "use this argument");
3511 
3512   prepare_invoke(byte_no, rmethod, r0, r2);
3513   __ verify_method_ptr(r2);
3514   __ verify_oop(r2);
3515   __ null_check(r2);
3516 
3517   // FIXME: profile the LambdaForm also
3518 
3519   // r13 is safe to use here as a scratch reg because it is about to
3520   // be clobbered by jump_from_interpreted().
3521   __ profile_final_call(r13);
3522   __ profile_arguments_type(r13, rmethod, r4, true);




3423   // r2: receiver
3424   // r3: flags
3425 
3426   // Special case of invokeinterface called for virtual method of
3427   // java.lang.Object.  See cpCacheOop.cpp for details.
3428   // This code isn't produced by javac, but could be produced by
3429   // another compliant java compiler.
3430   Label notMethod;
3431   __ tbz(r3, ConstantPoolCacheEntry::is_forced_virtual_shift, notMethod);
3432 
3433   invokevirtual_helper(rmethod, r2, r3);
3434   __ bind(notMethod);
3435 
3436   // Get receiver klass into r3 - also a null check
3437   __ restore_locals();
3438   __ null_check(r2, oopDesc::klass_offset_in_bytes());
3439   __ load_klass(r3, r2);
3440 
3441   Label no_such_interface, no_such_method;
3442 
3443   // Preserve method for throw_AbstractMethodErrorVerbose.
3444   __ mov(r16, rmethod);
3445   // Receiver subtype check against REFC.
3446   // Superklass in r0. Subklass in r3. Blows rscratch2, r13
3447   __ lookup_interface_method(// inputs: rec. class, interface, itable index
3448                              r3, r0, noreg,
3449                              // outputs: scan temp. reg, scan temp. reg
3450                              rscratch2, r13,
3451                              no_such_interface,
3452                              /*return_method=*/false);
3453 
3454   // profile this call
3455   __ profile_virtual_call(r3, r13, r19);
3456 
3457   // Get declaring interface class from method, and itable index
3458   __ ldr(r0, Address(rmethod, Method::const_offset()));
3459   __ ldr(r0, Address(r0, ConstMethod::constants_offset()));
3460   __ ldr(r0, Address(r0, ConstantPool::pool_holder_offset_in_bytes()));
3461   __ ldrw(rmethod, Address(rmethod, Method::itable_index_offset()));
3462   __ subw(rmethod, rmethod, Method::itable_index_max);
3463   __ negw(rmethod, rmethod);
3464 
3465   // Preserve recvKlass for throw_AbstractMethodErrorVerbose.
3466   __ mov(rlocals, r3);
3467   __ lookup_interface_method(// inputs: rec. class, interface, itable index
3468                              rlocals, r0, rmethod,
3469                              // outputs: method, scan temp. reg
3470                              rmethod, r13,
3471                              no_such_interface);
3472 
3473   // rmethod,: methodOop to call
3474   // r2: receiver
3475   // Check for abstract method error
3476   // Note: This should be done more efficiently via a throw_abstract_method_error
3477   //       interpreter entry point and a conditional jump to it in case of a null
3478   //       method.
3479   __ cbz(rmethod, no_such_method);
3480 
3481   __ profile_arguments_type(r3, rmethod, r13, true);
3482 
3483   // do the call
3484   // r2: receiver
3485   // rmethod,: methodOop
3486   __ jump_from_interpreted(rmethod, r3);
3487   __ should_not_reach_here();
3488 
3489   // exception handling code follows...
3490   // note: must restore interpreter registers to canonical
3491   //       state for exception handling to work correctly!
3492 
3493   __ bind(no_such_method);
3494   // throw exception
3495   __ restore_bcp();      // bcp must be correct for exception handler   (was destroyed)
3496   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3497   // Pass arguments for generating a verbose error message.
3498   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose), r3, r16);
3499   // the call_VM checks for exception, so we should never return here.
3500   __ should_not_reach_here();
3501 
3502   __ bind(no_such_interface);
3503   // throw exception
3504   __ restore_bcp();      // bcp must be correct for exception handler   (was destroyed)
3505   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
3506   // Pass arguments for generating a verbose error message.
3507   __ call_VM(noreg, CAST_FROM_FN_PTR(address,
3508                    InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose), r3, r0);
3509   // the call_VM checks for exception, so we should never return here.
3510   __ should_not_reach_here();
3511   return;
3512 }
3513 
3514 void TemplateTable::invokehandle(int byte_no) {
3515   transition(vtos, vtos);
3516   assert(byte_no == f1_byte, "use this argument");
3517 
3518   prepare_invoke(byte_no, rmethod, r0, r2);
3519   __ verify_method_ptr(r2);
3520   __ verify_oop(r2);
3521   __ null_check(r2);
3522 
3523   // FIXME: profile the LambdaForm also
3524 
3525   // r13 is safe to use here as a scratch reg because it is about to
3526   // be clobbered by jump_from_interpreted().
3527   __ profile_final_call(r13);
3528   __ profile_arguments_type(r13, rmethod, r4, true);


< prev index next >