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 package compiler.arraycopy; 25 26 import java.lang.reflect.Field; 27 import java.lang.reflect.Method; 28 import java.lang.reflect.Modifier; 29 import java.util.HashMap; 30 31 abstract class TestInstanceCloneUtils { 32 static class Base implements Cloneable { 33 void initialize(Class c, int i) { 34 for (Field f : c.getDeclaredFields()) { 35 setVal(f, i); 36 i++; 37 } 38 if (c != Base.class) { 39 initialize(c.getSuperclass(), i); 40 } 41 } 42 43 Base(boolean initialize) { 44 if (initialize) { 45 initialize(getClass(), 0); 46 } 47 } 48 49 void setVal(Field f, int i) { 50 try { 51 if (f.getType() == int.class) { 52 f.setInt(this, i); 53 return; 54 } else if (f.getType() == short.class) { 55 f.setShort(this, (short)i); 56 return; 57 } else if (f.getType() == byte.class) { 58 f.setByte(this, (byte)i); 59 return; 60 } else if (f.getType() == long.class) { 61 f.setLong(this, i); 62 return; 63 } 64 } catch(IllegalAccessException iae) { 65 throw new RuntimeException("Getting fields failed"); 66 } 67 throw new RuntimeException("unexpected field type"); 68 } 69 70 int getVal(Field f) { 71 try { 72 if (f.getType() == int.class) { 73 return f.getInt(this); 74 } else if (f.getType() == short.class) { 75 return (int)f.getShort(this); 76 } else if (f.getType() == byte.class) { 77 return (int)f.getByte(this); 78 } else if (f.getType() == long.class) { 79 return (int)f.getLong(this); 80 } 81 } catch(IllegalAccessException iae) { 82 throw new RuntimeException("Setting fields failed"); 83 } 84 throw new RuntimeException("unexpected field type"); 85 } 86 87 boolean fields_equal(Class c, Base o) { 88 for (Field f : c.getDeclaredFields()) { 89 if (getVal(f) != o.getVal(f)) { 90 return false; 91 } 92 } 93 if (c != Base.class) { 94 return fields_equal(c.getSuperclass(), o); 95 } 96 return true; 97 } 98 99 public boolean equals(Object obj) { 100 return fields_equal(getClass(), (Base)obj); 101 } 102 103 String print_fields(Class c, String s) { 104 for (Field f : c.getDeclaredFields()) { 105 if (s != "") { 106 s += "\n"; 107 } 108 s = s + f + " = " + getVal(f); 109 } 110 if (c != Base.class) { 111 return print_fields(c.getSuperclass(), s); 112 } 113 return s; 114 } 115 116 public String toString() { 117 return print_fields(getClass(), ""); 118 } 119 120 int fields_sum(Class c, int s) { 121 for (Field f : c.getDeclaredFields()) { 122 s += getVal(f); 123 } 124 if (c != Base.class) { 125 return fields_sum(c.getSuperclass(), s); 126 } 127 return s; 128 } 129 130 public int sum() { 131 return fields_sum(getClass(), 0); 132 } 133 134 } 135 136 static class A extends Base { 137 int i1; 138 int i2; 139 int i3; 140 int i4; 141 int i5; 142 143 A(boolean initialize) { 144 super(initialize); 145 } 146 147 public Object clone() throws CloneNotSupportedException { 148 return super.clone(); 149 } 150 } 151 152 static class B extends A { 153 int i6; 154 155 B(boolean initialize) { 156 super(initialize); 157 } 158 } 159 160 static final class D extends Base { 161 byte i1; 162 short i2; 163 long i3; 164 int i4; 165 int i5; 166 167 D(boolean initialize) { 168 super(initialize); 169 } 170 171 public Object clone() throws CloneNotSupportedException { 172 return super.clone(); 173 } 174 } 175 176 static final class E extends Base { 177 int i1; 178 int i2; 179 int i3; 180 int i4; 181 int i5; 182 int i6; 183 int i7; 184 int i8; 185 int i9; 186 187 E(boolean initialize) { 188 super(initialize); 189 } 190 191 public Object clone() throws CloneNotSupportedException { 192 return super.clone(); 193 } 194 } 195 196 static final class F extends Base { 197 F(boolean initialize) { 198 super(initialize); 199 } 200 201 public Object clone() throws CloneNotSupportedException { 202 return super.clone(); 203 } 204 } 205 206 static class G extends Base { 207 int i1; 208 int i2; 209 int i3; 210 211 G(boolean initialize) { 212 super(initialize); 213 } 214 215 public Object myclone() throws CloneNotSupportedException { 216 return clone(); 217 } 218 } 219 220 static class H extends G { 221 int i4; 222 int i5; 223 224 H(boolean initialize) { 225 super(initialize); 226 } 227 228 public Object clone() throws CloneNotSupportedException { 229 return super.clone(); 230 } 231 } 232 233 static class J extends Base { 234 int i1; 235 int i2; 236 int i3; 237 238 J(boolean initialize) { 239 super(initialize); 240 } 241 242 public Object myclone() throws CloneNotSupportedException { 243 return clone(); 244 } 245 } 246 247 static class K extends J { 248 int i4; 249 int i5; 250 251 K(boolean initialize) { 252 super(initialize); 253 } 254 255 } 256 257 static final A a = new A(true); 258 static final B b = new B(true); 259 static final D d = new D(true); 260 static final E e = new E(true); 261 static final F f = new F(true); 262 static final G g = new G(true); 263 static final H h = new H(true); 264 static final J j = new J(true); 265 static final K k = new K(true); 266 267 final HashMap<String,Method> tests = new HashMap<>(); 268 { 269 for (Method m : this.getClass().getDeclaredMethods()) { 270 if (m.getName().matches("m[0-9]+")) { 271 assert(Modifier.isStatic(m.getModifiers())) : m; 272 tests.put(m.getName(), m); 273 } 274 } 275 } 276 277 boolean success = true; 278 279 void doTest(Base src, String name) throws Exception { 280 Method m = tests.get(name); 281 282 for (int i = 0; i < 20000; i++) { 283 boolean failure = false; 284 Base res = null; 285 int s = 0; 286 Class retType = m.getReturnType(); 287 if (retType.isPrimitive()) { 288 if (!retType.equals(Void.TYPE)) { 289 s = (int)m.invoke(null, src); 290 failure = (s != src.sum()); 291 } else { 292 m.invoke(null, src); 293 } 294 } else { 295 res = (Base)m.invoke(null, src); 296 failure = !res.equals(src); 297 } 298 if (failure) { 299 System.out.println("Test " + name + " failed"); 300 System.out.println("source: "); 301 System.out.println(src); 302 System.out.println("result: "); 303 if (m.getReturnType().isPrimitive()) { 304 System.out.println(s); 305 } else { 306 System.out.println(res); 307 } 308 success = false; 309 break; 310 } 311 } 312 } 313 314 }