Mercurial > hg > graal-jvmci-8
comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 6646:c38f13903fdf
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ just before the NPG (no perm gen) changeset
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 29 Oct 2012 21:10:04 +0100 |
parents | 7f813940ac35 |
children | da91efe96a93 |
comparison
equal
deleted
inserted
replaced
6590:dc5eec61daba | 6646:c38f13903fdf |
---|---|
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 has_receiver = | |
1650 code == Bytecodes::_invokespecial || | |
1651 code == Bytecodes::_invokevirtual || | |
1652 code == Bytecodes::_invokeinterface; | |
1653 const bool is_invokedynamic = (code == Bytecodes::_invokedynamic); | |
1654 | |
1655 bool will_link; | 1649 bool will_link; |
1656 ciMethod* target = stream()->get_method(will_link); | 1650 ciSignature* declared_signature = NULL; |
1651 ciMethod* target = stream()->get_method(will_link, &declared_signature); | |
1657 ciKlass* holder = stream()->get_declared_method_holder(); | 1652 ciKlass* holder = stream()->get_declared_method_holder(); |
1658 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"); | |
1659 | 1655 |
1660 // FIXME bail out for now | 1656 // FIXME bail out for now |
1661 if ((bc_raw == Bytecodes::_invokehandle || is_invokedynamic) && !will_link) { | 1657 if (Bytecodes::has_optional_appendix(bc_raw) && !will_link) { |
1662 BAILOUT("unlinked call site (FIXME needs patching or recompile support)"); | 1658 BAILOUT("unlinked call site (FIXME needs patching or recompile support)"); |
1663 } | 1659 } |
1664 | 1660 |
1665 // we have to make sure the argument size (incl. the receiver) | 1661 // we have to make sure the argument size (incl. the receiver) |
1666 // is correct for compilation (the call would fail later during | 1662 // is correct for compilation (the call would fail later during |
1688 | 1684 |
1689 // Some methods are obviously bindable without any type checks so | 1685 // Some methods are obviously bindable without any type checks so |
1690 // convert them directly to an invokespecial or invokestatic. | 1686 // convert them directly to an invokespecial or invokestatic. |
1691 if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) { | 1687 if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) { |
1692 switch (bc_raw) { | 1688 switch (bc_raw) { |
1693 case Bytecodes::_invokevirtual: code = Bytecodes::_invokespecial; break; | 1689 case Bytecodes::_invokevirtual: |
1694 case Bytecodes::_invokehandle: code = Bytecodes::_invokestatic; break; | 1690 code = Bytecodes::_invokespecial; |
1691 break; | |
1692 case Bytecodes::_invokehandle: | |
1693 code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial; | |
1694 break; | |
1695 } | 1695 } |
1696 } | 1696 } |
1697 | 1697 |
1698 // Push appendix argument (MethodType, CallSite, etc.), if one. | 1698 // Push appendix argument (MethodType, CallSite, etc.), if one. |
1699 if (stream()->has_appendix()) { | 1699 if (stream()->has_appendix()) { |
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 | 1881 ValueStack* state_before = copy_state_exhandling(); |
1882 // We require the debug info to be the "state before" because | 1882 |
1883 // invokedynamics may deoptimize. | 1883 // The bytecode (code) might change in this method so we are checking this very late. |
1884 ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling(); | 1884 const bool has_receiver = |
1885 | 1885 code == Bytecodes::_invokespecial || |
1886 code == Bytecodes::_invokevirtual || | |
1887 code == Bytecodes::_invokeinterface; | |
1886 Values* args = state()->pop_arguments(target->arg_size_no_receiver()); | 1888 Values* args = state()->pop_arguments(target->arg_size_no_receiver()); |
1887 Value recv = has_receiver ? apop() : NULL; | 1889 Value recv = has_receiver ? apop() : NULL; |
1888 int vtable_index = methodOopDesc::invalid_vtable_index; | 1890 int vtable_index = methodOopDesc::invalid_vtable_index; |
1889 | 1891 |
1890 #ifdef SPARC | 1892 #ifdef SPARC |
3056 break; | 3058 break; |
3057 } | 3059 } |
3058 | 3060 |
3059 case vmIntrinsics::_Reference_get: | 3061 case vmIntrinsics::_Reference_get: |
3060 { | 3062 { |
3061 if (UseG1GC) { | 3063 { |
3062 // With java.lang.ref.reference.get() we must go through the | 3064 // With java.lang.ref.reference.get() we must go through the |
3063 // intrinsic - when G1 is enabled - even when get() is the root | 3065 // intrinsic - when G1 is enabled - even when get() is the root |
3064 // method of the compile so that, if necessary, the value in | 3066 // method of the compile so that, if necessary, the value in |
3065 // the referent field of the reference object gets recorded by | 3067 // the referent field of the reference object gets recorded by |
3066 // the pre-barrier code. | 3068 // the pre-barrier code. |
3068 // field is recorded by the G1 SATB pre barrier. This will | 3070 // field is recorded by the G1 SATB pre barrier. This will |
3069 // result in the referent being marked live and the reference | 3071 // result in the referent being marked live and the reference |
3070 // object removed from the list of discovered references during | 3072 // object removed from the list of discovered references during |
3071 // reference processing. | 3073 // reference processing. |
3072 | 3074 |
3075 // Also we need intrinsic to prevent commoning reads from this field | |
3076 // across safepoint since GC can change its value. | |
3077 | |
3073 // Set up a stream so that appending instructions works properly. | 3078 // Set up a stream so that appending instructions works properly. |
3074 ciBytecodeStream s(scope->method()); | 3079 ciBytecodeStream s(scope->method()); |
3075 s.reset_to_bci(0); | 3080 s.reset_to_bci(0); |
3076 scope_data()->set_stream(&s); | 3081 scope_data()->set_stream(&s); |
3077 s.next(); | 3082 s.next(); |
3224 return NULL; | 3229 return NULL; |
3225 } | 3230 } |
3226 | 3231 |
3227 | 3232 |
3228 bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { | 3233 bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { |
3229 if (!InlineNatives ) INLINE_BAILOUT("intrinsic method inlining disabled"); | |
3230 if (callee->is_synchronized()) { | 3234 if (callee->is_synchronized()) { |
3231 // We don't currently support any synchronized intrinsics | 3235 // We don't currently support any synchronized intrinsics |
3232 return false; | 3236 return false; |
3233 } | 3237 } |
3234 | 3238 |
3235 // callee seems like a good candidate | 3239 // callee seems like a good candidate |
3236 // determine id | 3240 // determine id |
3241 vmIntrinsics::ID id = callee->intrinsic_id(); | |
3242 if (!InlineNatives && id != vmIntrinsics::_Reference_get) { | |
3243 // InlineNatives does not control Reference.get | |
3244 INLINE_BAILOUT("intrinsic method inlining disabled"); | |
3245 } | |
3237 bool preserves_state = false; | 3246 bool preserves_state = false; |
3238 bool cantrap = true; | 3247 bool cantrap = true; |
3239 vmIntrinsics::ID id = callee->intrinsic_id(); | |
3240 switch (id) { | 3248 switch (id) { |
3241 case vmIntrinsics::_arraycopy: | 3249 case vmIntrinsics::_arraycopy: |
3242 if (!InlineArrayCopy) return false; | 3250 if (!InlineArrayCopy) return false; |
3243 break; | 3251 break; |
3244 | 3252 |
3374 case vmIntrinsics::_compareAndSwapObject: | 3382 case vmIntrinsics::_compareAndSwapObject: |
3375 append_unsafe_CAS(callee); | 3383 append_unsafe_CAS(callee); |
3376 return true; | 3384 return true; |
3377 | 3385 |
3378 case vmIntrinsics::_Reference_get: | 3386 case vmIntrinsics::_Reference_get: |
3379 // It is only when G1 is enabled that we absolutely | 3387 // Use the intrinsic version of Reference.get() so that the value in |
3380 // need to use the intrinsic version of Reference.get() | 3388 // the referent field can be registered by the G1 pre-barrier code. |
3381 // so that the value in the referent field, if necessary, | 3389 // Also to prevent commoning reads from this field across safepoint |
3382 // can be registered by the pre-barrier code. | 3390 // since GC can change its value. |
3383 if (!UseG1GC) return false; | |
3384 preserves_state = true; | 3391 preserves_state = true; |
3385 break; | 3392 break; |
3386 | 3393 |
3387 default : return false; // do not inline | 3394 default : return false; // do not inline |
3388 } | 3395 } |
3814 | 3821 |
3815 return true; | 3822 return true; |
3816 } | 3823 } |
3817 | 3824 |
3818 | 3825 |
3819 bool GraphBuilder::for_method_handle_inline(ciMethod* callee) { | 3826 bool GraphBuilder::try_method_handle_inline(ciMethod* callee) { |
3820 ValueStack* state_before = state()->copy_for_parsing(); | 3827 ValueStack* state_before = state()->copy_for_parsing(); |
3821 vmIntrinsics::ID iid = callee->intrinsic_id(); | 3828 vmIntrinsics::ID iid = callee->intrinsic_id(); |
3822 switch (iid) { | 3829 switch (iid) { |
3823 case vmIntrinsics::_invokeBasic: | 3830 case vmIntrinsics::_invokeBasic: |
3824 { | 3831 { |
3849 if (type->is_constant()) { | 3856 if (type->is_constant()) { |
3850 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(); |
3851 // 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 |
3852 // a better target. | 3859 // a better target. |
3853 if (target->is_method_handle_intrinsic()) { | 3860 if (target->is_method_handle_intrinsic()) { |
3854 if (for_method_handle_inline(target)) { | 3861 if (try_method_handle_inline(target)) { |
3855 return true; | 3862 return true; |
3856 } | 3863 } |
3857 } else { | 3864 } else { |
3858 ciSignature* signature = target->signature(); | 3865 ciSignature* signature = target->signature(); |
3859 const int receiver_skip = target->is_static() ? 0 : 1; | 3866 const int receiver_skip = target->is_static() ? 0 : 1; |