1 /*
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2012, 2015 SAP AG. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
63 #ifndef PRODUCT
64 if (CountCompiledCalls) {
65 __ load_const(R11_scratch1, SharedRuntime::nof_megamorphic_calls_addr());
66 __ lwz(R12_scratch2, 0, R11_scratch1);
67 __ addi(R12_scratch2, R12_scratch2, 1);
68 __ stw(R12_scratch2, 0, R11_scratch1);
69 }
70 #endif
71
72 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1");
73
74 // Get receiver klass.
75 const Register rcvr_klass = R11_scratch1;
76
77 // We might implicit NULL fault here.
78 address npe_addr = __ pc(); // npe = null pointer exception
79 __ null_check(R3, oopDesc::klass_offset_in_bytes(), /*implicit only*/NULL);
80 __ load_klass(rcvr_klass, R3);
81
82 // Set method (in case of interpreted method), and destination address.
83 int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
84
85 #ifndef PRODUCT
86 if (DebugVtables) {
87 Label L;
88 // Check offset vs vtable length.
89 const Register vtable_len = R12_scratch2;
90 __ lwz(vtable_len, InstanceKlass::vtable_length_offset()*wordSize, rcvr_klass);
91 __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size());
92 __ bge(CCR0, L);
93 __ li(R12_scratch2, vtable_index);
94 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), R3_ARG1, R12_scratch2, false);
95 __ bind(L);
96 }
97 #endif
98
99 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
100
101 __ ld(R19_method, v_off, rcvr_klass);
102
103 #ifndef PRODUCT
104 if (DebugVtables) {
105 Label L;
106 __ cmpdi(CCR0, R19_method, 0);
107 __ bne(CCR0, L);
108 __ stop("Vtable entry is ZERO", 102);
109 __ bind(L);
110 }
111 #endif
112
113 // If the vtable entry is null, the method is abstract.
114 address ame_addr = __ pc(); // ame = abstract method error
115 __ null_check(R19_method, in_bytes(Method::from_compiled_offset()), /*implicit only*/NULL);
116 __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method);
117 __ mtctr(R12_scratch2);
118 __ bctr();
119 masm->flush();
146 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1");
147
148 // Entry arguments:
149 // R19_method: Interface
150 // R3_ARG1: Receiver
151 //
152
153 const Register rcvr_klass = R11_scratch1;
154 const Register vtable_len = R12_scratch2;
155 const Register itable_entry_addr = R21_tmp1;
156 const Register itable_interface = R22_tmp2;
157
158 // Get receiver klass.
159
160 // We might implicit NULL fault here.
161 address npe_addr = __ pc(); // npe = null pointer exception
162 __ null_check(R3_ARG1, oopDesc::klass_offset_in_bytes(), /*implicit only*/NULL);
163 __ load_klass(rcvr_klass, R3_ARG1);
164
165 BLOCK_COMMENT("Load start of itable entries into itable_entry.");
166 __ lwz(vtable_len, InstanceKlass::vtable_length_offset() * wordSize, rcvr_klass);
167 __ slwi(vtable_len, vtable_len, exact_log2(vtableEntry::size() * wordSize));
168 __ add(itable_entry_addr, vtable_len, rcvr_klass);
169
170 // Loop over all itable entries until desired interfaceOop(Rinterface) found.
171 BLOCK_COMMENT("Increment itable_entry_addr in loop.");
172 const int vtable_base_offset = InstanceKlass::vtable_start_offset() * wordSize;
173 __ addi(itable_entry_addr, itable_entry_addr, vtable_base_offset + itableOffsetEntry::interface_offset_in_bytes());
174
175 const int itable_offset_search_inc = itableOffsetEntry::size() * wordSize;
176 Label search;
177 __ bind(search);
178 __ ld(itable_interface, 0, itable_entry_addr);
179
180 // Handle IncompatibleClassChangeError in itable stubs.
181 // If the entry is NULL then we've reached the end of the table
182 // without finding the expected interface, so throw an exception.
183 BLOCK_COMMENT("Handle IncompatibleClassChangeError in itable stubs.");
184 Label throw_icce;
185 __ cmpdi(CCR1, itable_interface, 0);
186 __ cmpd(CCR0, itable_interface, R19_method);
187 __ addi(itable_entry_addr, itable_entry_addr, itable_offset_search_inc);
188 __ beq(CCR1, throw_icce);
189 __ bne(CCR0, search);
190
191 // Entry found and itable_entry_addr points to it, get offset of vtable for interface.
192
|
1 /*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2012, 2015 SAP AG. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
63 #ifndef PRODUCT
64 if (CountCompiledCalls) {
65 __ load_const(R11_scratch1, SharedRuntime::nof_megamorphic_calls_addr());
66 __ lwz(R12_scratch2, 0, R11_scratch1);
67 __ addi(R12_scratch2, R12_scratch2, 1);
68 __ stw(R12_scratch2, 0, R11_scratch1);
69 }
70 #endif
71
72 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1");
73
74 // Get receiver klass.
75 const Register rcvr_klass = R11_scratch1;
76
77 // We might implicit NULL fault here.
78 address npe_addr = __ pc(); // npe = null pointer exception
79 __ null_check(R3, oopDesc::klass_offset_in_bytes(), /*implicit only*/NULL);
80 __ load_klass(rcvr_klass, R3);
81
82 // Set method (in case of interpreted method), and destination address.
83 int entry_offset = in_bytes(InstanceKlass::vtable_start_offset()) + vtable_index*vtableEntry::size_in_bytes();
84
85 #ifndef PRODUCT
86 if (DebugVtables) {
87 Label L;
88 // Check offset vs vtable length.
89 const Register vtable_len = R12_scratch2;
90 __ lwz(vtable_len, in_bytes(InstanceKlass::vtable_length_offset()), rcvr_klass);
91 __ cmpwi(CCR0, vtable_len, vtable_index*vtableEntry::size());
92 __ bge(CCR0, L);
93 __ li(R12_scratch2, vtable_index);
94 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), R3_ARG1, R12_scratch2, false);
95 __ bind(L);
96 }
97 #endif
98
99 int v_off = entry_offset + vtableEntry::method_offset_in_bytes();
100
101 __ ld(R19_method, v_off, rcvr_klass);
102
103 #ifndef PRODUCT
104 if (DebugVtables) {
105 Label L;
106 __ cmpdi(CCR0, R19_method, 0);
107 __ bne(CCR0, L);
108 __ stop("Vtable entry is ZERO", 102);
109 __ bind(L);
110 }
111 #endif
112
113 // If the vtable entry is null, the method is abstract.
114 address ame_addr = __ pc(); // ame = abstract method error
115 __ null_check(R19_method, in_bytes(Method::from_compiled_offset()), /*implicit only*/NULL);
116 __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method);
117 __ mtctr(R12_scratch2);
118 __ bctr();
119 masm->flush();
146 assert(VtableStub::receiver_location() == R3_ARG1->as_VMReg(), "receiver expected in R3_ARG1");
147
148 // Entry arguments:
149 // R19_method: Interface
150 // R3_ARG1: Receiver
151 //
152
153 const Register rcvr_klass = R11_scratch1;
154 const Register vtable_len = R12_scratch2;
155 const Register itable_entry_addr = R21_tmp1;
156 const Register itable_interface = R22_tmp2;
157
158 // Get receiver klass.
159
160 // We might implicit NULL fault here.
161 address npe_addr = __ pc(); // npe = null pointer exception
162 __ null_check(R3_ARG1, oopDesc::klass_offset_in_bytes(), /*implicit only*/NULL);
163 __ load_klass(rcvr_klass, R3_ARG1);
164
165 BLOCK_COMMENT("Load start of itable entries into itable_entry.");
166 __ lwz(vtable_len, in_bytes(InstanceKlass::vtable_length_offset()), rcvr_klass);
167 __ slwi(vtable_len, vtable_len, exact_log2(vtableEntry::size_in_bytes()));
168 __ add(itable_entry_addr, vtable_len, rcvr_klass);
169
170 // Loop over all itable entries until desired interfaceOop(Rinterface) found.
171 BLOCK_COMMENT("Increment itable_entry_addr in loop.");
172 const int vtable_base_offset = in_bytes(InstanceKlass::vtable_start_offset());
173 __ addi(itable_entry_addr, itable_entry_addr, vtable_base_offset + itableOffsetEntry::interface_offset_in_bytes());
174
175 const int itable_offset_search_inc = itableOffsetEntry::size() * wordSize;
176 Label search;
177 __ bind(search);
178 __ ld(itable_interface, 0, itable_entry_addr);
179
180 // Handle IncompatibleClassChangeError in itable stubs.
181 // If the entry is NULL then we've reached the end of the table
182 // without finding the expected interface, so throw an exception.
183 BLOCK_COMMENT("Handle IncompatibleClassChangeError in itable stubs.");
184 Label throw_icce;
185 __ cmpdi(CCR1, itable_interface, 0);
186 __ cmpd(CCR0, itable_interface, R19_method);
187 __ addi(itable_entry_addr, itable_entry_addr, itable_offset_search_inc);
188 __ beq(CCR1, throw_icce);
189 __ bne(CCR0, search);
190
191 // Entry found and itable_entry_addr points to it, get offset of vtable for interface.
192
|