1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 public class Main { main(String[] args)18 public static void main(String[] args) { 19 new Main().run(); 20 testPreserveFloat(); 21 testPreserveDouble(); 22 System.out.println("finish"); 23 } 24 run()25 public void run() { 26 double a[][] = new double[200][201]; 27 double b[] = new double[200]; 28 int n = 100; 29 30 foo1(a, n, b); 31 } 32 foo1(double a[][], int n, double b[])33 void foo1(double a[][], int n, double b[]) { 34 double t; 35 int i,k; 36 37 for (i = 0; i < n; i++) { 38 k = n - (i + 1); 39 b[k] /= a[k][k]; 40 t = -b[k]; 41 foo2(k + 1000, t, b); 42 } 43 } 44 foo2(int n, double c, double b[])45 void foo2(int n, double c, double b[]) { 46 try { 47 foo3(n, c, b); 48 } catch (Exception e) { 49 } 50 } 51 foo3(int n, double c, double b[])52 void foo3(int n, double c, double b[]) { 53 int i = 0; 54 for (i = 0; i < n; i++) { 55 b[i + 1] += c * b[i + 1]; 56 } 57 } 58 59 /* 60 * Test that we correctly preserve floating point registers when we deoptimize. 61 * 62 * Note: These tests rely on the deoptimization happening before the loop, 63 * so that the loop is interpreted and fills the provided arrays. However, 64 * the BCE transformation can be modified to execute the loop as many times 65 * as the compiler can guarantee no AIOOBE and only deoptimize thereafter, 66 * just before the throwing iteration. Then the floating point registers 67 * would no longer be used after the deoptimization and another approach 68 * would be needed to test this. 69 */ 70 testPreserveFloat()71 static public void testPreserveFloat() { 72 float[] array = new float[2]; 73 try { 74 $noinline$FloatFill(1.125f, 2.5f, array, 3); 75 throw new Error(); 76 } catch (ArrayIndexOutOfBoundsException expected) { 77 System.out.println("array[0]=" + array[0] + "f"); 78 System.out.println("array[1]=" + array[1] + "f"); 79 } 80 } 81 82 /// CHECK-START: void Main.$noinline$FloatFill(float, float, float[], int) BCE (after) 83 /// CHECK-DAG: Deoptimize 84 /// CHECK-DAG: Deoptimize 85 /// CHECK-DAG: Deoptimize 86 /// CHECK-NOT: Deoptimize 87 88 /// CHECK-START: void Main.$noinline$FloatFill(float, float, float[], int) BCE (after) 89 /// CHECK-NOT: BoundsCheck 90 $noinline$FloatFill(float f1, float f2, float[] array, int n)91 public static void $noinline$FloatFill(float f1, float f2, float[] array, int n) { 92 if (doThrow) { throw new Error(); } 93 for (int i = 0; i < n; ++i) { 94 array[i] = ((i & 1) == 1) ? f1 : f2; 95 f1 += 1.5f; 96 f2 += 2.25f; 97 } 98 } 99 testPreserveDouble()100 static public void testPreserveDouble() { 101 double[] array = new double[2]; 102 try { 103 $noinline$DoubleFill(2.125, 3.5, array, 3); 104 throw new Error(); 105 } catch (ArrayIndexOutOfBoundsException expected) { 106 System.out.println("array[0]=" + array[0]); 107 System.out.println("array[1]=" + array[1]); 108 } 109 } 110 111 /// CHECK-START: void Main.$noinline$DoubleFill(double, double, double[], int) BCE (after) 112 /// CHECK-DAG: Deoptimize 113 /// CHECK-DAG: Deoptimize 114 /// CHECK-DAG: Deoptimize 115 /// CHECK-NOT: Deoptimize 116 117 /// CHECK-START: void Main.$noinline$DoubleFill(double, double, double[], int) BCE (after) 118 /// CHECK-NOT: BoundsCheck 119 $noinline$DoubleFill(double d1, double d2, double[] array, int n)120 public static void $noinline$DoubleFill(double d1, double d2, double[] array, int n) { 121 if (doThrow) { throw new Error(); } 122 for (int i = 0; i < n; ++i) { 123 array[i] = ((i & 1) == 1) ? d1 : d2; 124 d1 += 1.5; 125 d2 += 2.25; 126 } 127 } 128 129 public static boolean doThrow = false; 130 } 131 132