166 } |
166 } |
167 |
167 |
168 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code, |
168 void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code, |
169 const methodHandle& method, |
169 const methodHandle& method, |
170 int vtable_index, |
170 int vtable_index, |
171 bool sender_is_interface, |
171 bool sender_is_interface) { |
172 InstanceKlass* pool_holder) { |
|
173 bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean |
172 bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean |
174 assert(method->interpreter_entry() != NULL, "should have been set at this point"); |
173 assert(method->interpreter_entry() != NULL, "should have been set at this point"); |
175 assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); |
174 assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); |
176 |
175 |
177 int byte_no = -1; |
176 int byte_no = -1; |
262 method->name() != vmSymbols::object_initializer_name()) { |
261 method->name() != vmSymbols::object_initializer_name()) { |
263 do_resolve = false; |
262 do_resolve = false; |
264 } |
263 } |
265 // Don't mark invokestatic to method as resolved if the holder class has not yet completed |
264 // Don't mark invokestatic to method as resolved if the holder class has not yet completed |
266 // initialization. An invokestatic must only proceed if the class is initialized, but if |
265 // initialization. An invokestatic must only proceed if the class is initialized, but if |
267 // we resolve it before then that class initialization check is skipped. However if the call |
266 // we resolve it before then that class initialization check is skipped. |
268 // is from the same class we can resolve as we must be executing with <clinit> on our call stack. |
267 if (invoke_code == Bytecodes::_invokestatic && !method->method_holder()->is_initialized()) { |
269 if (invoke_code == Bytecodes::_invokestatic && |
|
270 !method->method_holder()->is_initialized() && |
|
271 method->method_holder() != pool_holder) { |
|
272 do_resolve = false; |
268 do_resolve = false; |
273 } |
269 } |
274 if (do_resolve) { |
270 if (do_resolve) { |
275 assert(method->method_holder()->is_initialized() || |
|
276 method->method_holder()->is_reentrant_initialization(Thread::current()), |
|
277 "invalid class initalization state"); |
|
278 set_bytecode_1(invoke_code); |
271 set_bytecode_1(invoke_code); |
279 } |
272 } |
280 } else if (byte_no == 2) { |
273 } else if (byte_no == 2) { |
281 if (change_to_virtual) { |
274 if (change_to_virtual) { |
282 assert(invoke_code == Bytecodes::_invokeinterface, ""); |
275 assert(invoke_code == Bytecodes::_invokeinterface, ""); |
315 } |
308 } |
316 NOT_PRODUCT(verify(tty)); |
309 NOT_PRODUCT(verify(tty)); |
317 } |
310 } |
318 |
311 |
319 void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, const methodHandle& method, |
312 void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, const methodHandle& method, |
320 bool sender_is_interface, InstanceKlass* pool_holder) { |
313 bool sender_is_interface) { |
321 int index = Method::nonvirtual_vtable_index; |
314 int index = Method::nonvirtual_vtable_index; |
322 // index < 0; FIXME: inline and customize set_direct_or_vtable_call |
315 // index < 0; FIXME: inline and customize set_direct_or_vtable_call |
323 set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface, pool_holder); |
316 set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface); |
324 } |
317 } |
325 |
318 |
326 void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) { |
319 void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) { |
327 // either the method is a miranda or its holder should accept the given index |
320 // either the method is a miranda or its holder should accept the given index |
328 assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); |
321 assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); |
329 // index >= 0; FIXME: inline and customize set_direct_or_vtable_call |
322 // index >= 0; FIXME: inline and customize set_direct_or_vtable_call |
330 set_direct_or_vtable_call(invoke_code, method, index, false, NULL /* not used */); |
323 set_direct_or_vtable_call(invoke_code, method, index, false); |
331 } |
324 } |
332 |
325 |
333 void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, |
326 void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, |
334 Klass* referenced_klass, |
327 Klass* referenced_klass, |
335 const methodHandle& method, int index) { |
328 const methodHandle& method, int index) { |