1 /*
   2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 
  25 package org.graalvm.compiler.replacements.test;
  26 
  27 import org.graalvm.compiler.core.test.GraalCompilerTest;
  28 import org.junit.Test;
  29 
  30 import jdk.vm.ci.code.InstalledCode;
  31 import jdk.vm.ci.code.InvalidInstalledCodeException;
  32 import jdk.vm.ci.meta.ResolvedJavaMethod;
  33 
  34 public class IntegerExactExceptionTest extends GraalCompilerTest {
  35 
  36     static int intCounter = 32;
  37 
  38     public void testIntegerExactOverflowSnippet(int input) {
  39         try {
  40             intCounter = Math.addExact(intCounter, input);
  41         } catch (ArithmeticException e) {
  42             intCounter = intCounter / 2;
  43         }
  44     }
  45 
  46     @Test
  47     public void testIntegerExact() throws InvalidInstalledCodeException {
  48         ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowSnippet");
  49         InstalledCode code = getCode(method);
  50         code.executeVarargs(this, Integer.MAX_VALUE);
  51 
  52         if (!code.isValid()) {
  53             code = getCode(method);
  54             code.executeVarargs(this, Integer.MAX_VALUE);
  55             assertTrue(code.isValid());
  56         }
  57     }
  58 
  59     public void testIntegerExactOverflowWithoutHandlerSnippetW(int input) {
  60         try {
  61             intCounter = Math.addExact(intCounter, input);
  62         } finally {
  63             intCounter = intCounter / 2;
  64         }
  65     }
  66 
  67     @Test
  68     public void testIntegerExactWithoutHandler() throws InvalidInstalledCodeException {
  69         ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowWithoutHandlerSnippetW");
  70         InstalledCode code = getCode(method);
  71 
  72         try {
  73             code.executeVarargs(this, Integer.MAX_VALUE);
  74         } catch (ArithmeticException e) {
  75             // An ArithmeticException is expected to be thrown.
  76         }
  77 
  78         if (!code.isValid()) {
  79             code = getCode(method);
  80             try {
  81                 code.executeVarargs(this, Integer.MAX_VALUE);
  82             } catch (ArithmeticException e) {
  83                 // An ArithmeticException is expected to be thrown.
  84             }
  85             assertTrue(code.isValid());
  86         }
  87     }
  88 
  89     public void testIntegerExactOverflowWithoutUse1(int input) {
  90         Math.addExact(intCounter, input);
  91     }
  92 
  93     public void testIntegerExactOverflowWithoutUse2(int input, boolean cond) {
  94         if (cond) {
  95             Math.addExact(intCounter, input);
  96         } else {
  97             intCounter = Math.addExact(intCounter, input);
  98         }
  99     }
 100 
 101     public void testIntegerExactOverflowWithoutUse3() {
 102         Math.addExact(Integer.MAX_VALUE, 1);
 103     }
 104 
 105     @Test
 106     public void testIntegerExactWithoutUse1() throws InvalidInstalledCodeException {
 107         ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowWithoutUse1");
 108         InstalledCode code = getCode(method);
 109 
 110         boolean gotException = false;
 111         try {
 112             code.executeVarargs(this, Integer.MAX_VALUE);
 113         } catch (ArithmeticException e) {
 114             gotException = true;
 115         }
 116         assertTrue(gotException);
 117     }
 118 
 119     @Test
 120     public void testIntegerExactWithoutUse2() throws InvalidInstalledCodeException {
 121         ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowWithoutUse2");
 122         InstalledCode code = getCode(method);
 123 
 124         boolean gotException = false;
 125         try {
 126             code.executeVarargs(this, Integer.MAX_VALUE, true);
 127         } catch (ArithmeticException e) {
 128             gotException = true;
 129         }
 130         assertTrue(gotException);
 131     }
 132 
 133     @Test
 134     public void testIntegerExactWithoutUse3() throws InvalidInstalledCodeException {
 135         ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowWithoutUse3");
 136         InstalledCode code = getCode(method);
 137 
 138         boolean gotException = false;
 139         try {
 140             code.executeVarargs(this);
 141         } catch (ArithmeticException e) {
 142             gotException = true;
 143         }
 144         assertTrue(gotException);
 145     }
 146 
 147     static long longCounter = 10;
 148 
 149     public void testLongExactOverflowSnippet(long input) {
 150         try {
 151             longCounter = Math.addExact(longCounter, input);
 152         } catch (ArithmeticException e) {
 153             longCounter = longCounter / 2;
 154         }
 155     }
 156 
 157     @Test
 158     public void testLongExact() throws InvalidInstalledCodeException {
 159         ResolvedJavaMethod method = getResolvedJavaMethod("testLongExactOverflowSnippet");
 160         InstalledCode code = getCode(method);
 161         code.executeVarargs(this, Long.MAX_VALUE);
 162 
 163         if (!code.isValid()) {
 164             code = getCode(method);
 165             code.executeVarargs(this, Long.MAX_VALUE);
 166             assertTrue(code.isValid());
 167         }
 168     }
 169 
 170     public void testLongExactWithoutHandlerSnippet(long input) {
 171         try {
 172             longCounter = Math.addExact(longCounter, input);
 173         } finally {
 174             longCounter = longCounter / 2;
 175         }
 176     }
 177 
 178     @Test
 179     public void testLongExactWithoutHandler() throws InvalidInstalledCodeException {
 180         ResolvedJavaMethod method = getResolvedJavaMethod("testLongExactWithoutHandlerSnippet");
 181         InstalledCode code = getCode(method);
 182 
 183         try {
 184             code.executeVarargs(this, Long.MAX_VALUE);
 185         } catch (ArithmeticException e) {
 186             // An ArithmeticException is expected to be thrown.
 187         }
 188 
 189         if (!code.isValid()) {
 190             code = getCode(method);
 191             try {
 192                 code.executeVarargs(this, Long.MAX_VALUE);
 193             } catch (ArithmeticException e) {
 194                 // An ArithmeticException is expected to be thrown.
 195             }
 196             assertTrue(code.isValid());
 197         }
 198     }
 199 
 200     public void testLongExactOverflowWithoutUse1(long input) {
 201         Math.addExact(longCounter, input);
 202     }
 203 
 204     public void testLongExactOverflowWithoutUse2(long input, boolean cond) {
 205         if (cond) {
 206             Math.addExact(longCounter, input);
 207         } else {
 208             longCounter = Math.addExact(longCounter, input);
 209         }
 210     }
 211 
 212     @Test
 213     public void testLongExactWithoutUse1() throws InvalidInstalledCodeException {
 214         ResolvedJavaMethod method = getResolvedJavaMethod("testLongExactOverflowWithoutUse1");
 215         InstalledCode code = getCode(method);
 216 
 217         boolean gotException = false;
 218         try {
 219             code.executeVarargs(this, Long.MAX_VALUE);
 220         } catch (ArithmeticException e) {
 221             gotException = true;
 222         }
 223         assertTrue(gotException);
 224     }
 225 
 226     @Test
 227     public void testLongExactWithoutUse2() throws InvalidInstalledCodeException {
 228         ResolvedJavaMethod method = getResolvedJavaMethod("testLongExactOverflowWithoutUse2");
 229         InstalledCode code = getCode(method);
 230 
 231         boolean gotException = false;
 232         try {
 233             code.executeVarargs(this, Long.MAX_VALUE, true);
 234         } catch (ArithmeticException e) {
 235             gotException = true;
 236         }
 237         assertTrue(gotException);
 238     }
 239 }