comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 3900:a32de5085326

7079673: JSR 292: C1 should inline bytecoded method handle adapters Reviewed-by: never
author twisti
date Thu, 01 Sep 2011 01:31:25 -0700
parents de847cac9235
children aa67216400d3
comparison
equal deleted inserted replaced
3899:c124e2e7463e 3900:a32de5085326
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());
1579 // convert them directly to an invokespecial. 1581 // convert them directly to an invokespecial.
1580 if (target->is_loaded() && !target->is_abstract() && 1582 if (target->is_loaded() && !target->is_abstract() &&
1581 target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) { 1583 target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
1582 code = Bytecodes::_invokespecial; 1584 code = Bytecodes::_invokespecial;
1583 } 1585 }
1586
1587 bool is_invokedynamic = code == Bytecodes::_invokedynamic;
1584 1588
1585 // NEEDS_CLEANUP 1589 // NEEDS_CLEANUP
1586 // I've added the target-is_loaded() test below but I don't really understand 1590 // I've added the target-is_loaded() test below but I don't really understand
1587 // how klass->is_loaded() can be true and yet target->is_loaded() is false. 1591 // how klass->is_loaded() can be true and yet target->is_loaded() is false.
1588 // this happened while running the JCK invokevirtual tests under doit. TKR 1592 // this happened while running the JCK invokevirtual tests under doit. TKR
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);
1738 bool is_loaded = target->is_loaded(); 1747 bool is_loaded = target->is_loaded();
1739 bool has_receiver = 1748 bool has_receiver =
1740 code == Bytecodes::_invokespecial || 1749 code == Bytecodes::_invokespecial ||
1741 code == Bytecodes::_invokevirtual || 1750 code == Bytecodes::_invokevirtual ||
1742 code == Bytecodes::_invokeinterface; 1751 code == Bytecodes::_invokeinterface;
1743 bool is_invokedynamic = code == Bytecodes::_invokedynamic;
1744 ValueType* result_type = as_ValueType(target->return_type()); 1752 ValueType* result_type = as_ValueType(target->return_type());
1745 1753
1746 // We require the debug info to be the "state before" because 1754 // We require the debug info to be the "state before" because
1747 // invokedynamics may deoptimize. 1755 // invokedynamics may deoptimize.
1748 ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling(); 1756 ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling();
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
3395 _state = orig_state; 3403 _state = orig_state;
3396 _last = orig_last; 3404 _last = orig_last;
3397 } 3405 }
3398 3406
3399 3407
3400 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) { 3408 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, BlockBegin* cont_block) {
3401 assert(!callee->is_native(), "callee must not be native"); 3409 assert(!callee->is_native(), "callee must not be native");
3402 if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) { 3410 if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
3403 INLINE_BAILOUT("inlining prohibited by policy"); 3411 INLINE_BAILOUT("inlining prohibited by policy");
3404 } 3412 }
3405 // first perform tests of things it's not possible to inline 3413 // first perform tests of things it's not possible to inline
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");