478 } |
478 } |
479 |
479 |
480 |
480 |
481 void LIRGenerator::array_range_check(LIR_Opr array, LIR_Opr index, |
481 void LIRGenerator::array_range_check(LIR_Opr array, LIR_Opr index, |
482 CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info) { |
482 CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info) { |
483 CodeStub* stub = new RangeCheckStub(range_check_info, index); |
483 CodeStub* stub = new RangeCheckStub(range_check_info, index, array); |
484 if (index->is_constant()) { |
484 if (index->is_constant()) { |
485 cmp_mem_int(lir_cond_belowEqual, array, arrayOopDesc::length_offset_in_bytes(), |
485 cmp_mem_int(lir_cond_belowEqual, array, arrayOopDesc::length_offset_in_bytes(), |
486 index->as_jint(), null_check_info); |
486 index->as_jint(), null_check_info); |
487 __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch |
487 __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch |
488 } else { |
488 } else { |
492 } |
492 } |
493 } |
493 } |
494 |
494 |
495 |
495 |
496 void LIRGenerator::nio_range_check(LIR_Opr buffer, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) { |
496 void LIRGenerator::nio_range_check(LIR_Opr buffer, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) { |
497 CodeStub* stub = new RangeCheckStub(info, index, true); |
497 CodeStub* stub = new RangeCheckStub(info, index); |
498 if (index->is_constant()) { |
498 if (index->is_constant()) { |
499 cmp_mem_int(lir_cond_belowEqual, buffer, java_nio_Buffer::limit_offset(), index->as_jint(), info); |
499 cmp_mem_int(lir_cond_belowEqual, buffer, java_nio_Buffer::limit_offset(), index->as_jint(), info); |
500 __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch |
500 __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch |
501 } else { |
501 } else { |
502 cmp_reg_mem(lir_cond_aboveEqual, index, buffer, |
502 cmp_reg_mem(lir_cond_aboveEqual, index, buffer, |
1590 } |
1590 } |
1591 |
1591 |
1592 if (GenerateRangeChecks && needs_range_check) { |
1592 if (GenerateRangeChecks && needs_range_check) { |
1593 if (use_length) { |
1593 if (use_length) { |
1594 __ cmp(lir_cond_belowEqual, length.result(), index.result()); |
1594 __ cmp(lir_cond_belowEqual, length.result(), index.result()); |
1595 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); |
1595 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result(), array.result())); |
1596 } else { |
1596 } else { |
1597 array_range_check(array.result(), index.result(), null_check_info, range_check_info); |
1597 array_range_check(array.result(), index.result(), null_check_info, range_check_info); |
1598 // range_check also does the null check |
1598 // range_check also does the null check |
1599 null_check_info = NULL; |
1599 null_check_info = NULL; |
1600 } |
1600 } |
1754 index.load_item(); |
1754 index.load_item(); |
1755 |
1755 |
1756 LIR_Opr result = rlock_result(x); |
1756 LIR_Opr result = rlock_result(x); |
1757 if (GenerateRangeChecks) { |
1757 if (GenerateRangeChecks) { |
1758 CodeEmitInfo* info = state_for(x); |
1758 CodeEmitInfo* info = state_for(x); |
1759 CodeStub* stub = new RangeCheckStub(info, index.result(), true); |
1759 CodeStub* stub = new RangeCheckStub(info, index.result()); |
1760 if (index.result()->is_constant()) { |
1760 if (index.result()->is_constant()) { |
1761 cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), index.result()->as_jint(), info); |
1761 cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), index.result()->as_jint(), info); |
1762 __ branch(lir_cond_belowEqual, T_INT, stub); |
1762 __ branch(lir_cond_belowEqual, T_INT, stub); |
1763 } else { |
1763 } else { |
1764 cmp_reg_mem(lir_cond_aboveEqual, index.result(), buf.result(), |
1764 cmp_reg_mem(lir_cond_aboveEqual, index.result(), buf.result(), |
1835 } |
1835 } |
1836 } |
1836 } |
1837 |
1837 |
1838 if (GenerateRangeChecks && needs_range_check) { |
1838 if (GenerateRangeChecks && needs_range_check) { |
1839 if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) { |
1839 if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) { |
1840 __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result())); |
1840 __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result(), array.result())); |
1841 } else if (use_length) { |
1841 } else if (use_length) { |
1842 // TODO: use a (modified) version of array_range_check that does not require a |
1842 // TODO: use a (modified) version of array_range_check that does not require a |
1843 // constant length to be loaded to a register |
1843 // constant length to be loaded to a register |
1844 __ cmp(lir_cond_belowEqual, length.result(), index.result()); |
1844 __ cmp(lir_cond_belowEqual, length.result(), index.result()); |
1845 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); |
1845 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result(), array.result())); |
1846 } else { |
1846 } else { |
1847 array_range_check(array.result(), index.result(), null_check_info, range_check_info); |
1847 array_range_check(array.result(), index.result(), null_check_info, range_check_info); |
1848 // The range check performs the null check, so clear it out for the load |
1848 // The range check performs the null check, so clear it out for the load |
1849 null_check_info = NULL; |
1849 null_check_info = NULL; |
1850 } |
1850 } |