1 /* |
1 /* |
2 * Copyright (c) 1997, 2013, 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. |
2181 Register intf_klass, |
2181 Register intf_klass, |
2182 RegisterOrConstant itable_index, |
2182 RegisterOrConstant itable_index, |
2183 Register method_result, |
2183 Register method_result, |
2184 Register scan_temp, |
2184 Register scan_temp, |
2185 Register sethi_temp, |
2185 Register sethi_temp, |
2186 Label& L_no_such_interface) { |
2186 Label& L_no_such_interface, |
|
2187 bool return_method) { |
2187 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); |
2188 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); |
2188 assert(itable_index.is_constant() || itable_index.as_register() == method_result, |
2189 assert(!return_method || itable_index.is_constant() || itable_index.as_register() == method_result, |
2189 "caller must use same register for non-constant itable index as for method"); |
2190 "caller must use same register for non-constant itable index as for method"); |
2190 |
2191 |
2191 Label L_no_such_interface_restore; |
2192 Label L_no_such_interface_restore; |
2192 bool did_save = false; |
2193 bool did_save = false; |
2193 if (scan_temp == noreg || sethi_temp == noreg) { |
2194 if (scan_temp == noreg || sethi_temp == noreg) { |
2227 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp); |
2228 // Hoisted: add(scan_temp, BytesPerLong-1, scan_temp); |
2228 and3(scan_temp, -round_to_unit, scan_temp); |
2229 and3(scan_temp, -round_to_unit, scan_temp); |
2229 } |
2230 } |
2230 add(recv_klass, scan_temp, scan_temp); |
2231 add(recv_klass, scan_temp, scan_temp); |
2231 |
2232 |
2232 // Adjust recv_klass by scaled itable_index, so we can free itable_index. |
2233 if (return_method) { |
2233 RegisterOrConstant itable_offset = itable_index; |
2234 // Adjust recv_klass by scaled itable_index, so we can free itable_index. |
2234 itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset); |
2235 RegisterOrConstant itable_offset = itable_index; |
2235 itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset); |
2236 itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset); |
2236 add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass); |
2237 itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset); |
|
2238 add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass); |
|
2239 } |
2237 |
2240 |
2238 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { |
2241 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { |
2239 // if (scan->interface() == intf) { |
2242 // if (scan->interface() == intf) { |
2240 // result = (klass + scan->offset() + itable_index); |
2243 // result = (klass + scan->offset() + itable_index); |
2241 // } |
2244 // } |
2266 bind(L_search); |
2269 bind(L_search); |
2267 } |
2270 } |
2268 |
2271 |
2269 bind(L_found_method); |
2272 bind(L_found_method); |
2270 |
2273 |
2271 // Got a hit. |
2274 if (return_method) { |
2272 int ito_offset = itableOffsetEntry::offset_offset_in_bytes(); |
2275 // Got a hit. |
2273 // scan_temp[-scan_step] points to the vtable offset we need |
2276 int ito_offset = itableOffsetEntry::offset_offset_in_bytes(); |
2274 ito_offset -= scan_step; |
2277 // scan_temp[-scan_step] points to the vtable offset we need |
2275 lduw(scan_temp, ito_offset, scan_temp); |
2278 ito_offset -= scan_step; |
2276 ld_ptr(recv_klass, scan_temp, method_result); |
2279 lduw(scan_temp, ito_offset, scan_temp); |
|
2280 ld_ptr(recv_klass, scan_temp, method_result); |
|
2281 } |
2277 |
2282 |
2278 if (did_save) { |
2283 if (did_save) { |
2279 Label L_done; |
2284 Label L_done; |
2280 ba(L_done); |
2285 ba(L_done); |
2281 delayed()->restore(); |
2286 delayed()->restore(); |