Mercurial > hg > graal-jvmci-8
comparison src/share/vm/c1/c1_LIRGenerator.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 | 252d541466ea |
children | 9acbfe04b5c3 |
comparison
equal
deleted
inserted
replaced
12961:4748b3308cda | 12962:5ccbab1c69f3 |
---|---|
2645 __ profile_type(new LIR_Address(mdp, md_offset, T_METADATA), | 2645 __ profile_type(new LIR_Address(mdp, md_offset, T_METADATA), |
2646 value.result(), exact_klass, profiled_k, new_pointer_register(), not_null, exact_signature_k != NULL); | 2646 value.result(), exact_klass, profiled_k, new_pointer_register(), not_null, exact_signature_k != NULL); |
2647 return result; | 2647 return result; |
2648 } | 2648 } |
2649 | 2649 |
2650 // profile parameters on entry to the root of the compilation | |
2651 void LIRGenerator::profile_parameters(Base* x) { | |
2652 if (compilation()->profile_parameters()) { | |
2653 CallingConvention* args = compilation()->frame_map()->incoming_arguments(); | |
2654 ciMethodData* md = scope()->method()->method_data_or_null(); | |
2655 assert(md != NULL, "Sanity"); | |
2656 | |
2657 if (md->parameters_type_data() != NULL) { | |
2658 ciParametersTypeData* parameters_type_data = md->parameters_type_data(); | |
2659 ciTypeStackSlotEntries* parameters = parameters_type_data->parameters(); | |
2660 LIR_Opr mdp = LIR_OprFact::illegalOpr; | |
2661 for (int java_index = 0, i = 0, j = 0; j < parameters_type_data->number_of_parameters(); i++) { | |
2662 LIR_Opr src = args->at(i); | |
2663 assert(!src->is_illegal(), "check"); | |
2664 BasicType t = src->type(); | |
2665 if (t == T_OBJECT || t == T_ARRAY) { | |
2666 intptr_t profiled_k = parameters->type(j); | |
2667 Local* local = x->state()->local_at(java_index)->as_Local(); | |
2668 ciKlass* exact = profile_arg_type(md, md->byte_offset_of_slot(parameters_type_data, ParametersTypeData::type_offset(0)), | |
2669 in_bytes(ParametersTypeData::type_offset(j)) - in_bytes(ParametersTypeData::type_offset(0)), | |
2670 profiled_k, local, mdp, false, local->declared_type()->as_klass()); | |
2671 // If the profile is known statically set it once for all and do not emit any code | |
2672 if (exact != NULL) { | |
2673 md->set_parameter_type(j, exact); | |
2674 } | |
2675 j++; | |
2676 } | |
2677 java_index += type2size[t]; | |
2678 } | |
2679 } | |
2680 } | |
2681 } | |
2682 | |
2650 void LIRGenerator::do_Base(Base* x) { | 2683 void LIRGenerator::do_Base(Base* x) { |
2651 __ std_entry(LIR_OprFact::illegalOpr); | 2684 __ std_entry(LIR_OprFact::illegalOpr); |
2652 // Emit moves from physical registers / stack slots to virtual registers | 2685 // Emit moves from physical registers / stack slots to virtual registers |
2653 CallingConvention* args = compilation()->frame_map()->incoming_arguments(); | 2686 CallingConvention* args = compilation()->frame_map()->incoming_arguments(); |
2654 IRScope* irScope = compilation()->hir()->top_scope(); | 2687 IRScope* irScope = compilation()->hir()->top_scope(); |
2720 } | 2753 } |
2721 } | 2754 } |
2722 | 2755 |
2723 // increment invocation counters if needed | 2756 // increment invocation counters if needed |
2724 if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting. | 2757 if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting. |
2758 profile_parameters(x); | |
2725 CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, false); | 2759 CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, false); |
2726 increment_invocation_counter(info); | 2760 increment_invocation_counter(info); |
2727 } | 2761 } |
2728 | 2762 |
2729 // all blocks with a successor must end with an unconditional jump | 2763 // all blocks with a successor must end with an unconditional jump |
3079 default: ShouldNotReachHere(); break; | 3113 default: ShouldNotReachHere(); break; |
3080 } | 3114 } |
3081 } | 3115 } |
3082 | 3116 |
3083 void LIRGenerator::profile_arguments(ProfileCall* x) { | 3117 void LIRGenerator::profile_arguments(ProfileCall* x) { |
3084 if (MethodData::profile_arguments()) { | 3118 if (compilation()->profile_arguments()) { |
3085 int bci = x->bci_of_invoke(); | 3119 int bci = x->bci_of_invoke(); |
3086 ciMethodData* md = x->method()->method_data_or_null(); | 3120 ciMethodData* md = x->method()->method_data_or_null(); |
3087 ciProfileData* data = md->bci_to_data(bci); | 3121 ciProfileData* data = md->bci_to_data(bci); |
3088 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) { | 3122 if ((data->is_CallTypeData() && data->as_CallTypeData()->has_arguments()) || |
3123 (data->is_VirtualCallTypeData() && data->as_VirtualCallTypeData()->has_arguments())) { | |
3089 ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset(); | 3124 ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset(); |
3090 int base_offset = md->byte_offset_of_slot(data, extra); | 3125 int base_offset = md->byte_offset_of_slot(data, extra); |
3091 LIR_Opr mdp = LIR_OprFact::illegalOpr; | 3126 LIR_Opr mdp = LIR_OprFact::illegalOpr; |
3092 ciTypeStackSlotEntries* args = data->is_CallTypeData() ? ((ciCallTypeData*)data)->args() : ((ciVirtualCallTypeData*)data)->args(); | 3127 ciTypeStackSlotEntries* args = data->is_CallTypeData() ? ((ciCallTypeData*)data)->args() : ((ciVirtualCallTypeData*)data)->args(); |
3093 | 3128 |
3109 !x->arg_needs_null_check(i+start), sig_stream.next_klass()); | 3144 !x->arg_needs_null_check(i+start), sig_stream.next_klass()); |
3110 if (exact != NULL) { | 3145 if (exact != NULL) { |
3111 md->set_argument_type(bci, i, exact); | 3146 md->set_argument_type(bci, i, exact); |
3112 } | 3147 } |
3113 } | 3148 } |
3149 } else { | |
3150 #ifdef ASSERT | |
3151 Bytecodes::Code code = x->method()->raw_code_at_bci(x->bci_of_invoke()); | |
3152 int n = x->nb_profiled_args(); | |
3153 assert(MethodData::profile_parameters() && x->inlined() && | |
3154 ((code == Bytecodes::_invokedynamic && n <= 1) || (code == Bytecodes::_invokehandle && n <= 2)), | |
3155 "only at JSR292 bytecodes"); | |
3156 #endif | |
3157 } | |
3158 } | |
3159 } | |
3160 | |
3161 // profile parameters on entry to an inlined method | |
3162 void LIRGenerator::profile_parameters_at_call(ProfileCall* x) { | |
3163 if (compilation()->profile_parameters() && x->inlined()) { | |
3164 ciMethodData* md = x->callee()->method_data_or_null(); | |
3165 if (md != NULL) { | |
3166 ciParametersTypeData* parameters_type_data = md->parameters_type_data(); | |
3167 if (parameters_type_data != NULL) { | |
3168 ciTypeStackSlotEntries* parameters = parameters_type_data->parameters(); | |
3169 LIR_Opr mdp = LIR_OprFact::illegalOpr; | |
3170 bool has_receiver = !x->callee()->is_static(); | |
3171 ciSignature* sig = x->callee()->signature(); | |
3172 ciSignatureStream sig_stream(sig, has_receiver ? x->callee()->holder() : NULL); | |
3173 int i = 0; // to iterate on the Instructions | |
3174 Value arg = x->recv(); | |
3175 bool not_null = false; | |
3176 int bci = x->bci_of_invoke(); | |
3177 Bytecodes::Code bc = x->method()->java_code_at_bci(bci); | |
3178 // The first parameter is the receiver so that's what we start | |
3179 // with if it exists. On exception if method handle call to | |
3180 // virtual method has receiver in the args list | |
3181 if (arg == NULL || !Bytecodes::has_receiver(bc)) { | |
3182 i = 1; | |
3183 arg = x->profiled_arg_at(0); | |
3184 not_null = !x->arg_needs_null_check(0); | |
3185 } | |
3186 int k = 0; // to iterate on the profile data | |
3187 for (;;) { | |
3188 intptr_t profiled_k = parameters->type(k); | |
3189 ciKlass* exact = profile_arg_type(md, md->byte_offset_of_slot(parameters_type_data, ParametersTypeData::type_offset(0)), | |
3190 in_bytes(ParametersTypeData::type_offset(k)) - in_bytes(ParametersTypeData::type_offset(0)), | |
3191 profiled_k, arg, mdp, not_null, sig_stream.next_klass()); | |
3192 // If the profile is known statically set it once for all and do not emit any code | |
3193 if (exact != NULL) { | |
3194 md->set_parameter_type(k, exact); | |
3195 } | |
3196 k++; | |
3197 if (k >= parameters_type_data->number_of_parameters()) { | |
3198 #ifdef ASSERT | |
3199 int extra = 0; | |
3200 if (MethodData::profile_arguments() && TypeProfileParmsLimit != -1 && | |
3201 x->nb_profiled_args() >= TypeProfileParmsLimit && | |
3202 x->recv() != NULL && Bytecodes::has_receiver(bc)) { | |
3203 extra += 1; | |
3204 } | |
3205 assert(i == x->nb_profiled_args() - extra || (TypeProfileParmsLimit != -1 && TypeProfileArgsLimit > TypeProfileParmsLimit), "unused parameters?"); | |
3206 #endif | |
3207 break; | |
3208 } | |
3209 arg = x->profiled_arg_at(i); | |
3210 not_null = !x->arg_needs_null_check(i); | |
3211 i++; | |
3212 } | |
3213 } | |
3114 } | 3214 } |
3115 } | 3215 } |
3116 } | 3216 } |
3117 | 3217 |
3118 void LIRGenerator::do_ProfileCall(ProfileCall* x) { | 3218 void LIRGenerator::do_ProfileCall(ProfileCall* x) { |
3122 // tmp is used to hold the counters on SPARC | 3222 // tmp is used to hold the counters on SPARC |
3123 LIR_Opr tmp = new_pointer_register(); | 3223 LIR_Opr tmp = new_pointer_register(); |
3124 | 3224 |
3125 if (x->nb_profiled_args() > 0) { | 3225 if (x->nb_profiled_args() > 0) { |
3126 profile_arguments(x); | 3226 profile_arguments(x); |
3227 } | |
3228 | |
3229 // profile parameters on inlined method entry including receiver | |
3230 if (x->recv() != NULL || x->nb_profiled_args() > 0) { | |
3231 profile_parameters_at_call(x); | |
3127 } | 3232 } |
3128 | 3233 |
3129 if (x->recv() != NULL) { | 3234 if (x->recv() != NULL) { |
3130 LIRItem value(x->recv(), this); | 3235 LIRItem value(x->recv(), this); |
3131 value.load_item(); | 3236 value.load_item(); |