Ejemplo n.º 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;
 }
Ejemplo n.º 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;
   }
 }
Ejemplo n.º 3
0
// Free CompiledICHolder*s that are no longer in use
void InlineCacheBuffer::release_pending_icholders() {
  assert(SafepointSynchronize::is_at_safepoint(), "should only be called during a safepoint");
  CompiledICHolder* holder = _pending_released;
  _pending_released = NULL;
  while (holder != NULL) {
    CompiledICHolder* next = holder->next();
    delete holder;
    holder = next;
    _pending_count--;
  }
  assert(_pending_count == 0, "wrong count");
}
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;
}
Ejemplo n.º 5
0
// Iterate over metadata calling this function.   Used by RedefineClasses
// Copied from nmethod::metadata_do
void AOTCompiledMethod::metadata_do(void f(Metadata*)) {
  address low_boundary = verified_entry_point();
  {
    // Visit all immediate references that are embedded in the instruction stream.
    RelocIterator iter(this, low_boundary);
    while (iter.next()) {
      if (iter.type() == relocInfo::metadata_type ) {
        metadata_Relocation* r = iter.metadata_reloc();
        // In this metadata, we must only follow those metadatas directly embedded in
        // the code.  Other metadatas (oop_index>0) are seen as part of
        // the metadata section below.
        assert(1 == (r->metadata_is_immediate()) +
               (r->metadata_addr() >= metadata_begin() && r->metadata_addr() < metadata_end()),
               "metadata must be found in exactly one place");
        if (r->metadata_is_immediate() && r->metadata_value() != NULL) {
          Metadata* md = r->metadata_value();
          if (md != _method) f(md);
        }
      } else if (iter.type() == relocInfo::virtual_call_type) {
        // Check compiledIC holders associated with this nmethod
        CompiledIC *ic = CompiledIC_at(&iter);
        if (ic->is_icholder_call()) {
          CompiledICHolder* cichk = ic->cached_icholder();
          f(cichk->holder_method());
          f(cichk->holder_klass());
        } else {
          // Get Klass* or NULL (if value is -1) from GOT cell of virtual call PLT stub.
          Metadata* ic_oop = ic->cached_metadata();
          if (ic_oop != NULL) {
            f(ic_oop);
          }
        }
      } else if (iter.type() == relocInfo::static_call_type ||
                 iter.type() == relocInfo::opt_virtual_call_type){
        // Check Method* in AOT c2i stub for other calls.
        Metadata* meta = (Metadata*)nativeLoadGot_at(nativePltCall_at(iter.addr())->plt_c2i_stub())->data();
        if (meta != NULL) {
          f(meta);
        }
      }
    }
  }

  // Visit the metadata section
  for (Metadata** p = metadata_begin(); p < metadata_end(); p++) {
    Metadata* m = *p;

    intptr_t meta = (intptr_t)m;
    if ((meta & 1) == 1) {
      // already resolved
      m = (Metadata*)(meta & ~1);
    } else {
      continue;
    }
    assert(Metaspace::contains(m), "");
    f(m);
  }

  // Visit metadata not embedded in the other places.
  if (_method != NULL) f(_method);
}