/* * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 8066103 * @summary C2's range check smearing allows out of bound array accesses * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestRangeCheckSmearing * */ public class TestRangeCheckSmearing { // first range check is i + max of all constants static int m1(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+9]; if (allaccesses) { res += array[i+8]; res += array[i+7]; res += array[i+6]; res += array[i+5]; res += array[i+4]; res += array[i+3]; res += array[i+2]; res += array[i+1]; } return res; } // first range check is i + min of all constants static int m2(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+1]; if (allaccesses) { res += array[i+2]; res += array[i+3]; res += array[i+4]; res += array[i+5]; res += array[i+6]; res += array[i+7]; res += array[i+8]; res += array[i+9]; } return res; } // first range check is not i + min/max of all constants static int m3(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; if (allaccesses) { res += array[i+2]; res += array[i+1]; res += array[i+4]; res += array[i+5]; res += array[i+6]; res += array[i+7]; res += array[i+8]; res += array[i+9]; } return res; } static int m4(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; if (allaccesses) { res += array[i+4]; res += array[i+1]; res += array[i+2]; res += array[i+5]; res += array[i+6]; res += array[i+7]; res += array[i+8]; res += array[i+9]; } return res; } static int m5(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; res += array[i+2]; if (allaccesses) { res += array[i+1]; res += array[i+4]; res += array[i+5]; res += array[i+6]; res += array[i+7]; res += array[i+8]; res += array[i+9]; } return res; } static int m6(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; res += array[i+4]; if (allaccesses) { res += array[i+2]; res += array[i+1]; res += array[i+5]; res += array[i+6]; res += array[i+7]; res += array[i+8]; res += array[i+9]; } return res; } static int m7(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; res += array[i+2]; res += array[i+4]; if (allaccesses) { res += array[i+1]; res += array[i+5]; res += array[i+6]; res += array[i+7]; res += array[i+8]; res += array[i+9]; } return res; } static int m8(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; res += array[i+4]; res += array[i+2]; if (allaccesses) { res += array[i+1]; res += array[i+5]; res += array[i+6]; res += array[i+7]; res += array[i+8]; res += array[i+9]; } return res; } static int m9(int[] array, int i) { int res = 0; res += array[i+3]; res += array[i+3]; return res; } static int m10(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; if (allaccesses) { res += array[i-2]; res += array[i-1]; res += array[i-4]; res += array[i-5]; res += array[i-6]; } return res; } static int m11(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; if (allaccesses) { res += array[i-2]; res += array[i-1]; res += array[i-3]; res += array[i+4]; res += array[i+5]; res += array[i+6]; } return res; } static int m12(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; res += array[i-2]; if (allaccesses) { res += array[i+5]; res += array[i+6]; } return res; } static int m13(int[] array, int i, boolean allaccesses) { int res = 0; res += array[i+3]; res += array[i+6]; if (allaccesses) { res += array[i-2]; res += array[i-3]; } return res; } static public void main(String[] args) { boolean success = true; boolean exception = false; int[] array = new int[10]; for (int i = 0; i < 20000; i++) { m1(array, 0, (i % 2) == 0); } exception = false; try { m1(array, 8, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m1"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m1"); success = false; } for (int i = 0; i < 20000; i++) { m2(array, 0, (i % 2) == 0); } exception = false; try { m2(array, -9, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m2"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m2"); success = false; } for (int i = 0; i < 20000; i++) { m3(array, 0, (i % 2) == 0); } exception = false; try { m3(array, 8, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m3"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m3"); success = false; } for (int i = 0; i < 20000; i++) { m4(array, 0, (i % 2) == 0); } exception = false; try { m4(array, -9, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m4"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m4"); success = false; } for (int i = 0; i < 20000; i++) { m5(array, 0, (i % 2) == 0); } exception = false; try { m5(array, -3, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m5"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m5"); success = false; } for (int i = 0; i < 20000; i++) { m6(array, 0, (i % 2) == 0); } exception = false; try { m6(array, 6, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m6"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m6"); success = false; } for (int i = 0; i < 20000; i++) { m7(array, 0, (i % 2) == 0); } exception = false; try { m7(array, 6, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m7"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m7"); success = false; } for (int i = 0; i < 20000; i++) { m8(array, 0, (i % 2) == 0); } exception = false; try { m8(array, -3, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m8"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m8"); success = false; } for (int i = 0; i < 20000; i++) { m9(array, 0); } for (int i = 0; i < 20000; i++) { m10(array, 6, (i % 2) == 0); } exception = false; try { m10(array, 15, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m10"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m10"); success = false; } for (int i = 0; i < 20000; i++) { m11(array, 3, (i % 2) == 0); } exception = false; try { m11(array, 12, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m11"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m11"); success = false; } for (int i = 0; i < 20000; i++) { m12(array, 3, (i % 2) == 0); } exception = false; try { m12(array, -3, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m12"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m12"); success = false; } for (int i = 0; i < 20000; i++) { m13(array, 3, (i % 2) == 0); } exception = false; try { m13(array, 6, false); } catch(ArrayIndexOutOfBoundsException aioob) { exception = true; System.out.println("ArrayIndexOutOfBoundsException thrown in m13"); } if (!exception) { System.out.println("ArrayIndexOutOfBoundsException was not thrown in m13"); success = false; } if (!success) { throw new RuntimeException("Some tests failed"); } } }