1 /* 2 * Copyright (c) 2010, 2011, 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 /** 26 * @test 27 * @bug 6991596 28 * @summary JSR 292 unimplemented adapter_opt_i2i and adapter_opt_l2i on SPARC 29 * 30 * @run main/othervm -ea -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6991596 31 */ 32 33 import java.lang.invoke.*; 34 35 public class Test6991596 { 36 private static final Class CLASS = Test6991596.class; 37 private static final String NAME = "foo"; 38 private static final boolean DEBUG = System.getProperty("DEBUG", "false").equals("true"); 39 40 public static void main(String[] args) throws Throwable { 41 testboolean(); 42 testbyte(); 43 testchar(); 44 testshort(); 45 testint(); 46 testlong(); 47 } 48 49 // Helpers to get various methods. 50 static MethodHandle getmh1(Class ret, Class arg) throws ReflectiveOperationException { 51 return MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(ret, arg)); 52 } 53 static MethodHandle getmh2(MethodHandle mh1, Class ret, Class arg) { 54 return MethodHandles.explicitCastArguments(mh1, MethodType.methodType(ret, arg)); 55 } 56 static MethodHandle getmh3(MethodHandle mh1, Class ret, Class arg) { 57 return MethodHandles.explicitCastArguments(mh1, MethodType.methodType(ret, arg)); 58 } 59 60 // test adapter_opt_i2i 61 static void testboolean() throws Throwable { 62 boolean[] a = new boolean[] { 63 true, 64 false 65 }; 66 for (int i = 0; i < a.length; i++) { 67 doboolean(a[i]); 68 } 69 } 70 static void doboolean(boolean x) throws Throwable { 71 if (DEBUG) System.out.println("boolean=" + x); 72 73 // boolean 74 { 75 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 76 MethodHandle mh2 = getmh2(mh1, boolean.class, boolean.class); 77 // TODO add this for all cases when the bugs are fixed. 78 //MethodHandle mh3 = getmh3(mh1, boolean.class, boolean.class); 79 boolean a = (boolean) mh1.invokeExact((boolean) x); 80 boolean b = (boolean) mh2.invokeExact(x); 81 //boolean c = mh3.<boolean>invokeExact((boolean) x); 82 check(x, a, b); 83 //check(x, c, x); 84 } 85 86 // byte 87 { 88 MethodHandle mh1 = getmh1( byte.class, byte.class ); 89 MethodHandle mh2 = getmh2(mh1, byte.class, boolean.class); 90 byte a = (byte) mh1.invokeExact((byte) (x ? 1 : 0)); 91 byte b = (byte) mh2.invokeExact(x); 92 check(x, a, b); 93 } 94 95 // char 96 { 97 MethodHandle mh1 = getmh1( char.class, char.class); 98 MethodHandle mh2 = getmh2(mh1, char.class, boolean.class); 99 char a = (char) mh1.invokeExact((char) (x ? 1 : 0)); 100 char b = (char) mh2.invokeExact(x); 101 check(x, a, b); 102 } 103 104 // short 105 { 106 MethodHandle mh1 = getmh1( short.class, short.class); 107 MethodHandle mh2 = getmh2(mh1, short.class, boolean.class); 108 short a = (short) mh1.invokeExact((short) (x ? 1 : 0)); 109 short b = (short) mh2.invokeExact(x); 110 check(x, a, b); 111 } 112 } 113 114 static void testbyte() throws Throwable { 115 byte[] a = new byte[] { 116 Byte.MIN_VALUE, 117 Byte.MIN_VALUE + 1, 118 -0x0F, 119 -1, 120 0, 121 1, 122 0x0F, 123 Byte.MAX_VALUE - 1, 124 Byte.MAX_VALUE 125 }; 126 for (int i = 0; i < a.length; i++) { 127 dobyte(a[i]); 128 } 129 } 130 static void dobyte(byte x) throws Throwable { 131 if (DEBUG) System.out.println("byte=" + x); 132 133 // boolean 134 { 135 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 136 MethodHandle mh2 = getmh2(mh1, boolean.class, byte.class); 137 boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 138 boolean b = (boolean) mh2.invokeExact(x); 139 check(x, a, b); 140 } 141 142 // byte 143 { 144 MethodHandle mh1 = getmh1( byte.class, byte.class); 145 MethodHandle mh2 = getmh2(mh1, byte.class, byte.class); 146 byte a = (byte) mh1.invokeExact((byte) x); 147 byte b = (byte) mh2.invokeExact(x); 148 check(x, a, b); 149 } 150 151 // char 152 { 153 MethodHandle mh1 = getmh1( char.class, char.class); 154 MethodHandle mh2 = getmh2(mh1, char.class, byte.class); 155 char a = (char) mh1.invokeExact((char) x); 156 char b = (char) mh2.invokeExact(x); 157 check(x, a, b); 158 } 159 160 // short 161 { 162 MethodHandle mh1 = getmh1( short.class, short.class); 163 MethodHandle mh2 = getmh2(mh1, short.class, byte.class); 164 short a = (short) mh1.invokeExact((short) x); 165 short b = (short) mh2.invokeExact(x); 166 check(x, a, b); 167 } 168 } 169 170 static void testchar() throws Throwable { 171 char[] a = new char[] { 172 Character.MIN_VALUE, 173 Character.MIN_VALUE + 1, 174 0x000F, 175 0x00FF, 176 0x0FFF, 177 Character.MAX_VALUE - 1, 178 Character.MAX_VALUE 179 }; 180 for (int i = 0; i < a.length; i++) { 181 dochar(a[i]); 182 } 183 } 184 static void dochar(char x) throws Throwable { 185 if (DEBUG) System.out.println("char=" + x); 186 187 // boolean 188 { 189 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 190 MethodHandle mh2 = getmh2(mh1, boolean.class, char.class); 191 boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 192 boolean b = (boolean) mh2.invokeExact(x); 193 check(x, a, b); 194 } 195 196 // byte 197 { 198 MethodHandle mh1 = getmh1( byte.class, byte.class); 199 MethodHandle mh2 = getmh2(mh1, byte.class, char.class); 200 byte a = (byte) mh1.invokeExact((byte) x); 201 byte b = (byte) mh2.invokeExact(x); 202 check(x, a, b); 203 } 204 205 // char 206 { 207 MethodHandle mh1 = getmh1( char.class, char.class); 208 MethodHandle mh2 = getmh2(mh1, char.class, char.class); 209 char a = (char) mh1.invokeExact((char) x); 210 char b = (char) mh2.invokeExact(x); 211 check(x, a, b); 212 } 213 214 // short 215 { 216 MethodHandle mh1 = getmh1( short.class, short.class); 217 MethodHandle mh2 = getmh2(mh1, short.class, char.class); 218 short a = (short) mh1.invokeExact((short) x); 219 short b = (short) mh2.invokeExact(x); 220 check(x, a, b); 221 } 222 } 223 224 static void testshort() throws Throwable { 225 short[] a = new short[] { 226 Short.MIN_VALUE, 227 Short.MIN_VALUE + 1, 228 -0x0FFF, 229 -0x00FF, 230 -0x000F, 231 -1, 232 0, 233 1, 234 0x000F, 235 0x00FF, 236 0x0FFF, 237 Short.MAX_VALUE - 1, 238 Short.MAX_VALUE 239 }; 240 for (int i = 0; i < a.length; i++) { 241 doshort(a[i]); 242 } 243 } 244 static void doshort(short x) throws Throwable { 245 if (DEBUG) System.out.println("short=" + x); 246 247 // boolean 248 { 249 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 250 MethodHandle mh2 = getmh2(mh1, boolean.class, short.class); 251 boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 252 boolean b = (boolean) mh2.invokeExact(x); 253 check(x, a, b); 254 } 255 256 // byte 257 { 258 MethodHandle mh1 = getmh1( byte.class, byte.class); 259 MethodHandle mh2 = getmh2(mh1, byte.class, short.class); 260 byte a = (byte) mh1.invokeExact((byte) x); 261 byte b = (byte) mh2.invokeExact(x); 262 check(x, a, b); 263 } 264 265 // char 266 { 267 MethodHandle mh1 = getmh1( char.class, char.class); 268 MethodHandle mh2 = getmh2(mh1, char.class, short.class); 269 char a = (char) mh1.invokeExact((char) x); 270 char b = (char) mh2.invokeExact(x); 271 check(x, a, b); 272 } 273 274 // short 275 { 276 MethodHandle mh1 = getmh1( short.class, short.class); 277 MethodHandle mh2 = getmh2(mh1, short.class, short.class); 278 short a = (short) mh1.invokeExact((short) x); 279 short b = (short) mh2.invokeExact(x); 280 check(x, a, b); 281 } 282 } 283 284 static void testint() throws Throwable { 285 int[] a = new int[] { 286 Integer.MIN_VALUE, 287 Integer.MIN_VALUE + 1, 288 -0x0FFFFFFF, 289 -0x00FFFFFF, 290 -0x000FFFFF, 291 -0x0000FFFF, 292 -0x00000FFF, 293 -0x000000FF, 294 -0x0000000F, 295 -1, 296 0, 297 1, 298 0x0000000F, 299 0x000000FF, 300 0x00000FFF, 301 0x0000FFFF, 302 0x000FFFFF, 303 0x00FFFFFF, 304 0x0FFFFFFF, 305 Integer.MAX_VALUE - 1, 306 Integer.MAX_VALUE 307 }; 308 for (int i = 0; i < a.length; i++) { 309 doint(a[i]); 310 } 311 } 312 static void doint(int x) throws Throwable { 313 if (DEBUG) System.out.println("int=" + x); 314 315 // boolean 316 { 317 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 318 MethodHandle mh2 = getmh2(mh1, boolean.class, int.class); 319 boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 320 boolean b = (boolean) mh2.invokeExact(x); 321 check(x, a, b); 322 } 323 324 // byte 325 { 326 MethodHandle mh1 = getmh1( byte.class, byte.class); 327 MethodHandle mh2 = getmh2(mh1, byte.class, int.class); 328 byte a = (byte) mh1.invokeExact((byte) x); 329 byte b = (byte) mh2.invokeExact(x); 330 check(x, a, b); 331 } 332 333 // char 334 { 335 MethodHandle mh1 = getmh1( char.class, char.class); 336 MethodHandle mh2 = getmh2(mh1, char.class, int.class); 337 char a = (char) mh1.invokeExact((char) x); 338 char b = (char) mh2.invokeExact(x); 339 check(x, a, b); 340 } 341 342 // short 343 { 344 MethodHandle mh1 = getmh1( short.class, short.class); 345 MethodHandle mh2 = getmh2(mh1, short.class, int.class); 346 short a = (short) mh1.invokeExact((short) x); 347 short b = (short) mh2.invokeExact(x); 348 assert a == b : a + " != " + b; 349 check(x, a, b); 350 } 351 352 // int 353 { 354 MethodHandle mh1 = getmh1( int.class, int.class); 355 MethodHandle mh2 = getmh2(mh1, int.class, int.class); 356 int a = (int) mh1.invokeExact((int) x); 357 int b = (int) mh2.invokeExact(x); 358 check(x, a, b); 359 } 360 } 361 362 // test adapter_opt_l2i 363 static void testlong() throws Throwable { 364 long[] a = new long[] { 365 Long.MIN_VALUE, 366 Long.MIN_VALUE + 1, 367 -0x000000000FFFFFFFL, 368 -0x0000000000FFFFFFL, 369 -0x00000000000FFFFFL, 370 -0x000000000000FFFFL, 371 -0x0000000000000FFFL, 372 -0x00000000000000FFL, 373 -0x000000000000000FL, 374 -1L, 375 0L, 376 1L, 377 0x000000000000000FL, 378 0x00000000000000FFL, 379 0x0000000000000FFFL, 380 0x0000000000000FFFL, 381 0x000000000000FFFFL, 382 0x00000000000FFFFFL, 383 0x0000000000FFFFFFL, 384 0x000000000FFFFFFFL, 385 Long.MAX_VALUE - 1, 386 Long.MAX_VALUE 387 }; 388 for (int i = 0; i < a.length; i++) { 389 dolong(a[i]); 390 } 391 } 392 static void dolong(long x) throws Throwable { 393 if (DEBUG) System.out.println("long=" + x); 394 395 // boolean 396 { 397 MethodHandle mh1 = getmh1( boolean.class, boolean.class); 398 MethodHandle mh2 = getmh2(mh1, boolean.class, long.class); 399 boolean a = (boolean) mh1.invokeExact((x & 1L) == 1L); 400 boolean b = (boolean) mh2.invokeExact(x); 401 check(x, a, b); 402 } 403 404 // byte 405 { 406 MethodHandle mh1 = getmh1( byte.class, byte.class); 407 MethodHandle mh2 = getmh2(mh1, byte.class, long.class); 408 byte a = (byte) mh1.invokeExact((byte) x); 409 byte b = (byte) mh2.invokeExact(x); 410 check(x, a, b); 411 } 412 413 // char 414 { 415 MethodHandle mh1 = getmh1( char.class, char.class); 416 MethodHandle mh2 = getmh2(mh1, char.class, long.class); 417 char a = (char) mh1.invokeExact((char) x); 418 char b = (char) mh2.invokeExact(x); 419 check(x, a, b); 420 } 421 422 // short 423 { 424 MethodHandle mh1 = getmh1( short.class, short.class); 425 MethodHandle mh2 = getmh2(mh1, short.class, long.class); 426 short a = (short) mh1.invokeExact((short) x); 427 short b = (short) mh2.invokeExact(x); 428 check(x, a, b); 429 } 430 431 // int 432 { 433 MethodHandle mh1 = getmh1( int.class, int.class); 434 MethodHandle mh2 = getmh2(mh1, int.class, long.class); 435 int a = (int) mh1.invokeExact((int) x); 436 int b = (int) mh2.invokeExact(x); 437 check(x, a, b); 438 } 439 } 440 441 static void check(boolean x, boolean e, boolean a) { p(z2h(x), z2h(e), z2h(a)); assert e == a : z2h(x) + ": " + z2h(e) + " != " + z2h(a); } 442 static void check(boolean x, byte e, byte a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); } 443 static void check(boolean x, int e, int a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); } 444 445 static void check(int x, boolean e, boolean a) { p(i2h(x), z2h(e), z2h(a)); assert e == a : i2h(x) + ": " + z2h(e) + " != " + z2h(a); } 446 static void check(int x, byte e, byte a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); } 447 static void check(int x, int e, int a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); } 448 449 static void check(long x, boolean e, boolean a) { p(l2h(x), z2h(e), z2h(a)); assert e == a : l2h(x) + ": " + z2h(e) + " != " + z2h(a); } 450 static void check(long x, byte e, byte a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); } 451 static void check(long x, int e, int a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); } 452 453 static void p(String x, String e, String a) { if (DEBUG) System.out.println(x + ": expected: " + e + ", actual: " + a); } 454 455 static String z2h(boolean x) { return x ? "1" : "0"; } 456 static String i2h(int x) { return Integer.toHexString(x); } 457 static String l2h(long x) { return Long.toHexString(x); } 458 459 // to int 460 public static boolean foo(boolean i) { return i; } 461 public static byte foo(byte i) { return i; } 462 public static char foo(char i) { return i; } 463 public static short foo(short i) { return i; } 464 public static int foo(int i) { return i; } 465 }