Top


定義場所(file name)

hotspot/src/share/vm/oops/instanceKlass.cpp

名前(function name)

bool instanceKlass::link_class_impl(
    instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) {

本体部(body)

  {- -------------------------------------------
  (1) 初期化しようとしてエラーが起こった状態であれば, NoClassDefFoundError
      ---------------------------------------- -}

      // check for error state
      if (this_oop->is_in_error_state()) {
        ResourceMark rm(THREAD);
        THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(),
                   this_oop->external_name(), false);
      }

  {- -------------------------------------------
  (1) 既にリンク済みであれば, (することがないので) ここでリターン.
      ---------------------------------------- -}

      // return if already verified
      if (this_oop->is_linked()) {
        return true;
      }

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

      // Timing
      // timer handles recursion
      assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl");
      JavaThread* jt = (JavaThread*)THREAD;

  {- -------------------------------------------
  (1) まずスーパークラスに対して instanceKlass::link_class_impl() を呼び出し, 
      リンク処理を行っておく.
      ---------------------------------------- -}

      // link super class before linking this class
      instanceKlassHandle super(THREAD, this_oop->super());
      if (super.not_null()) {
        if (super->is_interface()) {  // check if super class is an interface
          ResourceMark rm(THREAD);
          Exceptions::fthrow(
            THREAD_AND_LOCATION,
            vmSymbols::java_lang_IncompatibleClassChangeError(),
            "class %s has interface %s as super class",
            this_oop->external_name(),
            super->external_name()
          );
          return false;
        }

        link_class_impl(super, throw_verifyerror, CHECK_false);
      }

  {- -------------------------------------------
  (1) 次に, 実装しているインターフェース全てに対して 
      instanceKlass::link_class_impl() を呼び出し, 
      リンク処理を行っておく.
      ---------------------------------------- -}

      // link all interfaces implemented by this class before linking this class
      objArrayHandle interfaces (THREAD, this_oop->local_interfaces());
      int num_interfaces = interfaces->length();
      for (int index = 0; index < num_interfaces; index++) {
        HandleMark hm(THREAD);
        instanceKlassHandle ih(THREAD, klassOop(interfaces->obj_at(index)));
        link_class_impl(ih, throw_verifyerror, CHECK_false);
      }

  {- -------------------------------------------
  (1) 既にリンク済みであれば, (することがないので) ここでリターン.
      (コメントによると, これはスーパークラスのリンク中に
      このクラスまでリンクされたケース)
      ---------------------------------------- -}

      // in case the class is linked in the process of linking its superclasses
      if (this_oop->is_linked()) {
        return true;
      }

  {- -------------------------------------------
  (1) (プロファイル情報の記録) ("sun.cls.classLinkedTime", "sun.cls.classLinkedTime.self", "sun.cls.linkedClasses")
      (See: PerfClassTraceTime, ClassLoader::perf_class_link_time(), ClassLoader::perf_class_link_selftime(), ClassLoader::perf_classes_linked())
      ---------------------------------------- -}

      // trace only the link time for this klass that includes
      // the verification time
      PerfClassTraceTime vmtimer(ClassLoader::perf_class_link_time(),
                                 ClassLoader::perf_class_link_selftime(),
                                 ClassLoader::perf_classes_linked(),
                                 jt->get_thread_stat()->perf_recursion_counts_addr(),
                                 jt->get_thread_stat()->perf_timers_addr(),
                                 PerfClassTraceTime::CLASS_LINK);

  {- -------------------------------------------
  (1) 以下のブロック内で, 対象クラスのリンク処理を行う.
      ---------------------------------------- -}

      // verification & rewriting
      {

    {- -------------------------------------------
  (1.1) (以下の処理は ... で排他した状態で行う)
        ---------------------------------------- -}

        ObjectLocker ol(this_oop, THREAD);

    {- -------------------------------------------
  (1.1) 既にリンク済みであれば, (することがないので) 以下のブロックはスキップする
        (というか残りの処理はリターンするだけ)
        ---------------------------------------- -}

        // rewritten will have been set if loader constraint error found
        // on an earlier link attempt
        // don't verify or rewrite if already rewritten
        if (!this_oop->is_linked()) {

    {- -------------------------------------------
  (1.1) まだ rewrite 処理が行われてなければ, 
        以下の if ブロック内で verification 処理と rewrite 処理を行う.
        ---------------------------------------- -}

          if (!this_oop->is_rewritten()) {
            {

      {- -------------------------------------------
  (1.1.1) (プロファイル情報の記録) ("sun.cls.classLinkedTime", "sun.cls.classLinkedTime.self", "sun.cls.linkedClasses")
          (See: PerfClassTraceTime, ClassLoader::perf_class_verify_time(), ClassLoader::perf_class_verify_selftime(), ClassLoader::perf_classes_verified())
          ---------------------------------------- -}

              // Timer includes any side effects of class verification (resolution,
              // etc), but not recursive entry into verify_code().
              PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
                                       ClassLoader::perf_class_verify_selftime(),
                                       ClassLoader::perf_classes_verified(),
                                       jt->get_thread_stat()->perf_recursion_counts_addr(),
                                       jt->get_thread_stat()->perf_timers_addr(),
                                       PerfClassTraceTime::CLASS_VERIFY);

      {- -------------------------------------------
  (1.1.1) instanceKlass::verify_code() を呼んで, バイトコードの verification を行う.
          (もし verification が失敗すれば, ここでリターン)
          ---------------------------------------- -}

              bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD);
              if (!verify_ok) {
                return false;
              }
            }

      {- -------------------------------------------
  (1.1.1) 既にリンク済みであれば, (することがないので) ここでリターン.
          (コメントによると, これは verification 処理中に
          このクラスがリンクされたケース. 
          変なクラスローダーを作ればあり得なくはない模様)
          ---------------------------------------- -}

            // Just in case a side-effect of verify linked this class already
            // (which can sometimes happen since the verifier loads classes
            // using custom class loaders, which are free to initialize things)
            if (this_oop->is_linked()) {
              return true;
            }

      {- -------------------------------------------
  (1.1.1) instanceKlass::rewrite_class() を呼んで, バイトコードの rewrite を行う.
          ---------------------------------------- -}

            // also sets rewritten
            this_oop->rewrite_class(CHECK_false);
          }

    {- -------------------------------------------
  (1.1) instanceKlass::relocate_and_link_methods() を呼んで, 
        バイトコード中の再配置(?)を行う.
        ---------------------------------------- -}

          // relocate jsrs and link methods after they are all rewritten
          this_oop->relocate_and_link_methods(CHECK_false);

    {- -------------------------------------------
  (1.1) klassVtable::initialize_vtable() 及び klassVtable::initialize_itable() を呼んで, 
        vtable と itable を生成する.
        ---------------------------------------- -}

          // Initialize the vtable and interface table after
          // methods have been rewritten since rewrite may
          // fabricate new methodOops.
          // also does loader constraint checking
          if (!this_oop()->is_shared()) {
            ResourceMark rm(THREAD);
            this_oop->vtable()->initialize_vtable(true, CHECK_false);
            this_oop->itable()->initialize_itable(true, CHECK_false);
          }

    {- -------------------------------------------
  (1.1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
        ---------------------------------------- -}

    #ifdef ASSERT
          else {
            ResourceMark rm(THREAD);
            this_oop->vtable()->verify(tty, true);
            // In case itable verification is ever added.
            // this_oop->itable()->verify(tty, true);
          }
    #endif

    {- -------------------------------------------
  (1.1) 
        ---------------------------------------- -}

          this_oop->set_init_state(linked);

    {- -------------------------------------------
  (1.1) (JVMTI のフック点)
        ---------------------------------------- -}

          if (JvmtiExport::should_post_class_prepare()) {
            Thread *thread = THREAD;
            assert(thread->is_Java_thread(), "thread->is_Java_thread()");
            JvmtiExport::post_class_prepare((JavaThread *) thread, this_oop());
          }
        }
      }

  {- -------------------------------------------
  (1) 結果をリターン
      ---------------------------------------- -}

      return true;
    }

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