diff -r 2667e5c45e24 -r f8a45a60bc6b src/cpu/sparc/vm/templateTable_sparc.cpp --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Tue Aug 08 12:02:01 2017 +0100 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Sep 29 14:30:05 2017 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -3165,15 +3165,15 @@ assert(byte_no == f1_byte, "use this argument"); const Register Rinterface = G1_scratch; + const Register Rmethod = Lscratch; const Register Rret = G3_scratch; - const Register Rindex = Lscratch; const Register O0_recv = O0; const Register O1_flags = O1; const Register O2_Klass = O2; const Register Rscratch = G4_scratch; assert_different_registers(Rscratch, G5_method); - prepare_invoke(byte_no, Rinterface, Rret, Rindex, O0_recv, O1_flags); + prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags); // get receiver klass __ null_check(O0_recv, oopDesc::klass_offset_in_bytes()); @@ -3193,58 +3193,40 @@ __ bind(notMethod); + Register Rtemp = O1_flags; + + Label L_no_such_interface; + + // Receiver subtype check against REFC. + __ lookup_interface_method(// inputs: rec. class, interface, itable index + O2_Klass, Rinterface, noreg, + // outputs: temp reg1, temp reg2, temp reg3 + G5_method, Rscratch, Rtemp, + L_no_such_interface, + /*return_method=*/false); + __ profile_virtual_call(O2_Klass, O4); // // find entry point to call // - // compute start of first itableOffsetEntry (which is at end of vtable) - const int base = InstanceKlass::vtable_start_offset() * wordSize; - Label search; - Register Rtemp = O1_flags; - - __ ld(O2_Klass, InstanceKlass::vtable_length_offset() * wordSize, Rtemp); - if (align_object_offset(1) > 1) { - __ round_to(Rtemp, align_object_offset(1)); - } - __ sll(Rtemp, LogBytesPerWord, Rtemp); // Rscratch *= 4; - if (Assembler::is_simm13(base)) { - __ add(Rtemp, base, Rtemp); - } else { - __ set(base, Rscratch); - __ add(Rscratch, Rtemp, Rtemp); - } - __ add(O2_Klass, Rtemp, Rscratch); - - __ bind(search); - - __ ld_ptr(Rscratch, itableOffsetEntry::interface_offset_in_bytes(), Rtemp); - { - Label ok; - - // Check that entry is non-null. Null entries are probably a bytecode - // problem. If the interface isn't implemented by the receiver class, - // the VM should throw IncompatibleClassChangeError. linkResolver checks - // this too but that's only if the entry isn't already resolved, so we - // need to check again. - __ br_notnull_short( Rtemp, Assembler::pt, ok); - call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); - __ should_not_reach_here(); - __ bind(ok); - } - - __ cmp(Rinterface, Rtemp); - __ brx(Assembler::notEqual, true, Assembler::pn, search); - __ delayed()->add(Rscratch, itableOffsetEntry::size() * wordSize, Rscratch); - - // entry found and Rscratch points to it - __ ld(Rscratch, itableOffsetEntry::offset_offset_in_bytes(), Rscratch); - - assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below"); - __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex); // Rindex *= 8; - __ add(Rscratch, Rindex, Rscratch); - __ ld_ptr(O2_Klass, Rscratch, G5_method); + // Get declaring interface class from method + __ ld_ptr(Rmethod, Method::const_offset(), Rinterface); + __ ld_ptr(Rinterface, ConstMethod::constants_offset(), Rinterface); + __ ld_ptr(Rinterface, ConstantPool::pool_holder_offset_in_bytes(), Rinterface); + + // Get itable index from method + const Register Rindex = G5_method; + __ ld(Rmethod, Method::itable_index_offset(), Rindex); + __ sub(Rindex, Method::itable_index_max, Rindex); + __ neg(Rindex); + + __ lookup_interface_method(// inputs: rec. class, interface, itable index + O2_Klass, Rinterface, Rindex, + // outputs: method, scan temp reg, temp reg + G5_method, Rscratch, Rtemp, + L_no_such_interface); // Check for abstract method error. { @@ -3260,6 +3242,10 @@ __ profile_arguments_type(G5_method, Rcall, Gargs, true); __ call_from_interpreter(Rcall, Gargs, Rret); + + __ bind(L_no_such_interface); + call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); + __ should_not_reach_here(); } void TemplateTable::invokehandle(int byte_no) {