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