1.1 --- a/src/share/vm/ci/ciMethod.cpp Wed Oct 23 10:00:39 2013 +0200 1.2 +++ b/src/share/vm/ci/ciMethod.cpp Wed Oct 23 12:40:23 2013 +0200 1.3 @@ -565,6 +565,116 @@ 1.4 if (_limit < MorphismLimit) _limit++; 1.5 } 1.6 1.7 + 1.8 +void ciMethod::assert_virtual_call_type_ok(int bci) { 1.9 + assert(java_code_at_bci(bci) == Bytecodes::_invokevirtual || 1.10 + java_code_at_bci(bci) == Bytecodes::_invokeinterface, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)))); 1.11 +} 1.12 + 1.13 +void ciMethod::assert_call_type_ok(int bci) { 1.14 + assert(java_code_at_bci(bci) == Bytecodes::_invokestatic || 1.15 + java_code_at_bci(bci) == Bytecodes::_invokespecial || 1.16 + java_code_at_bci(bci) == Bytecodes::_invokedynamic, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci)))); 1.17 +} 1.18 + 1.19 +/** 1.20 + * Check whether profiling provides a type for the argument i to the 1.21 + * call at bci bci 1.22 + * 1.23 + * @param bci bci of the call 1.24 + * @param i argument number 1.25 + * @return profiled type 1.26 + * 1.27 + * If the profile reports that the argument may be null, return false 1.28 + * at least for now. 1.29 + */ 1.30 +ciKlass* ciMethod::argument_profiled_type(int bci, int i) { 1.31 + if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) { 1.32 + ciProfileData* data = method_data()->bci_to_data(bci); 1.33 + if (data != NULL) { 1.34 + if (data->is_VirtualCallTypeData()) { 1.35 + assert_virtual_call_type_ok(bci); 1.36 + ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData(); 1.37 + if (i >= call->number_of_arguments()) { 1.38 + return NULL; 1.39 + } 1.40 + ciKlass* type = call->valid_argument_type(i); 1.41 + if (type != NULL && !call->argument_maybe_null(i)) { 1.42 + return type; 1.43 + } 1.44 + } else if (data->is_CallTypeData()) { 1.45 + assert_call_type_ok(bci); 1.46 + ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData(); 1.47 + if (i >= call->number_of_arguments()) { 1.48 + return NULL; 1.49 + } 1.50 + ciKlass* type = call->valid_argument_type(i); 1.51 + if (type != NULL && !call->argument_maybe_null(i)) { 1.52 + return type; 1.53 + } 1.54 + } 1.55 + } 1.56 + } 1.57 + return NULL; 1.58 +} 1.59 + 1.60 +/** 1.61 + * Check whether profiling provides a type for the return value from 1.62 + * the call at bci bci 1.63 + * 1.64 + * @param bci bci of the call 1.65 + * @return profiled type 1.66 + * 1.67 + * If the profile reports that the argument may be null, return false 1.68 + * at least for now. 1.69 + */ 1.70 +ciKlass* ciMethod::return_profiled_type(int bci) { 1.71 + if (MethodData::profile_return() && method_data() != NULL && method_data()->is_mature()) { 1.72 + ciProfileData* data = method_data()->bci_to_data(bci); 1.73 + if (data != NULL) { 1.74 + if (data->is_VirtualCallTypeData()) { 1.75 + assert_virtual_call_type_ok(bci); 1.76 + ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData(); 1.77 + ciKlass* type = call->valid_return_type(); 1.78 + if (type != NULL && !call->return_maybe_null()) { 1.79 + return type; 1.80 + } 1.81 + } else if (data->is_CallTypeData()) { 1.82 + assert_call_type_ok(bci); 1.83 + ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData(); 1.84 + ciKlass* type = call->valid_return_type(); 1.85 + if (type != NULL && !call->return_maybe_null()) { 1.86 + return type; 1.87 + } 1.88 + } 1.89 + } 1.90 + } 1.91 + return NULL; 1.92 +} 1.93 + 1.94 +/** 1.95 + * Check whether profiling provides a type for the parameter i 1.96 + * 1.97 + * @param i parameter number 1.98 + * @return profiled type 1.99 + * 1.100 + * If the profile reports that the argument may be null, return false 1.101 + * at least for now. 1.102 + */ 1.103 +ciKlass* ciMethod::parameter_profiled_type(int i) { 1.104 + if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) { 1.105 + ciParametersTypeData* parameters = method_data()->parameters_type_data(); 1.106 + if (parameters != NULL && i < parameters->number_of_parameters()) { 1.107 + ciKlass* type = parameters->valid_parameter_type(i); 1.108 + if (type != NULL && !parameters->parameter_maybe_null(i)) { 1.109 + return type; 1.110 + } 1.111 + } 1.112 + } 1.113 + return NULL; 1.114 +} 1.115 + 1.116 + 1.117 // ------------------------------------------------------------------ 1.118 // ciMethod::find_monomorphic_target 1.119 //