| /* |
| * Copyright (c) 2021, Red Hat, Inc. 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 8259609 8276116 |
| * @summary C2: optimize long range checks in long counted loops |
| * @requires vm.compiler2.enabled |
| * @requires vm.compMode != "Xcomp" |
| * @library /test/lib / |
| * @modules java.base/jdk.internal.util |
| * @build jdk.test.whitebox.WhiteBox |
| * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox |
| * |
| * @run main/othervm -ea -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseOnStackReplacement |
| * -XX:+UnlockExperimentalVMOptions -XX:PerMethodSpecTrapLimit=5000 -XX:PerMethodTrapLimit=100 |
| * TestLongRangeCheck |
| * |
| */ |
| |
| import jdk.internal.util.Preconditions; |
| import jdk.test.whitebox.WhiteBox; |
| import java.lang.reflect.Method; |
| import compiler.whitebox.CompilerWhiteBoxTest; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.net.URLClassLoader; |
| import java.nio.file.Paths; |
| import java.lang.reflect.InvocationTargetException; |
| |
| public class TestLongRangeCheck { |
| private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); |
| |
| private static void assertIsCompiled(Method m) { |
| if (!WHITE_BOX.isMethodCompiled(m) || WHITE_BOX.getMethodCompilationLevel(m) != CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) { |
| throw new RuntimeException("should still be compiled"); |
| } |
| } |
| |
| private static void assertIsNotCompiled(Method m) { |
| if (WHITE_BOX.isMethodCompiled(m) && WHITE_BOX.getMethodCompilationLevel(m) == CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) { |
| throw new RuntimeException("should have been deoptimized"); |
| } |
| } |
| |
| private static void compile(Method m) { |
| WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); |
| assertIsCompiled(m); |
| } |
| |
| public static ClassLoader newClassLoader() { |
| try { |
| return new URLClassLoader(new URL[] { |
| Paths.get(System.getProperty("test.classes",".")).toUri().toURL(), |
| }, null); |
| } catch (MalformedURLException e){ |
| throw new RuntimeException("Unexpected URL conversion failure", e); |
| } |
| } |
| |
| private static void test(String method, long start, long stop, long length, long offset) throws Exception { |
| Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod(method, long.class, long.class, long.class, long.class); |
| m.invoke(null, start, stop, length, offset); // run once so all classes are loaded |
| compile(m); |
| |
| m.invoke(null, start, stop, length, offset); |
| assertIsCompiled(m); |
| try { |
| m.invoke(null, start-1, stop, length, offset); |
| throw new RuntimeException("should have thrown"); |
| } catch(InvocationTargetException e) { |
| if (!(e.getCause() instanceof IndexOutOfBoundsException)) { |
| throw new RuntimeException("unexpected exception"); |
| } |
| } |
| assertIsNotCompiled(m); |
| |
| m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod(method, long.class, long.class, long.class, long.class); |
| m.invoke(null, start, stop, length, offset); // run once so all classes are loaded |
| compile(m); |
| assertIsCompiled(m); |
| |
| m.invoke(null, start, stop, length, offset); |
| assertIsCompiled(m); |
| try { |
| m.invoke(null, stop, stop + 100, length, offset); |
| throw new RuntimeException("should have thrown"); |
| } catch(InvocationTargetException e) { |
| if (!(e.getCause() instanceof IndexOutOfBoundsException)) { |
| throw new RuntimeException("unexpected exception"); |
| } |
| } |
| assertIsNotCompiled(m); |
| |
| m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod(method, long.class, long.class, long.class, long.class); |
| m.invoke(null, start, stop, length, offset); // run once so all classes are loaded |
| compile(m); |
| |
| m.invoke(null, start, stop, length, offset); |
| assertIsCompiled(m); |
| try { |
| m.invoke(null, start, stop+1, length, offset); |
| throw new RuntimeException("should have thrown"); |
| } catch(InvocationTargetException e) { |
| if (!(e.getCause() instanceof IndexOutOfBoundsException)) { |
| throw new RuntimeException("unexpected exception"); |
| } |
| } |
| assertIsNotCompiled(m); |
| } |
| |
| private static void testOverflow(String method, long start, long stop, long length, long offset0, long offset1) throws Exception { |
| Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod(method, long.class, long.class, long.class, long.class); |
| m.invoke(null, start, stop, length, offset0); |
| compile(m); |
| |
| m.invoke(null, start, stop, length, offset0); |
| assertIsCompiled(m); |
| try { |
| m.invoke(null, start, stop, length, offset1); |
| throw new RuntimeException("should have thrown"); |
| } catch(InvocationTargetException e) { |
| if (!(e.getCause() instanceof IndexOutOfBoundsException)) { |
| throw new RuntimeException("unexpected exception"); |
| } |
| } |
| assertIsNotCompiled(m); |
| } |
| |
| private static void testConditional(String method, long start, long stop, long length, long offset0, long offset1, long start1, long stop1) throws Exception { |
| Method m; |
| |
| if (start1 != start) { |
| m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod(method, long.class, long.class, long.class, long.class, long.class, long.class); |
| m.invoke(null, start, stop, length, offset0, start, stop); |
| compile(m); |
| |
| m.invoke(null, start, stop, length, offset0, start, stop); |
| assertIsCompiled(m); |
| try { |
| m.invoke(null, start, stop, length, offset1, start1-1, stop1); |
| throw new RuntimeException("should have thrown"); |
| } catch(InvocationTargetException e) { |
| if (!(e.getCause() instanceof IndexOutOfBoundsException)) { |
| throw new RuntimeException("unexpected exception"); |
| } |
| } |
| assertIsNotCompiled(m); |
| } |
| |
| if (stop1 != stop) { |
| m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod(method, long.class, long.class, long.class, long.class, long.class, long.class); |
| m.invoke(null, start, stop, length, offset0, start, stop); |
| compile(m); |
| |
| m.invoke(null, start, stop, length, offset0, start, stop); |
| assertIsCompiled(m); |
| try { |
| m.invoke(null, start, stop, length, offset1, start1, stop1+1); |
| throw new RuntimeException("should have thrown"); |
| } catch(InvocationTargetException e) { |
| if (!(e.getCause() instanceof IndexOutOfBoundsException)) { |
| throw new RuntimeException("unexpected exception"); |
| } |
| } |
| assertIsNotCompiled(m); |
| } |
| |
| m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod(method, long.class, long.class, long.class, long.class, long.class, long.class); |
| m.invoke(null, start, stop, length, offset0, start, stop); |
| compile(m); |
| |
| m.invoke(null, start, stop, length, offset0, start, stop); |
| assertIsCompiled(m); |
| |
| m.invoke(null, start, stop, length, offset1, start1, stop1); |
| assertIsCompiled(m); |
| } |
| |
| public static void main(String[] args) throws Exception { |
| |
| test("testStridePosScalePos", 0, 100, 100, 0); |
| |
| test("testStrideNegScaleNeg", 0, 100, 100, 100); |
| |
| test("testStrideNegScalePos", 0, 100, 100, 0); |
| |
| test("testStridePosScaleNeg", 0, 100, 100, 99); |
| |
| test("testStridePosScalePosNotOne", 0, 100, 1090, 0); |
| |
| test("testStrideNegScaleNegNotOne", 0, 100, 1090, 1100); |
| |
| test("testStrideNegScalePosNotOne", 0, 100, 1090, 0); |
| |
| test("testStridePosScaleNegNotOne", 0, 100, 1090, 1089); |
| |
| long v = ((long)Integer.MAX_VALUE / 10000) * 250000; |
| |
| test("testStridePosNotOneScalePos", -v, v, v * 2, v); |
| |
| test("testStrideNegNotOneScaleNeg", -v, v, v * 2, v); |
| |
| test("testStrideNegNotOneScalePos", -v, v, v * 2, v); |
| |
| test("testStridePosNotOneScaleNeg", -v, v, v * 2, v-1); |
| |
| // offset causes overflow |
| testOverflow("testStridePosScalePos", 0, 100, 100, 0, Long.MAX_VALUE - 50); |
| testOverflow("testStrideNegScaleNeg", 0, 100, 100, 100, Long.MIN_VALUE + 50); |
| testOverflow("testStrideNegScalePos", 0, 100, 100, 0, Long.MAX_VALUE - 50); |
| testOverflow("testStridePosScaleNeg", 0, 100, 100, 99, Long.MIN_VALUE + 50); |
| |
| // no spurious deopt if the range check doesn't fail because not executed |
| testConditional("testStridePosScalePosConditional", 0, 100, 100, 0, -50, 50, 100); |
| testConditional("testStridePosScalePosConditional", 0, 100, Long.MAX_VALUE, 0, Long.MAX_VALUE - 50, 0, 50); |
| testConditional("testStrideNegScaleNegConditional", 0, 100, 100, 100, 50, 0, 51); |
| testConditional("testStrideNegScaleNegConditional", 0, 100, Long.MAX_VALUE, 100, Long.MIN_VALUE + 50, 52, 100); |
| testConditional("testStrideNegScalePosConditional", 0, 100, 100, 0, -50, 50, 100); |
| testConditional("testStrideNegScalePosConditional", 0, 100, Long.MAX_VALUE, 100, Long.MAX_VALUE - 50, 0, 50); |
| testConditional("testStridePosScaleNegConditional", 0, 100, 100, 99, 50, 0, 51); |
| testConditional("testStridePosScaleNegConditional", 0, 100, Long.MAX_VALUE, 99, Long.MIN_VALUE + 50, 52, 100); |
| |
| test("testStridePosScalePosInIntLoop", 0, 100, 100, 0); |
| |
| test("testStrideNegScaleNegInIntLoop", 0, 100, 100, 100); |
| |
| test("testStrideNegScalePosInIntLoop", 0, 100, 100, 0); |
| |
| test("testStridePosScaleNegInIntLoop", 0, 100, 100, 99); |
| |
| test("testStridePosScalePosNotOneInIntLoop", 0, 100, 1090, 0); |
| |
| test("testStrideNegScaleNegNotOneInIntLoop", 0, 100, 1090, 1100); |
| |
| test("testStrideNegScalePosNotOneInIntLoop", 0, 100, 1090, 0); |
| |
| test("testStridePosScaleNegNotOneInIntLoop", 0, 100, 1090, 1089); |
| |
| v = ((long)Integer.MAX_VALUE / 10000) * 9999; |
| |
| test("testStridePosNotOneScalePosInIntLoop", -v, v, v * 4, 2 * v); |
| |
| test("testStrideNegNotOneScaleNegInIntLoop", -v, v, v * 4, 2 * v); |
| |
| test("testStrideNegNotOneScalePosInIntLoop", -v, v, v * 4, 2 * v); |
| |
| test("testStridePosNotOneScaleNegInIntLoop", -v, v, v * 4, 2 * v - 1); |
| |
| // offset causes overflow |
| testOverflow("testStridePosScalePosInIntLoop", 0, 100, 100, 0, Long.MAX_VALUE - 50); |
| testOverflow("testStrideNegScaleNegInIntLoop", 0, 100, 100, 100, Long.MIN_VALUE + 50); |
| testOverflow("testStrideNegScalePosInIntLoop", 0, 100, 100, 0, Long.MAX_VALUE - 50); |
| testOverflow("testStridePosScaleNegInIntLoop", 0, 100, 100, 99, Long.MIN_VALUE + 50); |
| // no spurious deopt if the range check doesn't fail because not executed |
| testConditional("testStridePosScalePosConditionalInIntLoop", 0, 100, 100, 0, -50, 50, 100); |
| testConditional("testStridePosScalePosConditionalInIntLoop", 0, 100, Long.MAX_VALUE, 0, Long.MAX_VALUE - 50, 0, 50); |
| testConditional("testStrideNegScaleNegConditionalInIntLoop", 0, 100, 100, 100, 50, 0, 51); |
| testConditional("testStrideNegScaleNegConditionalInIntLoop", 0, 100, Long.MAX_VALUE, 100, Long.MIN_VALUE + 50, 52, 100); |
| testConditional("testStrideNegScalePosConditionalInIntLoop", 0, 100, 100, 0, -50, 50, 100); |
| testConditional("testStrideNegScalePosConditionalInIntLoop", 0, 100, Long.MAX_VALUE, 100, Long.MAX_VALUE - 50, 0, 50); |
| testConditional("testStridePosScaleNegConditionalInIntLoop", 0, 100, 100, 99, 50, 0, 51); |
| testConditional("testStridePosScaleNegConditionalInIntLoop", 0, 100, Long.MAX_VALUE, 99, Long.MIN_VALUE + 50, 52, 100); |
| |
| test("testStridePosScalePosNotOneInIntLoop2", 0, 100, 1090, 0); |
| |
| test("testStrideNegScaleNegNotOneInIntLoop2", 0, 100, 1090, 1100); |
| |
| test("testStrideNegScalePosNotOneInIntLoop2", 0, 100, 1090, 0); |
| |
| test("testStridePosScaleNegNotOneInIntLoop2", 0, 100, 1090, 1089); |
| |
| { |
| Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod("testStridePosScalePosInIntLoopOverflow", long.class, long.class, long.class, long.class); |
| long stride = 1 << 14; |
| long scale = 1 << 15; |
| long offset = stride * scale * 4; |
| long length = offset + stride * scale * 3 + 1; |
| long stop = stride * 5; |
| |
| m.invoke(null, 0, stop, length, offset); |
| compile(m); |
| |
| m.invoke(null, 0, stop, length, offset); |
| // deoptimizes even though no range check fails |
| } |
| { |
| Method m = newClassLoader().loadClass("TestLongRangeCheck").getDeclaredMethod("testStridePosScalePosInIntLoopOverflow", long.class, long.class, long.class, long.class); |
| long stride = 1 << 14; |
| long scale = 1 << 15; |
| long offset = stride * scale * 4; |
| long length = offset + stride * scale * 3 + 1; |
| long stop = stride * 5; |
| |
| m.invoke(null, 0, stop, length, offset); |
| compile(m); |
| |
| offset = 0; |
| stop = stride * 5; |
| |
| try { |
| m.invoke(null, 0, stop, length, offset); |
| throw new RuntimeException("should have thrown"); |
| } catch(InvocationTargetException e) { |
| if (!(e.getCause() instanceof IndexOutOfBoundsException)) { |
| throw new RuntimeException("unexpected exception"); |
| } |
| } |
| assertIsNotCompiled(m); |
| } |
| } |
| |
| public static void testStridePosScalePos(long start, long stop, long length, long offset) { |
| final long scale = 1; |
| final long stride = 1; |
| for (long i = start; i < stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScaleNeg(long start, long stop, long length, long offset) { |
| final long scale = -1; |
| final long stride = 1; |
| for (long i = stop; i > start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScalePos(long start, long stop, long length, long offset) { |
| final long scale = 1; |
| final long stride = 1; |
| for (long i = stop-1; i >= start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScaleNeg(long start, long stop, long length, long offset) { |
| final long scale = -1; |
| final long stride = 1; |
| for (long i = start; i < stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScalePosNotOne(long start, long stop, long length, long offset) { |
| final long scale = 11; |
| final long stride = 1; |
| for (long i = start; i < stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScaleNegNotOne(long start, long stop, long length, long offset) { |
| final long scale = -11; |
| final long stride = 1; |
| for (long i = stop; i > start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScalePosNotOne(long start, long stop, long length, long offset) { |
| final long scale = 11; |
| final long stride = 1; |
| for (long i = stop-1; i >= start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScaleNegNotOne(long start, long stop, long length, long offset) { |
| final long scale = -11; |
| final long stride = 1; |
| for (long i = start; i < stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosNotOneScalePos(long start, long stop, long length, long offset) { |
| final long scale = 1; |
| final long stride = Integer.MAX_VALUE / 10000; |
| for (long i = start; i < stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegNotOneScaleNeg(long start, long stop, long length, long offset) { |
| final long scale = -1; |
| final long stride = Integer.MAX_VALUE / 10000; |
| for (long i = stop; i > start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegNotOneScalePos(long start, long stop, long length, long offset) { |
| final long scale = 1; |
| final long stride = Integer.MAX_VALUE / 10000; |
| for (long i = stop-1; i >= start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosNotOneScaleNeg(long start, long stop, long length, long offset) { |
| final long scale = -1; |
| final long stride = Integer.MAX_VALUE / 10000; |
| for (long i = start; i < stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScalePosConditional(long start, long stop, long length, long offset, long start2, long stop2) { |
| Preconditions.checkIndex(0, length, null); |
| final long scale = 1; |
| final long stride = 1; |
| for (long i = start; i < stop; i += stride) { |
| if (i >= start2 && i < stop2) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |
| |
| public static void testStrideNegScaleNegConditional(long start, long stop, long length, long offset, long start2, long stop2) { |
| final long scale = -1; |
| final long stride = 1; |
| for (long i = stop; i > start; i -= stride) { |
| if (i >= start2 && i < stop2) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |
| |
| public static void testStrideNegScalePosConditional(long start, long stop, long length, long offset, long start2, long stop2) { |
| final long scale = 1; |
| final long stride = 1; |
| for (long i = stop-1; i >= start; i -= stride) { |
| if (i >= start2 && i < stop2) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |
| |
| public static void testStridePosScaleNegConditional(long start, long stop, long length, long offset, long start2, long stop2) { |
| final long scale = -1; |
| final long stride = 1; |
| for (long i = start; i < stop; i += stride) { |
| if (i >= start2 && i < stop2) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |
| |
| private static void checkInputs(long... inputs) { |
| for (int i = 0; i < inputs.length; i++) { |
| if ((long)((int)inputs[i]) != inputs[i]) { |
| throw new RuntimeException("bad arguments"); |
| } |
| } |
| } |
| |
| public static void testStridePosScalePosInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = 1; |
| final int stride = 1; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScaleNegInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = -1; |
| final int stride = 1; |
| for (int i = (int)stop; i > (int)start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScalePosInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = 1; |
| final int stride = 1; |
| for (int i = (int)(stop-1); i >= (int)start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScaleNegInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = -1; |
| final int stride = 1; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScalePosNotOneInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = 11; |
| final int stride = 1; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScaleNegNotOneInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = -11; |
| final int stride = 1; |
| for (int i = (int)stop; i > (int)start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScalePosNotOneInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = 11; |
| final int stride = 1; |
| for (int i = (int)(stop-1); i >= (int)start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScaleNegNotOneInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = -11; |
| final int stride = 1; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosNotOneScalePosInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = 2; |
| final int stride = Integer.MAX_VALUE / 10000; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegNotOneScaleNegInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = -2; |
| final int stride = Integer.MAX_VALUE / 10000; |
| for (int i = (int)stop; i > (int)start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegNotOneScalePosInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = 2; |
| final int stride = Integer.MAX_VALUE / 10000; |
| for (int i = (int)(stop-1); i >= (int)start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosNotOneScaleNegInIntLoop(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final long scale = -2; |
| final int stride = Integer.MAX_VALUE / 10000; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScalePosConditionalInIntLoop(long start, long stop, long length, long offset, long start2, long stop2) { |
| checkInputs(start, stop, start2, stop2); |
| final long scale = 1; |
| final int stride = 1; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| if (i >= (int)start2 && i < (int)stop2) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |
| |
| public static void testStrideNegScaleNegConditionalInIntLoop(long start, long stop, long length, long offset, long start2, long stop2) { |
| checkInputs(start, stop, start2, stop2); |
| final long scale = -1; |
| final int stride = 1; |
| for (int i = (int)stop; i > (int)start; i -= stride) { |
| if (i >= (int)start2 && i < (int)stop2) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |
| |
| public static void testStrideNegScalePosConditionalInIntLoop(long start, long stop, long length, long offset, long start2, long stop2) { |
| checkInputs(start, stop, start2, stop2); |
| final long scale = 1; |
| final int stride = 1; |
| for (int i = (int)(stop-1); i >= (int)start; i -= stride) { |
| if (i >= (int)start2 && i < (int)stop2) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |
| |
| public static void testStridePosScaleNegConditionalInIntLoop(long start, long stop, long length, long offset, long start2, long stop2) { |
| checkInputs(start, stop, start2, stop2); |
| final long scale = -1; |
| final int stride = 1; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| if (i >= (int)start2 && i < (int)stop2) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |
| |
| public static void testStridePosScalePosNotOneInIntLoop2(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final int scale = 11; |
| final int stride = 1; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScaleNegNotOneInIntLoop2(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final int scale = -11; |
| final int stride = 1; |
| for (int i = (int)stop; i > (int)start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStrideNegScalePosNotOneInIntLoop2(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final int scale = 11; |
| final int stride = 1; |
| for (int i = (int)(stop-1); i >= (int)start; i -= stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScaleNegNotOneInIntLoop2(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final int scale = -11; |
| final int stride = 1; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| |
| public static void testStridePosScalePosInIntLoopOverflow(long start, long stop, long length, long offset) { |
| checkInputs(start, stop); |
| final int scale = 1 << 15; |
| final int stride = 1 << 14; |
| for (int i = (int)start; i < (int)stop; i += stride) { |
| Preconditions.checkIndex(scale * i + offset, length, null); |
| } |
| } |
| } |