Path: blob/master/test/hotspot/jtreg/compiler/intrinsics/mathexact/Verify.java
41153 views
/*1* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package compiler.intrinsics.mathexact;2425import jdk.test.lib.Utils;2627import java.util.Random;2829/**30* The class depends on Utils class from testlibrary package.31* It uses factory method that obtains random generator.32*/33public class Verify {34public static String throwWord(boolean threw) {35return (threw ? "threw" : "didn't throw");36}3738public static void verifyResult(UnaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int value) {39if (exception1 != exception2) {40throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value);41}42if (result1 != result2) {43throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);44}45}4647public static void verifyResult(UnaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long value) {48if (exception1 != exception2) {49throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value);50}51if (result1 != result2) {52throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);53}54}5556private static void verifyResult(BinaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int a, int b) {57if (exception1 != exception2) {58throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);59}60if (result1 != result2) {61throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);62}63}6465private static void verifyResult(BinaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long a, long b) {66if (exception1 != exception2) {67throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);68}69if (result1 != result2) {70throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);71}72}737475public static void verifyUnary(int a, UnaryMethod method) {76boolean exception1 = false, exception2 = false;77int result1 = 0, result2 = 0;78try {79result1 = method.checkMethod(a);80} catch (ArithmeticException e) {81exception1 = true;82}83try {84result2 = method.safeMethod(a);85} catch (ArithmeticException e) {86exception2 = true;87}8889verifyResult(method, result1, result2, exception1, exception2, a);90}9192public static void verifyUnary(long a, UnaryLongMethod method) {93boolean exception1 = false, exception2 = false;94long result1 = 0, result2 = 0;95try {96result1 = method.checkMethod(a);97} catch (ArithmeticException e) {98exception1 = true;99}100try {101result2 = method.safeMethod(a);102} catch (ArithmeticException e) {103exception2 = true;104}105106verifyResult(method, result1, result2, exception1, exception2, a);107}108109110public static void verifyBinary(int a, int b, BinaryMethod method) {111boolean exception1 = false, exception2 = false;112int result1 = 0, result2 = 0;113try {114result1 = method.checkMethod(a, b);115} catch (ArithmeticException e) {116exception1 = true;117}118try {119result2 = method.safeMethod(a, b);120} catch (ArithmeticException e) {121exception2 = true;122}123124verifyResult(method, result1, result2, exception1, exception2, a, b);125}126127public static void verifyBinary(long a, long b, BinaryLongMethod method) {128boolean exception1 = false, exception2 = false;129long result1 = 0, result2 = 0;130try {131result1 = method.checkMethod(a, b);132} catch (ArithmeticException e) {133exception1 = true;134}135try {136result2 = method.safeMethod(a, b);137} catch (ArithmeticException e) {138exception2 = true;139}140141verifyResult(method, result1, result2, exception1, exception2, a, b);142}143144145public static class LoadTest {146public static Random rnd = Utils.getRandomInstance();147public static int[] values = new int[256];148149public static void init() {150for (int i = 0; i < values.length; ++i) {151values[i] = rnd.nextInt();152}153}154155public static void verify(BinaryMethod method) {156for (int i = 0; i < 50000; ++i) {157Verify.verifyBinary(values[i & 255], values[i & 255] - i, method);158Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method);159Verify.verifyBinary(values[i & 255], values[i & 255], method);160if ((i & 1) == 1 && i > 5) {161Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method);162} else {163Verify.verifyBinary(values[i & 255] - i, values[i & 255] + i, method);164}165Verify.verifyBinary(values[i & 255], values[(i + 1) & 255], method);166}167}168}169170public static class NonConstantTest {171public static Random rnd = Utils.getRandomInstance();172public static int[] values = new int[] { Integer.MAX_VALUE, Integer.MIN_VALUE };173174public static void verify(BinaryMethod method) {175for (int i = 0; i < 50000; ++i) {176int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();177Verify.verifyBinary(rnd1, rnd2, method);178Verify.verifyBinary(rnd1, rnd2 + 1, method);179Verify.verifyBinary(rnd1 + 1, rnd2, method);180Verify.verifyBinary(rnd1 - 1, rnd2, method);181Verify.verifyBinary(rnd1, rnd2 - 1, method);182Verify.verifyBinary(0, values[0], method);183Verify.verifyBinary(values[0], 0, method);184Verify.verifyBinary(0, values[1], method);185Verify.verifyBinary(values[1], 0, method);186}187}188}189190public static class NonConstantLongTest {191public static long[] values = { Long.MIN_VALUE, Long.MAX_VALUE, 0, Long.MAX_VALUE - 1831 };192public static Random rnd = Utils.getRandomInstance();193194public static void verify(BinaryLongMethod method) {195for (int i = 0; i < 50000; ++i) {196long rnd1 = rnd.nextLong(), rnd2 = rnd.nextLong();197Verify.verifyBinary(rnd1, rnd2, method);198Verify.verifyBinary(rnd1, rnd2 + 1, method);199Verify.verifyBinary(rnd1 + 1, rnd2, method);200Verify.verifyBinary(rnd1 - 1, rnd2, method);201Verify.verifyBinary(rnd1, rnd2 - 1, method);202Verify.verifyBinary(rnd1 + Long.MAX_VALUE - rnd2, rnd2 + 1, method);203Verify.verifyBinary(values[0], values[2], method);204Verify.verifyBinary(values[1], values[2], method);205Verify.verifyBinary(values[3], 74L, method);206}207}208}209210public static class LoopDependentTest {211public static Random rnd = Utils.getRandomInstance();212213public static void verify(BinaryMethod method) {214int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();215runTest(rnd1, rnd2, method);216}217218private static void runTest(int rnd1, int rnd2, BinaryMethod method) {219for (int i = 0; i < 50000; ++i) {220Verify.verifyBinary(rnd1 + i, rnd2 + i, method);221Verify.verifyBinary(rnd1 + i, rnd2 + (i & 0xff), method);222Verify.verifyBinary(rnd1 - i, rnd2 - (i & 0xff), method);223Verify.verifyBinary(rnd1 + i + 1, rnd2 + i + 2, method);224Verify.verifyBinary(rnd1 + i * 2, rnd2 + i, method);225}226}227}228229public static class ConstantTest {230public static void verify(BinaryMethod method) {231for (int i = 0; i < 50000; ++i) {232Verify.verifyBinary(5, 7, method);233Verify.verifyBinary(Integer.MAX_VALUE, 1, method);234Verify.verifyBinary(Integer.MIN_VALUE, -1, method);235Verify.verifyBinary(Integer.MAX_VALUE, -1, method);236Verify.verifyBinary(Integer.MIN_VALUE, 1, method);237Verify.verifyBinary(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2, method);238Verify.verifyBinary(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3, method);239Verify.verifyBinary(Integer.MAX_VALUE, Integer.MIN_VALUE, method);240}241}242}243244public static class ConstantLongTest {245public static void verify(BinaryLongMethod method) {246for (int i = 0; i < 50000; ++i) {247Verify.verifyBinary(5, 7, method);248Verify.verifyBinary(Long.MAX_VALUE, 1, method);249Verify.verifyBinary(Long.MIN_VALUE, -1, method);250Verify.verifyBinary(Long.MAX_VALUE, -1, method);251Verify.verifyBinary(Long.MIN_VALUE, 1, method);252Verify.verifyBinary(Long.MAX_VALUE / 2, Long.MAX_VALUE / 2, method);253Verify.verifyBinary(Long.MAX_VALUE / 2, (Long.MAX_VALUE / 2) + 3, method);254Verify.verifyBinary(Long.MAX_VALUE, Long.MIN_VALUE, method);255}256}257}258259public static interface BinaryMethod {260int safeMethod(int a, int b);261int checkMethod(int a, int b);262int unchecked(int a, int b);263String name();264}265266public static interface UnaryMethod {267int safeMethod(int value);268int checkMethod(int value);269int unchecked(int value);270String name();271}272273public static interface BinaryLongMethod {274long safeMethod(long a, long b);275long checkMethod(long a, long b);276long unchecked(long a, long b);277String name();278}279280public static interface UnaryLongMethod {281long safeMethod(long value);282long checkMethod(long value);283long unchecked(long value);284String name();285}286287public static class UnaryToBinary implements BinaryMethod {288private final UnaryMethod method;289public UnaryToBinary(UnaryMethod method) {290this.method = method;291}292293@Override294public int safeMethod(int a, int b) {295return method.safeMethod(a);296}297298@Override299public int checkMethod(int a, int b) {300return method.checkMethod(a);301}302303@Override304public int unchecked(int a, int b) {305return method.unchecked(a);306307}308309@Override310public String name() {311return method.name();312}313}314315public static class UnaryToBinaryLong implements BinaryLongMethod {316private final UnaryLongMethod method;317public UnaryToBinaryLong(UnaryLongMethod method) {318this.method = method;319}320321@Override322public long safeMethod(long a, long b) {323return method.safeMethod(a);324}325326@Override327public long checkMethod(long a, long b) {328return method.checkMethod(a);329}330331@Override332public long unchecked(long a, long b) {333return method.unchecked(a);334335}336337@Override338public String name() {339return method.name();340}341}342343344public static class AddExactI implements BinaryMethod {345@Override346public int safeMethod(int x, int y) {347int r = x + y;348// HD 2-12 Overflow iff both arguments have the opposite sign of the result349if (((x ^ r) & (y ^ r)) < 0) {350throw new ArithmeticException("integer overflow");351}352return r;353354}355356@Override357public int checkMethod(int a, int b) {358return Math.addExact(a, b);359}360361@Override362public String name() {363return "addExact";364}365366@Override367public int unchecked(int a, int b) {368return a + b;369}370}371372public static class AddExactL implements BinaryLongMethod {373@Override374public long safeMethod(long x, long y) {375long r = x + y;376// HD 2-12 Overflow iff both arguments have the opposite sign of the result377if (((x ^ r) & (y ^ r)) < 0) {378throw new ArithmeticException("integer overflow");379}380return r;381382}383384@Override385public long checkMethod(long a, long b) {386return Math.addExact(a, b);387}388389@Override390public String name() {391return "addExactLong";392}393394@Override395public long unchecked(long a, long b) {396return a + b;397}398}399400public static class MulExactI implements BinaryMethod {401@Override402public int safeMethod(int x, int y) {403long r = (long)x * (long)y;404if ((int)r != r) {405throw new ArithmeticException("integer overflow");406}407return (int)r;408409}410411@Override412public int checkMethod(int a, int b) {413return Math.multiplyExact(a, b);414}415416@Override417public int unchecked(int a, int b) {418return a * b;419}420421@Override422public String name() {423return "multiplyExact";424}425}426427public static class MulExactL implements BinaryLongMethod {428@Override429public long safeMethod(long x, long y) {430long r = x * y;431long ax = Math.abs(x);432long ay = Math.abs(y);433if (((ax | ay) >>> 31 != 0)) {434// Some bits greater than 2^31 that might cause overflow435// Check the result using the divide operator436// and check for the special case of Long.MIN_VALUE * -1437if (((y != 0) && (r / y != x)) ||438(x == Long.MIN_VALUE && y == -1)) {439throw new ArithmeticException("long overflow");440}441}442return r;443}444445@Override446public long checkMethod(long a, long b) {447return Math.multiplyExact(a, b);448}449450@Override451public long unchecked(long a, long b) {452return a * b;453}454455@Override456public String name() {457return "multiplyExact";458}459}460461public static class NegExactL implements UnaryLongMethod {462@Override463public long safeMethod(long a) {464if (a == Long.MIN_VALUE) {465throw new ArithmeticException("long overflow");466}467468return -a;469470}471472@Override473public long checkMethod(long value) {474return Math.negateExact(value);475}476477@Override478public long unchecked(long value) {479return -value;480}481482@Override483public String name() {484return "negateExactLong";485}486}487488public static class NegExactI implements UnaryMethod {489@Override490public int safeMethod(int a) {491if (a == Integer.MIN_VALUE) {492throw new ArithmeticException("integer overflow");493}494495return -a;496497}498499@Override500public int checkMethod(int value) {501return Math.negateExact(value);502}503504@Override505public int unchecked(int value) {506return -value;507}508509@Override510public String name() {511return "negateExact";512}513}514515public static class SubExactI implements BinaryMethod {516@Override517public int safeMethod(int x, int y) {518int r = x - y;519// HD 2-12 Overflow iff the arguments have different signs and520// the sign of the result is different than the sign of x521if (((x ^ y) & (x ^ r)) < 0) {522throw new ArithmeticException("integer overflow");523}524return r;525}526527@Override528public int checkMethod(int a, int b) {529return Math.subtractExact(a, b);530}531532@Override533public int unchecked(int a, int b) {534return a - b;535}536537@Override538public String name() {539return "subtractExact";540}541}542543public static class SubExactL implements BinaryLongMethod {544@Override545public long safeMethod(long x, long y) {546long r = x - y;547// HD 2-12 Overflow iff the arguments have different signs and548// the sign of the result is different than the sign of x549if (((x ^ y) & (x ^ r)) < 0) {550throw new ArithmeticException("integer overflow");551}552return r;553}554555@Override556public long checkMethod(long a, long b) {557return Math.subtractExact(a, b);558}559560@Override561public long unchecked(long a, long b) {562return a - b;563}564565@Override566public String name() {567return "subtractExactLong";568}569}570571static class IncExactL implements UnaryLongMethod {572@Override573public long safeMethod(long a) {574if (a == Long.MAX_VALUE) {575throw new ArithmeticException("long overflow");576}577578return a + 1L;579580}581582@Override583public long checkMethod(long value) {584return Math.incrementExact(value);585}586587@Override588public long unchecked(long value) {589return value + 1;590}591592@Override593public String name() {594return "incrementExactLong";595}596}597598static class IncExactI implements UnaryMethod {599@Override600public int safeMethod(int a) {601if (a == Integer.MAX_VALUE) {602throw new ArithmeticException("integer overflow");603}604605return a + 1;606}607608@Override609public int checkMethod(int value) {610return Math.incrementExact(value);611}612613@Override614public int unchecked(int value) {615return value + 1;616}617618@Override619public String name() {620return "incrementExact";621}622}623624static class DecExactL implements UnaryLongMethod {625@Override626public long safeMethod(long a) {627if (a == Long.MIN_VALUE) {628throw new ArithmeticException("long overflow");629}630631return a - 1L;632}633634@Override635public long checkMethod(long value) {636return Math.decrementExact(value);637}638639@Override640public long unchecked(long value) {641return value - 1;642}643644@Override645public String name() {646return "decExactLong";647}648}649650static class DecExactI implements UnaryMethod {651@Override652public int safeMethod(int a) {653if (a == Integer.MIN_VALUE) {654throw new ArithmeticException("integer overflow");655}656657return a - 1;658}659660@Override661public int checkMethod(int value) {662return Math.decrementExact(value);663}664665@Override666public int unchecked(int value) {667return value - 1;668}669670@Override671public String name() {672return "decrementExact";673}674}675676}677678679