Top


定義場所(file name)

hotspot/src/share/vm/interpreter/linkResolver.cpp

説明(description)

// throws runtime exceptions

名前(function name)

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

本体部(body)

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      // resolved method is selected method unless we have an old-style lookup
      methodHandle sel_method(THREAD, resolved_method());

  {- -------------------------------------------
  (1) もし以下の 3つの条件が成り立つ場合は解決をやり直す.
      * 
      * 
      * 
      (再解決する場合, もし見つからなければ AbstractMethodError)
      (この条件については, Java 仮想マシン仕様の invokespecial の仕様を参照)
      ---------------------------------------- -}

      // check if this is an old-style super call and do a new lookup if so
      { KlassHandle method_klass  = KlassHandle(THREAD,
                                                resolved_method->method_holder());

        if (check_access &&
            // a) check if ACC_SUPER flag is set for the current class
            current_klass->is_super() &&
            // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
            current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() &&
            // c) check if the method is not <init>
            resolved_method->name() != vmSymbols::object_initializer_name()) {
          // 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(),
                      methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
                                                resolved_method->name(),
                                                resolved_method->signature()));
          }
        }
      }

  {- -------------------------------------------
  (1) もし解決結果が static method であれば IncompatibleClassChangeError.
      ---------------------------------------- -}

      // 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", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
                                                                                                                 resolved_method->name(),
                                                                                                                 resolved_method->signature()));
        THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
      }

  {- -------------------------------------------
  (1) もし解決結果が abstract method だったら, AbstractMethodError.
      ---------------------------------------- -}

      // check if abstract
      if (sel_method->is_abstract()) {
        ResourceMark rm(THREAD);
        THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
                  methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
                                                          sel_method->name(),
                                                          sel_method->signature()));
      }

  {- -------------------------------------------
  (1) CallInfo::set_static() を呼んで, 
      引数で渡された CallInfo オブジェクト内に
      解決結果をセットする
      ---------------------------------------- -}

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

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.