これらは, 同期排他処理 (monitorenter/monitorexit 命令, synchronized 修飾子, wait()/notify()/notifyAll() メソッド, 等) のためのクラス (See: here for details).
Java の同期排他処理のための関数を納めた名前空間(AllStatic クラス).
同期排他関係の処理は基本的に全てこのクラスに実装されている.
((cite: hotspot/src/share/vm/runtime/synchronizer.hpp))
class ObjectSynchronizer : AllStatic {
ただし, いちいちこいつを呼んでると遅いので, インタープリタや JIT 生成コードの fast path では使われない.
(このクラスには fast path 用のメソッドも定義されているのだが, 実際の fast path の処理部にはそのメソッドの内容がコピーされ手動でアセンブリに直された状態で展開されている)
(そのため, このクラスの fast path 用のメソッドを変更する際には (その展開箇所も含めて) 全部変えないと不整合が起きてまずい, とのこと)
((cite: hotspot/src/share/vm/runtime/synchronizer.cpp))
// The "core" versions of monitor enter and exit reside in this file.
// The interpreter and compilers contain specialized transliterated
// variants of the enter-exit fast-path operations. See i486.ad fast_lock(),
// for instance. If you make changes here, make sure to modify the
// interpreter, and both C1 and C2 fast-path inline locking code emission.
//
//
// -----------------------------------------------------------------------------
以下の処理で使用される. (他の使用箇所は?? #TODO)
(See: here and here for details)
(See: here for details)
(See: here for details)
内部には, 同期排他処理のための以下のようなメソッドが定義されている.
(わざわざ名前に "fast_" とつけて高速版だと分かるようにしたとのこと. また, これらはアセンブリ版がインタープリタや C1/C2 JIT 内部にコピーされているので, 変更する際には全部変えないと不整合になってまずい, とのこと)
((cite: hotspot/src/share/vm/runtime/synchronizer.hpp))
// This is full version of monitor enter and exit. I choose not
// to use enter() and exit() in order to make sure user be ware
// of the performance and semantics difference. They are normally
// used by ObjectLocker etc. The interpreter and compiler use
// assembly copies of these routines. Please keep them synchornized.
//
// attempt_rebias flag is used by UseBiasedLocking implementation
static void fast_enter (Handle obj, BasicLock* lock, bool attempt_rebias, TRAPS);
static void fast_exit (oop obj, BasicLock* lock, Thread* THREAD);
((cite: hotspot/src/share/vm/runtime/synchronizer.hpp))
// WARNING: They are ONLY used to handle the slow cases. They should
// only be used when the fast cases failed. Use of these functions
// without previous fast case check may cause fatal error.
static void slow_enter (Handle obj, BasicLock* lock, TRAPS);
static void slow_exit (oop obj, BasicLock* lock, Thread* THREAD);
(インタープリタ, JIT 生成コード, JNI を問わずこれが使われる)
((cite: hotspot/src/share/vm/runtime/synchronizer.hpp))
// Handle all interpreter, compiler and jni cases
static void wait (Handle obj, jlong millis, TRAPS);
static void notify (Handle obj, TRAPS);
static void notifyall (Handle obj, TRAPS);
((cite: hotspot/src/share/vm/runtime/synchronizer.hpp))
// Used only to handle jni locks or other unmatched monitor enter/exit
// Internally they will use heavy weight monitor.
static void jni_enter (Handle obj, TRAPS);
static bool jni_try_enter(Handle obj, Thread* THREAD); // Implements Unsafe.tryMonitorEnter
static void jni_exit (oop obj, Thread* THREAD);
See: here for details
HotSpot 内で「Java オブジェクトのロックを取得して何らかの処理を行う」場合用のユーティリティ・クラス(StackObjクラス).
(例えば, クラスローディング処理中だけはロックしておきたい, 等).
ロックの確保/開放処理をソースコード上のスコープに合わせて行ってくれる (ただし, pending exception がセットされているかもしれないので必要に応じてチェックするように, とのこと).
((cite: hotspot/src/share/vm/runtime/synchronizer.hpp))
// ObjectLocker enforced balanced locking and can never thrown an
// IllegalMonitorStateException. However, a pending exception may
// have to pass through, and we must also be able to deal with
// asynchronous exceptions. The caller is responsible for checking
// the threads pending exception if needed.
// doLock was added to support classloading with UnsyncloadClass which
// requires flag based choice of locking the classloader lock.
class ObjectLocker : public StackObj {
HotSpot 内の様々な箇所で使用されている (#TODO).
定義されているフィールドは以下の通り.
(BasicLock (displaced header) はオブジェクト内にフィールドとして保持している)
((cite: hotspot/src/share/vm/runtime/synchronizer.hpp))
Thread* _thread;
Handle _obj;
BasicLock _lock;
bool _dolock; // default true
コンストラクタで ObjectSynchronizer::fast_enter() を呼んでロックを確保し, デストラクタで ObjectSynchronizer::fast_exit() で解放している.
(ただし, doLock コンストラクタ引数が false の場合は, 何も処理を行わない)
((cite: hotspot/src/share/vm/runtime/synchronizer.cpp))
// -----------------------------------------------------------------------------
// Internal VM locks on java objects
// standard constructor, allows locking failures
ObjectLocker::ObjectLocker(Handle obj, Thread* thread, bool doLock) {
_dolock = doLock;
_thread = thread;
debug_only(if (StrictSafepointChecks) _thread->check_for_valid_safepoint_state(false);)
_obj = obj;
if (_dolock) {
TEVENT (ObjectLocker) ;
ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread);
}
}
ObjectLocker::~ObjectLocker() {
if (_dolock) {
ObjectSynchronizer::fast_exit(_obj(), &_lock, _thread);
}
}
See: here for details
ObjectSynchronizer クラス内で使用される補助クラス.
JNI の DetachCurrentThread() 関数の処理で使用される補助クラス. カレントスレッドがロックを握っている ObjectMonitor のロックを開放する (JNI の仕様で DetachCurrentThread() 時には対象のスレッドが保持しているロックを全て解放しなければいけないと規定されている).
((cite: hotspot/src/share/vm/runtime/synchronizer.cpp))
// Iterate through monitor cache and attempt to release thread's monitors
// Gives up on a particular monitor if an exception occurs, but continues
// the overall iteration, swallowing the exception.
class ReleaseJavaMonitorsClosure: public MonitorClosure {
ObjectSynchronizer::release_monitors_owned_by_thread() 内で(のみ)使用されている (See: here for details).
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.