comparison src/share/vm/c1/c1_RangeCheckElimination.cpp @ 8869:d595e8ddadd9

8010934: assert failure in c1_LinearScan.cpp: "asumption: non-Constant instructions have only virtual operands" Summary: incorrect code to skip some ArrayLength instructions in LIRGenerator Reviewed-by: kvn
author roland
date Fri, 29 Mar 2013 17:25:27 +0100
parents 46f6f063b272
children 6a3629cf7075
comparison
equal deleted inserted replaced
8868:30f42e691e70 8869:d595e8ddadd9
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()) {