hotspot/src/share/vm/oops/methodOop.cpp
void methodOopDesc::set_native_function(address function, bool post_event_flag) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(function != NULL, "use clear_native_function to unregister natives");
{- -------------------------------------------
(1) もう既に誰かが同じアドレスへと登録を終えていたら, することはないので, ここでリターン.
(これは, 複数のスレッドが同時に set_native_function() を呼ぶと起こりうる)
---------------------------------------- -}
address* native_function = native_function_addr();
// We can see racers trying to place the same native function into place. Once
// is plenty.
address current = *native_function;
if (current == function) return;
{- -------------------------------------------
(1) (JVMTI のフック点)
---------------------------------------- -}
if (post_event_flag && JvmtiExport::should_post_native_method_bind() &&
function != NULL) {
// native_method_throw_unsatisfied_link_error_entry() should only
// be passed when post_event_flag is false.
assert(function !=
SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
"post_event_flag mis-match");
// post the bind event, and possible change the bind function
JvmtiExport::post_native_method_bind(this, &function);
}
{- -------------------------------------------
(1) methodOop の native_function_addr の位置に指定されたアドレスを書き込む.
また, 古い内容に対して JIT compiled code が生成されていたら
nmethod::make_not_entrant() で無効にしておく.
---------------------------------------- -}
*native_function = function;
// This function can be called more than once. We must make sure that we always
// use the latest registered method -> check if a stub already has been generated.
// If so, we have to make it not_entrant.
nmethod* nm = code(); // Put it into local variable to guard against concurrent updates
if (nm != NULL) {
nm->make_not_entrant();
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.