Mercurial > hg > graal-compiler
comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 12962:5ccbab1c69f3
8026251: New type profiling points: parameters to methods
Summary: x86 interpreter and c1 type profiling for parameters on method entries
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Tue, 22 Oct 2013 09:51:47 +0200 |
parents | ce0cc25bc5e2 |
children | 0d1661d63d70 |
comparison
equal
deleted
inserted
replaced
12961:4748b3308cda | 12962:5ccbab1c69f3 |
---|---|
1468 // return value, if any, of the inlined method on operand stack. | 1468 // return value, if any, of the inlined method on operand stack. |
1469 int invoke_bci = state()->caller_state()->bci(); | 1469 int invoke_bci = state()->caller_state()->bci(); |
1470 set_state(state()->caller_state()->copy_for_parsing()); | 1470 set_state(state()->caller_state()->copy_for_parsing()); |
1471 if (x != NULL) { | 1471 if (x != NULL) { |
1472 state()->push(x->type(), x); | 1472 state()->push(x->type(), x); |
1473 if (profile_calls() && MethodData::profile_return() && x->type()->is_object_kind()) { | 1473 if (profile_return() && x->type()->is_object_kind()) { |
1474 ciMethod* caller = state()->scope()->method(); | 1474 ciMethod* caller = state()->scope()->method(); |
1475 ciMethodData* md = caller->method_data_or_null(); | 1475 ciMethodData* md = caller->method_data_or_null(); |
1476 ciProfileData* data = md->bci_to_data(invoke_bci); | 1476 ciProfileData* data = md->bci_to_data(invoke_bci); |
1477 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { | 1477 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { |
1478 bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return(); | 1478 bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return(); |
1670 assert(DeoptC1, "need debug information"); | 1670 assert(DeoptC1, "need debug information"); |
1671 return compilation()->dependency_recorder(); | 1671 return compilation()->dependency_recorder(); |
1672 } | 1672 } |
1673 | 1673 |
1674 // How many arguments do we want to profile? | 1674 // How many arguments do we want to profile? |
1675 Values* GraphBuilder::args_list_for_profiling(int& start, bool may_have_receiver) { | 1675 Values* GraphBuilder::args_list_for_profiling(ciMethod* target, int& start, bool may_have_receiver) { |
1676 int n = 0; | 1676 int n = 0; |
1677 assert(start == 0, "should be initialized"); | 1677 bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci())); |
1678 if (MethodData::profile_arguments()) { | 1678 start = has_receiver ? 1 : 0; |
1679 if (profile_arguments()) { | |
1679 ciProfileData* data = method()->method_data()->bci_to_data(bci()); | 1680 ciProfileData* data = method()->method_data()->bci_to_data(bci()); |
1680 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { | 1681 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { |
1681 n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments(); | 1682 n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments(); |
1682 bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci())); | 1683 } |
1683 start = has_receiver ? 1 : 0; | 1684 } |
1685 // If we are inlining then we need to collect arguments to profile parameters for the target | |
1686 if (profile_parameters() && target != NULL) { | |
1687 if (target->method_data() != NULL && target->method_data()->parameters_type_data() != NULL) { | |
1688 // The receiver is profiled on method entry so it's included in | |
1689 // the number of parameters but here we're only interested in | |
1690 // actual arguments. | |
1691 n = MAX2(n, target->method_data()->parameters_type_data()->number_of_parameters() - start); | |
1684 } | 1692 } |
1685 } | 1693 } |
1686 if (n > 0) { | 1694 if (n > 0) { |
1687 return new Values(n); | 1695 return new Values(n); |
1688 } | 1696 } |
1689 return NULL; | 1697 return NULL; |
1690 } | 1698 } |
1691 | 1699 |
1692 // Collect arguments that we want to profile in a list | 1700 // Collect arguments that we want to profile in a list |
1693 Values* GraphBuilder::collect_args_for_profiling(Values* args, bool may_have_receiver) { | 1701 Values* GraphBuilder::collect_args_for_profiling(Values* args, ciMethod* target, bool may_have_receiver) { |
1694 int start = 0; | 1702 int start = 0; |
1695 Values* obj_args = args_list_for_profiling(start, may_have_receiver); | 1703 Values* obj_args = args_list_for_profiling(target, start, may_have_receiver); |
1696 if (obj_args == NULL) { | 1704 if (obj_args == NULL) { |
1697 return NULL; | 1705 return NULL; |
1698 } | 1706 } |
1699 int s = obj_args->size(); | 1707 int s = obj_args->size(); |
1700 for (int i = start, j = 0; j < s; i++) { | 1708 for (int i = start, j = 0; j < s; i++) { |
2004 if (cha_monomorphic_target != NULL) { | 2012 if (cha_monomorphic_target != NULL) { |
2005 target_klass = cha_monomorphic_target->holder(); | 2013 target_klass = cha_monomorphic_target->holder(); |
2006 } else if (exact_target != NULL) { | 2014 } else if (exact_target != NULL) { |
2007 target_klass = exact_target->holder(); | 2015 target_klass = exact_target->holder(); |
2008 } | 2016 } |
2009 profile_call(target, recv, target_klass, collect_args_for_profiling(args, false), false); | 2017 profile_call(target, recv, target_klass, collect_args_for_profiling(args, NULL, false), false); |
2010 } | 2018 } |
2011 } | 2019 } |
2012 | 2020 |
2013 Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before); | 2021 Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before); |
2014 // push result | 2022 // push result |
2019 push(result_type, round_fp(result)); | 2027 push(result_type, round_fp(result)); |
2020 } else { | 2028 } else { |
2021 push(result_type, result); | 2029 push(result_type, result); |
2022 } | 2030 } |
2023 } | 2031 } |
2024 if (profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) { | 2032 if (profile_return() && result_type->is_object_kind()) { |
2025 profile_return_type(result, target); | 2033 profile_return_type(result, target); |
2026 } | 2034 } |
2027 } | 2035 } |
2028 | 2036 |
2029 | 2037 |
3559 Value recv = NULL; | 3567 Value recv = NULL; |
3560 if (has_receiver) { | 3568 if (has_receiver) { |
3561 recv = args->at(0); | 3569 recv = args->at(0); |
3562 null_check(recv); | 3570 null_check(recv); |
3563 } | 3571 } |
3564 profile_call(callee, recv, NULL, collect_args_for_profiling(args, true), true); | 3572 profile_call(callee, recv, NULL, collect_args_for_profiling(args, callee, true), true); |
3565 } | 3573 } |
3566 } | 3574 } |
3567 } | 3575 } |
3568 | 3576 |
3569 Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before, | 3577 Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before, |
3570 preserves_state, cantrap); | 3578 preserves_state, cantrap); |
3571 // append instruction & push result | 3579 // append instruction & push result |
3572 Value value = append_split(result); | 3580 Value value = append_split(result); |
3573 if (result_type != voidType) push(result_type, value); | 3581 if (result_type != voidType) push(result_type, value); |
3574 | 3582 |
3575 if (callee != method() && profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) { | 3583 if (callee != method() && profile_return() && result_type->is_object_kind()) { |
3576 profile_return_type(result, callee); | 3584 profile_return_type(result, callee); |
3577 } | 3585 } |
3578 | 3586 |
3579 // done | 3587 // done |
3580 return true; | 3588 return true; |
3818 // this may be redundant here... | 3826 // this may be redundant here... |
3819 compilation()->set_would_profile(true); | 3827 compilation()->set_would_profile(true); |
3820 | 3828 |
3821 if (profile_calls()) { | 3829 if (profile_calls()) { |
3822 int start = 0; | 3830 int start = 0; |
3823 Values* obj_args = args_list_for_profiling(start, has_receiver); | 3831 Values* obj_args = args_list_for_profiling(callee, start, has_receiver); |
3824 if (obj_args != NULL) { | 3832 if (obj_args != NULL) { |
3825 int s = obj_args->size(); | 3833 int s = obj_args->size(); |
3826 // if called through method handle invoke, some arguments may have been popped | 3834 // if called through method handle invoke, some arguments may have been popped |
3827 for (int i = args_base+start, j = 0; j < obj_args->size() && i < state()->stack_size(); ) { | 3835 for (int i = args_base+start, j = 0; j < obj_args->size() && i < state()->stack_size(); ) { |
3828 Value v = state()->stack_at_inc(i); | 3836 Value v = state()->stack_at_inc(i); |