src/share/vm/c1/c1_GraphBuilder.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/c1/c1_GraphBuilder.cpp

src/share/vm/c1/c1_GraphBuilder.cpp

Print this page
rev 5100 : 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
Summary: Do patching rather bailing out for unlinked call with appendix
Reviewed-by: twisti, kvn

*** 1665,1677 **** ciMethod* target = stream()->get_method(will_link, &declared_signature); ciKlass* holder = stream()->get_declared_method_holder(); const Bytecodes::Code bc_raw = stream()->cur_bc_raw(); assert(declared_signature != NULL, "cannot be null"); ! // FIXME bail out for now ! if (Bytecodes::has_optional_appendix(bc_raw) && !will_link) { ! BAILOUT("unlinked call site (FIXME needs patching or recompile support)"); } // we have to make sure the argument size (incl. the receiver) // is correct for compilation (the call would fail later during // linkage anyway) - was bug (gri 7/28/99) --- 1665,1676 ---- ciMethod* target = stream()->get_method(will_link, &declared_signature); ciKlass* holder = stream()->get_declared_method_holder(); const Bytecodes::Code bc_raw = stream()->cur_bc_raw(); assert(declared_signature != NULL, "cannot be null"); ! if (!C1PatchInvokeDynamic && Bytecodes::has_optional_appendix(bc_raw) && !will_link) { ! BAILOUT("unlinked call site (C1PatchInvokeDynamic is off)"); } // we have to make sure the argument size (incl. the receiver) // is correct for compilation (the call would fail later during // linkage anyway) - was bug (gri 7/28/99)
*** 1711,1724 **** break; case Bytecodes::_invokehandle: code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial; break; } } // Push appendix argument (MethodType, CallSite, etc.), if one. ! if (stream()->has_appendix()) { ciObject* appendix = stream()->get_appendix(); Value arg = append(new Constant(new ObjectConstant(appendix))); apush(arg); } --- 1710,1736 ---- break; case Bytecodes::_invokehandle: code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial; break; } + } else { + if (bc_raw == Bytecodes::_invokehandle) { + assert(!will_link, "should come here only for unlinked call"); + code = Bytecodes::_invokespecial; + } } // Push appendix argument (MethodType, CallSite, etc.), if one. ! bool patch_for_appendix = false; ! int patching_appendix_arg = 0; ! if (C1PatchInvokeDynamic && ! (Bytecodes::has_optional_appendix(bc_raw) && (!will_link || PatchALot))) { ! Value arg = append(new Constant(new ObjectConstant(compilation()->env()->unloaded_ciinstance()), copy_state_before())); ! apush(arg); ! patch_for_appendix = true; ! patching_appendix_arg = (will_link && stream()->has_appendix()) ? 0 : 1; ! } else if (stream()->has_appendix()) { ciObject* appendix = stream()->get_appendix(); Value arg = append(new Constant(new ObjectConstant(appendix))); apush(arg); }
*** 1730,1740 **** ciMethod* exact_target = NULL; Value better_receiver = NULL; if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() && !(// %%% FIXME: Are both of these relevant? target->is_method_handle_intrinsic() || ! target->is_compiled_lambda_form())) { Value receiver = NULL; ciInstanceKlass* receiver_klass = NULL; bool type_is_exact = false; // try to find a precise receiver type if (will_link && !target->is_static()) { --- 1742,1753 ---- ciMethod* exact_target = NULL; Value better_receiver = NULL; if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() && !(// %%% FIXME: Are both of these relevant? target->is_method_handle_intrinsic() || ! target->is_compiled_lambda_form()) && ! !patch_for_appendix) { Value receiver = NULL; ciInstanceKlass* receiver_klass = NULL; bool type_is_exact = false; // try to find a precise receiver type if (will_link && !target->is_static()) {
*** 1848,1858 **** } // check if we could do inlining if (!PatchALot && Inline && klass->is_loaded() && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) ! && target->is_loaded()) { // callee is known => check if we have static binding assert(target->is_loaded(), "callee must be known"); if (code == Bytecodes::_invokestatic || code == Bytecodes::_invokespecial || code == Bytecodes::_invokevirtual && target->is_final_method() || --- 1861,1872 ---- } // check if we could do inlining if (!PatchALot && Inline && klass->is_loaded() && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) ! && target->is_loaded() ! && !patch_for_appendix) { // callee is known => check if we have static binding assert(target->is_loaded(), "callee must be known"); if (code == Bytecodes::_invokestatic || code == Bytecodes::_invokespecial || code == Bytecodes::_invokevirtual && target->is_final_method() ||
*** 1899,1909 **** // The bytecode (code) might change in this method so we are checking this very late. const bool has_receiver = code == Bytecodes::_invokespecial || code == Bytecodes::_invokevirtual || code == Bytecodes::_invokeinterface; ! Values* args = state()->pop_arguments(target->arg_size_no_receiver()); Value recv = has_receiver ? apop() : NULL; int vtable_index = Method::invalid_vtable_index; #ifdef SPARC // Currently only supported on Sparc. --- 1913,1923 ---- // The bytecode (code) might change in this method so we are checking this very late. const bool has_receiver = code == Bytecodes::_invokespecial || code == Bytecodes::_invokevirtual || code == Bytecodes::_invokeinterface; ! Values* args = state()->pop_arguments(target->arg_size_no_receiver() + patching_appendix_arg); Value recv = has_receiver ? apop() : NULL; int vtable_index = Method::invalid_vtable_index; #ifdef SPARC // Currently only supported on Sparc.
src/share/vm/c1/c1_GraphBuilder.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File