235 assert(nm->contains(ic_call), "must be in compiled method"); |
235 assert(nm->contains(ic_call), "must be in compiled method"); |
236 |
236 |
237 initialize_from_iter(iter); |
237 initialize_from_iter(iter); |
238 } |
238 } |
239 |
239 |
240 bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { |
240 // This function may fail for two reasons: either due to running out of vtable |
|
241 // stubs, or due to running out of IC stubs in an attempted transition to a |
|
242 // transitional state. The needs_ic_stub_refill value will be set if the failure |
|
243 // was due to running out of IC stubs, in which case the caller will refill IC |
|
244 // stubs and retry. |
|
245 bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, |
|
246 bool& needs_ic_stub_refill, TRAPS) { |
241 assert(CompiledICLocker::is_safe(_method), "mt unsafe call"); |
247 assert(CompiledICLocker::is_safe(_method), "mt unsafe call"); |
242 assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); |
248 assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); |
243 assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); |
249 assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); |
244 |
250 |
245 address entry; |
251 address entry; |
257 assert(k->verify_itable_index(itable_index), "sanity check"); |
263 assert(k->verify_itable_index(itable_index), "sanity check"); |
258 #endif //ASSERT |
264 #endif //ASSERT |
259 CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(), |
265 CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(), |
260 call_info->resolved_klass(), false); |
266 call_info->resolved_klass(), false); |
261 holder->claim(); |
267 holder->claim(); |
262 InlineCacheBuffer::create_transition_stub(this, holder, entry); |
268 if (!InlineCacheBuffer::create_transition_stub(this, holder, entry)) { |
|
269 delete holder; |
|
270 needs_ic_stub_refill = true; |
|
271 return false; |
|
272 } |
263 } else { |
273 } else { |
264 assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable"); |
274 assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable"); |
265 // Can be different than selected_method->vtable_index(), due to package-private etc. |
275 // Can be different than selected_method->vtable_index(), due to package-private etc. |
266 int vtable_index = call_info->vtable_index(); |
276 int vtable_index = call_info->vtable_index(); |
267 assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); |
277 assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); |
268 entry = VtableStubs::find_vtable_stub(vtable_index); |
278 entry = VtableStubs::find_vtable_stub(vtable_index); |
269 if (entry == NULL) { |
279 if (entry == NULL) { |
270 return false; |
280 return false; |
271 } |
281 } |
272 InlineCacheBuffer::create_transition_stub(this, NULL, entry); |
282 if (!InlineCacheBuffer::create_transition_stub(this, NULL, entry)) { |
|
283 needs_ic_stub_refill = true; |
|
284 return false; |
|
285 } |
273 } |
286 } |
274 |
287 |
275 if (TraceICs) { |
288 if (TraceICs) { |
276 ResourceMark rm; |
289 ResourceMark rm; |
277 assert(!call_info->selected_method().is_null(), "Unexpected null selected method"); |
290 assert(!call_info->selected_method().is_null(), "Unexpected null selected method"); |
348 is_call_to_interpreted = _call->is_call_to_interpreted(dest); |
361 is_call_to_interpreted = _call->is_call_to_interpreted(dest); |
349 } |
362 } |
350 return is_call_to_interpreted; |
363 return is_call_to_interpreted; |
351 } |
364 } |
352 |
365 |
353 void CompiledIC::set_to_clean(bool in_use) { |
366 bool CompiledIC::set_to_clean(bool in_use) { |
354 assert(CompiledICLocker::is_safe(_method), "mt unsafe call"); |
367 assert(CompiledICLocker::is_safe(_method), "mt unsafe call"); |
355 if (TraceInlineCacheClearing || TraceICs) { |
368 if (TraceInlineCacheClearing || TraceICs) { |
356 tty->print_cr("IC@" INTPTR_FORMAT ": set to clean", p2i(instruction_address())); |
369 tty->print_cr("IC@" INTPTR_FORMAT ": set to clean", p2i(instruction_address())); |
357 print(); |
370 print(); |
358 } |
371 } |
371 } else { |
384 } else { |
372 set_ic_destination_and_value(entry, (void*)NULL); |
385 set_ic_destination_and_value(entry, (void*)NULL); |
373 } |
386 } |
374 } else { |
387 } else { |
375 // Unsafe transition - create stub. |
388 // Unsafe transition - create stub. |
376 InlineCacheBuffer::create_transition_stub(this, NULL, entry); |
389 if (!InlineCacheBuffer::create_transition_stub(this, NULL, entry)) { |
|
390 return false; |
|
391 } |
377 } |
392 } |
378 // We can't check this anymore. With lazy deopt we could have already |
393 // We can't check this anymore. With lazy deopt we could have already |
379 // cleaned this IC entry before we even return. This is possible if |
394 // cleaned this IC entry before we even return. This is possible if |
380 // we ran out of space in the inline cache buffer trying to do the |
395 // we ran out of space in the inline cache buffer trying to do the |
381 // set_next and we safepointed to free up space. This is a benign |
396 // set_next and we safepointed to free up space. This is a benign |
382 // race because the IC entry was complete when we safepointed so |
397 // race because the IC entry was complete when we safepointed so |
383 // cleaning it immediately is harmless. |
398 // cleaning it immediately is harmless. |
384 // assert(is_clean(), "sanity check"); |
399 // assert(is_clean(), "sanity check"); |
|
400 return true; |
385 } |
401 } |
386 |
402 |
387 bool CompiledIC::is_clean() const { |
403 bool CompiledIC::is_clean() const { |
388 assert(CompiledICLocker::is_safe(_method), "mt unsafe call"); |
404 assert(CompiledICLocker::is_safe(_method), "mt unsafe call"); |
389 bool is_clean = false; |
405 bool is_clean = false; |
391 is_clean = dest == _call->get_resolve_call_stub(is_optimized()); |
407 is_clean = dest == _call->get_resolve_call_stub(is_optimized()); |
392 assert(!is_clean || is_optimized() || cached_value() == NULL, "sanity check"); |
408 assert(!is_clean || is_optimized() || cached_value() == NULL, "sanity check"); |
393 return is_clean; |
409 return is_clean; |
394 } |
410 } |
395 |
411 |
396 void CompiledIC::set_to_monomorphic(CompiledICInfo& info) { |
412 bool CompiledIC::set_to_monomorphic(CompiledICInfo& info) { |
397 assert(CompiledICLocker::is_safe(_method), "mt unsafe call"); |
413 assert(CompiledICLocker::is_safe(_method), "mt unsafe call"); |
398 // Updating a cache to the wrong entry can cause bugs that are very hard |
414 // Updating a cache to the wrong entry can cause bugs that are very hard |
399 // to track down - if cache entry gets invalid - we just clean it. In |
415 // to track down - if cache entry gets invalid - we just clean it. In |
400 // this way it is always the same code path that is responsible for |
416 // this way it is always the same code path that is responsible for |
401 // updating and resolving an inline cache |
417 // updating and resolving an inline cache |
428 (info.to_aot() ? "aot" : "interpreter"), |
444 (info.to_aot() ? "aot" : "interpreter"), |
429 method->print_value_string()); |
445 method->print_value_string()); |
430 } |
446 } |
431 } else { |
447 } else { |
432 // Call via method-klass-holder |
448 // Call via method-klass-holder |
433 InlineCacheBuffer::create_transition_stub(this, info.claim_cached_icholder(), info.entry()); |
449 CompiledICHolder* holder = info.claim_cached_icholder(); |
|
450 if (!InlineCacheBuffer::create_transition_stub(this, holder, info.entry())) { |
|
451 delete holder; |
|
452 return false; |
|
453 } |
434 if (TraceICs) { |
454 if (TraceICs) { |
435 ResourceMark rm(thread); |
455 ResourceMark rm(thread); |
436 tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", p2i(instruction_address())); |
456 tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", p2i(instruction_address())); |
437 } |
457 } |
438 } |
458 } |
448 // non-verified entry point |
468 // non-verified entry point |
449 bool safe = SafepointSynchronize::is_at_safepoint() || |
469 bool safe = SafepointSynchronize::is_at_safepoint() || |
450 (!is_in_transition_state() && (info.is_optimized() || static_bound || is_clean())); |
470 (!is_in_transition_state() && (info.is_optimized() || static_bound || is_clean())); |
451 |
471 |
452 if (!safe) { |
472 if (!safe) { |
453 InlineCacheBuffer::create_transition_stub(this, info.cached_metadata(), info.entry()); |
473 if (!InlineCacheBuffer::create_transition_stub(this, info.cached_metadata(), info.entry())) { |
|
474 return false; |
|
475 } |
454 } else { |
476 } else { |
455 if (is_optimized()) { |
477 if (is_optimized()) { |
456 set_ic_destination(info.entry()); |
478 set_ic_destination(info.entry()); |
457 } else { |
479 } else { |
458 set_ic_destination_and_value(info.entry(), info.cached_metadata()); |
480 set_ic_destination_and_value(info.entry(), info.cached_metadata()); |
473 // we ran out of space in the inline cache buffer trying to do the |
495 // we ran out of space in the inline cache buffer trying to do the |
474 // set_next and we safepointed to free up space. This is a benign |
496 // set_next and we safepointed to free up space. This is a benign |
475 // race because the IC entry was complete when we safepointed so |
497 // race because the IC entry was complete when we safepointed so |
476 // cleaning it immediately is harmless. |
498 // cleaning it immediately is harmless. |
477 // assert(is_call_to_compiled() || is_call_to_interpreted(), "sanity check"); |
499 // assert(is_call_to_compiled() || is_call_to_interpreted(), "sanity check"); |
|
500 return true; |
478 } |
501 } |
479 |
502 |
480 |
503 |
481 // is_optimized: Compiler has generated an optimized call (i.e. fixed, no inline cache) |
504 // is_optimized: Compiler has generated an optimized call (i.e. fixed, no inline cache) |
482 // static_bound: The call can be static bound. If it isn't also optimized, the property |
505 // static_bound: The call can be static bound. If it isn't also optimized, the property |
573 } |
596 } |
574 } |
597 } |
575 |
598 |
576 // ---------------------------------------------------------------------------- |
599 // ---------------------------------------------------------------------------- |
577 |
600 |
578 void CompiledStaticCall::set_to_clean(bool in_use) { |
601 bool CompiledStaticCall::set_to_clean(bool in_use) { |
579 // in_use is unused but needed to match template function in CompiledMethod |
602 // in_use is unused but needed to match template function in CompiledMethod |
580 assert(CompiledICLocker::is_safe(instruction_address()), "mt unsafe call"); |
603 assert(CompiledICLocker::is_safe(instruction_address()), "mt unsafe call"); |
581 // Reset call site |
604 // Reset call site |
582 MutexLockerEx pl(SafepointSynchronize::is_at_safepoint() ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag); |
605 MutexLockerEx pl(SafepointSynchronize::is_at_safepoint() ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag); |
583 set_destination_mt_safe(resolve_call_stub()); |
606 set_destination_mt_safe(resolve_call_stub()); |
584 |
607 |
585 // Do not reset stub here: It is too expensive to call find_stub. |
608 // Do not reset stub here: It is too expensive to call find_stub. |
586 // Instead, rely on caller (nmethod::clear_inline_caches) to clear |
609 // Instead, rely on caller (nmethod::clear_inline_caches) to clear |
587 // both the call and its stub. |
610 // both the call and its stub. |
|
611 return true; |
588 } |
612 } |
589 |
613 |
590 bool CompiledStaticCall::is_clean() const { |
614 bool CompiledStaticCall::is_clean() const { |
591 return destination() == resolve_call_stub(); |
615 return destination() == resolve_call_stub(); |
592 } |
616 } |