hotspot/src/share/vm/compiler/compileBroker.cpp
// ------------------------------------------------------------------
// CompileBroker::make_compiler_thread
CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
CompilerThread* compiler_thread = NULL;
klassOop k =
SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
true, CHECK_0);
instanceKlassHandle klass (THREAD, k);
{- -------------------------------------------
(1) 新しい java.lang.Thread オブジェクト(以下の thread_oop)を確保する.
---------------------------------------- -}
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
Handle string = java_lang_String::create_from_str(name, CHECK_0);
{- -------------------------------------------
(1) JavaCalls::call_special() 経由で java.lang.Thread() のコンストラクタを呼び出し,
thread_oop オブジェクトを初期化しておく.
---------------------------------------- -}
// Initialize thread_oop to put it into the system threadGroup
Handle thread_group (THREAD, Universe::system_thread_group());
JavaValue result(T_VOID);
JavaCalls::call_special(&result, thread_oop,
klass,
vmSymbols::object_initializer_name(),
vmSymbols::threadgroup_string_void_signature(),
thread_group,
string,
CHECK_0);
{- -------------------------------------------
(1) 新しい CompilerThread オブジェクトを確保する (この際に対応する新しいスレッドが生成される).
生成されたスレッドについては, java_lang_Thread::set_thread() を呼んで
thread_oop オブジェクトの eetop フィールドにセットしておく. (See: [here](no30595cP.html) for details)
(あわせて, java_lang_Thread::set_priority() 等を呼んで thread_oop オブジェクトの優先度等も設定しておく)
最後に Thread::start() を呼んで, 生成した CompilerThread スレッドの実行を開始させる.
(なお, これらの処理は Threads_lock で排他した状態で行う)
(また, CompilerThread オブジェクトの確保に失敗した場合は vm_exit_during_initialization() で異常終了)
---------------------------------------- -}
{
MutexLocker mu(Threads_lock, THREAD);
compiler_thread = new CompilerThread(queue, counters);
// At this point the new CompilerThread data-races with this startup
// thread (which I believe is the primoridal thread and NOT the VM
// thread). This means Java bytecodes being executed at startup can
// queue compile jobs which will run at whatever default priority the
// newly created CompilerThread runs at.
// At this point it may be possible that no osthread was created for the
// JavaThread due to lack of memory. We would have to throw an exception
// in that case. However, since this must work and we do not allow
// exceptions anyway, check and abort if this fails.
if (compiler_thread == NULL || compiler_thread->osthread() == NULL){
vm_exit_during_initialization("java.lang.OutOfMemoryError",
"unable to create new native thread");
}
java_lang_Thread::set_thread(thread_oop(), compiler_thread);
// Note that this only sets the JavaThread _priority field, which by
// definition is limited to Java priorities and not OS priorities.
// The os-priority is set in the CompilerThread startup code itself
java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
// CLEANUP PRIORITIES: This -if- statement hids a bug whereby the compiler
// threads never have their OS priority set. The assumption here is to
// enable the Performance group to do flag tuning, figure out a suitable
// CompilerThreadPriority, and then remove this 'if' statement (and
// comment) and unconditionally set the priority.
// Compiler Threads should be at the highest Priority
if ( CompilerThreadPriority != -1 )
os::set_native_priority( compiler_thread, CompilerThreadPriority );
else
os::set_native_priority( compiler_thread, os::java_to_os_priority[NearMaxPriority]);
// Note that I cannot call os::set_priority because it expects Java
// priorities and I am *explicitly* using OS priorities so that it's
// possible to set the compiler thread priority higher than any Java
// thread.
java_lang_Thread::set_daemon(thread_oop());
compiler_thread->set_threadObj(thread_oop());
Threads::add(compiler_thread);
Thread::start(compiler_thread);
}
{- -------------------------------------------
(1)
---------------------------------------- -}
// Let go of Threads_lock before yielding
os::yield(); // make sure that the compiler thread is started early (especially helpful on SOLARIS)
{- -------------------------------------------
(1) 結果をリターン
---------------------------------------- -}
return compiler_thread;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.