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