Mercurial > hg > truffle
diff src/share/vm/ci/ciMethod.cpp @ 12966:b2ee5dc63353
8024070: C2 needs some form of type speculation
Summary: record unused type profile information with type system, propagate and use it.
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Wed, 23 Oct 2013 12:40:23 +0200 |
parents | c775af091fe9 |
children | 096c224171c4 183bd5c00828 e46f2ee62e78 |
line wrap: on
line diff
--- a/src/share/vm/ci/ciMethod.cpp Wed Oct 23 10:00:39 2013 +0200 +++ b/src/share/vm/ci/ciMethod.cpp Wed Oct 23 12:40:23 2013 +0200 @@ -565,6 +565,116 @@ if (_limit < MorphismLimit) _limit++; } + +void ciMethod::assert_virtual_call_type_ok(int bci) { + assert(java_code_at_bci(bci) == Bytecodes::_invokevirtual || + java_code_at_bci(bci) == Bytecodes::_invokeinterface, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)))); +} + +void ciMethod::assert_call_type_ok(int bci) { + assert(java_code_at_bci(bci) == Bytecodes::_invokestatic || + java_code_at_bci(bci) == Bytecodes::_invokespecial || + java_code_at_bci(bci) == Bytecodes::_invokedynamic, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)))); +} + +/** + * Check whether profiling provides a type for the argument i to the + * call at bci bci + * + * @param bci bci of the call + * @param i argument number + * @return profiled type + * + * If the profile reports that the argument may be null, return false + * at least for now. + */ +ciKlass* ciMethod::argument_profiled_type(int bci, int i) { + if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) { + ciProfileData* data = method_data()->bci_to_data(bci); + if (data != NULL) { + if (data->is_VirtualCallTypeData()) { + assert_virtual_call_type_ok(bci); + ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData(); + if (i >= call->number_of_arguments()) { + return NULL; + } + ciKlass* type = call->valid_argument_type(i); + if (type != NULL && !call->argument_maybe_null(i)) { + return type; + } + } else if (data->is_CallTypeData()) { + assert_call_type_ok(bci); + ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData(); + if (i >= call->number_of_arguments()) { + return NULL; + } + ciKlass* type = call->valid_argument_type(i); + if (type != NULL && !call->argument_maybe_null(i)) { + return type; + } + } + } + } + return NULL; +} + +/** + * Check whether profiling provides a type for the return value from + * the call at bci bci + * + * @param bci bci of the call + * @return profiled type + * + * If the profile reports that the argument may be null, return false + * at least for now. + */ +ciKlass* ciMethod::return_profiled_type(int bci) { + if (MethodData::profile_return() && method_data() != NULL && method_data()->is_mature()) { + ciProfileData* data = method_data()->bci_to_data(bci); + if (data != NULL) { + if (data->is_VirtualCallTypeData()) { + assert_virtual_call_type_ok(bci); + ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData(); + ciKlass* type = call->valid_return_type(); + if (type != NULL && !call->return_maybe_null()) { + return type; + } + } else if (data->is_CallTypeData()) { + assert_call_type_ok(bci); + ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData(); + ciKlass* type = call->valid_return_type(); + if (type != NULL && !call->return_maybe_null()) { + return type; + } + } + } + } + return NULL; +} + +/** + * Check whether profiling provides a type for the parameter i + * + * @param i parameter number + * @return profiled type + * + * If the profile reports that the argument may be null, return false + * at least for now. + */ +ciKlass* ciMethod::parameter_profiled_type(int i) { + if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) { + ciParametersTypeData* parameters = method_data()->parameters_type_data(); + if (parameters != NULL && i < parameters->number_of_parameters()) { + ciKlass* type = parameters->valid_parameter_type(i); + if (type != NULL && !parameters->parameter_maybe_null(i)) { + return type; + } + } + } + return NULL; +} + + // ------------------------------------------------------------------ // ciMethod::find_monomorphic_target //