comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 6892:fd1d564dd460

8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920) Reviewed-by: kvn
author twisti
date Mon, 22 Oct 2012 16:56:03 -0700
parents c3e799c37717
children bb33c6fdcf0d
comparison
equal deleted inserted replaced
6891:67f4c477c9ab 6892:fd1d564dd460
1842 if (code == Bytecodes::_invokestatic || 1842 if (code == Bytecodes::_invokestatic ||
1843 code == Bytecodes::_invokespecial || 1843 code == Bytecodes::_invokespecial ||
1844 code == Bytecodes::_invokevirtual && target->is_final_method() || 1844 code == Bytecodes::_invokevirtual && target->is_final_method() ||
1845 code == Bytecodes::_invokedynamic) { 1845 code == Bytecodes::_invokedynamic) {
1846 ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target; 1846 ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
1847 bool success = false; 1847 // static binding => check if callee is ok
1848 if (target->is_method_handle_intrinsic()) { 1848 bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
1849 // method handle invokes 1849
1850 success = try_method_handle_inline(target);
1851 } else {
1852 // static binding => check if callee is ok
1853 success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
1854 }
1855 CHECK_BAILOUT(); 1850 CHECK_BAILOUT();
1856
1857 clear_inline_bailout(); 1851 clear_inline_bailout();
1852
1858 if (success) { 1853 if (success) {
1859 // Register dependence if JVMTI has either breakpoint 1854 // Register dependence if JVMTI has either breakpoint
1860 // setting or hotswapping of methods capabilities since they may 1855 // setting or hotswapping of methods capabilities since they may
1861 // cause deoptimization. 1856 // cause deoptimization.
1862 if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) { 1857 if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
3199 if (msg != NULL) { 3194 if (msg != NULL) {
3200 print_inlining(callee, msg, /*success*/ false); 3195 print_inlining(callee, msg, /*success*/ false);
3201 return false; 3196 return false;
3202 } 3197 }
3203 3198
3199 // method handle invokes
3200 if (callee->is_method_handle_intrinsic()) {
3201 return try_method_handle_inline(callee);
3202 }
3203
3204 // handle intrinsics 3204 // handle intrinsics
3205 if (callee->intrinsic_id() != vmIntrinsics::_none) { 3205 if (callee->intrinsic_id() != vmIntrinsics::_none) {
3206 if (try_inline_intrinsics(callee)) { 3206 if (try_inline_intrinsics(callee)) {
3207 print_inlining(callee, "intrinsic"); 3207 print_inlining(callee, "intrinsic");
3208 return true; 3208 return true;
3883 // get MethodHandle receiver 3883 // get MethodHandle receiver
3884 const int args_base = state()->stack_size() - callee->arg_size(); 3884 const int args_base = state()->stack_size() - callee->arg_size();
3885 ValueType* type = state()->stack_at(args_base)->type(); 3885 ValueType* type = state()->stack_at(args_base)->type();
3886 if (type->is_constant()) { 3886 if (type->is_constant()) {
3887 ciMethod* target = type->as_ObjectType()->constant_value()->as_method_handle()->get_vmtarget(); 3887 ciMethod* target = type->as_ObjectType()->constant_value()->as_method_handle()->get_vmtarget();
3888 guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove 3888 // We don't do CHA here so only inline static and statically bindable methods.
3889 Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual; 3889 if (target->is_static() || target->can_be_statically_bound()) {
3890 if (try_inline(target, /*holder_known*/ true, bc)) { 3890 Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
3891 return true; 3891 if (try_inline(target, /*holder_known*/ true, bc)) {
3892 return true;
3893 }
3894 } else {
3895 print_inlining(target, "not static or statically bindable", /*success*/ false);
3892 } 3896 }
3893 } else { 3897 } else {
3894 print_inlining(callee, "receiver not constant", /*success*/ false); 3898 print_inlining(callee, "receiver not constant", /*success*/ false);
3895 } 3899 }
3896 } 3900 }
3939 state()->stack_at_put(args_base + receiver_skip + j, c); 3943 state()->stack_at_put(args_base + receiver_skip + j, c);
3940 } 3944 }
3941 } 3945 }
3942 j += t->size(); // long and double take two slots 3946 j += t->size(); // long and double take two slots
3943 } 3947 }
3944 Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual; 3948 // We don't do CHA here so only inline static and statically bindable methods.
3945 if (try_inline(target, /*holder_known*/ true, bc)) { 3949 if (target->is_static() || target->can_be_statically_bound()) {
3946 return true; 3950 Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
3951 if (try_inline(target, /*holder_known*/ true, bc)) {
3952 return true;
3953 }
3954 } else {
3955 print_inlining(target, "not static or statically bindable", /*success*/ false);
3947 } 3956 }
3948 } 3957 }
3949 } else { 3958 } else {
3950 print_inlining(callee, "MemberName not constant", /*success*/ false); 3959 print_inlining(callee, "MemberName not constant", /*success*/ false);
3951 } 3960 }