1 /* 2 * Copyright (c) 2016, 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 * @test 26 * @bug 8130847 8156760 27 * @summary Eliminated instance/array written to by an array copy variant must be correctly initialized when reallocated at a deopt 28 * 29 * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement 30 * compiler.arraycopy.TestEliminatedArrayCopyDeopt 31 * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement 32 * -XX:+IgnoreUnrecognizedVMOptions -XX:-ReduceInitialCardMarks 33 * compiler.arraycopy.TestEliminatedArrayCopyDeopt 34 */ 35 36 // Test that if an ArrayCopy node is eliminated because it doesn't 37 // escape, then the correct field/array element values are captured so 38 // on a deoptimization, when the object/array is reallocated, it is 39 // correctly initialized 40 41 package compiler.arraycopy; 42 43 public class TestEliminatedArrayCopyDeopt { 44 45 static class A implements Cloneable { 46 int f0; 47 int f1; 48 int f2; 49 int f3; 50 int f4; 51 int f5; 52 int f6; 53 int f7; 54 int f8; 55 int f9; 56 int f10; 57 int f11; 58 int f12; 59 int f13; 60 int f14; 61 int f15; 62 63 public Object clone() throws CloneNotSupportedException { 64 return super.clone(); 65 } 66 } 67 68 // Clone 69 static boolean m1(A a, boolean flag) throws CloneNotSupportedException { 70 A c = (A)a.clone(); 71 if (flag) { 72 // never taken branch that causes the deoptimization 73 if (c.f0 != 0x42) { 74 return false; 75 } 76 } 77 return true; 78 } 79 80 // Array clone 81 static int[] m2_src = null; 82 static boolean m2(boolean flag) throws CloneNotSupportedException { 83 int[] src = new int[10]; 84 m2_src = src; 85 for (int i = 0; i < src.length; i++) { 86 src[i] = 0x42+i; 87 } 88 int[] c = (int[])src.clone(); 89 if (flag) { 90 for (int i = 0; i < c.length; i++) { 91 if (c[i] != src[i]) { 92 return false; 93 } 94 } 95 } 96 return true; 97 } 98 99 // Array copy 100 static boolean m3(int[] src, boolean flag) { 101 int[] dst = new int[10]; 102 System.arraycopy(src, 0, dst, 0, 10); 103 if (flag) { 104 for (int i = 0; i < dst.length; i++) { 105 if (dst[i] != src[i]) { 106 return false; 107 } 108 } 109 } 110 return true; 111 } 112 113 // Array copy of subrange 114 static boolean m4(int[] src, boolean flag) { 115 int[] dst = new int[10]; 116 dst[0] = 0x42; 117 dst[1] = 0x42 - 1; 118 dst[2] = 0x42 - 2; 119 dst[8] = 0x42 - 8; 120 dst[9] = 0x42 - 9; 121 int src_off = 2; 122 int dst_off = 3; 123 int len = 5; 124 System.arraycopy(src, src_off, dst, dst_off, len); 125 if (flag) { 126 for (int i = 0; i < dst.length; i++) { 127 if (i >= dst_off && i < dst_off + len) { 128 if (dst[i] != src[i - dst_off + src_off]) { 129 return false; 130 } 131 } else { 132 if (dst[i] != 0x42-i) { 133 return false; 134 } 135 } 136 } 137 } 138 return true; 139 } 140 141 // Array copy with Phi 142 static boolean m5(int[] src, boolean flag1, boolean flag2) { 143 int[] dst = new int[10]; 144 if (flag1) { 145 System.arraycopy(src, 0, dst, 0, 10); 146 } 147 if (flag2) { 148 for (int i = 0; i < dst.length; i++) { 149 if (dst[i] != src[i]) { 150 return false; 151 } 152 } 153 } 154 return true; 155 } 156 157 static public void main(String[] args) throws Exception { 158 boolean success = true; 159 A a = new A(); 160 a.f0 = 0x42; 161 for (int i = 0; i < 20000; i++) { 162 m1(a, false); 163 } 164 if (!m1(a, true)) { 165 System.out.println("m1 failed"); 166 success = false; 167 } 168 169 for (int i = 0; i < 20000; i++) { 170 m2(false); 171 } 172 if (!m2(true)) { 173 System.out.println("m2 failed"); 174 success = false; 175 } 176 177 int[] src = new int[10]; 178 for (int i = 0; i < src.length; i++) { 179 src[i] = 0x42+i; 180 } 181 182 for (int i = 0; i < 20000; i++) { 183 m3(src, false); 184 } 185 if (!m3(src, true)) { 186 System.out.println("m3 failed"); 187 success = false; 188 } 189 190 for (int i = 0; i < 20000; i++) { 191 m4(src, false); 192 } 193 if (!m4(src, true)) { 194 System.out.println("m4 failed"); 195 success = false; 196 } 197 198 for (int i = 0; i < 20000; i++) { 199 m5(src, i%2 == 0, false); 200 } 201 if (!m5(src, true, true)) { 202 System.out.println("m4 failed"); 203 success = false; 204 } 205 206 if (!success) { 207 throw new RuntimeException("Test failed"); 208 } 209 } 210 }