< prev index next >
src/share/vm/opto/ifnode.cpp
Print this page
*** 21,30 ****
--- 21,31 ----
* questions.
*
*/
#include "precompiled.hpp"
+ #include "ci/ciTypeFlow.hpp"
#include "memory/allocation.inline.hpp"
#include "opto/addnode.hpp"
#include "opto/castnode.hpp"
#include "opto/cfgnode.hpp"
#include "opto/connode.hpp"
*** 766,776 ****
}
// Do this If and the dominating If both branch out to an uncommon trap
bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn) {
ProjNode* otherproj = proj->other_if_proj();
! CallStaticJavaNode* dom_unc = otherproj->is_uncommon_trap_proj(Deoptimization::Reason_none);
if (otherproj->outcnt() == 1 && dom_unc != NULL) {
CallStaticJavaNode* unc = NULL;
ProjNode* unc_proj = uncommon_trap_proj(unc);
if (unc_proj != NULL && unc_proj->outcnt() == 1) {
--- 767,783 ----
}
// Do this If and the dominating If both branch out to an uncommon trap
bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn) {
ProjNode* otherproj = proj->other_if_proj();
! // Dominating uncommon trap must have 'Reason_unstable_if' to ensure re-execution of folded Ifs
! CallStaticJavaNode* dom_unc = otherproj->is_uncommon_trap_proj(Deoptimization::Reason_unstable_if);
!
! // We need to re-execute the check after deoptimization
! if (!dom_unc->jvms()->should_reexecute()) {
! return false;
! }
if (otherproj->outcnt() == 1 && dom_unc != NULL) {
CallStaticJavaNode* unc = NULL;
ProjNode* unc_proj = uncommon_trap_proj(unc);
if (unc_proj != NULL && unc_proj->outcnt() == 1) {
*** 782,797 ****
}
assert(r->has_phi() == NULL, "simple region shouldn't have a phi");
} else if (dom_unc->in(0) != otherproj || unc->in(0) != unc_proj) {
return false;
}
// See merge_uncommon_traps: the reason of the uncommon trap
// will be changed and the state of the dominating If will be
// used. Checked that we didn't apply this transformation in a
// previous compilation and it didn't cause too many traps
! if (!igvn->C->too_many_traps(dom_unc->jvms()->method(), dom_unc->jvms()->bci(), Deoptimization::Reason_unstable_fused_if) &&
! !igvn->C->too_many_traps(dom_unc->jvms()->method(), dom_unc->jvms()->bci(), Deoptimization::Reason_range_check)) {
success = unc_proj;
fail = unc_proj->other_if_proj();
return true;
}
}
--- 789,820 ----
}
assert(r->has_phi() == NULL, "simple region shouldn't have a phi");
} else if (dom_unc->in(0) != otherproj || unc->in(0) != unc_proj) {
return false;
}
+
+ // Check if the bci of the dominating uncommon trap dominates the bci
+ // of the dominated uncommon trap. Otherwise we may not re-execute
+ // the dominated check after deoptimization from the merged uncommon trap.
+ ciMethod* method = unc->jvms()->method();
+ ciMethod* dom_method = dom_unc->jvms()->method();
+ if (method != dom_method) {
+ return false;
+ }
+ ciTypeFlow* flow = dom_method->get_flow_analysis();
+ int bci = unc->jvms()->bci();
+ int dom_bci = dom_unc->jvms()->bci();
+ if (!flow->is_dominated_by(bci, dom_bci)) {
+ return false;
+ }
+
// See merge_uncommon_traps: the reason of the uncommon trap
// will be changed and the state of the dominating If will be
// used. Checked that we didn't apply this transformation in a
// previous compilation and it didn't cause too many traps
! if (!igvn->C->too_many_traps(dom_method, dom_bci, Deoptimization::Reason_unstable_fused_if) &&
! !igvn->C->too_many_traps(dom_method, dom_bci, Deoptimization::Reason_range_check)) {
success = unc_proj;
fail = unc_proj->other_if_proj();
return true;
}
}
< prev index next >