hotspot/src/share/vm/oops/objArrayKlass.cpp
klassOop objArrayKlass::array_klass_impl(objArrayKlassHandle this_oop, bool or_null, int n, TRAPS) {
{- -------------------------------------------
(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.