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