1 /* 2 * Copyright (c) 2015, 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 8072016 27 * @summary Infinite deoptimization/recompilation cycles in case of arraycopy with tightly coupled allocation 28 * @library /testlibrary /test/lib / 29 * @modules java.base/jdk.internal.misc 30 * java.management 31 * @build TestArrayCopyNoInitDeopt 32 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 33 * jdk.test.lib.Platform 34 * @run main/othervm -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 35 * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=020 36 * TestArrayCopyNoInitDeopt 37 */ 38 39 import sun.hotspot.WhiteBox; 40 import sun.hotspot.code.NMethod; 41 import jdk.test.lib.Platform; 42 import java.lang.reflect.*; 43 import compiler.whitebox.CompilerWhiteBoxTest; 44 45 public class TestArrayCopyNoInitDeopt { 46 47 public static int[] m1(Object src) { 48 if (src == null) return null; 49 int[] dest = new int[10]; 50 try { 51 System.arraycopy(src, 0, dest, 0, 10); 52 } catch (ArrayStoreException npe) { 53 } 54 return dest; 55 } 56 57 static Object m2_src(Object src) { 58 return src; 59 } 60 61 public static int[] m2(Object src) { 62 if (src == null) return null; 63 src = m2_src(src); 64 int[] dest = new int[10]; 65 try { 66 System.arraycopy(src, 0, dest, 0, 10); 67 } catch (ArrayStoreException npe) { 68 } 69 return dest; 70 } 71 72 private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 73 private static final int TIERED_STOP_AT_LEVEL = WHITE_BOX.getIntxVMFlag("TieredStopAtLevel").intValue(); 74 75 static boolean deoptimize(Method method, Object src_obj) throws Exception { 76 for (int i = 0; i < 10; i++) { 77 method.invoke(null, src_obj); 78 if (!WHITE_BOX.isMethodCompiled(method)) { 79 return true; 80 } 81 } 82 return false; 83 } 84 85 static public void main(String[] args) throws Exception { 86 // Only execute if C2 is available 87 if (Platform.isServer() && 88 TIERED_STOP_AT_LEVEL == CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) { 89 int[] src = new int[10]; 90 Object src_obj = new Object(); 91 Method method_m1 = TestArrayCopyNoInitDeopt.class.getMethod("m1", Object.class); 92 Method method_m2 = TestArrayCopyNoInitDeopt.class.getMethod("m2", Object.class); 93 94 // Warm up 95 for (int i = 0; i < 20000; i++) { 96 m1(src); 97 } 98 99 // And make sure m1 is compiled by C2 100 WHITE_BOX.enqueueMethodForCompilation(method_m1, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 101 102 if (!WHITE_BOX.isMethodCompiled(method_m1)) { 103 throw new RuntimeException("m1 not compiled"); 104 } 105 106 // should deoptimize for type check 107 if (!deoptimize(method_m1, src_obj)) { 108 throw new RuntimeException("m1 not deoptimized"); 109 } 110 111 WHITE_BOX.enqueueMethodForCompilation(method_m1, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 112 113 if (!WHITE_BOX.isMethodCompiled(method_m1)) { 114 throw new RuntimeException("m1 not recompiled"); 115 } 116 117 if (deoptimize(method_m1, src_obj)) { 118 throw new RuntimeException("m1 deoptimized again"); 119 } 120 121 if (WHITE_BOX.getUintxVMFlag("TypeProfileLevel") == 20) { 122 // Same test as above but with speculative types 123 124 // Warm up & make sure we collect type profiling 125 for (int i = 0; i < 20000; i++) { 126 m2(src); 127 } 128 129 // And make sure m2 is compiled by C2 130 WHITE_BOX.enqueueMethodForCompilation(method_m2, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 131 132 if (!WHITE_BOX.isMethodCompiled(method_m2)) { 133 throw new RuntimeException("m2 not compiled"); 134 } 135 136 // should deoptimize for speculative type check 137 if (!deoptimize(method_m2, src_obj)) { 138 throw new RuntimeException("m2 not deoptimized"); 139 } 140 141 WHITE_BOX.enqueueMethodForCompilation(method_m2, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 142 143 if (!WHITE_BOX.isMethodCompiled(method_m2)) { 144 throw new RuntimeException("m2 not recompiled"); 145 } 146 147 // should deoptimize for actual type check 148 if (!deoptimize(method_m2, src_obj)) { 149 throw new RuntimeException("m2 not deoptimized"); 150 } 151 152 WHITE_BOX.enqueueMethodForCompilation(method_m2, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 153 154 if (!WHITE_BOX.isMethodCompiled(method_m2)) { 155 throw new RuntimeException("m2 not recompiled"); 156 } 157 158 if (deoptimize(method_m2, src_obj)) { 159 throw new RuntimeException("m2 deoptimized again"); 160 } 161 } 162 } 163 } 164 }