3163 void TemplateTable::invokeinterface(int byte_no) { |
3163 void TemplateTable::invokeinterface(int byte_no) { |
3164 transition(vtos, vtos); |
3164 transition(vtos, vtos); |
3165 assert(byte_no == f1_byte, "use this argument"); |
3165 assert(byte_no == f1_byte, "use this argument"); |
3166 |
3166 |
3167 const Register Rinterface = G1_scratch; |
3167 const Register Rinterface = G1_scratch; |
|
3168 const Register Rmethod = Lscratch; |
3168 const Register Rret = G3_scratch; |
3169 const Register Rret = G3_scratch; |
3169 const Register Rindex = Lscratch; |
|
3170 const Register O0_recv = O0; |
3170 const Register O0_recv = O0; |
3171 const Register O1_flags = O1; |
3171 const Register O1_flags = O1; |
3172 const Register O2_Klass = O2; |
3172 const Register O2_Klass = O2; |
3173 const Register Rscratch = G4_scratch; |
3173 const Register Rscratch = G4_scratch; |
3174 assert_different_registers(Rscratch, G5_method); |
3174 assert_different_registers(Rscratch, G5_method); |
3175 |
3175 |
3176 prepare_invoke(byte_no, Rinterface, Rret, Rindex, O0_recv, O1_flags); |
3176 prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags); |
3177 |
3177 |
3178 // get receiver klass |
3178 // get receiver klass |
3179 __ null_check(O0_recv, oopDesc::klass_offset_in_bytes()); |
3179 __ null_check(O0_recv, oopDesc::klass_offset_in_bytes()); |
3180 __ load_klass(O0_recv, O2_Klass); |
3180 __ load_klass(O0_recv, O2_Klass); |
3181 |
3181 |
3191 |
3191 |
3192 invokeinterface_object_method(O2_Klass, Rinterface, Rret, O1_flags); |
3192 invokeinterface_object_method(O2_Klass, Rinterface, Rret, O1_flags); |
3193 |
3193 |
3194 __ bind(notMethod); |
3194 __ bind(notMethod); |
3195 |
3195 |
|
3196 Register Rtemp = O1_flags; |
|
3197 |
|
3198 Label L_no_such_interface; |
|
3199 |
|
3200 // Receiver subtype check against REFC. |
|
3201 __ lookup_interface_method(// inputs: rec. class, interface, itable index |
|
3202 O2_Klass, Rinterface, noreg, |
|
3203 // outputs: temp reg1, temp reg2, temp reg3 |
|
3204 G5_method, Rscratch, Rtemp, |
|
3205 L_no_such_interface, |
|
3206 /*return_method=*/false); |
|
3207 |
3196 __ profile_virtual_call(O2_Klass, O4); |
3208 __ profile_virtual_call(O2_Klass, O4); |
3197 |
3209 |
3198 // |
3210 // |
3199 // find entry point to call |
3211 // find entry point to call |
3200 // |
3212 // |
3201 |
3213 |
3202 // compute start of first itableOffsetEntry (which is at end of vtable) |
3214 // Get declaring interface class from method |
3203 const int base = InstanceKlass::vtable_start_offset() * wordSize; |
3215 __ ld_ptr(Rmethod, Method::const_offset(), Rinterface); |
3204 Label search; |
3216 __ ld_ptr(Rinterface, ConstMethod::constants_offset(), Rinterface); |
3205 Register Rtemp = O1_flags; |
3217 __ ld_ptr(Rinterface, ConstantPool::pool_holder_offset_in_bytes(), Rinterface); |
3206 |
3218 |
3207 __ ld(O2_Klass, InstanceKlass::vtable_length_offset() * wordSize, Rtemp); |
3219 // Get itable index from method |
3208 if (align_object_offset(1) > 1) { |
3220 const Register Rindex = G5_method; |
3209 __ round_to(Rtemp, align_object_offset(1)); |
3221 __ ld(Rmethod, Method::itable_index_offset(), Rindex); |
3210 } |
3222 __ sub(Rindex, Method::itable_index_max, Rindex); |
3211 __ sll(Rtemp, LogBytesPerWord, Rtemp); // Rscratch *= 4; |
3223 __ neg(Rindex); |
3212 if (Assembler::is_simm13(base)) { |
3224 |
3213 __ add(Rtemp, base, Rtemp); |
3225 __ lookup_interface_method(// inputs: rec. class, interface, itable index |
3214 } else { |
3226 O2_Klass, Rinterface, Rindex, |
3215 __ set(base, Rscratch); |
3227 // outputs: method, scan temp reg, temp reg |
3216 __ add(Rscratch, Rtemp, Rtemp); |
3228 G5_method, Rscratch, Rtemp, |
3217 } |
3229 L_no_such_interface); |
3218 __ add(O2_Klass, Rtemp, Rscratch); |
|
3219 |
|
3220 __ bind(search); |
|
3221 |
|
3222 __ ld_ptr(Rscratch, itableOffsetEntry::interface_offset_in_bytes(), Rtemp); |
|
3223 { |
|
3224 Label ok; |
|
3225 |
|
3226 // Check that entry is non-null. Null entries are probably a bytecode |
|
3227 // problem. If the interface isn't implemented by the receiver class, |
|
3228 // the VM should throw IncompatibleClassChangeError. linkResolver checks |
|
3229 // this too but that's only if the entry isn't already resolved, so we |
|
3230 // need to check again. |
|
3231 __ br_notnull_short( Rtemp, Assembler::pt, ok); |
|
3232 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); |
|
3233 __ should_not_reach_here(); |
|
3234 __ bind(ok); |
|
3235 } |
|
3236 |
|
3237 __ cmp(Rinterface, Rtemp); |
|
3238 __ brx(Assembler::notEqual, true, Assembler::pn, search); |
|
3239 __ delayed()->add(Rscratch, itableOffsetEntry::size() * wordSize, Rscratch); |
|
3240 |
|
3241 // entry found and Rscratch points to it |
|
3242 __ ld(Rscratch, itableOffsetEntry::offset_offset_in_bytes(), Rscratch); |
|
3243 |
|
3244 assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below"); |
|
3245 __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex); // Rindex *= 8; |
|
3246 __ add(Rscratch, Rindex, Rscratch); |
|
3247 __ ld_ptr(O2_Klass, Rscratch, G5_method); |
|
3248 |
3230 |
3249 // Check for abstract method error. |
3231 // Check for abstract method error. |
3250 { |
3232 { |
3251 Label ok; |
3233 Label ok; |
3252 __ br_notnull_short(G5_method, Assembler::pt, ok); |
3234 __ br_notnull_short(G5_method, Assembler::pt, ok); |
3258 Register Rcall = Rinterface; |
3240 Register Rcall = Rinterface; |
3259 assert_different_registers(Rcall, G5_method, Gargs, Rret); |
3241 assert_different_registers(Rcall, G5_method, Gargs, Rret); |
3260 |
3242 |
3261 __ profile_arguments_type(G5_method, Rcall, Gargs, true); |
3243 __ profile_arguments_type(G5_method, Rcall, Gargs, true); |
3262 __ call_from_interpreter(Rcall, Gargs, Rret); |
3244 __ call_from_interpreter(Rcall, Gargs, Rret); |
|
3245 |
|
3246 __ bind(L_no_such_interface); |
|
3247 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); |
|
3248 __ should_not_reach_here(); |
3263 } |
3249 } |
3264 |
3250 |
3265 void TemplateTable::invokehandle(int byte_no) { |
3251 void TemplateTable::invokehandle(int byte_no) { |
3266 transition(vtos, vtos); |
3252 transition(vtos, vtos); |
3267 assert(byte_no == f1_byte, "use this argument"); |
3253 assert(byte_no == f1_byte, "use this argument"); |