< prev index next >

src/hotspot/cpu/ppc/templateTable_ppc_64.cpp

Print this page




3568   generate_vtable_call(Rrecv_klass, Rmethod, Rret, Rscratch);
3569 }
3570 
3571 void TemplateTable::invokeinterface(int byte_no) {
3572   assert(byte_no == f1_byte, "use this argument");
3573   transition(vtos, vtos);
3574 
3575   const Register Rscratch1        = R11_scratch1,
3576                  Rscratch2        = R12_scratch2,
3577                  Rmethod          = R6_ARG4,
3578                  Rmethod2         = R9_ARG7,
3579                  Rinterface_klass = R5_ARG3,
3580                  Rret_addr        = R8_ARG6,
3581                  Rindex           = R10_ARG8,
3582                  Rreceiver        = R3_ARG1,
3583                  Rrecv_klass      = R4_ARG2,
3584                  Rflags           = R7_ARG5;
3585 
3586   prepare_invoke(byte_no, Rinterface_klass, Rret_addr, Rmethod, Rreceiver, Rflags, Rscratch1);
3587 
3588   // Get receiver klass.



3589   __ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2);
3590   __ load_klass(Rrecv_klass, Rreceiver);
3591 
3592   // Check corner case object method.
3593   Label LobjectMethod, L_no_such_interface, Lthrow_ame;





3594   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift);
3595   __ btrue(CCR0, LobjectMethod);
























3596 
3597   __ lookup_interface_method(Rrecv_klass, Rinterface_klass, noreg, noreg, Rscratch1, Rscratch2,
3598                              L_no_such_interface, /*return_method=*/false);
3599 
3600   __ profile_virtual_call(Rrecv_klass, Rscratch1, Rscratch2, false);
3601 
3602   // Find entry point to call.
3603 
3604   // Get declaring interface class from method
3605   __ ld(Rinterface_klass, in_bytes(Method::const_offset()), Rmethod);
3606   __ ld(Rinterface_klass, in_bytes(ConstMethod::constants_offset()), Rinterface_klass);
3607   __ ld(Rinterface_klass, ConstantPool::pool_holder_offset_in_bytes(), Rinterface_klass);
3608 
3609   // Get itable index from method
3610   __ lwa(Rindex, in_bytes(Method::itable_index_offset()), Rmethod);
3611   __ subfic(Rindex, Rindex, Method::itable_index_max);
3612 
3613   __ lookup_interface_method(Rrecv_klass, Rinterface_klass, Rindex, Rmethod2, Rscratch1, Rscratch2,
3614                              L_no_such_interface);
3615 
3616   __ cmpdi(CCR0, Rmethod2, 0);
3617   __ beq(CCR0, Lthrow_ame);
3618   // Found entry. Jump off!
3619   // Argument and return type profiling.
3620   __ profile_arguments_type(Rmethod2, Rscratch1, Rscratch2, true);
3621   //__ profile_called_method(Rindex, Rscratch1);
3622   __ call_from_interpreter(Rmethod2, Rret_addr, Rscratch1, Rscratch2);
3623 
3624   // Vtable entry was NULL => Throw abstract method error.
3625   __ bind(Lthrow_ame);
3626   // Pass arguments for generating a verbose error message.
3627   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose),
3628           Rrecv_klass, Rmethod);
3629 
3630   // Interface was not found => Throw incompatible class change error.
3631   __ bind(L_no_such_interface);
3632   // Pass arguments for generating a verbose error message.
3633   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose),
3634           Rrecv_klass, Rinterface_klass);
3635   DEBUG_ONLY( __ should_not_reach_here(); )
3636 
3637   // Special case of invokeinterface called for virtual method of
3638   // java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
3639   // The invokeinterface was rewritten to a invokevirtual, hence we have
3640   // to handle this corner case. This code isn't produced by javac, but could
3641   // be produced by another compliant java compiler.
3642   __ bind(LobjectMethod);
3643   invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2);
3644 }
3645 
3646 void TemplateTable::invokedynamic(int byte_no) {
3647   transition(vtos, vtos);
3648 
3649   const Register Rret_addr = R3_ARG1,
3650                  Rflags    = R4_ARG2,
3651                  Rmethod   = R22_tmp2,
3652                  Rscratch1 = R11_scratch1,
3653                  Rscratch2 = R12_scratch2;
3654 
3655   prepare_invoke(byte_no, Rmethod, Rret_addr, Rscratch1, noreg, Rflags, Rscratch2);
3656 
3657   // Profile this call.
3658   __ profile_call(Rscratch1, Rscratch2);
3659 
3660   // Off we go. With the new method handles, we don't jump to a method handle
3661   // entry any more. Instead, we pushed an "appendix" in prepare invoke, which happens
3662   // to be the callsite object the bootstrap method returned. This is passed to a
3663   // "link" method which does the dispatch (Most likely just grabs the MH stored




3568   generate_vtable_call(Rrecv_klass, Rmethod, Rret, Rscratch);
3569 }
3570 
3571 void TemplateTable::invokeinterface(int byte_no) {
3572   assert(byte_no == f1_byte, "use this argument");
3573   transition(vtos, vtos);
3574 
3575   const Register Rscratch1        = R11_scratch1,
3576                  Rscratch2        = R12_scratch2,
3577                  Rmethod          = R6_ARG4,
3578                  Rmethod2         = R9_ARG7,
3579                  Rinterface_klass = R5_ARG3,
3580                  Rret_addr        = R8_ARG6,
3581                  Rindex           = R10_ARG8,
3582                  Rreceiver        = R3_ARG1,
3583                  Rrecv_klass      = R4_ARG2,
3584                  Rflags           = R7_ARG5;
3585 
3586   prepare_invoke(byte_no, Rinterface_klass, Rret_addr, Rmethod, Rreceiver, Rflags, Rscratch1);
3587 
3588   // First check for Object case, then private interface method,
3589   // then regular interface method.
3590 
3591   // Get receiver klass - this is also a null check
3592   __ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2);
3593   __ load_klass(Rrecv_klass, Rreceiver);
3594 
3595   // Check corner case object method.
3596   // Special case of invokeinterface called for virtual method of
3597   // java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
3598   // The invokeinterface was rewritten to a invokevirtual, hence we have
3599   // to handle this corner case.
3600 
3601   Label LnotObjectMethod, Lthrow_ame;
3602   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift);
3603   __ bfalse(CCR0, LnotObjectMethod);
3604   invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rmethod, Rscratch1, Rscratch2);
3605   __ bind(LnotObjectMethod);
3606 
3607   // Check for private method invocation - indicated by vfinal
3608   Label LnotVFinal, L_no_such_interface, L_subtype;
3609 
3610   __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
3611   __ bfalse(CCR0, LnotVFinal);
3612 
3613   __ check_klass_subtype(Rrecv_klass, Rinterface_klass, Rscratch, Rscratch1, subtype);
3614   // If we get here the typecheck failed
3615   __ b(L_no_such_interface);
3616   __ bind(subtype);
3617 
3618   // do the call
3619 
3620   Register Rscratch = Rflags; // Rflags is dead now.
3621 
3622   __ profile_final_call(Rscratch1, Rscratch);
3623   __ profile_arguments_type(Rindex, Rscratch, Rrecv_klass /* scratch */, true);
3624 
3625   __ call_from_interpreter(Rindex, Rret_addr, Rscratch, Rrecv_klass /* scratch */);
3626 
3627   __ bind(LnotVFinal);
3628 
3629   __ lookup_interface_method(Rrecv_klass, Rinterface_klass, noreg, noreg, Rscratch1, Rscratch2,
3630                              L_no_such_interface, /*return_method=*/false);
3631 
3632   __ profile_virtual_call(Rrecv_klass, Rscratch1, Rscratch2, false);
3633 
3634   // Find entry point to call.
3635 
3636   // Get declaring interface class from method
3637   __ ld(Rinterface_klass, in_bytes(Method::const_offset()), Rmethod);
3638   __ ld(Rinterface_klass, in_bytes(ConstMethod::constants_offset()), Rinterface_klass);
3639   __ ld(Rinterface_klass, ConstantPool::pool_holder_offset_in_bytes(), Rinterface_klass);
3640 
3641   // Get itable index from method
3642   __ lwa(Rindex, in_bytes(Method::itable_index_offset()), Rmethod);
3643   __ subfic(Rindex, Rindex, Method::itable_index_max);
3644 
3645   __ lookup_interface_method(Rrecv_klass, Rinterface_klass, Rindex, Rmethod2, Rscratch1, Rscratch2,
3646                              L_no_such_interface);
3647 
3648   __ cmpdi(CCR0, Rmethod2, 0);
3649   __ beq(CCR0, Lthrow_ame);
3650   // Found entry. Jump off!
3651   // Argument and return type profiling.
3652   __ profile_arguments_type(Rmethod2, Rscratch1, Rscratch2, true);
3653   //__ profile_called_method(Rindex, Rscratch1);
3654   __ call_from_interpreter(Rmethod2, Rret_addr, Rscratch1, Rscratch2);
3655 
3656   // Vtable entry was NULL => Throw abstract method error.
3657   __ bind(Lthrow_ame);
3658   // Pass arguments for generating a verbose error message.
3659   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodErrorVerbose),
3660           Rrecv_klass, Rmethod);
3661 
3662   // Interface was not found => Throw incompatible class change error.
3663   __ bind(L_no_such_interface);
3664   // Pass arguments for generating a verbose error message.
3665   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose),
3666           Rrecv_klass, Rinterface_klass);
3667   DEBUG_ONLY( __ should_not_reach_here(); )








3668 }
3669 
3670 void TemplateTable::invokedynamic(int byte_no) {
3671   transition(vtos, vtos);
3672 
3673   const Register Rret_addr = R3_ARG1,
3674                  Rflags    = R4_ARG2,
3675                  Rmethod   = R22_tmp2,
3676                  Rscratch1 = R11_scratch1,
3677                  Rscratch2 = R12_scratch2;
3678 
3679   prepare_invoke(byte_no, Rmethod, Rret_addr, Rscratch1, noreg, Rflags, Rscratch2);
3680 
3681   // Profile this call.
3682   __ profile_call(Rscratch1, Rscratch2);
3683 
3684   // Off we go. With the new method handles, we don't jump to a method handle
3685   // entry any more. Instead, we pushed an "appendix" in prepare invoke, which happens
3686   // to be the callsite object the bootstrap method returned. This is passed to a
3687   // "link" method which does the dispatch (Most likely just grabs the MH stored


< prev index next >