src/share/vm/opto/parse2.cpp
Print this page
*** 103,116 ****
// Do the range check
if (GenerateRangeChecks && need_range_check) {
// Range is constant in array-oop, so we can use the original state of mem
Node* len = load_array_length(ary);
// Test length vs index (standard trick using unsigned compare)
Node* chk = _gvn.transform( new (C, 3) CmpUNode(idx, len) );
BoolTest::mask btest = BoolTest::lt;
! Node* tst = _gvn.transform( new (C, 2) BoolNode(chk, btest) );
// Branch to failure if out of bounds
{ BuildCutout unless(this, tst, PROB_MAX);
if (C->allow_range_check_smearing()) {
// Do not use builtin_throw, since range checks are sometimes
// made more stringent by an optimistic transformation.
--- 103,125 ----
// Do the range check
if (GenerateRangeChecks && need_range_check) {
// Range is constant in array-oop, so we can use the original state of mem
Node* len = load_array_length(ary);
+ Node* tst;
+ if (sizetype->_hi <= 0) {
+ // If the greatest array bound is negative, we can conclude that we're
+ // compiling unreachable code, but the unsigned compare trick used below
+ // only works with non-negative lengths. Instead, hack "tst" to be zero so
+ // the uncommon_trap path will always be taken.
+ tst = _gvn.intcon(0);
+ } else {
// Test length vs index (standard trick using unsigned compare)
Node* chk = _gvn.transform( new (C, 3) CmpUNode(idx, len) );
BoolTest::mask btest = BoolTest::lt;
! tst = _gvn.transform( new (C, 2) BoolNode(chk, btest) );
! }
// Branch to failure if out of bounds
{ BuildCutout unless(this, tst, PROB_MAX);
if (C->allow_range_check_smearing()) {
// Do not use builtin_throw, since range checks are sometimes
// made more stringent by an optimistic transformation.