1 /* |
1 /* |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2012, 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. |
79 |
79 |
80 #ifndef PRODUCT |
80 #ifndef PRODUCT |
81 if (DebugVtables) { |
81 if (DebugVtables) { |
82 Label L; |
82 Label L; |
83 // check offset vs vtable length |
83 // check offset vs vtable length |
84 __ cmpl(Address(rax, instanceKlass::vtable_length_offset()*wordSize), vtable_index*vtableEntry::size()); |
84 __ cmpl(Address(rax, InstanceKlass::vtable_length_offset()*wordSize), vtable_index*vtableEntry::size()); |
85 __ jcc(Assembler::greater, L); |
85 __ jcc(Assembler::greater, L); |
86 __ movl(rbx, vtable_index); |
86 __ movl(rbx, vtable_index); |
87 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), rcx, rbx); |
87 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), rcx, rbx); |
88 __ bind(L); |
88 __ bind(L); |
89 } |
89 } |
90 #endif // PRODUCT |
90 #endif // PRODUCT |
91 |
91 |
92 const Register method = rbx; |
92 const Register method = rbx; |
93 |
93 |
94 // load methodOop and target address |
94 // load Method* and target address |
95 __ lookup_virtual_method(rax, vtable_index, method); |
95 __ lookup_virtual_method(rax, vtable_index, method); |
96 |
96 |
97 if (DebugVtables) { |
97 if (DebugVtables) { |
98 Label L; |
98 Label L; |
99 __ cmpptr(method, (int32_t)NULL_WORD); |
99 __ cmpptr(method, (int32_t)NULL_WORD); |
100 __ jcc(Assembler::equal, L); |
100 __ jcc(Assembler::equal, L); |
101 __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); |
101 __ cmpptr(Address(method, Method::from_compiled_offset()), (int32_t)NULL_WORD); |
102 __ jcc(Assembler::notZero, L); |
102 __ jcc(Assembler::notZero, L); |
103 __ stop("Vtable entry is NULL"); |
103 __ stop("Vtable entry is NULL"); |
104 __ bind(L); |
104 __ bind(L); |
105 } |
105 } |
106 |
106 |
107 // rax,: receiver klass |
107 // rax,: receiver klass |
108 // method (rbx): methodOop |
108 // method (rbx): Method* |
109 // rcx: receiver |
109 // rcx: receiver |
110 address ame_addr = __ pc(); |
110 address ame_addr = __ pc(); |
111 __ jmp( Address(method, methodOopDesc::from_compiled_offset())); |
111 __ jmp( Address(method, Method::from_compiled_offset())); |
112 |
112 |
113 masm->flush(); |
113 masm->flush(); |
114 |
114 |
115 if (PrintMiscellaneous && (WizardMode || Verbose)) { |
115 if (PrintMiscellaneous && (WizardMode || Verbose)) { |
116 tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d", |
116 tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d", |
157 // Most registers are in use; we'll use rax, rbx, rsi, rdi |
157 // Most registers are in use; we'll use rax, rbx, rsi, rdi |
158 // (If we need to make rsi, rdi callee-save, do a push/pop here.) |
158 // (If we need to make rsi, rdi callee-save, do a push/pop here.) |
159 const Register method = rbx; |
159 const Register method = rbx; |
160 Label throw_icce; |
160 Label throw_icce; |
161 |
161 |
162 // Get methodOop and entrypoint for compiler |
162 // Get Method* and entrypoint for compiler |
163 __ lookup_interface_method(// inputs: rec. class, interface, itable index |
163 __ lookup_interface_method(// inputs: rec. class, interface, itable index |
164 rsi, rax, itable_index, |
164 rsi, rax, itable_index, |
165 // outputs: method, scan temp. reg |
165 // outputs: method, scan temp. reg |
166 method, rdi, |
166 method, rdi, |
167 throw_icce); |
167 throw_icce); |
168 |
168 |
169 // method (rbx): methodOop |
169 // method (rbx): Method* |
170 // rcx: receiver |
170 // rcx: receiver |
171 |
171 |
172 #ifdef ASSERT |
172 #ifdef ASSERT |
173 if (DebugVtables) { |
173 if (DebugVtables) { |
174 Label L1; |
174 Label L1; |
175 __ cmpptr(method, (int32_t)NULL_WORD); |
175 __ cmpptr(method, (int32_t)NULL_WORD); |
176 __ jcc(Assembler::equal, L1); |
176 __ jcc(Assembler::equal, L1); |
177 __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD); |
177 __ cmpptr(Address(method, Method::from_compiled_offset()), (int32_t)NULL_WORD); |
178 __ jcc(Assembler::notZero, L1); |
178 __ jcc(Assembler::notZero, L1); |
179 __ stop("methodOop is null"); |
179 __ stop("Method* is null"); |
180 __ bind(L1); |
180 __ bind(L1); |
181 } |
181 } |
182 #endif // ASSERT |
182 #endif // ASSERT |
183 |
183 |
184 address ame_addr = __ pc(); |
184 address ame_addr = __ pc(); |
185 __ jmp(Address(method, methodOopDesc::from_compiled_offset())); |
185 __ jmp(Address(method, Method::from_compiled_offset())); |
186 |
186 |
187 __ bind(throw_icce); |
187 __ bind(throw_icce); |
188 __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); |
188 __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); |
189 masm->flush(); |
189 masm->flush(); |
190 |
190 |