src/share/vm/c1/c1_GraphBuilder.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/c1

src/share/vm/c1/c1_GraphBuilder.cpp

Print this page
rev 5462 : 8026251: New type profiling points: parameters to methods
Summary: x86 interpreter and c1 type profiling for parameters on method entries
Reviewed-by:


1453     }
1454 
1455     // If the inlined method is synchronized, the monitor must be
1456     // released before we jump to the continuation block.
1457     if (method()->is_synchronized()) {
1458       assert(state()->locks_size() == 1, "receiver must be locked here");
1459       monitorexit(state()->lock_at(0), SynchronizationEntryBCI);
1460     }
1461 
1462     if (need_mem_bar) {
1463       append(new MemBar(lir_membar_storestore));
1464     }
1465 
1466     // State at end of inlined method is the state of the caller
1467     // without the method parameters on stack, including the
1468     // return value, if any, of the inlined method on operand stack.
1469     int invoke_bci = state()->caller_state()->bci();
1470     set_state(state()->caller_state()->copy_for_parsing());
1471     if (x != NULL) {
1472       state()->push(x->type(), x);
1473       if (profile_calls() && MethodData::profile_return() && x->type()->is_object_kind()) {
1474         ciMethod* caller = state()->scope()->method();
1475         ciMethodData* md = caller->method_data_or_null();
1476         ciProfileData* data = md->bci_to_data(invoke_bci);
1477         if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
1478           bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return();
1479           // May not be true in case of an inlined call through a method handle intrinsic.
1480           if (has_return) {
1481             profile_return_type(x, method(), caller, invoke_bci);
1482           }
1483         }
1484       }
1485     }
1486     Goto* goto_callee = new Goto(continuation(), false);
1487 
1488     // See whether this is the first return; if so, store off some
1489     // of the state for later examination
1490     if (num_returns() == 0) {
1491       set_inline_cleanup_info();
1492     }
1493 


1655       StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching);
1656       if (!needs_patching) store = _memory->store(store);
1657       if (store != NULL) {
1658         append(store);
1659       }
1660       break;
1661     }
1662     default:
1663       ShouldNotReachHere();
1664       break;
1665   }
1666 }
1667 
1668 
1669 Dependencies* GraphBuilder::dependency_recorder() const {
1670   assert(DeoptC1, "need debug information");
1671   return compilation()->dependency_recorder();
1672 }
1673 
1674 // How many arguments do we want to profile?
1675 Values* GraphBuilder::args_list_for_profiling(int& start, bool may_have_receiver) {
1676   int n = 0;
1677   assert(start == 0, "should be initialized");
1678   if (MethodData::profile_arguments()) {

1679     ciProfileData* data = method()->method_data()->bci_to_data(bci());
1680     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       bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci()));
1683       start = has_receiver ? 1 : 0;







1684     }
1685   }
1686   if (n > 0) {
1687     return new Values(n);
1688   }
1689   return NULL;
1690 }
1691 
1692 // Collect arguments that we want to profile in a list
1693 Values* GraphBuilder::collect_args_for_profiling(Values* args, bool may_have_receiver) {
1694   int start = 0;
1695   Values* obj_args = args_list_for_profiling(start, may_have_receiver);
1696   if (obj_args == NULL) {
1697     return NULL;
1698   }
1699   int s = obj_args->size();
1700   for (int i = start, j = 0; j < s; i++) {
1701     if (args->at(i)->type()->is_object_kind()) {
1702       obj_args->push(args->at(i));
1703       j++;
1704     }
1705   }
1706   assert(s == obj_args->length(), "missed on arg?");
1707   return obj_args;
1708 }
1709 
1710 
1711 void GraphBuilder::invoke(Bytecodes::Code code) {
1712   bool will_link;
1713   ciSignature* declared_signature = NULL;
1714   ciMethod*             target = stream()->get_method(will_link, &declared_signature);
1715   ciKlass*              holder = stream()->get_declared_method_holder();


1989     // logic or the unverified entry point.  Profiling of calls
1990     // requires that the null check is performed in all cases.
1991     null_check(recv);
1992   }
1993 
1994   if (is_profiling()) {
1995     if (recv != NULL && profile_calls()) {
1996       null_check(recv);
1997     }
1998     // Note that we'd collect profile data in this method if we wanted it.
1999     compilation()->set_would_profile(true);
2000 
2001     if (profile_calls()) {
2002       assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
2003       ciKlass* target_klass = NULL;
2004       if (cha_monomorphic_target != NULL) {
2005         target_klass = cha_monomorphic_target->holder();
2006       } else if (exact_target != NULL) {
2007         target_klass = exact_target->holder();
2008       }
2009       profile_call(target, recv, target_klass, collect_args_for_profiling(args, false), false);
2010     }
2011   }
2012 
2013   Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
2014   // push result
2015   append_split(result);
2016 
2017   if (result_type != voidType) {
2018     if (method()->is_strict()) {
2019       push(result_type, round_fp(result));
2020     } else {
2021       push(result_type, result);
2022     }
2023   }
2024   if (profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) {
2025     profile_return_type(result, target);
2026   }
2027 }
2028 
2029 
2030 void GraphBuilder::new_instance(int klass_index) {
2031   ValueStack* state_before = copy_state_exhandling();
2032   bool will_link;
2033   ciKlass* klass = stream()->get_klass(will_link);
2034   assert(klass->is_instance_klass(), "must be an instance klass");
2035   NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before);
2036   _memory->new_instance(new_instance);
2037   apush(append_split(new_instance));
2038 }
2039 
2040 
2041 void GraphBuilder::new_type_array() {
2042   ValueStack* state_before = copy_state_exhandling();
2043   apush(append_split(new NewTypeArray(ipop(), (BasicType)stream()->get_index(), state_before)));
2044 }


3544   }
3545   // create intrinsic node
3546   const bool has_receiver = !callee->is_static();
3547   ValueType* result_type = as_ValueType(callee->return_type());
3548   ValueStack* state_before = copy_state_for_exception();
3549 
3550   Values* args = state()->pop_arguments(callee->arg_size());
3551 
3552   if (is_profiling()) {
3553     // Don't profile in the special case where the root method
3554     // is the intrinsic
3555     if (callee != method()) {
3556       // Note that we'd collect profile data in this method if we wanted it.
3557       compilation()->set_would_profile(true);
3558       if (profile_calls()) {
3559         Value recv = NULL;
3560         if (has_receiver) {
3561           recv = args->at(0);
3562           null_check(recv);
3563         }
3564         profile_call(callee, recv, NULL, collect_args_for_profiling(args, true), true);
3565       }
3566     }
3567   }
3568 
3569   Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before,
3570                                     preserves_state, cantrap);
3571   // append instruction & push result
3572   Value value = append_split(result);
3573   if (result_type != voidType) push(result_type, value);
3574 
3575   if (callee != method() && profile_calls() && MethodData::profile_return() && result_type->is_object_kind()) {
3576     profile_return_type(result, callee);
3577   }
3578 
3579   // done
3580   return true;
3581 }
3582 
3583 
3584 bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) {
3585   // Introduce a new callee continuation point - all Ret instructions
3586   // will be replaced with Gotos to this point.
3587   BlockBegin* cont = block_at(next_bci());
3588   assert(cont != NULL, "continuation must exist (BlockListBuilder starts a new block after a jsr");
3589 
3590   // Note: can not assign state to continuation yet, as we have to
3591   // pick up the state from the Ret instructions.
3592 
3593   // Push callee scope
3594   push_scope_for_jsr(cont, jsr_dest_bci);
3595 


3803 
3804   // Insert null check if necessary
3805   Value recv = NULL;
3806   if (has_receiver) {
3807     // note: null check must happen even if first instruction of callee does
3808     //       an implicit null check since the callee is in a different scope
3809     //       and we must make sure exception handling does the right thing
3810     assert(!callee->is_static(), "callee must not be static");
3811     assert(callee->arg_size() > 0, "must have at least a receiver");
3812     recv = state()->stack_at(args_base);
3813     null_check(recv);
3814   }
3815 
3816   if (is_profiling()) {
3817     // Note that we'd collect profile data in this method if we wanted it.
3818     // this may be redundant here...
3819     compilation()->set_would_profile(true);
3820 
3821     if (profile_calls()) {
3822       int start = 0;
3823       Values* obj_args = args_list_for_profiling(start, has_receiver);
3824       if (obj_args != NULL) {
3825         int s = obj_args->size();
3826         // 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(); ) {
3828           Value v = state()->stack_at_inc(i);
3829           if (v->type()->is_object_kind()) {
3830             obj_args->push(v);
3831             j++;
3832           }
3833         }
3834 #ifdef ASSERT
3835         {
3836           bool ignored_will_link;
3837           ciSignature* declared_signature = NULL;
3838           ciMethod* real_target = method()->get_method_at_bci(bci(), ignored_will_link, &declared_signature);
3839           assert(s == obj_args->length() || real_target->is_method_handle_intrinsic(), "missed on arg?");
3840         }
3841 #endif
3842       }
3843       profile_call(callee, recv, holder_known ? callee->holder() : NULL, obj_args, true);




1453     }
1454 
1455     // If the inlined method is synchronized, the monitor must be
1456     // released before we jump to the continuation block.
1457     if (method()->is_synchronized()) {
1458       assert(state()->locks_size() == 1, "receiver must be locked here");
1459       monitorexit(state()->lock_at(0), SynchronizationEntryBCI);
1460     }
1461 
1462     if (need_mem_bar) {
1463       append(new MemBar(lir_membar_storestore));
1464     }
1465 
1466     // State at end of inlined method is the state of the caller
1467     // without the method parameters on stack, including the
1468     // return value, if any, of the inlined method on operand stack.
1469     int invoke_bci = state()->caller_state()->bci();
1470     set_state(state()->caller_state()->copy_for_parsing());
1471     if (x != NULL) {
1472       state()->push(x->type(), x);
1473       if (profile_return() && x->type()->is_object_kind()) {
1474         ciMethod* caller = state()->scope()->method();
1475         ciMethodData* md = caller->method_data_or_null();
1476         ciProfileData* data = md->bci_to_data(invoke_bci);
1477         if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
1478           bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return();
1479           // May not be true in case of an inlined call through a method handle intrinsic.
1480           if (has_return) {
1481             profile_return_type(x, method(), caller, invoke_bci);
1482           }
1483         }
1484       }
1485     }
1486     Goto* goto_callee = new Goto(continuation(), false);
1487 
1488     // See whether this is the first return; if so, store off some
1489     // of the state for later examination
1490     if (num_returns() == 0) {
1491       set_inline_cleanup_info();
1492     }
1493 


1655       StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching);
1656       if (!needs_patching) store = _memory->store(store);
1657       if (store != NULL) {
1658         append(store);
1659       }
1660       break;
1661     }
1662     default:
1663       ShouldNotReachHere();
1664       break;
1665   }
1666 }
1667 
1668 
1669 Dependencies* GraphBuilder::dependency_recorder() const {
1670   assert(DeoptC1, "need debug information");
1671   return compilation()->dependency_recorder();
1672 }
1673 
1674 // How many arguments do we want to profile?
1675 Values* GraphBuilder::args_list_for_profiling(ciMethod* target, int& start, bool may_have_receiver) {
1676   int n = 0;
1677   bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci()));
1678   start = has_receiver ? 1 : 0;
1679   if (profile_arguments()) {
1680     ciProfileData* data = method()->method_data()->bci_to_data(bci());
1681     if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
1682       n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments();
1683     }
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);
1692     }
1693   }
1694   if (n > 0) {
1695     return new Values(n);
1696   }
1697   return NULL;
1698 }
1699 
1700 // Collect arguments that we want to profile in a list
1701 Values* GraphBuilder::collect_args_for_profiling(Values* args, ciMethod* target, bool may_have_receiver) {
1702   int start = 0;
1703   Values* obj_args = args_list_for_profiling(target, start, may_have_receiver);
1704   if (obj_args == NULL) {
1705     return NULL;
1706   }
1707   int s = obj_args->size();
1708   for (int i = start, j = 0; j < s; i++) {
1709     if (args->at(i)->type()->is_object_kind()) {
1710       obj_args->push(args->at(i));
1711       j++;
1712     }
1713   }
1714   assert(s == obj_args->length(), "missed on arg?");
1715   return obj_args;
1716 }
1717 
1718 
1719 void GraphBuilder::invoke(Bytecodes::Code code) {
1720   bool will_link;
1721   ciSignature* declared_signature = NULL;
1722   ciMethod*             target = stream()->get_method(will_link, &declared_signature);
1723   ciKlass*              holder = stream()->get_declared_method_holder();


1997     // logic or the unverified entry point.  Profiling of calls
1998     // requires that the null check is performed in all cases.
1999     null_check(recv);
2000   }
2001 
2002   if (is_profiling()) {
2003     if (recv != NULL && profile_calls()) {
2004       null_check(recv);
2005     }
2006     // Note that we'd collect profile data in this method if we wanted it.
2007     compilation()->set_would_profile(true);
2008 
2009     if (profile_calls()) {
2010       assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
2011       ciKlass* target_klass = NULL;
2012       if (cha_monomorphic_target != NULL) {
2013         target_klass = cha_monomorphic_target->holder();
2014       } else if (exact_target != NULL) {
2015         target_klass = exact_target->holder();
2016       }
2017       profile_call(target, recv, target_klass, collect_args_for_profiling(args, NULL, false), false);
2018     }
2019   }
2020 
2021   Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
2022   // push result
2023   append_split(result);
2024 
2025   if (result_type != voidType) {
2026     if (method()->is_strict()) {
2027       push(result_type, round_fp(result));
2028     } else {
2029       push(result_type, result);
2030     }
2031   }
2032   if (profile_return() && result_type->is_object_kind()) {
2033     profile_return_type(result, target);
2034   }
2035 }
2036 
2037 
2038 void GraphBuilder::new_instance(int klass_index) {
2039   ValueStack* state_before = copy_state_exhandling();
2040   bool will_link;
2041   ciKlass* klass = stream()->get_klass(will_link);
2042   assert(klass->is_instance_klass(), "must be an instance klass");
2043   NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before);
2044   _memory->new_instance(new_instance);
2045   apush(append_split(new_instance));
2046 }
2047 
2048 
2049 void GraphBuilder::new_type_array() {
2050   ValueStack* state_before = copy_state_exhandling();
2051   apush(append_split(new NewTypeArray(ipop(), (BasicType)stream()->get_index(), state_before)));
2052 }


3552   }
3553   // create intrinsic node
3554   const bool has_receiver = !callee->is_static();
3555   ValueType* result_type = as_ValueType(callee->return_type());
3556   ValueStack* state_before = copy_state_for_exception();
3557 
3558   Values* args = state()->pop_arguments(callee->arg_size());
3559 
3560   if (is_profiling()) {
3561     // Don't profile in the special case where the root method
3562     // is the intrinsic
3563     if (callee != method()) {
3564       // Note that we'd collect profile data in this method if we wanted it.
3565       compilation()->set_would_profile(true);
3566       if (profile_calls()) {
3567         Value recv = NULL;
3568         if (has_receiver) {
3569           recv = args->at(0);
3570           null_check(recv);
3571         }
3572         profile_call(callee, recv, NULL, collect_args_for_profiling(args, callee, true), true);
3573       }
3574     }
3575   }
3576 
3577   Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before,
3578                                     preserves_state, cantrap);
3579   // append instruction & push result
3580   Value value = append_split(result);
3581   if (result_type != voidType) push(result_type, value);
3582 
3583   if (callee != method() && profile_return() && result_type->is_object_kind()) {
3584     profile_return_type(result, callee);
3585   }
3586 
3587   // done
3588   return true;
3589 }
3590 
3591 
3592 bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) {
3593   // Introduce a new callee continuation point - all Ret instructions
3594   // will be replaced with Gotos to this point.
3595   BlockBegin* cont = block_at(next_bci());
3596   assert(cont != NULL, "continuation must exist (BlockListBuilder starts a new block after a jsr");
3597 
3598   // Note: can not assign state to continuation yet, as we have to
3599   // pick up the state from the Ret instructions.
3600 
3601   // Push callee scope
3602   push_scope_for_jsr(cont, jsr_dest_bci);
3603 


3811 
3812   // Insert null check if necessary
3813   Value recv = NULL;
3814   if (has_receiver) {
3815     // note: null check must happen even if first instruction of callee does
3816     //       an implicit null check since the callee is in a different scope
3817     //       and we must make sure exception handling does the right thing
3818     assert(!callee->is_static(), "callee must not be static");
3819     assert(callee->arg_size() > 0, "must have at least a receiver");
3820     recv = state()->stack_at(args_base);
3821     null_check(recv);
3822   }
3823 
3824   if (is_profiling()) {
3825     // Note that we'd collect profile data in this method if we wanted it.
3826     // this may be redundant here...
3827     compilation()->set_would_profile(true);
3828 
3829     if (profile_calls()) {
3830       int start = 0;
3831       Values* obj_args = args_list_for_profiling(callee, start, has_receiver);
3832       if (obj_args != NULL) {
3833         int s = obj_args->size();
3834         // if called through method handle invoke, some arguments may have been popped
3835         for (int i = args_base+start, j = 0; j < obj_args->size() && i < state()->stack_size(); ) {
3836           Value v = state()->stack_at_inc(i);
3837           if (v->type()->is_object_kind()) {
3838             obj_args->push(v);
3839             j++;
3840           }
3841         }
3842 #ifdef ASSERT
3843         {
3844           bool ignored_will_link;
3845           ciSignature* declared_signature = NULL;
3846           ciMethod* real_target = method()->get_method_at_bci(bci(), ignored_will_link, &declared_signature);
3847           assert(s == obj_args->length() || real_target->is_method_handle_intrinsic(), "missed on arg?");
3848         }
3849 #endif
3850       }
3851       profile_call(callee, recv, holder_known ? callee->holder() : NULL, obj_args, true);


src/share/vm/c1/c1_GraphBuilder.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File