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