void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
                                                    Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
  // check if receiver exists
  if (check_null_and_abstract && recv.is_null()) {
    THROW(vmSymbols::java_lang_NullPointerException());
  }

  // check if private interface method
  if (resolved_klass->is_interface() && resolved_method->is_private()) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s",
                 Method::name_and_sig_as_C_string(resolved_klass(),
                                                  resolved_method->name(),
                                                  resolved_method->signature()));
    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  }

  // check if receiver klass implements the resolved interface
  if (!recv_klass->is_subtype_of(resolved_klass())) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
                 recv_klass()->external_name(),
                 resolved_klass()->external_name());
    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  }

  // do lookup based on receiver klass
  methodHandle sel_method;
  // This search must match the linktime preparation search for itable initialization
  // to correctly enforce loader constraints for interface method inheritance
  lookup_instance_method_in_klasses(sel_method, recv_klass,
            resolved_method->name(),
            resolved_method->signature(), CHECK);
  if (sel_method.is_null() && !check_null_and_abstract) {
    // In theory this is a harmless placeholder value, but
    // in practice leaving in null affects the nsk default method tests.
    // This needs further study.
    sel_method = resolved_method;
  }
  // check if method exists
  if (sel_method.is_null()) {
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
              Method::name_and_sig_as_C_string(recv_klass(),
                                                      resolved_method->name(),
                                                      resolved_method->signature()));
  }
  // check access
  // Throw Illegal Access Error if sel_method is not public.
  if (!sel_method->is_public()) {
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
              Method::name_and_sig_as_C_string(recv_klass(),
                                               sel_method->name(),
                                               sel_method->signature()));
  }
  // check if abstract
  if (check_null_and_abstract && sel_method->is_abstract()) {
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
              Method::name_and_sig_as_C_string(recv_klass(),
                                                      sel_method->name(),
                                                      sel_method->signature()));
  }

  if (TraceItables && Verbose) {
    ResourceMark rm(THREAD);
    tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
                   (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
                   (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
                   Method::name_and_sig_as_C_string(resolved_klass(),
                                                    resolved_method->name(),
                                                    resolved_method->signature()),
                   sel_method->method_holder()->internal_name()
                  );
    sel_method->access_flags().print_on(tty);
    if (sel_method->is_default_method()) {
      tty->print("default ");
    }
    if (sel_method->is_overpass()) {
      tty->print("overpass");
    }
    tty->cr();
  }
  // setup result
  if (!resolved_method->has_itable_index()) {
    int vtable_index = resolved_method->vtable_index();
    assert(vtable_index == sel_method->vtable_index(), "sanity check");
    result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
  } else {
    int itable_index = resolved_method()->itable_index();
    result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
  }
}
void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
                                                    Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
   
  if (check_null_and_abstract && recv.is_null()) {
    THROW(vmSymbols::java_lang_NullPointerException());
  }

   
  if (resolved_klass->is_interface() && resolved_method->is_private()) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s",
                 Method::name_and_sig_as_C_string(resolved_klass(),
                                                  resolved_method->name(),
                                                  resolved_method->signature()));
    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  }

   
  if (!recv_klass->is_subtype_of(resolved_klass())) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
                 recv_klass()->external_name(),
                 resolved_klass()->external_name());
    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  }

   
  methodHandle sel_method;
   
   
  lookup_instance_method_in_klasses(sel_method, recv_klass,
            resolved_method->name(),
            resolved_method->signature(), CHECK);
  if (sel_method.is_null() && !check_null_and_abstract) {
     
     
     
    sel_method = resolved_method;
  }
   
  if (sel_method.is_null()) {
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
              Method::name_and_sig_as_C_string(recv_klass(),
                                                      resolved_method->name(),
                                                      resolved_method->signature()));
  }
   
   
  if (!sel_method->is_public()) {
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
              Method::name_and_sig_as_C_string(recv_klass(),
                                               sel_method->name(),
                                               sel_method->signature()));
  }
   
  if (check_null_and_abstract && sel_method->is_abstract()) {
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
              Method::name_and_sig_as_C_string(recv_klass(),
                                                      sel_method->name(),
                                                      sel_method->signature()));
  }

  if (TraceItables && Verbose) {
    ResourceMark rm(THREAD);
    tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
                   (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
                   (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
                   Method::name_and_sig_as_C_string(resolved_klass(),
                                                    resolved_method->name(),
                                                    resolved_method->signature()),
                   sel_method->method_holder()->internal_name()
                  );
    sel_method->access_flags().print_on(tty);
    if (sel_method->is_default_method()) {
      tty->print("default ");
    }
    if (sel_method->is_overpass()) {
      tty->print("overpass");
    }
    tty->cr();
  }
   
  if (!resolved_method->has_itable_index()) {
    int vtable_index = resolved_method->vtable_index();
    assert(vtable_index == sel_method->vtable_index(), "sanity check");
    result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
  } else {
    int itable_index = resolved_method()->itable_index();
    result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
  }
}