src/share/vm/opto/parse2.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/parse2.cpp

Print this page
rev 9360 : 8137168: Replace IfNode with a new RangeCheckNode for range checks
Summary: new RangeCheckNode to enable optimization of explicit library level range checks
Reviewed-by:


 119   }
 120 
 121   // Do the range check
 122   if (GenerateRangeChecks && need_range_check) {
 123     Node* tst;
 124     if (sizetype->_hi <= 0) {
 125       // The greatest array bound is negative, so we can conclude that we're
 126       // compiling unreachable code, but the unsigned compare trick used below
 127       // only works with non-negative lengths.  Instead, hack "tst" to be zero so
 128       // the uncommon_trap path will always be taken.
 129       tst = _gvn.intcon(0);
 130     } else {
 131       // Range is constant in array-oop, so we can use the original state of mem
 132       Node* len = load_array_length(ary);
 133 
 134       // Test length vs index (standard trick using unsigned compare)
 135       Node* chk = _gvn.transform( new CmpUNode(idx, len) );
 136       BoolTest::mask btest = BoolTest::lt;
 137       tst = _gvn.transform( new BoolNode(chk, btest) );
 138     }






 139     // Branch to failure if out of bounds
 140     { BuildCutout unless(this, tst, PROB_MAX);


 141       if (C->allow_range_check_smearing()) {
 142         // Do not use builtin_throw, since range checks are sometimes
 143         // made more stringent by an optimistic transformation.
 144         // This creates "tentative" range checks at this point,
 145         // which are not guaranteed to throw exceptions.
 146         // See IfNode::Ideal, is_range_check, adjust_check.
 147         uncommon_trap(Deoptimization::Reason_range_check,
 148                       Deoptimization::Action_make_not_entrant,
 149                       NULL, "range_check");
 150       } else {
 151         // If we have already recompiled with the range-check-widening
 152         // heroic optimization turned off, then we must really be throwing
 153         // range check exceptions.
 154         builtin_throw(Deoptimization::Reason_range_check, idx);
 155       }
 156     }
 157   }
 158   // Check for always knowing you are throwing a range-check exception
 159   if (stopped())  return top();
 160 




 119   }
 120 
 121   // Do the range check
 122   if (GenerateRangeChecks && need_range_check) {
 123     Node* tst;
 124     if (sizetype->_hi <= 0) {
 125       // The greatest array bound is negative, so we can conclude that we're
 126       // compiling unreachable code, but the unsigned compare trick used below
 127       // only works with non-negative lengths.  Instead, hack "tst" to be zero so
 128       // the uncommon_trap path will always be taken.
 129       tst = _gvn.intcon(0);
 130     } else {
 131       // Range is constant in array-oop, so we can use the original state of mem
 132       Node* len = load_array_length(ary);
 133 
 134       // Test length vs index (standard trick using unsigned compare)
 135       Node* chk = _gvn.transform( new CmpUNode(idx, len) );
 136       BoolTest::mask btest = BoolTest::lt;
 137       tst = _gvn.transform( new BoolNode(chk, btest) );
 138     }
 139     RangeCheckNode* rc = new RangeCheckNode(control(), tst, PROB_MAX, COUNT_UNKNOWN);
 140     _gvn.set_type(rc, rc->Value(&_gvn));
 141     if (!tst->is_Con()) {
 142       record_for_igvn(rc);
 143     }
 144     set_control(_gvn.transform(new IfTrueNode(rc)));
 145     // Branch to failure if out of bounds
 146     {
 147       PreserveJVMState pjvms(this);
 148       set_control(_gvn.transform(new IfFalseNode(rc)));
 149       if (C->allow_range_check_smearing()) {
 150         // Do not use builtin_throw, since range checks are sometimes
 151         // made more stringent by an optimistic transformation.
 152         // This creates "tentative" range checks at this point,
 153         // which are not guaranteed to throw exceptions.
 154         // See IfNode::Ideal, is_range_check, adjust_check.
 155         uncommon_trap(Deoptimization::Reason_range_check,
 156                       Deoptimization::Action_make_not_entrant,
 157                       NULL, "range_check");
 158       } else {
 159         // If we have already recompiled with the range-check-widening
 160         // heroic optimization turned off, then we must really be throwing
 161         // range check exceptions.
 162         builtin_throw(Deoptimization::Reason_range_check, idx);
 163       }
 164     }
 165   }
 166   // Check for always knowing you are throwing a range-check exception
 167   if (stopped())  return top();
 168 


src/share/vm/opto/parse2.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File