Top


定義場所(file name)

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

説明(description)

// Revised lookup semantics   introduced 1.3 (Kestral beta)

名前(function name)

void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {

本体部(body)

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

      // Note:  Arrays can have intermediate array supers.  Use java_super to skip them.
      KlassHandle super (THREAD, klass()->java_super());
      int nofNewEntries = 0;


  {- -------------------------------------------
  (1) (トレース出力)
      ---------------------------------------- -}

      if (PrintVtables && !klass()->oop_is_array()) {
        ResourceMark rm(THREAD);
        tty->print_cr("Initializing: %s", _klass->name()->as_C_string());
      }

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

    #ifdef ASSERT
      oop* end_of_obj = (oop*)_klass() + _klass()->size();
      oop* end_of_vtable = (oop*)&table()[_length];
      assert(end_of_vtable <= end_of_obj, "vtable extends beyond end");
    #endif

  {- -------------------------------------------
  (1) 起動中であれば (= Universe::is_bootstrapping() が true であれば), 
      単にクリアするだけにして, ここでリターン.
      ---------------------------------------- -}

      if (Universe::is_bootstrapping()) {
        // just clear everything
        for (int i = 0; i < _length; i++) table()[i].clear();
        return;
      }

  {- -------------------------------------------
  (1) klassVtable::initialize_from_super() を呼んで, 
      スーパークラスの vtable の中身をコピーする.
      ---------------------------------------- -}

      int super_vtable_len = initialize_from_super(super);

  {- -------------------------------------------
  (1) 配列クラスの場合は, (新しいメソッドが追加されることはないので) ここで終了
      ---------------------------------------- -}

      if (klass()->oop_is_array()) {
        assert(super_vtable_len == _length, "arrays shouldn't introduce new methods");

  {- -------------------------------------------
  (1) 配列クラスでない場合は, 以下のブロック内で
      新しいエントリを vtable に追加する.
      ---------------------------------------- -}

      } else {

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

        assert(_klass->oop_is_instance(), "must be instanceKlass");

    {- -------------------------------------------
  (1.1) 定義されているメソッドを辿り
        それぞれについて klassVtable::update_inherited_vtable() を呼んで
        vtable エントリに追加する必要があるかどうか調べる.
        必要がある場合は, klassVtable::put_method_at() を呼んで vtable に追加する.

        (新しい要素は, スーパークラスのメソッドをコピーした領域の後ろに順番に追加している)
        ---------------------------------------- -}

        objArrayHandle methods(THREAD, ik()->methods());
        int len = methods()->length();
        int initialized = super_vtable_len;

        // update_inherited_vtable can stop for gc - ensure using handles
        for (int i = 0; i < len; i++) {
          HandleMark hm(THREAD);
          assert(methods()->obj_at(i)->is_method(), "must be a methodOop");
          methodHandle mh(THREAD, (methodOop)methods()->obj_at(i));

          bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, checkconstraints, CHECK);

          if (needs_new_entry) {
            put_method_at(mh(), initialized);
            mh()->set_vtable_index(initialized); // set primary vtable index
            initialized++;
          }
        }

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

        // add miranda methods; it will also update the value of initialized
        fill_in_mirandas(initialized);

    {- -------------------------------------------
  (1.1) vtable に領域が残っている場合は, NULL を詰めておく
        (コメントによると, vtable が埋まらないケースもある模様)
        ---------------------------------------- -}

        // In class hierarchies where the accessibility is not increasing (i.e., going from private ->
        // package_private -> publicprotected), the vtable might actually be smaller than our initial
        // calculation.
        assert(initialized <= _length, "vtable initialization failed");
        for(;initialized < _length; initialized++) {
          put_method_at(NULL, initialized);
        }

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

        NOT_PRODUCT(verify(tty, true));
      }
    }

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