Question on HotSpot JIT and invokeinterface
Pekka Enberg
penberg at cs.helsinki.fi
Tue Feb 24 23:58:40 PST 2009
Hi all,
I have a question regarding HotSpot JIT and invokeinterface.
There's a nice description of how HotSpot implements JIT'ed invokeinterface
at HotSpot Internals wiki:
http://wikis.sun.com/display/HotSpotInternals/InterfaceCalls
Unfortunately there are no pointers to the actual code. I recently started
looking at how the interface resolution stubs are generated and spent quite
a lot of time figuring out what was going on!
I think I got it mostly right but thought I thought I'd get a second
opinion. Maybe this is something that could be added to the wiki as well?
---
[Assuming 32-bit x86 here.]
I think it's the VtableStubs::create_itable_stub() function in
src/cpu/x86/vm/vtableStubs_x86_32.cpp. Tracing trough the the callers in
reverse order, we have:
VtableStubs::create_itable_stub()
VtableStubs::create_stub()
CompiledIC::set_to_megamorphic()
SharedRuntime::handle_ic_miss_helper()
SharedRuntime::handle_wrong_method_ic_miss()
and in src/cpu/x86/vm/sharedRuntime_x86_32.cpp we have
SharedRuntime::generate_stubs()
that generates a resolve blob that points to
SharedRuntime::handle_wrong_method_ic_miss():
_ic_miss_blob = generate_resolve_blob(
CAST_FROM_FN_PTR(
address, SharedRuntime::handle_wrong_method_ic_miss), "ic_miss_stub");
Now the IC miss stub is called if we can't find a method in the inline cache.
The instruction sequence of _ic_miss_blob is returned by:
static address SharedRuntime::get_ic_miss_stub() {
assert(_ic_miss_blob!= NULL, "oops");
return _ic_miss_blob->instructions_begin();
}
Looking at a reverse call-graph:
SharedRuntime::get_ic_miss_stub()
SharedRuntime::generate_i2c2i_adapters()
AdapterHandlerLibrary::get_create_adapter_index()
AdapterHandlerLibrary::get_adapter()
methodOopDesc::make_adapters()
we can see how a method oop adapter has a pointer to the IC miss stub. To
complete the explanation, lets look at how HotSpot loads a Java class and jumps
into the main() method:
src/os/linux/launcher/java.c::main()
src/os/linux/launcher/java.c::CallStaticVoidMethod()
src/share/vm/prims/jni.cpp::jni_invoke_static()
src/share/vm/runtime/javaCalls.cpp::JavaCalls::call()
src/share/vm/runtime/javaCalls.cpp::JavaCalls::call_helper()
Now JavaCalls::call_helper() does:
src/share/vm/runtime/stubRoutines.hpp::StubRoutines::call_stub()
which returns a function pointer to a stub and calls that. The call stub in
turn delegates to is something called the entry point which is
obtained in JavaCalls::call_helper() as follows:
address entry_point = method->from_interpreted_entry();
Now when a method is compiled into native code, the
src/share/vm/ci/ciEnv.cpp:ciEnv::register_method()
function calls
src/share/vm/oops/methodOop.cpp::methodOopDesc::set_code()
which sets up _from_interpreted_entry like this:
mh->_from_interpreted_entry = mh->get_i2c_entry();
where get_i2_c_entry() looks like this:
address methodOopDesc::get_i2c_entry() {
assert(_adapter != NULL, "must have");
return _adapter->get_i2c_entry();
}
The _adapter of type class AdapterHandlerEntry which are created in
src/cpu/x86/vm/sharedRuntime_x86_32.cpp::SharedRuntime::generate_i2c2i_adapters()
which we know already to jump to a stub returned by
SharedRuntime::get_ic_miss_stub() if a method cannot be found in the
inline cache.
---
That's it! Comments and corrections are most appreciated!
Regards,
Pekka
More information about the hotspot-dev
mailing list