src/share/vm/c1/c1_LIRGenerator.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/c1/c1_LIRGenerator.cpp Mon Apr 26 03:24:23 2010
--- new/src/share/vm/c1/c1_LIRGenerator.cpp Mon Apr 26 03:24:22 2010
*** 2369,2401 ****
--- 2369,2409 ----
// emit invoke code
bool optimized = x->target_is_loaded() && x->target_is_final();
assert(receiver->is_illegal() || receiver->is_equal(LIR_Assembler::receiverOpr()), "must match");
+ // JSR 292
+ // Preserve the SP over MethodHandle call sites.
+ ciMethod* target = x->target();
+ if (target->is_method_handle_invoke()) {
+ info->set_is_method_handle_invoke(true);
+ __ move(FrameMap::stack_pointer(), FrameMap::method_handle_invoke_SP_save_opr());
+ }
+
switch (x->code()) {
case Bytecodes::_invokestatic:
! __ call_static(x->target(), result_register,
SharedRuntime::get_resolve_static_call_stub(),
arg_list, info);
break;
case Bytecodes::_invokespecial:
case Bytecodes::_invokevirtual:
case Bytecodes::_invokeinterface:
// for final target we still produce an inline cache, in order
// to be able to call mixed mode
if (x->code() == Bytecodes::_invokespecial || optimized) {
! __ call_opt_virtual(x->target(), receiver, result_register,
SharedRuntime::get_resolve_opt_virtual_call_stub(),
arg_list, info);
} else if (x->vtable_index() < 0) {
! __ call_icvirtual(x->target(), receiver, result_register,
SharedRuntime::get_resolve_virtual_call_stub(),
arg_list, info);
} else {
int entry_offset = instanceKlass::vtable_start_offset() + x->vtable_index() * vtableEntry::size();
int vtable_offset = entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
! __ call_virtual(x->target(), receiver, result_register, vtable_offset, arg_list, info);
}
break;
case Bytecodes::_invokedynamic: {
ciBytecodeStream bcs(x->scope()->method());
bcs.force_bci(x->bci());
*** 2430,2449 ****
--- 2438,2463 ----
__ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
// Load target MethodHandle from CallSite object.
__ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
! __ call_dynamic(x->target(), receiver, result_register,
SharedRuntime::get_resolve_opt_virtual_call_stub(),
arg_list, info);
break;
}
default:
ShouldNotReachHere();
break;
}
+ // JSR 292
+ // Restore the SP after MethodHandle call sites.
+ if (target->is_method_handle_invoke()) {
+ __ move(FrameMap::method_handle_invoke_SP_save_opr(), FrameMap::stack_pointer());
+ }
+
if (x->type()->is_float() || x->type()->is_double()) {
// Force rounding of results from non-strictfp when in strictfp
// scope (or when we don't know the strictness of the callee, to
// be safe.)
if (method()->is_strict()) {
src/share/vm/c1/c1_LIRGenerator.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File