EVALUATION
The distance for call instruction (call to dtrace_method_entry) in compiled native wraper > 32 bits
since libjvm.so is loaded far from code cache where native wraper is placed:
0xfffffffb84500000 jdk/6_14/ea/b02/binaries/solaris-sparcv9/fastdebug/jre/lib/sparcv9/server/libjvm.so
Call arguments:
[7] Assembler::wdisp(0xfffffffbec8085bc, 0x0, 0x1e, 0x108, 0x528, 0x54), at 0xfffffffb6541e74c
[8] NativeInstruction::set_wdisp(0x7fda9b4f, 0xfffffffbec8085bc, 0x1e, 0xffffffff7dafe218, 0xffffffff7dafeb78, 0x20), at 0xfffffffb65bcf0a8
[9] NativeCall::set_destination(0xffffffff79512d24, 0xfffffffb65d1b2e0, 0xffffffffffffffff, 0x5, 0x0, 0xffffffff7951301d), at 0xfffffffb65bcebf8
[10] Relocation::pd_set_call_destination(0xffffffff7dafdb58, 0xfffffffb65d1b2e0, 0xffffffff7dafeb78, 0xffffffff7dafdc80, 0x100139268, 0x100139268), at 0xfffffffb65cf6e58
void set_destination(address dest) { set_long_at(0, set_wdisp(long_at(0), dest - instruction_address(), call_displacement_width)); }
instruction_address() = 0xffffffff79512d24
dest = 0xfffffffb65d1b2e0
long_at(0) = 0x7fda9b4f
dest - instruction_address() = 0xfffffffbec8085bc ( -0x4137f7a44 ) does not fit into 32 bits.
call_displacement_width = 0x1e (30)
[t@2 l@2]: x 0xfffffffb65d1b2e0
0xfffffffb65d1b2e0: dtrace_method_entry : 0x9de3bed0
The NativeFarCall should be used instead of NativeCall.
This is the code in SharedRuntime::generate_native_wrapper() which generates the call:
__ call_VM_leaf(L7_thread_cache,
CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
G2_thread, O1);
The code in MacroAssembler::call() generates call() instead of jumpl_to()
because the wrapper is generated, first, in AdapterHandlerLibrary::_buffer which is
at the same address space as libjvm.so:
[t@1 l@1]: x 0xfffffffb634745a4
0xfffffffb634745a4: __1cVAdapterHandlerLibraryH_buffer_+0x00fc: 0xca70a218
__1cVAdapterHandlerLibraryH_buffer_ == AdapterHandlerLibrary::_buffer
|