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);