1 /* |
1 /* |
2 * Copyright (c) 1997, 2014, 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. |
4851 void MacroAssembler::lookup_interface_method(Register recv_klass, |
4851 void MacroAssembler::lookup_interface_method(Register recv_klass, |
4852 Register intf_klass, |
4852 Register intf_klass, |
4853 RegisterOrConstant itable_index, |
4853 RegisterOrConstant itable_index, |
4854 Register method_result, |
4854 Register method_result, |
4855 Register scan_temp, |
4855 Register scan_temp, |
4856 Label& L_no_such_interface) { |
4856 Label& L_no_such_interface, |
4857 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); |
4857 bool return_method) { |
|
4858 assert_different_registers(recv_klass, intf_klass, scan_temp); |
|
4859 assert_different_registers(method_result, intf_klass, scan_temp); |
|
4860 assert(recv_klass != method_result || !return_method, |
|
4861 "recv_klass can be destroyed when method isn't needed"); |
|
4862 |
4858 assert(itable_index.is_constant() || itable_index.as_register() == method_result, |
4863 assert(itable_index.is_constant() || itable_index.as_register() == method_result, |
4859 "caller must use same register for non-constant itable index as for method"); |
4864 "caller must use same register for non-constant itable index as for method"); |
4860 |
4865 |
4861 // Compute start of first itableOffsetEntry (which is at the end of the vtable) |
4866 // Compute start of first itableOffsetEntry (which is at the end of the vtable) |
4862 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; |
4867 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; |
4874 // Round up to align_object_offset boundary |
4879 // Round up to align_object_offset boundary |
4875 // see code for InstanceKlass::start_of_itable! |
4880 // see code for InstanceKlass::start_of_itable! |
4876 round_to(scan_temp, BytesPerLong); |
4881 round_to(scan_temp, BytesPerLong); |
4877 } |
4882 } |
4878 |
4883 |
4879 // Adjust recv_klass by scaled itable_index, so we can free itable_index. |
4884 if (return_method) { |
4880 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below"); |
4885 // Adjust recv_klass by scaled itable_index, so we can free itable_index. |
4881 lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off)); |
4886 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below"); |
|
4887 lea(recv_klass, Address(recv_klass, itable_index, Address::times_ptr, itentry_off)); |
|
4888 } |
4882 |
4889 |
4883 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { |
4890 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { |
4884 // if (scan->interface() == intf) { |
4891 // if (scan->interface() == intf) { |
4885 // result = (klass + scan->offset() + itable_index); |
4892 // result = (klass + scan->offset() + itable_index); |
4886 // } |
4893 // } |
4910 addptr(scan_temp, scan_step); |
4917 addptr(scan_temp, scan_step); |
4911 } |
4918 } |
4912 |
4919 |
4913 bind(found_method); |
4920 bind(found_method); |
4914 |
4921 |
4915 // Got a hit. |
4922 if (return_method) { |
4916 movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes())); |
4923 // Got a hit. |
4917 movptr(method_result, Address(recv_klass, scan_temp, Address::times_1)); |
4924 movl(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes())); |
|
4925 movptr(method_result, Address(recv_klass, scan_temp, Address::times_1)); |
|
4926 } |
4918 } |
4927 } |
4919 |
4928 |
4920 |
4929 |
4921 // virtual method calling |
4930 // virtual method calling |
4922 void MacroAssembler::lookup_virtual_method(Register recv_klass, |
4931 void MacroAssembler::lookup_virtual_method(Register recv_klass, |