src/cpu/sparc/vm/templateTable_sparc.cpp

changeset 8997
f8a45a60bc6b
parent 8368
32b682649973
child 9041
95a08233f46c
equal deleted inserted replaced
8996:2667e5c45e24 8997:f8a45a60bc6b
1 /* 1 /*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
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");

mercurial