643 Constant *const_instr = new Constant(new IntConstant(constant)); |
643 Constant *const_instr = new Constant(new IntConstant(constant)); |
644 insert_position = insert_after(insert_position, const_instr, bci); |
644 insert_position = insert_after(insert_position, const_instr, bci); |
645 return predicate_add(left, left_const, cond, const_instr, state, insert_position); |
645 return predicate_add(left, left_const, cond, const_instr, state, insert_position); |
646 } |
646 } |
647 |
647 |
648 // Insert deoptimization, returns true if sucessful or false if range check should not be removed |
648 // Insert deoptimization |
649 void RangeCheckEliminator::insert_deoptimization(ValueStack *state, Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper, AccessIndexed *ai) { |
649 void RangeCheckEliminator::insert_deoptimization(ValueStack *state, Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper, AccessIndexed *ai) { |
650 assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before"); |
650 assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before"); |
651 bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr); |
651 bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr); |
652 |
652 |
653 int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1); |
653 int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1); |
667 // Compare for smaller or equal 0 |
667 // Compare for smaller or equal 0 |
668 insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci); |
668 insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci); |
669 } |
669 } |
670 } |
670 } |
671 |
671 |
|
672 // No upper check required -> skip |
|
673 if (!upper_check) return; |
|
674 |
672 // We need to know length of array |
675 // We need to know length of array |
673 if (!length_instr) { |
676 if (!length_instr) { |
674 // Load length if necessary |
677 // Load length if necessary |
675 ArrayLength *length = new ArrayLength(array_instr, state->copy()); |
678 ArrayLength *length = new ArrayLength(array_instr, state->copy()); |
676 NOT_PRODUCT(length->set_printable_bci(ai->printable_bci())); |
679 NOT_PRODUCT(length->set_printable_bci(ai->printable_bci())); |
677 length->set_exception_state(length->state_before()); |
680 length->set_exception_state(length->state_before()); |
678 length->set_flag(Instruction::DeoptimizeOnException, true); |
681 length->set_flag(Instruction::DeoptimizeOnException, true); |
679 insert_position = insert_position->insert_after(length); |
682 insert_position = insert_position->insert_after(length); |
680 length_instr = length; |
683 length_instr = length; |
681 } |
684 } |
682 |
|
683 // No upper check required -> skip |
|
684 if (!upper_check) return; |
|
685 |
685 |
686 if (!upper_instr) { |
686 if (!upper_instr) { |
687 // Compare for geq array.length |
687 // Compare for geq array.length |
688 insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci); |
688 insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci); |
689 } else { |
689 } else { |
775 void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) { |
775 void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) { |
776 TRACE_RANGE_CHECK_ELIMINATION( |
776 TRACE_RANGE_CHECK_ELIMINATION( |
777 tty->fill_to(block->dominator_depth()*2) |
777 tty->fill_to(block->dominator_depth()*2) |
778 ); |
778 ); |
779 TRACE_RANGE_CHECK_ELIMINATION( |
779 TRACE_RANGE_CHECK_ELIMINATION( |
780 tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), ai->length()->id()) |
780 tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), (ai->length() != NULL ? ai->length()->id() :-1 )) |
781 ); |
781 ); |
782 |
782 |
783 if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) { |
783 if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) { |
784 Bound *index_bound = get_bound(ai->index()); |
784 Bound *index_bound = get_bound(ai->index()); |
785 if (!index_bound->has_lower() || !index_bound->has_upper()) { |
785 if (!index_bound->has_lower() || !index_bound->has_upper()) { |