26 #include "c1/c1_CFGPrinter.hpp" |
26 #include "c1/c1_CFGPrinter.hpp" |
27 #include "c1/c1_Canonicalizer.hpp" |
27 #include "c1/c1_Canonicalizer.hpp" |
28 #include "c1/c1_Compilation.hpp" |
28 #include "c1/c1_Compilation.hpp" |
29 #include "c1/c1_GraphBuilder.hpp" |
29 #include "c1/c1_GraphBuilder.hpp" |
30 #include "c1/c1_InstructionPrinter.hpp" |
30 #include "c1/c1_InstructionPrinter.hpp" |
|
31 #include "ci/ciCallSite.hpp" |
31 #include "ci/ciField.hpp" |
32 #include "ci/ciField.hpp" |
32 #include "ci/ciKlass.hpp" |
33 #include "ci/ciKlass.hpp" |
|
34 #include "ci/ciMethodHandle.hpp" |
33 #include "compiler/compileBroker.hpp" |
35 #include "compiler/compileBroker.hpp" |
34 #include "interpreter/bytecode.hpp" |
36 #include "interpreter/bytecode.hpp" |
35 #include "runtime/sharedRuntime.hpp" |
37 #include "runtime/sharedRuntime.hpp" |
36 #include "runtime/compilationPolicy.hpp" |
38 #include "runtime/compilationPolicy.hpp" |
37 #include "utilities/bitMap.inline.hpp" |
39 #include "utilities/bitMap.inline.hpp" |
1422 Goto* goto_callee = new Goto(continuation(), false); |
1424 Goto* goto_callee = new Goto(continuation(), false); |
1423 |
1425 |
1424 // See whether this is the first return; if so, store off some |
1426 // See whether this is the first return; if so, store off some |
1425 // of the state for later examination |
1427 // of the state for later examination |
1426 if (num_returns() == 0) { |
1428 if (num_returns() == 0) { |
1427 set_inline_cleanup_info(_block, _last, state()); |
1429 set_inline_cleanup_info(); |
1428 } |
1430 } |
1429 |
1431 |
1430 // The current bci() is in the wrong scope, so use the bci() of |
1432 // The current bci() is in the wrong scope, so use the bci() of |
1431 // the continuation point. |
1433 // the continuation point. |
1432 append_with_bci(goto_callee, scope_data()->continuation()->bci()); |
1434 append_with_bci(goto_callee, scope_data()->continuation()->bci()); |
1691 if (!PatchALot && Inline && klass->is_loaded() && |
1695 if (!PatchALot && Inline && klass->is_loaded() && |
1692 (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) |
1696 (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) |
1693 && target->will_link(klass, callee_holder, code)) { |
1697 && target->will_link(klass, callee_holder, code)) { |
1694 // callee is known => check if we have static binding |
1698 // callee is known => check if we have static binding |
1695 assert(target->is_loaded(), "callee must be known"); |
1699 assert(target->is_loaded(), "callee must be known"); |
1696 if (code == Bytecodes::_invokestatic |
1700 if (code == Bytecodes::_invokestatic || |
1697 || code == Bytecodes::_invokespecial |
1701 code == Bytecodes::_invokespecial || |
1698 || code == Bytecodes::_invokevirtual && target->is_final_method() |
1702 code == Bytecodes::_invokevirtual && target->is_final_method() || |
1699 ) { |
1703 code == Bytecodes::_invokedynamic) { |
1700 // static binding => check if callee is ok |
1704 ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target; |
1701 ciMethod* inline_target = (cha_monomorphic_target != NULL) |
1705 bool success = false; |
1702 ? cha_monomorphic_target |
1706 if (target->is_method_handle_invoke()) { |
1703 : target; |
1707 // method handle invokes |
1704 bool res = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL)); |
1708 success = !is_invokedynamic ? for_method_handle_inline(target) : for_invokedynamic_inline(target); |
|
1709 } |
|
1710 if (!success) { |
|
1711 // static binding => check if callee is ok |
|
1712 success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL)); |
|
1713 } |
1705 CHECK_BAILOUT(); |
1714 CHECK_BAILOUT(); |
1706 |
1715 |
1707 #ifndef PRODUCT |
1716 #ifndef PRODUCT |
1708 // printing |
1717 // printing |
1709 if (PrintInlining && !res) { |
1718 if (PrintInlining && !success) { |
1710 // if it was successfully inlined, then it was already printed. |
1719 // if it was successfully inlined, then it was already printed. |
1711 print_inline_result(inline_target, res); |
1720 print_inline_result(inline_target, success); |
1712 } |
1721 } |
1713 #endif |
1722 #endif |
1714 clear_inline_bailout(); |
1723 clear_inline_bailout(); |
1715 if (res) { |
1724 if (success) { |
1716 // Register dependence if JVMTI has either breakpoint |
1725 // Register dependence if JVMTI has either breakpoint |
1717 // setting or hotswapping of methods capabilities since they may |
1726 // setting or hotswapping of methods capabilities since they may |
1718 // cause deoptimization. |
1727 // cause deoptimization. |
1719 if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) { |
1728 if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) { |
1720 dependency_recorder()->assert_evol_method(inline_target); |
1729 dependency_recorder()->assert_evol_method(inline_target); |
3036 } else if (callee->should_not_inline()) { |
3044 } else if (callee->should_not_inline()) { |
3037 // callee is excluded |
3045 // callee is excluded |
3038 INLINE_BAILOUT("disallowed by CompilerOracle") |
3046 INLINE_BAILOUT("disallowed by CompilerOracle") |
3039 } else if (!callee->can_be_compiled()) { |
3047 } else if (!callee->can_be_compiled()) { |
3040 // callee is not compilable (prob. has breakpoints) |
3048 // callee is not compilable (prob. has breakpoints) |
3041 INLINE_BAILOUT("not compilable") |
3049 INLINE_BAILOUT("not compilable (disabled)") |
3042 } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) { |
3050 } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) { |
3043 // intrinsics can be native or not |
3051 // intrinsics can be native or not |
3044 return true; |
3052 return true; |
3045 } else if (callee->is_native()) { |
3053 } else if (callee->is_native()) { |
3046 // non-intrinsic natives cannot be inlined |
3054 // non-intrinsic natives cannot be inlined |
3466 const int args_base = state()->stack_size() - callee->arg_size(); |
3474 const int args_base = state()->stack_size() - callee->arg_size(); |
3467 assert(args_base >= 0, "stack underflow during inlining"); |
3475 assert(args_base >= 0, "stack underflow during inlining"); |
3468 |
3476 |
3469 // Insert null check if necessary |
3477 // Insert null check if necessary |
3470 Value recv = NULL; |
3478 Value recv = NULL; |
3471 if (code() != Bytecodes::_invokestatic) { |
3479 if (code() != Bytecodes::_invokestatic && |
|
3480 code() != Bytecodes::_invokedynamic) { |
3472 // note: null check must happen even if first instruction of callee does |
3481 // note: null check must happen even if first instruction of callee does |
3473 // an implicit null check since the callee is in a different scope |
3482 // an implicit null check since the callee is in a different scope |
3474 // and we must make sure exception handling does the right thing |
3483 // and we must make sure exception handling does the right thing |
3475 assert(!callee->is_static(), "callee must not be static"); |
3484 assert(!callee->is_static(), "callee must not be static"); |
3476 assert(callee->arg_size() > 0, "must have at least a receiver"); |
3485 assert(callee->arg_size() > 0, "must have at least a receiver"); |
3494 // Introduce a new callee continuation point - if the callee has |
3503 // Introduce a new callee continuation point - if the callee has |
3495 // more than one return instruction or the return does not allow |
3504 // more than one return instruction or the return does not allow |
3496 // fall-through of control flow, all return instructions of the |
3505 // fall-through of control flow, all return instructions of the |
3497 // callee will need to be replaced by Goto's pointing to this |
3506 // callee will need to be replaced by Goto's pointing to this |
3498 // continuation point. |
3507 // continuation point. |
3499 BlockBegin* cont = block_at(next_bci()); |
3508 BlockBegin* cont = cont_block != NULL ? cont_block : block_at(next_bci()); |
3500 bool continuation_existed = true; |
3509 bool continuation_existed = true; |
3501 if (cont == NULL) { |
3510 if (cont == NULL) { |
3502 cont = new BlockBegin(next_bci()); |
3511 cont = new BlockBegin(next_bci()); |
3503 // low number so that continuation gets parsed as early as possible |
3512 // low number so that continuation gets parsed as early as possible |
3504 cont->set_depth_first_number(0); |
3513 cont->set_depth_first_number(0); |
3606 // off the Goto to the continuation, allowing control to fall |
3615 // off the Goto to the continuation, allowing control to fall |
3607 // through back into the caller block and effectively performing |
3616 // through back into the caller block and effectively performing |
3608 // block merging. This allows load elimination and CSE to take place |
3617 // block merging. This allows load elimination and CSE to take place |
3609 // across multiple callee scopes if they are relatively simple, and |
3618 // across multiple callee scopes if they are relatively simple, and |
3610 // is currently essential to making inlining profitable. |
3619 // is currently essential to making inlining profitable. |
3611 if ( num_returns() == 1 |
3620 if (cont_block == NULL) { |
3612 && block() == orig_block |
3621 if (num_returns() == 1 |
3613 && block() == inline_cleanup_block()) { |
3622 && block() == orig_block |
3614 _last = inline_cleanup_return_prev(); |
3623 && block() == inline_cleanup_block()) { |
3615 _state = inline_cleanup_state(); |
3624 _last = inline_cleanup_return_prev(); |
3616 } else if (continuation_preds == cont->number_of_preds()) { |
3625 _state = inline_cleanup_state(); |
3617 // Inlining caused that the instructions after the invoke in the |
3626 } else if (continuation_preds == cont->number_of_preds()) { |
3618 // caller are not reachable any more. So skip filling this block |
3627 // Inlining caused that the instructions after the invoke in the |
3619 // with instructions! |
3628 // caller are not reachable any more. So skip filling this block |
3620 assert (cont == continuation(), ""); |
3629 // with instructions! |
3621 assert(_last && _last->as_BlockEnd(), ""); |
3630 assert(cont == continuation(), ""); |
3622 _skip_block = true; |
|
3623 } else { |
|
3624 // Resume parsing in continuation block unless it was already parsed. |
|
3625 // Note that if we don't change _last here, iteration in |
|
3626 // iterate_bytecodes_for_block will stop when we return. |
|
3627 if (!continuation()->is_set(BlockBegin::was_visited_flag)) { |
|
3628 // add continuation to work list instead of parsing it immediately |
|
3629 assert(_last && _last->as_BlockEnd(), ""); |
3631 assert(_last && _last->as_BlockEnd(), ""); |
3630 scope_data()->parent()->add_to_work_list(continuation()); |
|
3631 _skip_block = true; |
3632 _skip_block = true; |
|
3633 } else { |
|
3634 // Resume parsing in continuation block unless it was already parsed. |
|
3635 // Note that if we don't change _last here, iteration in |
|
3636 // iterate_bytecodes_for_block will stop when we return. |
|
3637 if (!continuation()->is_set(BlockBegin::was_visited_flag)) { |
|
3638 // add continuation to work list instead of parsing it immediately |
|
3639 assert(_last && _last->as_BlockEnd(), ""); |
|
3640 scope_data()->parent()->add_to_work_list(continuation()); |
|
3641 _skip_block = true; |
|
3642 } |
3632 } |
3643 } |
3633 } |
3644 } |
3634 |
3645 |
3635 // Fill the exception handler for synchronized methods with instructions |
3646 // Fill the exception handler for synchronized methods with instructions |
3636 if (callee->is_synchronized() && sync_handler->state() != NULL) { |
3647 if (callee->is_synchronized() && sync_handler->state() != NULL) { |
3640 } |
3651 } |
3641 |
3652 |
3642 compilation()->notice_inlined_method(callee); |
3653 compilation()->notice_inlined_method(callee); |
3643 |
3654 |
3644 return true; |
3655 return true; |
|
3656 } |
|
3657 |
|
3658 |
|
3659 bool GraphBuilder::for_method_handle_inline(ciMethod* callee) { |
|
3660 assert(!callee->is_static(), "change next line"); |
|
3661 int index = state()->stack_size() - (callee->arg_size_no_receiver() + 1); |
|
3662 Value receiver = state()->stack_at(index); |
|
3663 |
|
3664 if (receiver->type()->is_constant()) { |
|
3665 ciMethodHandle* method_handle = receiver->type()->as_ObjectType()->constant_value()->as_method_handle(); |
|
3666 |
|
3667 // Set the callee to have access to the class and signature in |
|
3668 // the MethodHandleCompiler. |
|
3669 method_handle->set_callee(callee); |
|
3670 method_handle->set_caller(method()); |
|
3671 |
|
3672 // Get an adapter for the MethodHandle. |
|
3673 ciMethod* method_handle_adapter = method_handle->get_method_handle_adapter(); |
|
3674 if (method_handle_adapter != NULL) { |
|
3675 return try_inline(method_handle_adapter, /*holder_known=*/ true); |
|
3676 } |
|
3677 } else if (receiver->as_CheckCast()) { |
|
3678 // Match MethodHandle.selectAlternative idiom |
|
3679 Phi* phi = receiver->as_CheckCast()->obj()->as_Phi(); |
|
3680 |
|
3681 if (phi != NULL && phi->operand_count() == 2) { |
|
3682 // Get the two MethodHandle inputs from the Phi. |
|
3683 Value op1 = phi->operand_at(0); |
|
3684 Value op2 = phi->operand_at(1); |
|
3685 ciMethodHandle* mh1 = op1->type()->as_ObjectType()->constant_value()->as_method_handle(); |
|
3686 ciMethodHandle* mh2 = op2->type()->as_ObjectType()->constant_value()->as_method_handle(); |
|
3687 |
|
3688 // Set the callee to have access to the class and signature in |
|
3689 // the MethodHandleCompiler. |
|
3690 mh1->set_callee(callee); |
|
3691 mh1->set_caller(method()); |
|
3692 mh2->set_callee(callee); |
|
3693 mh2->set_caller(method()); |
|
3694 |
|
3695 // Get adapters for the MethodHandles. |
|
3696 ciMethod* mh1_adapter = mh1->get_method_handle_adapter(); |
|
3697 ciMethod* mh2_adapter = mh2->get_method_handle_adapter(); |
|
3698 |
|
3699 if (mh1_adapter != NULL && mh2_adapter != NULL) { |
|
3700 set_inline_cleanup_info(); |
|
3701 |
|
3702 // Build the If guard |
|
3703 BlockBegin* one = new BlockBegin(next_bci()); |
|
3704 BlockBegin* two = new BlockBegin(next_bci()); |
|
3705 BlockBegin* end = new BlockBegin(next_bci()); |
|
3706 Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false)); |
|
3707 block()->set_end(iff->as_BlockEnd()); |
|
3708 |
|
3709 // Connect up the states |
|
3710 one->merge(block()->end()->state()); |
|
3711 two->merge(block()->end()->state()); |
|
3712 |
|
3713 // Save the state for the second inlinee |
|
3714 ValueStack* state_before = copy_state_before(); |
|
3715 |
|
3716 // Parse first adapter |
|
3717 _last = _block = one; |
|
3718 if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end)) { |
|
3719 restore_inline_cleanup_info(); |
|
3720 block()->clear_end(); // remove appended iff |
|
3721 return false; |
|
3722 } |
|
3723 |
|
3724 // Parse second adapter |
|
3725 _last = _block = two; |
|
3726 _state = state_before; |
|
3727 if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end)) { |
|
3728 restore_inline_cleanup_info(); |
|
3729 block()->clear_end(); // remove appended iff |
|
3730 return false; |
|
3731 } |
|
3732 |
|
3733 connect_to_end(end); |
|
3734 return true; |
|
3735 } |
|
3736 } |
|
3737 } |
|
3738 return false; |
|
3739 } |
|
3740 |
|
3741 |
|
3742 bool GraphBuilder::for_invokedynamic_inline(ciMethod* callee) { |
|
3743 // Get the MethodHandle from the CallSite. |
|
3744 ciCallSite* call_site = stream()->get_call_site(); |
|
3745 ciMethodHandle* method_handle = call_site->get_target(); |
|
3746 |
|
3747 // Inline constant and mutable call sites. We don't inline |
|
3748 // volatile call sites optimistically since they are specified |
|
3749 // to change their value often and that would result in a lot of |
|
3750 // deoptimizations and recompiles. |
|
3751 if (call_site->is_constant_call_site() || call_site->is_mutable_call_site()) { |
|
3752 // Set the callee to have access to the class and signature in the |
|
3753 // MethodHandleCompiler. |
|
3754 method_handle->set_callee(callee); |
|
3755 method_handle->set_caller(method()); |
|
3756 |
|
3757 // Get an adapter for the MethodHandle. |
|
3758 ciMethod* method_handle_adapter = method_handle->get_invokedynamic_adapter(); |
|
3759 if (method_handle_adapter != NULL) { |
|
3760 if (try_inline(method_handle_adapter, /*holder_known=*/ true)) { |
|
3761 // Add a dependence for invalidation of the optimization. |
|
3762 if (!call_site->is_constant_call_site()) { |
|
3763 dependency_recorder()->assert_call_site_target_value(call_site, method_handle); |
|
3764 } |
|
3765 return true; |
|
3766 } |
|
3767 } |
|
3768 } |
|
3769 return false; |
3645 } |
3770 } |
3646 |
3771 |
3647 |
3772 |
3648 void GraphBuilder::inline_bailout(const char* msg) { |
3773 void GraphBuilder::inline_bailout(const char* msg) { |
3649 assert(msg != NULL, "inline bailout msg must exist"); |
3774 assert(msg != NULL, "inline bailout msg must exist"); |