これらは, Garbage Collection 処理用の補助クラス. より具体的に言うと, GC によるポインタ移動の影響を HotSpot 内の他の部分から隠蔽するためのクラス (See: here for details).
Java のオブジェクト(oop) は GC 時に移動されることがある. このため HotSpot 内で oop のポインタを直接触っていると, いつの間にか不正なポインタ(dangling pointer)になっている恐れがあり面倒臭い.
そこで, HotSpot 内で oop のポインタを操作する場合は "Handle" というオブジェクトを介して関節参照している.
全ての Handle は GC 時の調査対象になり, オブジェクトが移動した場合は Handle 内のポインタも新しいものに書き換わる. このため, Handle を使うコードからは GC の影響を無視することができる.
(以下は Handle の使用例)
oop obj = ...;
Handle h1(obj); // allocate new handle
Handle h2(thread, obj); // faster allocation when current thread is known
Handle h3; // declare handle only, no allocation occurs
...
h3 = h1; // make h3 refer to same indirection as h1
oop obj2 = h2(); // get handle value
h1->print(); // invoking operation on oop
なお, Handle には各 oop クラスに対応するサブクラスが用意されている (コメントによると, クラスに応じた追加情報が付けられるし無駄なキャストも減る, とのこと).
oop Handle
methodOop methodHandle
instanceOop instanceHandle
さらに, klassOop については Klass クラスごとに Handle が用意されている (コメントによると, キャストなしで klass_part にアクセス可能にしてコードを書くのが楽にするため, とのこと).
klassOop Klass KlassHandle
klassOop methodKlass methodKlassHandle
klassOop instanceKlass instanceKlassHandle
((cite: hotspot/src/share/vm/runtime/handles.hpp))
//------------------------------------------------------------------------------------------------------------------------
// In order to preserve oops during garbage collection, they should be
// allocated and passed around via Handles within the VM. A handle is
// simply an extra indirection allocated in a thread local handle area.
//
// A handle is a ValueObj, so it can be passed around as a value, can
// be used as a parameter w/o using &-passing, and can be returned as a
// return value.
//
// oop parameters and return types should be Handles whenever feasible.
//
// Handles are declared in a straight-forward manner, e.g.
//
// oop obj = ...;
// Handle h1(obj); // allocate new handle
// Handle h2(thread, obj); // faster allocation when current thread is known
// Handle h3; // declare handle only, no allocation occurs
// ...
// h3 = h1; // make h3 refer to same indirection as h1
// oop obj2 = h2(); // get handle value
// h1->print(); // invoking operation on oop
//
// Handles are specialized for different oop types to provide extra type
// information and avoid unnecessary casting. For each oop type xxxOop
// there is a corresponding handle called xxxHandle, e.g.
//
// oop Handle
// methodOop methodHandle
// instanceOop instanceHandle
//
// For klassOops, it is often useful to model the Klass hierarchy in order
// to get access to the klass_part without casting. For each xxxKlass there
// is a corresponding handle called xxxKlassHandle, e.g.
//
// klassOop Klass KlassHandle
// klassOop methodKlass methodKlassHandle
// klassOop instanceKlass instanceKlassHandle
//
なお, Handle が必要とするデータは JavaThread 内にある HandleArea という Arena 上に確保されることになっている. (Handle オブジェクト自体はその領域を指すポインタだけを保持する. ポインタ1つなので ValueObj として扱われている)
((cite: hotspot/src/share/vm/runtime/handles.inline.hpp))
inline Handle::Handle(oop obj) {
if (obj == NULL) {
_handle = NULL;
} else {
_handle = Thread::current()->handle_area()->allocate_handle(obj);
}
}
そして, HandleArea 内のメモリ管理は, HandleMark というクラスにより, ソースコード上のスコープに合わせて行うことができるようになっている (参考: Region-based memory management).
(以下は使用例: スコープを抜けて HandleMark のデストラクタが呼ばれた段階で, そのスコープ内で確保した Handle が全て解放される)
((cite: hotspot/src/share/vm/runtime/javaCalls.cpp))
{ HandleMark hm(thread); // HandleMark used by HandleMarkCleaner
...
}
GC によるポインタ移動の影響を HotSpot 内の他の部分から隠蔽するためのクラス. HotSpot 内で Java のオブジェクト (oop) を操作する場合は Handle 経由で行う (See: here for details).
なお Handle 自体は ValueObj であり, メソッドの引数や返り値として使うこともできる.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
//------------------------------------------------------------------------------------------------------------------------
// Base class for all handles. Provides overloading of frequently
// used operators for ease of use.
class Handle VALUE_OBJ_CLASS_SPEC {
HotSpot 内の様々な箇所で使用されている (#TODO).
Handle が必要とするデータは HandleArea という Arena 上に確保される (Handle オブジェクト自体はその領域を指すポインタだけを保持する. このため ValueObj クラスになっている).
See: here for details
klassOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
//------------------------------------------------------------------------------------------------------------------------
// Base class for Handles containing klassOops. Provides overloading of frequently
// used operators for ease of use and typed access to the Klass part.
class KlassHandle: public Handle {
HotSpot 内の様々な箇所で使用されている (#TODO).
Klass の種別が分かっている場合は KlassHandle の各サブクラスも利用可能.
See: here for details
instanceOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(instance , is_instance )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
methodOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(method , is_method )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
名前が似ていて紛らわしいが java.lang.invoke.MethodHandle とは全く関係ない.
See: here for details
constMethodOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(constMethod , is_constMethod )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
methodDataOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(methodData , is_methodData )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
arrayOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(array , is_array )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
constantPoolOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(constantPool , is_constantPool )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
constantPoolCacheOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(constantPoolCache, is_constantPoolCache)
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
objArrayOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(objArray , is_objArray )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
typeArrayOopDesc 用の Handle クラス.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_HANDLE(typeArray , is_typeArray )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific Handles for different oop types
#define DEF_HANDLE(type, is_a) \
class type##Handle; \
class type##Handle: public Handle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が instanceKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(instanceKlass , oop_is_instance_slow )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が methodKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(methodKlass , oop_is_method )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が constMethodKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(constMethodKlass , oop_is_constMethod )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が klassKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(klassKlass , oop_is_klass )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が arrayKlassKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(arrayKlassKlass , oop_is_arrayKlass )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が objArrayKlassKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(objArrayKlassKlass , oop_is_objArrayKlass )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が typeArrayKlassKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(typeArrayKlassKlass , oop_is_typeArrayKlass)
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が arrayKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(arrayKlass , oop_is_array )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が typeArrayKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(typeArrayKlass , oop_is_typeArray_slow)
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が objArrayKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(objArrayKlass , oop_is_objArray_slow )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が constantPoolKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(constantPoolKlass , oop_is_constantPool )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
KlassHandle クラスのサブクラス. このクラスは Klass 種別が constantPoolCacheKlass の場合用.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
DEF_KLASS_HANDLE(constantPoolCacheKlass, oop_is_constantPool )
なお, このクラスはソースコード上で直接定義はされておらず, 以下のマクロを使って間接的に定義されている.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Specific KlassHandles for different Klass types
#define DEF_KLASS_HANDLE(type, is_a) \
class type##Handle : public KlassHandle { \
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
Handle クラス用の補助クラス.
Handle が必要とするデータを確保するための Arena クラス
(なお, Arena クラスなのでこの領域はスレッドローカル).
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// Thread local handle area
class HandleArea: public Arena {
各 Thread オブジェクトの _handle_area フィールドに(のみ)格納されている.
((cite: hotspot/src/share/vm/runtime/thread.hpp))
class Thread: public ThreadShadow {
...
protected:
...
// Thread local handle area for allocation of handles within the VM
HandleArea* _handle_area;
Thread::Thread() 内で(のみ)生成されている.
See: here for details
HandleArena クラス用のユーティリティ・クラス.
Handle の確保/開放をソースコード上のスコープに合わせて自動で行うことができる. (参考: Region-based memory management).
コンストラクタではその時点での HandleArea の先頭位置(top 位置)を記録し, デストラクタで記録した位置まで戻す (= その時点までに確保したハンドル領域を解放する).
((cite: hotspot/src/share/vm/runtime/handles.hpp))
//------------------------------------------------------------------------------------------------------------------------
// Handles are allocated in a (growable) thread local handle area. Deallocation
// is managed using a HandleMark. It should normally not be necessary to use
// HandleMarks manually.
//
// A HandleMark constructor will record the current handle area top, and the
// desctructor will reset the top, destroying all handles allocated in between.
// The following code will therefore NOT work:
//
// Handle h;
// {
// HandleMark hm;
// h = Handle(obj);
// }
// h()->print(); // WRONG, h destroyed by HandleMark destructor.
//
// If h has to be preserved, it can be converted to an oop or a local JNI handle
// across the HandleMark boundary.
// The base class of HandleMark should have been StackObj but we also heap allocate
// a HandleMark when a thread is created.
class HandleMark {
HotSpot 内の様々な箇所で使用されている (#TODO).
See: here for details
デバッグ用(開発時用)のクラス (#ifdef ASSERT 時以外には空のクラスとして定義される).
「あるコード範囲で Handle の確保操作が起きない」ということをコード上に明示したい場合に使用される.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
// A NoHandleMark stack object will verify that no handles are allocated
// in its scope. Enabled in debug mode only.
class NoHandleMark: public StackObj {
コード中で NoHandleMark 型の局所変数を宣言するだけ.
HotSpot 内の様々な箇所で使用されている (#TODO).
#ifdef ASSERT
でなければ, 中身のないクラスとして定義される.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
#ifdef ASSERT
NoHandleMark();
~NoHandleMark();
#else
NoHandleMark() {}
~NoHandleMark() {}
#endif
See: here for details
デバッグ用(開発時用)のクラス (#ifdef ASSERT 時以外には空のクラスとして定義される).
NoHandleMark の働きを一時的に無効化したい場合に使用する (ResetNoHandleMark のコンストラクタが呼ばれてからデストラクタが呼ばれるまでの間は NoHandleMark の効果がキャンセルされる).
((cite: hotspot/src/share/vm/runtime/handles.hpp))
class ResetNoHandleMark: public StackObj {
コード中で ResetNoHandleMark 型の局所変数を宣言するだけ.
HotSpot 内の様々な箇所で使用されている (#TODO).
#ifdef ASSERT
でなければ, 中身のないクラスとして定義される.
((cite: hotspot/src/share/vm/runtime/handles.hpp))
#ifdef ASSERT
ResetNoHandleMark();
~ResetNoHandleMark();
#else
ResetNoHandleMark() {}
~ResetNoHandleMark() {}
#endif
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.