comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 6634:7f813940ac35

7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites Reviewed-by: kvn
author twisti
date Tue, 28 Aug 2012 15:24:39 -0700
parents 7a302948f5a4
children da91efe96a93
comparison
equal deleted inserted replaced
6633:a5dd6e3ef9f3 6634:7f813940ac35
1644 return compilation()->dependency_recorder(); 1644 return compilation()->dependency_recorder();
1645 } 1645 }
1646 1646
1647 1647
1648 void GraphBuilder::invoke(Bytecodes::Code code) { 1648 void GraphBuilder::invoke(Bytecodes::Code code) {
1649 const bool is_invokedynamic = (code == Bytecodes::_invokedynamic);
1650
1651 bool will_link; 1649 bool will_link;
1652 ciMethod* target = stream()->get_method(will_link); 1650 ciSignature* declared_signature = NULL;
1651 ciMethod* target = stream()->get_method(will_link, &declared_signature);
1653 ciKlass* holder = stream()->get_declared_method_holder(); 1652 ciKlass* holder = stream()->get_declared_method_holder();
1654 const Bytecodes::Code bc_raw = stream()->cur_bc_raw(); 1653 const Bytecodes::Code bc_raw = stream()->cur_bc_raw();
1654 assert(declared_signature != NULL, "cannot be null");
1655 1655
1656 // FIXME bail out for now 1656 // FIXME bail out for now
1657 if ((bc_raw == Bytecodes::_invokehandle || is_invokedynamic) && !will_link) { 1657 if (Bytecodes::has_optional_appendix(bc_raw) && !will_link) {
1658 BAILOUT("unlinked call site (FIXME needs patching or recompile support)"); 1658 BAILOUT("unlinked call site (FIXME needs patching or recompile support)");
1659 } 1659 }
1660 1660
1661 // we have to make sure the argument size (incl. the receiver) 1661 // we have to make sure the argument size (incl. the receiver)
1662 // is correct for compilation (the call would fail later during 1662 // is correct for compilation (the call would fail later during
1838 code == Bytecodes::_invokedynamic) { 1838 code == Bytecodes::_invokedynamic) {
1839 ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target; 1839 ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
1840 bool success = false; 1840 bool success = false;
1841 if (target->is_method_handle_intrinsic()) { 1841 if (target->is_method_handle_intrinsic()) {
1842 // method handle invokes 1842 // method handle invokes
1843 success = for_method_handle_inline(target); 1843 success = try_method_handle_inline(target);
1844 } else { 1844 } else {
1845 // static binding => check if callee is ok 1845 // static binding => check if callee is ok
1846 success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver); 1846 success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
1847 } 1847 }
1848 CHECK_BAILOUT(); 1848 CHECK_BAILOUT();
1875 // stack at a ret in these situations.) 1875 // stack at a ret in these situations.)
1876 CHECK_BAILOUT(); 1876 CHECK_BAILOUT();
1877 1877
1878 // inlining not successful => standard invoke 1878 // inlining not successful => standard invoke
1879 bool is_loaded = target->is_loaded(); 1879 bool is_loaded = target->is_loaded();
1880 ValueType* result_type = as_ValueType(target->return_type()); 1880 ValueType* result_type = as_ValueType(declared_signature->return_type());
1881 ValueStack* state_before = copy_state_exhandling(); 1881 ValueStack* state_before = copy_state_exhandling();
1882 1882
1883 // The bytecode (code) might change in this method so we are checking this very late. 1883 // The bytecode (code) might change in this method so we are checking this very late.
1884 const bool has_receiver = 1884 const bool has_receiver =
1885 code == Bytecodes::_invokespecial || 1885 code == Bytecodes::_invokespecial ||
3821 3821
3822 return true; 3822 return true;
3823 } 3823 }
3824 3824
3825 3825
3826 bool GraphBuilder::for_method_handle_inline(ciMethod* callee) { 3826 bool GraphBuilder::try_method_handle_inline(ciMethod* callee) {
3827 ValueStack* state_before = state()->copy_for_parsing(); 3827 ValueStack* state_before = state()->copy_for_parsing();
3828 vmIntrinsics::ID iid = callee->intrinsic_id(); 3828 vmIntrinsics::ID iid = callee->intrinsic_id();
3829 switch (iid) { 3829 switch (iid) {
3830 case vmIntrinsics::_invokeBasic: 3830 case vmIntrinsics::_invokeBasic:
3831 { 3831 {
3856 if (type->is_constant()) { 3856 if (type->is_constant()) {
3857 ciMethod* target = type->as_ObjectType()->constant_value()->as_member_name()->get_vmtarget(); 3857 ciMethod* target = type->as_ObjectType()->constant_value()->as_member_name()->get_vmtarget();
3858 // If the target is another method handle invoke try recursivly to get 3858 // If the target is another method handle invoke try recursivly to get
3859 // a better target. 3859 // a better target.
3860 if (target->is_method_handle_intrinsic()) { 3860 if (target->is_method_handle_intrinsic()) {
3861 if (for_method_handle_inline(target)) { 3861 if (try_method_handle_inline(target)) {
3862 return true; 3862 return true;
3863 } 3863 }
3864 } else { 3864 } else {
3865 ciSignature* signature = target->signature(); 3865 ciSignature* signature = target->signature();
3866 const int receiver_skip = target->is_static() ? 0 : 1; 3866 const int receiver_skip = target->is_static() ? 0 : 1;