Top


定義場所(file name)

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

名前(function name)

klassOop objArrayKlass::array_klass_impl(objArrayKlassHandle this_oop, bool or_null, int n, TRAPS) {

本体部(body)

  {- -------------------------------------------
  (1) (assert)
      ---------------------------------------- -}

      assert(this_oop->dimension() <= n, "check order of chain");

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

      int dimension = this_oop->dimension();

  {- -------------------------------------------
  (1) まず, リターンすべき配列クラスの次元数を
      this_oop 引数の配列クラスの次元数と比較する.
      もし一致すれば, this_oop 引数をリターンするだけでいい (この場合はここで終了).
      ---------------------------------------- -}

      if (dimension == n)
        return this_oop();

  {- -------------------------------------------
  (1) (ここに来るのは, this_oop 引数のクラスでは次元数が足りない場合.
      この場合, this_oop より1つ高次元の配列クラスに処理を移譲することになる)
      ---------------------------------------- -}

  {- -------------------------------------------
  (1) (変数宣言など)
      (ak は, this_oop より1つ高次元の配列クラス(まだクラスが作成されてなければ null handle))
      ---------------------------------------- -}

      objArrayKlassHandle ak (THREAD, this_oop->higher_dimension());

  {- -------------------------------------------
  (1) もし, this_oop より1つ高次元の配列クラスがまだ作成されていなければ, 
      以下の if ブロック内で生成する.

      (ただし, or_null 引数が true の場合は, 作成せずここで NULL をリターンするだけ)

      (なお, 一度生成したら arrayKlass::set_higher_dimension() で結果をメモイズするため, 
      各次元数に付き最初の1回のみ配列クラスが作成される)
      ---------------------------------------- -}

      if (ak.is_null()) {
        if (or_null)  return NULL;

        ResourceMark rm;
        JavaThread *jt = (JavaThread *)THREAD;

    {- -------------------------------------------
  (1.1) (以下が作成処理.
        ロックを取ったあと objArrayKlassKlass::allocate_objArray_klass() で生成する.
        なお, ロックを取った後には DCL idiom でのチェックも行っている)
        ---------------------------------------- -}

        {
          MutexLocker mc(Compile_lock, THREAD);   // for vtables
          // Ensure atomic creation of higher dimensions
          MutexLocker mu(MultiArray_lock, THREAD);

          // Check if another thread beat us
          ak = objArrayKlassHandle(THREAD, this_oop->higher_dimension());
          if( ak.is_null() ) {

            // Create multi-dim klass object and link them together
            klassOop new_klass =
              objArrayKlassKlass::cast(Universe::objArrayKlassKlassObj())->
              allocate_objArray_klass(dimension + 1, this_oop, CHECK_NULL);
            ak = objArrayKlassHandle(THREAD, new_klass);
            ak->set_lower_dimension(this_oop());
            OrderAccess::storestore();
            this_oop->set_higher_dimension(ak());
            assert(ak->oop_is_objArray(), "incorrect initialization of objArrayKlass");
          }
        }
      } else {
        CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
      }

  {- -------------------------------------------
  (1) this_oop より1つ高次元の配列クラスに対して
      Klass::array_klass() を呼び出すことで,
      指定された次元数に対応する arrayKlass を取得する.
      その結果をリターン.

      (なお, or_null 引数が true の場合は, 
      Klass::array_klass() の代わりに Klass::array_klass_or_null() を使用)
      ---------------------------------------- -}

      if (or_null) {
        return ak->array_klass_or_null(n);
      }
      return ak->array_klass(n, CHECK_NULL);
    }

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