1.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Tue Aug 08 12:02:01 2017 +0100 1.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Sep 29 14:30:05 2017 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -3165,15 +3165,15 @@ 1.11 assert(byte_no == f1_byte, "use this argument"); 1.12 1.13 const Register Rinterface = G1_scratch; 1.14 + const Register Rmethod = Lscratch; 1.15 const Register Rret = G3_scratch; 1.16 - const Register Rindex = Lscratch; 1.17 const Register O0_recv = O0; 1.18 const Register O1_flags = O1; 1.19 const Register O2_Klass = O2; 1.20 const Register Rscratch = G4_scratch; 1.21 assert_different_registers(Rscratch, G5_method); 1.22 1.23 - prepare_invoke(byte_no, Rinterface, Rret, Rindex, O0_recv, O1_flags); 1.24 + prepare_invoke(byte_no, Rinterface, Rret, Rmethod, O0_recv, O1_flags); 1.25 1.26 // get receiver klass 1.27 __ null_check(O0_recv, oopDesc::klass_offset_in_bytes()); 1.28 @@ -3193,58 +3193,40 @@ 1.29 1.30 __ bind(notMethod); 1.31 1.32 + Register Rtemp = O1_flags; 1.33 + 1.34 + Label L_no_such_interface; 1.35 + 1.36 + // Receiver subtype check against REFC. 1.37 + __ lookup_interface_method(// inputs: rec. class, interface, itable index 1.38 + O2_Klass, Rinterface, noreg, 1.39 + // outputs: temp reg1, temp reg2, temp reg3 1.40 + G5_method, Rscratch, Rtemp, 1.41 + L_no_such_interface, 1.42 + /*return_method=*/false); 1.43 + 1.44 __ profile_virtual_call(O2_Klass, O4); 1.45 1.46 // 1.47 // find entry point to call 1.48 // 1.49 1.50 - // compute start of first itableOffsetEntry (which is at end of vtable) 1.51 - const int base = InstanceKlass::vtable_start_offset() * wordSize; 1.52 - Label search; 1.53 - Register Rtemp = O1_flags; 1.54 - 1.55 - __ ld(O2_Klass, InstanceKlass::vtable_length_offset() * wordSize, Rtemp); 1.56 - if (align_object_offset(1) > 1) { 1.57 - __ round_to(Rtemp, align_object_offset(1)); 1.58 - } 1.59 - __ sll(Rtemp, LogBytesPerWord, Rtemp); // Rscratch *= 4; 1.60 - if (Assembler::is_simm13(base)) { 1.61 - __ add(Rtemp, base, Rtemp); 1.62 - } else { 1.63 - __ set(base, Rscratch); 1.64 - __ add(Rscratch, Rtemp, Rtemp); 1.65 - } 1.66 - __ add(O2_Klass, Rtemp, Rscratch); 1.67 - 1.68 - __ bind(search); 1.69 - 1.70 - __ ld_ptr(Rscratch, itableOffsetEntry::interface_offset_in_bytes(), Rtemp); 1.71 - { 1.72 - Label ok; 1.73 - 1.74 - // Check that entry is non-null. Null entries are probably a bytecode 1.75 - // problem. If the interface isn't implemented by the receiver class, 1.76 - // the VM should throw IncompatibleClassChangeError. linkResolver checks 1.77 - // this too but that's only if the entry isn't already resolved, so we 1.78 - // need to check again. 1.79 - __ br_notnull_short( Rtemp, Assembler::pt, ok); 1.80 - call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); 1.81 - __ should_not_reach_here(); 1.82 - __ bind(ok); 1.83 - } 1.84 - 1.85 - __ cmp(Rinterface, Rtemp); 1.86 - __ brx(Assembler::notEqual, true, Assembler::pn, search); 1.87 - __ delayed()->add(Rscratch, itableOffsetEntry::size() * wordSize, Rscratch); 1.88 - 1.89 - // entry found and Rscratch points to it 1.90 - __ ld(Rscratch, itableOffsetEntry::offset_offset_in_bytes(), Rscratch); 1.91 - 1.92 - assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below"); 1.93 - __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex); // Rindex *= 8; 1.94 - __ add(Rscratch, Rindex, Rscratch); 1.95 - __ ld_ptr(O2_Klass, Rscratch, G5_method); 1.96 + // Get declaring interface class from method 1.97 + __ ld_ptr(Rmethod, Method::const_offset(), Rinterface); 1.98 + __ ld_ptr(Rinterface, ConstMethod::constants_offset(), Rinterface); 1.99 + __ ld_ptr(Rinterface, ConstantPool::pool_holder_offset_in_bytes(), Rinterface); 1.100 + 1.101 + // Get itable index from method 1.102 + const Register Rindex = G5_method; 1.103 + __ ld(Rmethod, Method::itable_index_offset(), Rindex); 1.104 + __ sub(Rindex, Method::itable_index_max, Rindex); 1.105 + __ neg(Rindex); 1.106 + 1.107 + __ lookup_interface_method(// inputs: rec. class, interface, itable index 1.108 + O2_Klass, Rinterface, Rindex, 1.109 + // outputs: method, scan temp reg, temp reg 1.110 + G5_method, Rscratch, Rtemp, 1.111 + L_no_such_interface); 1.112 1.113 // Check for abstract method error. 1.114 { 1.115 @@ -3260,6 +3242,10 @@ 1.116 1.117 __ profile_arguments_type(G5_method, Rcall, Gargs, true); 1.118 __ call_from_interpreter(Rcall, Gargs, Rret); 1.119 + 1.120 + __ bind(L_no_such_interface); 1.121 + call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError)); 1.122 + __ should_not_reach_here(); 1.123 } 1.124 1.125 void TemplateTable::invokehandle(int byte_no) {