Skip to content

Commit 552c686

Browse files
committed
Merge
2 parents d898d40 + d4b472f commit 552c686

File tree

15 files changed

+601
-205
lines changed

15 files changed

+601
-205
lines changed

hotspot/src/share/vm/c1/c1_RangeCheckElimination.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,11 @@ void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int
379379
aii->_max = idx;
380380
aii->_list = new AccessIndexedList();
381381
} else if (idx >= aii->_min && idx <= aii->_max) {
382-
remove_range_check(ai);
383-
return;
382+
// Guard against underflow/overflow (see 'range_cond' check in RangeCheckEliminator::in_block_motion)
383+
if (aii->_max < 0 || (aii->_max + min_jint) <= aii->_min) {
384+
remove_range_check(ai);
385+
return;
386+
}
384387
}
385388
aii->_min = MIN2(aii->_min, idx);
386389
aii->_max = MAX2(aii->_max, idx);
@@ -423,9 +426,9 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
423426
}
424427
}
425428
} else {
426-
int last_integer = 0;
429+
jint last_integer = 0;
427430
Instruction *last_instruction = index;
428-
int base = 0;
431+
jint base = 0;
429432
ArithmeticOp *ao = index->as_ArithmeticOp();
430433

431434
while (ao != NULL && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) {
@@ -437,12 +440,12 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
437440
}
438441

439442
if (c) {
440-
int value = c->type()->as_IntConstant()->value();
443+
jint value = c->type()->as_IntConstant()->value();
441444
if (value != min_jint) {
442445
if (ao->op() == Bytecodes::_isub) {
443446
value = -value;
444447
}
445-
base += value;
448+
base = java_add(base, value);
446449
last_integer = base;
447450
last_instruction = other;
448451
}
@@ -464,12 +467,12 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
464467
assert(info != NULL, "Info must not be null");
465468

466469
// if idx < 0, max > 0, max + idx may fall between 0 and
467-
// length-1 and if min < 0, min + idx may overflow and be >=
470+
// length-1 and if min < 0, min + idx may underflow/overflow and be >=
468471
// 0. The predicate wouldn't trigger but some accesses could
469472
// be with a negative index. This test guarantees that for the
470473
// min and max value that are kept the predicate can't let
471474
// some incorrect accesses happen.
472-
bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min);
475+
bool range_cond = (info->_max < 0 || (info->_max + min_jint) <= info->_min);
473476

474477
// Generate code only if more than 2 range checks can be eliminated because of that.
475478
// 2 because at least 2 comparisons are done
@@ -809,7 +812,7 @@ void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, Block
809812
);
810813

811814
remove_range_check(ai);
812-
} else if (_optimistic && loop_header) {
815+
} else if (false && _optimistic && loop_header) {
813816
assert(ai->array(), "Array must not be null!");
814817
assert(ai->index(), "Index must not be null!");
815818

hotspot/src/share/vm/classfile/verifier.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,11 +2081,12 @@ void ClassVerifier::verify_switch(
20812081
"low must be less than or equal to high in tableswitch");
20822082
return;
20832083
}
2084-
keys = high - low + 1;
2085-
if (keys < 0) {
2084+
int64_t keys64 = ((int64_t)high - low) + 1;
2085+
if (keys64 > 65535) { // Max code length
20862086
verify_error(ErrorContext::bad_code(bci), "too many keys in tableswitch");
20872087
return;
20882088
}
2089+
keys = (int)keys64;
20892090
delta = 1;
20902091
} else {
20912092
keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize);

hotspot/src/share/vm/interpreter/bytecodes.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,18 @@ int Bytecodes::special_length_at(Bytecodes::Code code, address bcp, address end)
114114
if (end != NULL && aligned_bcp + 3*jintSize >= end) {
115115
return -1; // don't read past end of code buffer
116116
}
117+
// Promote calculation to signed 64 bits to do range checks, used by the verifier.
117118
jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
118119
jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
119120
jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
120-
// only return len if it can be represented as a positive int;
121-
// return -1 otherwise
122-
return (len > 0 && len == (int)len) ? len : -1;
121+
// Only return len if it can be represented as a positive int and lo <= hi.
122+
// The caller checks for bytecode stream overflow.
123+
if (lo <= hi && len == (int)len) {
124+
assert(len > 0, "must be");
125+
return (int)len;
126+
} else {
127+
return -1;
128+
}
123129
}
124130

125131
case _lookupswitch: // fall through
@@ -131,9 +137,13 @@ int Bytecodes::special_length_at(Bytecodes::Code code, address bcp, address end)
131137
}
132138
jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
133139
jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
134-
// only return len if it can be represented as a positive int;
135-
// return -1 otherwise
136-
return (len > 0 && len == (int)len) ? len : -1;
140+
// Only return len if it can be represented as a positive int and npairs >= 0.
141+
if (npairs >= 0 && len == (int)len) {
142+
assert(len > 0, "must be");
143+
return (int)len;
144+
} else {
145+
return -1;
146+
}
137147
}
138148
}
139149
// Note: Length functions must return <=0 for invalid bytecodes.

hotspot/src/share/vm/opto/ifnode.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,46 @@ Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) {
882882
// then we are guaranteed to fail, so just start interpreting there.
883883
// We 'expand' the top 3 range checks to include all post-dominating
884884
// checks.
885+
//
886+
// Example:
887+
// a[i+x] // (1) 1 < x < 6
888+
// a[i+3] // (2)
889+
// a[i+4] // (3)
890+
// a[i+6] // max = max of all constants
891+
// a[i+2]
892+
// a[i+1] // min = min of all constants
893+
//
894+
// If x < 3:
895+
// (1) a[i+x]: Leave unchanged
896+
// (2) a[i+3]: Replace with a[i+max] = a[i+6]: i+x < i+3 <= i+6 -> (2) is covered
897+
// (3) a[i+4]: Replace with a[i+min] = a[i+1]: i+1 < i+4 <= i+6 -> (3) and all following checks are covered
898+
// Remove all other a[i+c] checks
899+
//
900+
// If x >= 3:
901+
// (1) a[i+x]: Leave unchanged
902+
// (2) a[i+3]: Replace with a[i+min] = a[i+1]: i+1 < i+3 <= i+x -> (2) is covered
903+
// (3) a[i+4]: Replace with a[i+max] = a[i+6]: i+1 < i+4 <= i+6 -> (3) and all following checks are covered
904+
// Remove all other a[i+c] checks
905+
//
906+
// We only need the top 2 range checks if x is the min or max of all constants.
907+
//
908+
// This, however, only works if the interval [i+min,i+max] is not larger than max_int (i.e. abs(max - min) < max_int):
909+
// The theoretical max size of an array is max_int with:
910+
// - Valid index space: [0,max_int-1]
911+
// - Invalid index space: [max_int,-1] // max_int, min_int, min_int - 1 ..., -1
912+
//
913+
// The size of the consecutive valid index space is smaller than the size of the consecutive invalid index space.
914+
// If we choose min and max in such a way that:
915+
// - abs(max - min) < max_int
916+
// - i+max and i+min are inside the valid index space
917+
// then all indices [i+min,i+max] must be in the valid index space. Otherwise, the invalid index space must be
918+
// smaller than the valid index space which is never the case for any array size.
919+
//
920+
// Choosing a smaller array size only makes the valid index space smaller and the invalid index space larger and
921+
// the argument above still holds.
922+
//
923+
// Note that the same optimization with the same maximal accepted interval size can also be found in C1.
924+
const jlong maximum_number_of_min_max_interval_indices = (jlong)max_jint;
885925

886926
// The top 3 range checks seen
887927
const int NRC =3;
@@ -915,13 +955,18 @@ Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) {
915955
found_immediate_dominator = true;
916956
break;
917957
}
918-
// Gather expanded bounds
919-
off_lo = MIN2(off_lo,offset2);
920-
off_hi = MAX2(off_hi,offset2);
921-
// Record top NRC range checks
922-
prev_checks[nb_checks%NRC].ctl = prev_dom;
923-
prev_checks[nb_checks%NRC].off = offset2;
924-
nb_checks++;
958+
959+
// "x - y" -> must add one to the difference for number of elements in [x,y]
960+
const jlong diff = (jlong)MIN2(offset2, off_lo) - (jlong)MAX2(offset2, off_hi);
961+
if (ABS(diff) < maximum_number_of_min_max_interval_indices) {
962+
// Gather expanded bounds
963+
off_lo = MIN2(off_lo, offset2);
964+
off_hi = MAX2(off_hi, offset2);
965+
// Record top NRC range checks
966+
prev_checks[nb_checks % NRC].ctl = prev_dom;
967+
prev_checks[nb_checks % NRC].off = offset2;
968+
nb_checks++;
969+
}
925970
}
926971
}
927972
prev_dom = dom;

0 commit comments

Comments
 (0)