diff --git a/src/hotspot/share/ci/ciCallProfile.hpp b/src/hotspot/share/ci/ciCallProfile.hpp index 96f5dc0ef95..caee8808378 100644 --- a/src/hotspot/share/ci/ciCallProfile.hpp +++ b/src/hotspot/share/ci/ciCallProfile.hpp @@ -28,6 +28,7 @@ #include "ci/ciClassList.hpp" #include "memory/allocation.hpp" +class CallGenerator; // ciCallProfile // // This class is used to determine the frequently called method @@ -58,9 +59,6 @@ class ciCallProfile : StackObj { void add_receiver(ciKlass* receiver, int receiver_count); - bool _polymorphic_enabled = false; - const double _polymorphic_inline_ratio[2] = {PolymorphicRecv0InlineRatio, PolymorphicRecv1InlineRatio}; - public: // Note: The following predicates return false for invalid profiles: bool has_receiver(int i) const { return _limit > i; } @@ -94,22 +92,6 @@ class ciCallProfile : StackObj { } return call; } - - void enable_polymorphic() { _polymorphic_enabled = true; } - - bool polymorphic_inline(int id) { - if (_polymorphic_enabled) { - return has_receiver(id) && receiver_prob(id) > _polymorphic_inline_ratio[id]; - } - return false; - } - - int polymorphic_devirtualize() { - if (_polymorphic_enabled) { - return _morphism; - } - return 0; - } }; #endif // SHARE_VM_CI_CICALLPROFILE_HPP diff --git a/src/hotspot/share/opto/doCall.cpp b/src/hotspot/share/opto/doCall.cpp index 9f59dae354b..6933db28c7c 100644 --- a/src/hotspot/share/opto/doCall.cpp +++ b/src/hotspot/share/opto/doCall.cpp @@ -233,40 +233,40 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool } } - if (PolymorphicInlining && morphism != 1) { - profile.enable_polymorphic(); - } + bool polymorphic_requirements_satisfied = true; if (receiver_method == NULL && (have_major_receiver || morphism == 1 || - (morphism >= 2 && PolymorphicInlining) || - (morphism == 2 && UseBimorphicInlining))) { + (morphism == 2 && UseBimorphicInlining) || + (morphism >= 2 && PolymorphicInlining))) { // receiver_method = profile.method(); // Profiles do not suggest methods now. Look it up in the major receiver. receiver_method = callee->resolve_invoke(jvms->method()->holder(), profile.receiver(0)); + if (!(have_major_receiver || morphism == 1 || (morphism == 2 && UseBimorphicInlining))) { + // triggerred by polymorphic, need additional check + polymorphic_requirements_satisfied = !(receiver_method->is_native() && cg_intrinsic); + } } - if (receiver_method != NULL && !(receiver_method->is_native() && cg_intrinsic)) { + + if (receiver_method != NULL && polymorphic_requirements_satisfied) { // The single majority receiver sufficiently outweighs the minority. CallGenerator* hit_cg = this->call_generator(receiver_method, - vtable_index, !call_does_dispatch, jvms, allow_inline && profile.polymorphic_inline(0), prof_factor); + vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); if (hit_cg != NULL) { // Look up second receiver. CallGenerator* next_hit_cg = NULL; ciMethod* next_receiver_method = NULL; - if (profile.polymorphic_inline(1)) { + if ((morphism == 2 && UseBimorphicInlining) || (morphism >= 2 && PolymorphicInlining)) { next_receiver_method = callee->resolve_invoke(jvms->method()->holder(), profile.receiver(1)); - if (next_receiver_method != NULL && !(next_receiver_method->is_native() && cg_intrinsic)) { - next_hit_cg = this->call_generator(next_receiver_method, - vtable_index, !call_does_dispatch, jvms, - allow_inline, prof_factor); + if (!(morphism == 2 && UseBimorphicInlining)) { + // triggerred by polymorphic, need additional check + polymorphic_requirements_satisfied = + !(receiver_method->is_native() && cg_intrinsic); } - } else if (morphism == 2 && UseBimorphicInlining) { - next_receiver_method = callee->resolve_invoke(jvms->method()->holder(), - profile.receiver(1)); - if (next_receiver_method != NULL) { + if (next_receiver_method != NULL && polymorphic_requirements_satisfied) { next_hit_cg = this->call_generator(next_receiver_method, vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); @@ -277,9 +277,10 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool } } } + int polymorphic_devirtualize = morphism >= 2 && PolymorphicInlining ? morphism : 0; bool polymorphic_recompile = PolymorphicInlining && next_hit_cg != NULL; CallGenerator* hit_cg_devirtual[ciCallProfile::MorphismLimit] = {0}; - for (int i = 2; i < profile.polymorphic_devirtualize(); i++) { + for (int i = 2; i < polymorphic_devirtualize; i++) { ciMethod*receiver_method_devirtual = callee->resolve_invoke(jvms->method()->holder(), profile.receiver(i)); if (receiver_method_devirtual != NULL && !(receiver_method_devirtual->is_native() && cg_intrinsic)) { @@ -296,7 +297,6 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool Deoptimization::DeoptReason reason = (morphism == 2 ? Deoptimization::Reason_bimorphic : Deoptimization::reason_class_check(speculative_receiver_type != NULL)); - if ((morphism == 1 || (morphism == 2 && next_hit_cg != NULL) || polymorphic_recompile) && !too_many_traps_or_recompiles(caller, bci, reason) ) { @@ -314,7 +314,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool } } if (miss_cg != NULL) { - for (int i = profile.polymorphic_devirtualize() - 1; i >= 2; i--) { + for (int i = polymorphic_devirtualize - 1; i >= 2; i--) { if (hit_cg_devirtual[i] != NULL) { assert(speculative_receiver_type == NULL, "shouldn't end up here if we used speculation"); trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(i), site_count, profile.receiver_count(i));