< 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,778 ---- } // 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); 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; } } --- 784,825 ---- } 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; } + + int dom_bci = dom_unc->jvms()->bci(); + ciMethod* dom_method = dom_unc->jvms()->method(); + + // Get block that contains the dominating uncommon trap + ciTypeFlow* flow = dom_method->get_flow_analysis(); + ciBlock* ciblk = dom_method->get_method_blocks()->block_containing(dom_bci); + ciTypeFlow::JsrSet* jsr = new ciTypeFlow::JsrSet(NULL); + ciTypeFlow::Block* block = flow->get_block_for(ciblk->index(), jsr, ciTypeFlow::no_create); + + // Check if the bci of the dominating uncommon trap dominates the bci + // of the dominated uncommon trap. Otherwise we would not re-execute + // the dominated check after deoptimization from the merged uncommon trap. + int bci = unc->jvms()->bci(); + bool dominated = false; + for (ciTypeFlow::SuccIter iter(block); !iter.done(); iter.next()) { + ciTypeFlow::Block* succ = iter.succ(); + if (succ->start() <= bci && bci < succ->limit()) { + dominated = true; + break; + } + } + if (!dominated) { + 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 >