// is_optimized: Compiler has generated an optimized call (i.e., no inline
// cache) static_bound: The call can be static bound (i.e, no need to use
// inline cache)
void CompiledIC::compute_monomorphic_entry(methodHandle method,
                                           KlassHandle receiver_klass,
                                           bool is_optimized,
                                           bool static_bound,
                                           CompiledICInfo& info,
                                           TRAPS) {
  nmethod* method_code = method->code();
  address entry = NULL;
  if (method_code != NULL && method_code->is_in_use()) {
    // Call to compiled code
    if (static_bound || is_optimized) {
      entry      = method_code->verified_entry_point();
    } else {
      entry      = method_code->entry_point();
    }
  }
  if (entry != NULL) {
    // Call to compiled code
    info.set_compiled_entry(entry, (static_bound || is_optimized) ? NULL : receiver_klass(), is_optimized);
  } else {
    // Note: the following problem exists with Compiler1:
    //   - at compile time we may or may not know if the destination is final
    //   - if we know that the destination is final, we will emit an optimized
    //     virtual call (no inline cache), and need a Method* to make a call
    //     to the interpreter
    //   - if we do not know if the destination is final, we emit a standard
    //     virtual call, and use CompiledICHolder to call interpreted code
    //     (no static call stub has been generated)
    //     However in that case we will now notice it is static_bound
    //     and convert the call into what looks to be an optimized
    //     virtual call. This causes problems in verifying the IC because
    //     it look vanilla but is optimized. Code in is_call_to_interpreted
    //     is aware of this and weakens its asserts.

    // static_bound should imply is_optimized -- otherwise we have a
    // performance bug (statically-bindable method is called via
    // dynamically-dispatched call note: the reverse implication isn't
    // necessarily true -- the call may have been optimized based on compiler
    // analysis (static_bound is only based on "final" etc.)
#ifdef COMPILER2
#ifdef TIERED
#if defined(ASSERT)
    // can't check the assert because we don't have the CompiledIC with which to
    // find the address if the call instruction.
    //
    // CodeBlob* cb = find_blob_unsafe(instruction_address());
    // assert(cb->is_compiled_by_c1() || !static_bound || is_optimized, "static_bound should imply is_optimized");
#endif // ASSERT
#else
    assert(!static_bound || is_optimized, "static_bound should imply is_optimized");
#endif // TIERED
#endif // COMPILER2
    if (is_optimized) {
      // Use stub entry
      info.set_interpreter_entry(method()->get_c2i_entry(), method());
    } else {
      // Use icholder entry
      CompiledICHolder* holder = new CompiledICHolder(method(), receiver_klass());
      info.set_icholder_entry(method()->get_c2i_unverified_entry(), holder);
    }
  }
  assert(info.is_optimized() == is_optimized, "must agree");
}