Mercurial > hg > truffle
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()) { |