--- old/src/share/vm/ci/ciMethod.cpp 2013-10-17 18:54:49.960764493 +0200 +++ new/src/share/vm/ci/ciMethod.cpp 2013-10-17 18:54:49.549779248 +0200 @@ -565,6 +565,92 @@ if (_limit < MorphismLimit) _limit++; } +// Return true if profiling provides a type for the argument nb to the +// call at bci. type is the profiled type. +// If the profile reports that the argument may be null, return false +// at least for now. +bool ciMethod::argument_profiled_type(int bci, int nb, ciKlass*& type) { + 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(java_code_at_bci(bci) == Bytecodes::_invokevirtual || + java_code_at_bci(bci) == Bytecodes::_invokeinterface, "unexpected bytecode"); + ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData(); + if (nb >= call->number_of_arguments()) { + return false; + } + type = call->valid_argument_type(nb); + if (type != NULL && !call->argument_maybe_null(nb)) { + return true; + } + } else if (data->is_CallTypeData()) { + assert(java_code_at_bci(bci) == Bytecodes::_invokestatic || + java_code_at_bci(bci) == Bytecodes::_invokespecial || + java_code_at_bci(bci) == Bytecodes::_invokedynamic, "unexpected bytecode"); + ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData(); + if (nb >= call->number_of_arguments()) { + return false; + } + type = call->valid_argument_type(nb); + if (type != NULL && !call->argument_maybe_null(nb)) { + return true; + } + } + } + } + return false; +} + +// Return true if profiling provides a type for the return value from +// the call at bci. type is the profiled type. +// If the profile reports that the argument may be null, return false +// at least for now. +bool ciMethod::return_profiled_type(int bci, ciKlass*& type) { + 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(java_code_at_bci(bci) == Bytecodes::_invokevirtual || + java_code_at_bci(bci) == Bytecodes::_invokeinterface, "unexpected bytecode"); + ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData(); + type = call->valid_return_type(); + if (type != NULL && !call->return_maybe_null()) { + return true; + } + } else if (data->is_CallTypeData()) { + assert(java_code_at_bci(bci) == Bytecodes::_invokestatic || + java_code_at_bci(bci) == Bytecodes::_invokespecial || + java_code_at_bci(bci) == Bytecodes::_invokedynamic, "unexpected bytecode"); + ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData(); + type = call->valid_return_type(); + if (type != NULL && !call->return_maybe_null()) { + return true; + } + } + } + } + return false; +} + +// Return true if profiling provides a type for the parameter nb to +// this method. type is the profiled type. +// If the profile reports that the argument may be null, return false +// at least for now. +bool ciMethod::parameter_profiled_type(int nb, ciKlass*& type) { + if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) { + ciParametersTypeData* parameters = method_data()->parameters_type_data(); + if (parameters != NULL && nb < parameters->number_of_parameters()) { + type = parameters->valid_parameter_type(nb); + if (type != NULL && !parameters->parameter_maybe_null(nb)) { + return true; + } + } + } + return false; +} + + // ------------------------------------------------------------------ // ciMethod::find_monomorphic_target //