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 24package compiler.arraycopy; 25 26import java.lang.annotation.Retention; 27import java.lang.annotation.RetentionPolicy; 28import java.lang.reflect.Method; 29import java.lang.reflect.Modifier; 30import java.util.HashMap; 31 32abstract class TestArrayCopyUtils { 33 public enum ArraySrc { 34 SMALL, 35 LARGE, 36 ZERO 37 } 38 39 public enum ArrayDst { 40 NONE, 41 NEW, 42 SRC 43 } 44 45 static class A { 46 } 47 48 static class B extends A { 49 } 50 51 static final A[] small_a_src = new A[5]; 52 static final A[] large_a_src = new A[10]; 53 static final A[] zero_a_src = new A[0]; 54 static final int[] small_int_src = new int[5]; 55 static final int[] large_int_src = new int[10]; 56 static final int[] zero_int_src = new int[0]; 57 static final Object[] small_object_src = new Object[5]; 58 static Object src; 59 60 @Retention(RetentionPolicy.RUNTIME) 61 @interface Args { 62 ArraySrc src(); 63 ArrayDst dst() default ArrayDst.NONE; 64 int[] extra_args() default {}; 65 } 66 67 final HashMap<String,Method> tests = new HashMap<>(); 68 { 69 for (Method m : this.getClass().getDeclaredMethods()) { 70 if (m.getName().matches("m[0-9]+(_check)?")) { 71 assert(Modifier.isStatic(m.getModifiers())) : m; 72 tests.put(m.getName(), m); 73 } 74 } 75 } 76 77 boolean success = true; 78 79 void doTest(String name) throws Exception { 80 Method m = tests.get(name); 81 Method m_check = tests.get(name + "_check"); 82 Class[] paramTypes = m.getParameterTypes(); 83 Object[] params = new Object[paramTypes.length]; 84 Class retType = m.getReturnType(); 85 boolean isIntArray = (retType.isPrimitive() && !retType.equals(Void.TYPE)) || 86 (retType.equals(Void.TYPE) && paramTypes[0].getComponentType().isPrimitive()) || 87 (retType.isArray() && retType.getComponentType().isPrimitive()); 88 89 Args args = m.getAnnotation(Args.class); 90 91 Object src = null; 92 switch(args.src()) { 93 case SMALL: { 94 if (isIntArray) { 95 src = small_int_src; 96 } else { 97 src = small_a_src; 98 } 99 break; 100 } 101 case LARGE: { 102 if (isIntArray) { 103 src = large_int_src; 104 } else { 105 src = large_a_src; 106 } 107 break; 108 } 109 case ZERO: { 110 if (isIntArray) { 111 src = zero_int_src; 112 } else { 113 src = zero_a_src; 114 } 115 break; 116 } 117 } 118 119 for (int i = 0; i < 20000; i++) { 120 boolean failure = false; 121 122 int p = 0; 123 124 if (params.length > 0) { 125 if (isIntArray) { 126 params[0] = ((int[])src).clone(); 127 } else { 128 params[0] = ((A[])src).clone(); 129 } 130 p++; 131 } 132 133 if (params.length > 1) { 134 switch(args.dst()) { 135 case NEW: { 136 if (isIntArray) { 137 params[1] = new int[((int[])params[0]).length]; 138 } else { 139 params[1] = new A[((A[])params[0]).length]; 140 } 141 p++; 142 break; 143 } 144 case SRC: { 145 params[1] = params[0]; 146 p++; 147 break; 148 } 149 case NONE: break; 150 } 151 } 152 153 for (int j = 0; j < args.extra_args().length; j++) { 154 params[p+j] = args.extra_args()[j]; 155 } 156 157 Object res = m.invoke(null, params); 158 159 if (retType.isPrimitive() && !retType.equals(Void.TYPE)) { 160 int s = (int)res; 161 int sum = 0; 162 int[] int_res = (int[])src; 163 for (int j = 0; j < int_res.length; j++) { 164 sum += int_res[j]; 165 } 166 failure = (s != sum); 167 if (failure) { 168 System.out.println("Test " + name + " failed: result = " + s + " != " + sum); 169 } 170 } else { 171 Object dest = null; 172 if (!retType.equals(Void.TYPE)) { 173 dest = res; 174 } else { 175 dest = params[1]; 176 } 177 178 if (m_check != null) { 179 failure = (boolean)m_check.invoke(null, new Object[] { src, dest }); 180 } else { 181 if (isIntArray) { 182 int[] int_res = (int[])src; 183 int[] int_dest = (int[])dest; 184 for (int j = 0; j < int_res.length; j++) { 185 if (int_res[j] != int_dest[j]) { 186 System.out.println("Test " + name + " failed for " + j + " src[" + j +"]=" + int_res[j] + ", dest[" + j + "]=" + int_dest[j]); 187 failure = true; 188 } 189 } 190 } else { 191 Object[] object_res = (Object[])src; 192 Object[] object_dest = (Object[])dest; 193 for (int j = 0; j < object_res.length; j++) { 194 if (object_res[j] != object_dest[j]) { 195 System.out.println("Test " + name + " failed for " + j + " src[" + j +"]=" + object_res[j] + ", dest[" + j + "]=" + object_dest[j]); 196 failure = true; 197 } 198 } 199 } 200 } 201 } 202 203 if (failure) { 204 success = false; 205 break; 206 } 207 } 208 } 209 210 TestArrayCopyUtils() { 211 for (int i = 0; i < small_a_src.length; i++) { 212 small_a_src[i] = new A(); 213 } 214 215 for (int i = 0; i < small_int_src.length; i++) { 216 small_int_src[i] = i; 217 } 218 219 for (int i = 0; i < large_int_src.length; i++) { 220 large_int_src[i] = i; 221 } 222 223 for (int i = 0; i < 5; i++) { 224 small_object_src[i] = new Object(); 225 } 226 } 227} 228