这是jvm当初始化类的时候,class的调用层级关系
instanceKlass::initialize()
-> instanceKlass::initialize_impl()
-> instanceKlass::link_class()
-> instanceKlass::link_class_impl()
-> instanceKlass::rewrite_class()
-> Rewriter::rewrite()
-> Rewriter::Rewriter()
-> methodOopDesc::link_method()
在方法methodOopDesc::link_method 设置到了对应的natvive方法的解释entry
[cpp] view plaincopy
void methodOopDesc::link_method(methodHandle h_method, TRAPS) {
assert(_i2i_entry == NULL, "should only be called once");
assert(_adapter == NULL, "init'd to NULL" );
assert( _code == NULL, "nothing compiled yet" );
// Setup interpreter entrypoint
assert(this == h_method(), "wrong h_method()" );
address entry = Interpreter::entry_for_method(h_method); //找到对应的方法 entry
assert(entry != NULL, "interpreter entry must be non-null");
// Sets both _i2i_entry and _from_interpreted_entry
set_interpreter_entry(entry); //并且把entry设置到了methodoop中
...
}
找到对应的方法类型的entry
函数entry_for_method 是从_entry_table数组中找到对应的entry
[cpp] view plaincopy
static address entry_for_method(methodHandle m) { return _entry_table[method_kind(m)]; }
在函数中TemplateInterpreterGenerator::generate_all,我们可以看到初始化了_entry_table entry数组,而这是在jvm初始化的时候(jint init_globals())初始化的。
[cpp] view plaincopy
#define method_entry(kind) \
{ CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \
}
// all non-native method kinds
method_entry(zerolocals)
method_entry(zerolocals_synchronized)
method_entry(empty)
method_entry(accessor)
method_entry(abstract)
method_entry(method_handle)
method_entry(java_lang_math_sin )
method_entry(java_lang_math_cos )
method_entry(java_lang_math_tan )
method_entry(java_lang_math_abs )
method_entry(java_lang_math_sqrt )
method_entry(java_lang_math_log )
method_entry(java_lang_math_log10)
// all native method kinds (must be one contiguous block)
Interpreter::_native_entry_begin = Interpreter::code()->code_end();
method_entry(native)
method_entry(native_synchronized)
Interpreter::_native_entry_end = Interpreter::code()->code_end();
#undef method_entry
而对应的不同的方法,使用不同的entry 是在函数generate_method_entry里定义的
[cpp] view plaincopy
address AbstractInterpreterGenerator::generate_method_entry(
AbstractInterpreter::MethodKind kind) {
// determine code generation flags
bool synchronized = false;
address entry_point = NULL;
switch (kind) {
case Interpreter::zerolocals : break;
case Interpreter::zerolocals_synchronized: synchronized = true; break;
case Interpreter::native : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false); break;
case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(true); break;
case Interpreter::empty : entry_point = ((InterpreterGenerator*) this)->generate_empty_entry(); break;
case Interpreter::accessor : entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry(); break;
case Interpreter::abstract : entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry(); break;
case Interpreter::method_handle : entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry();break;
case Interpreter::java_lang_math_sin : // fall thru
case Interpreter::java_lang_math_cos : // fall thru
case Interpreter::java_lang_math_tan : // fall thru
case Interpreter::java_lang_math_abs : // fall thru
case Interpreter::java_lang_math_log : // fall thru
case Interpreter::java_lang_math_log10 : // fall thru
case Interpreter::java_lang_math_sqrt : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind); break;
default : ShouldNotReachHere(); break;
}
if (entry_point) {
return entry_point;
}
return ((InterpreterGenerator*) this)->
generate_normal_entry(synchronized);
}
我们可以看到在 native,和native_synchronized的情况下,使用了generate_native_entry
在methodoop设置了entry
在方法methodOopDesc::link_method 中,设置了_i2i_entry,和_from_interpreted_entry为entry 也是就在native的情况下设置了generate_native_entry
[cpp] view plaincopy
void set_interpreter_entry(address entry) { _i2i_entry = entry; _from_interpreted_entry = entry; }