void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
                                                  KlassHandle current_klass, Handle recv, bool check_access, TRAPS) {

  // resolved method is selected method unless we have an old-style lookup
  // for a superclass method
  // Invokespecial for a superinterface, resolved method is selected method,
  // no checks for shadowing
  methodHandle sel_method(THREAD, resolved_method());

  if (check_access &&
      // check if the method is not <init>
      resolved_method->name() != vmSymbols::object_initializer_name()) {

  // check if this is an old-style super call and do a new lookup if so
        // a) check if ACC_SUPER flag is set for the current class
    if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
        // b) check if the class of the resolved_klass is a superclass
        // (not supertype in order to exclude interface classes) of the current class.
        // This check is not performed for super.invoke for interface methods
        // in super interfaces.
        current_klass->is_subclass_of(resolved_klass()) &&
        current_klass() != resolved_klass()) {
      // Lookup super method
      KlassHandle super_klass(THREAD, current_klass->super());
      lookup_instance_method_in_klasses(sel_method, super_klass,
                           resolved_method->name(),
                           resolved_method->signature(), CHECK);
      // check if found
      if (sel_method.is_null()) {
        ResourceMark rm(THREAD);
        THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
                  Method::name_and_sig_as_C_string(resolved_klass(),
                                            resolved_method->name(),
                                            resolved_method->signature()));
      } else if (sel_method() != resolved_method()) {
        check_method_loader_constraints(sel_method, resolved_klass,
                                        sel_method->name(), sel_method->signature(),
                                        current_klass, "method", CHECK);
      }
    }

    // Check that the class of objectref (the receiver) is the current class or interface,
    // or a subtype of the current class or interface (the sender), otherwise invokespecial
    // throws IllegalAccessError.
    // The verifier checks that the sender is a subtype of the class in the I/MR operand.
    // The verifier also checks that the receiver is a subtype of the sender, if the sender is
    // a class.  If the sender is an interface, the check has to be performed at runtime.
    InstanceKlass* sender = InstanceKlass::cast(current_klass());
    sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender;
    if (sender->is_interface() && recv.not_null()) {
      Klass* receiver_klass = recv->klass();
      if (!receiver_klass->is_subtype_of(sender)) {
        ResourceMark rm(THREAD);
        char buf[500];
        jio_snprintf(buf, sizeof(buf),
                     "Receiver class %s must be the current class or a subtype of interface %s",
                     receiver_klass->name()->as_C_string(),
                     sender->name()->as_C_string());
        THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf);
      }
    }
  }

  // check if not static
  if (sel_method->is_static()) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "Expecting non-static 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 abstract
  if (sel_method->is_abstract()) {
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
              Method::name_and_sig_as_C_string(resolved_klass(),
                                                      sel_method->name(),
                                                      sel_method->signature()));
  }

  if (TraceItables && Verbose) {
    ResourceMark rm(THREAD);
    tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
                 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
                 Method::name_and_sig_as_C_string(resolved_klass(),
                                                  sel_method->name(),
                                                  sel_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
  result.set_static(resolved_klass, sel_method, CHECK);
}
void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
                                                  KlassHandle current_klass, Handle recv, bool check_access, TRAPS) {

   
   
   
   
  methodHandle sel_method(THREAD, resolved_method());

  if (check_access &&
       
      resolved_method->name() != vmSymbols::object_initializer_name()) {

   
         
    if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
         
         
         
         
        current_klass->is_subclass_of(resolved_klass()) &&
        current_klass() != resolved_klass()) {
       
      KlassHandle super_klass(THREAD, current_klass->super());
      lookup_instance_method_in_klasses(sel_method, super_klass,
                           resolved_method->name(),
                           resolved_method->signature(), CHECK);
       
      if (sel_method.is_null()) {
        ResourceMark rm(THREAD);
        THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
                  Method::name_and_sig_as_C_string(resolved_klass(),
                                            resolved_method->name(),
                                            resolved_method->signature()));
      } else if (sel_method() != resolved_method()) {
        check_method_loader_constraints(sel_method, resolved_klass,
                                        sel_method->name(), sel_method->signature(),
                                        current_klass, "method", CHECK);
      }
    }

     
     
     
     
     
     
    InstanceKlass* sender = InstanceKlass::cast(current_klass());
    sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender;
    if (sender->is_interface() && recv.not_null()) {
      Klass* receiver_klass = recv->klass();
      if (!receiver_klass->is_subtype_of(sender)) {
        ResourceMark rm(THREAD);
        char buf[500];
        jio_snprintf(buf, sizeof(buf),
                     "Receiver class %s must be the current class or a subtype of interface %s",
                     receiver_klass->name()->as_C_string(),
                     sender->name()->as_C_string());
        THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf);
      }
    }
  }

   
  if (sel_method->is_static()) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "Expecting non-static 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 (sel_method->is_abstract()) {
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
              Method::name_and_sig_as_C_string(resolved_klass(),
                                                      sel_method->name(),
                                                      sel_method->signature()));
  }

  if (TraceItables && Verbose) {
    ResourceMark rm(THREAD);
    tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
                 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
                 Method::name_and_sig_as_C_string(resolved_klass(),
                                                  sel_method->name(),
                                                  sel_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();
  }

   
  result.set_static(resolved_klass, sel_method, CHECK);
}