예제 #1
0
 CompiledICHolder*    claim_cached_icholder() {
   assert(_is_icholder, "");
   assert(_cached_value != NULL, "must be non-NULL");
   _release_icholder = false;
   CompiledICHolder* icholder = (CompiledICHolder*)_cached_value;
   icholder->claim();
   return icholder;
 }
예제 #2
0
 ~CompiledICInfo() {
   // In rare cases the info is computed but not used, so release any
   // CompiledICHolder* that was created
   if (_release_icholder) {
     assert(_is_icholder, "must be");
     CompiledICHolder* icholder = (CompiledICHolder*)_cached_value;
     icholder->claim();
     delete icholder;
   }
 }
bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) {
  assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "");
  assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic");
  assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?");

  address entry;
  if (call_info->call_kind() == CallInfo::itable_call) {
    assert(bytecode == Bytecodes::_invokeinterface, "");
    int itable_index = call_info->itable_index();
    entry = VtableStubs::find_itable_stub(itable_index);
    if (entry == false) {
      return false;
    }
#ifdef ASSERT
    int index = call_info->resolved_method()->itable_index();
    assert(index == itable_index, "CallInfo pre-computes this");
    InstanceKlass* k = call_info->resolved_method()->method_holder();
    assert(k->verify_itable_index(itable_index), "sanity check");
#endif //ASSERT
    CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(),
                                                    call_info->resolved_klass()(), false);
    holder->claim();
    InlineCacheBuffer::create_transition_stub(this, holder, entry);
  } else {
    assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");
    // Can be different than selected_method->vtable_index(), due to package-private etc.
    int vtable_index = call_info->vtable_index();
    assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");
    entry = VtableStubs::find_vtable_stub(vtable_index);
    if (entry == NULL) {
      return false;
    }
    InlineCacheBuffer::create_transition_stub(this, NULL, entry);
  }

  if (TraceICs) {
    ResourceMark rm;
    tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT,
                   p2i(instruction_address()), call_info->selected_method()->print_value_string(), p2i(entry));
  }

  // We can't check this anymore. With lazy deopt we could have already
  // cleaned this IC entry before we even return. This is possible if
  // we ran out of space in the inline cache buffer trying to do the
  // set_next and we safepointed to free up space. This is a benign
  // race because the IC entry was complete when we safepointed so
  // cleaning it immediately is harmless.
  // assert(is_megamorphic(), "sanity check");
  return true;
}