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
|