1 /*
   2  * Copyright (c) 2016, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package runtime.valhalla.valuetypes;
  27 
  28 import jdk.experimental.value.MethodHandleBuilder;
  29 import jdk.experimental.bytecode.TypeTag;
  30 import java.lang.invoke.MethodHandle;
  31 import java.lang.invoke.MethodType;
  32 import java.lang.invoke.MethodHandles;
  33 
  34 import jdk.test.lib.Asserts;
  35 
  36 /*
  37  * @test TypedBytecodesTest
  38  * @summary Exercise typed bytecodes
  39  * @library /testlibrary /
  40  * @run main/othervm -Xint -noverify runtime.valhalla.valuetypes.TypedBytecodesTest
  41  *
  42  * To dump generated byte-code, add "-Dvalhalla.dumpIsolatedMethodClasses=/tmp/foo"
  43  */
  44 
  45 public class TypedBytecodesTest {
  46     public static void main(String[] args) throws Throwable {
  47         // type I tests
  48         typed_I_astore_0_aload_0_areturn_test();
  49         typed_I_astore_1_aload_1_areturn_test();
  50         typed_I_astore_2_aload_2_areturn_test();
  51         typed_I_astore_3_aload_3_areturn_test();
  52         typed_I_astore_aload_areturn_test();
  53         typed_I_aconst_null_areturn_test();
  54         typed_I_anewarray_aastore_aaload_areturn_test();
  55         // type F tests
  56         typed_F_astore_0_aload_0_areturn_test();
  57         typed_F_astore_1_aload_1_areturn_test();
  58         typed_F_astore_2_aload_2_areturn_test();
  59         typed_F_astore_3_aload_3_areturn_test();
  60         typed_F_astore_aload_areturn_test();
  61         typed_F_aconst_null_areturn_test();
  62         typed_F_anewarray_aastore_aaload_areturn_test();
  63     }
  64 
  65     /*
  66      * Typed 'I' bytecodes
  67      */
  68     
  69     static void typed_I_astore_0_aload_0_areturn_test() throws Throwable{
  70         int value = 42;
  71         MethodHandle mh =
  72             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_I_astore_0_aload_0_areturn_test",
  73                                          MethodType.methodType(int.class),
  74                                          CODE-> CODE.const_(value)
  75                                          .typed(TypeTag.I)
  76                                          .astore_0()
  77                                          .typed(TypeTag.I)
  78                                          .aload_0()
  79                                          .typed(TypeTag.I)
  80                                          .areturn());
  81         int r = (int) mh.invokeExact();
  82         Asserts.assertEquals(r, value, "invalid int value");
  83     }
  84 
  85     static void typed_I_astore_1_aload_1_areturn_test() throws Throwable {
  86         int value = 64;
  87         MethodHandle mh =
  88             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_I_astore_1_aload_1_areturn_test",
  89                                          MethodType.methodType(int.class),
  90                                          CODE-> CODE.const_(value)
  91                                          .typed(TypeTag.I)
  92                                          .astore_1()
  93                                          .typed(TypeTag.I)
  94                                          .aload_1()
  95                                          .typed(TypeTag.I)
  96                                          .areturn());
  97         int r = (int) mh.invokeExact();
  98         Asserts.assertEquals(r, value, "invalid int value");
  99     }
 100 
 101     static void typed_I_astore_2_aload_2_areturn_test() throws Throwable {
 102         int value = -1;
 103         MethodHandle mh =
 104             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_I_astore_2_aload_2_areturn_test",
 105                                          MethodType.methodType(int.class),
 106                                          CODE-> CODE.const_(value)
 107                                          .typed(TypeTag.I)
 108                                          .astore_2()
 109                                          .typed(TypeTag.I)
 110                                          .aload_2()
 111                                          .typed(TypeTag.I)
 112                                          .areturn());
 113         int r = (int) mh.invokeExact();
 114         Asserts.assertEquals(r, value, "invalid int value");
 115     }
 116     
 117     static void typed_I_astore_3_aload_3_areturn_test() throws Throwable {
 118         int value = Integer.MAX_VALUE;
 119         MethodHandle mh =
 120             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_I_astore_3_aload_3_areturn_test",
 121                                          MethodType.methodType(int.class),
 122                                          CODE-> CODE.const_(value)
 123                                          .typed(TypeTag.I)
 124                                          .astore_3()
 125                                          .typed(TypeTag.I)
 126                                          .aload_3()
 127                                          .typed(TypeTag.I)
 128                                          .areturn());
 129         int r = (int) mh.invokeExact();
 130         Asserts.assertEquals(r, value, "invalid int value");
 131     }
 132 
 133     static void typed_I_astore_aload_areturn_test() throws Throwable {
 134         int value = -314;
 135         MethodHandle mh =
 136             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_I_astore_aload_areturn_test",
 137                                          MethodType.methodType(int.class),
 138                                          CODE-> CODE.const_(value)
 139                                          .typed(TypeTag.I)
 140                                          .astore(5)
 141                                          .typed(TypeTag.I)
 142                                          .aload(5)
 143                                          .typed(TypeTag.I)
 144                                          .areturn());
 145         int r = (int) mh.invokeExact();
 146         Asserts.assertEquals(r, value, "invalid int value");
 147     }
 148 
 149     static void typed_I_aconst_null_areturn_test() throws Throwable {
 150         MethodHandle mh =
 151             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_I_aconst_null_areturn_test",
 152                                          MethodType.methodType(int.class),
 153                                          CODE-> CODE.typed(TypeTag.I)
 154                                          .aconst_null()
 155                                          .typed(TypeTag.I)
 156                                          .areturn());
 157         int r = (int) mh.invokeExact();
 158         Asserts.assertEquals(r, 0, "invalid int value");
 159     }
 160 
 161     static void typed_I_anewarray_aastore_aaload_areturn_test() throws Throwable {
 162         MethodHandle mh =
 163             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_I_anewarray_aastore_aaload_areturn_test",
 164                                          MethodType.methodType(int.class),
 165                                          CODE-> CODE.const_(3)
 166                                          .typed(TypeTag.I)
 167                                          .anewarray(void.class)
 168                                          .astore_1()
 169                                          .aload_1()
 170                                          .const_(0)
 171                                          .const_(4)
 172                                          .typed(TypeTag.I)
 173                                          .aastore()
 174                                          .aload_1()
 175                                          .const_(1)
 176                                          .const_(5)
 177                                          .typed(TypeTag.I)
 178                                          .aastore()
 179                                          .aload_1()
 180                                          .const_(2)
 181                                          .const_(6)
 182                                          .typed(TypeTag.I)
 183                                          .aastore()
 184                                          .aload_1()
 185                                          .const_(0)
 186                                          .typed(TypeTag.I)
 187                                          .aaload()
 188                                          .aload_1()
 189                                          .const_(1)
 190                                          .typed(TypeTag.I)
 191                                          .aaload()
 192                                          .iadd()
 193                                          .aload_1()
 194                                          .const_(2)
 195                                          .typed(TypeTag.I)
 196                                          .aaload()
 197                                          .iadd()
 198                                          .typed(TypeTag.I)
 199                                          .areturn());
 200         int r = (int) mh.invokeExact();
 201         Asserts.assertEquals(r, 15, "invalid int value");
 202     }
 203     
 204     /*
 205      * Typed 'F' bytecodes
 206      */
 207     
 208     static void typed_F_astore_0_aload_0_areturn_test() throws Throwable{
 209         float value = 42.0f;
 210         MethodHandle mh =
 211             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_F_astore_0_aload_0_areturn_test",
 212                                          MethodType.methodType(float.class),
 213                                          CODE-> CODE.const_(value)
 214                                          .typed(TypeTag.F)
 215                                          .astore_0()
 216                                          .typed(TypeTag.F)
 217                                          .aload_0()
 218                                          .typed(TypeTag.F)
 219                                          .areturn());
 220         float r = (float) mh.invokeExact();
 221         Asserts.assertEquals(r, value, "invalid float value");
 222     }
 223 
 224     static void typed_F_astore_1_aload_1_areturn_test() throws Throwable {
 225         float value = 64.128f;
 226         MethodHandle mh =
 227             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_F_astore_1_aload_1_areturn_test",
 228                                          MethodType.methodType(float.class),
 229                                          CODE-> CODE.const_(value)
 230                                          .typed(TypeTag.F)
 231                                          .astore_1()
 232                                          .typed(TypeTag.F)
 233                                          .aload_1()
 234                                          .typed(TypeTag.F)
 235                                          .areturn());
 236         float r = (float) mh.invokeExact();
 237         Asserts.assertEquals(r, value, "invalid float value");
 238     }
 239 
 240     static void typed_F_astore_2_aload_2_areturn_test() throws Throwable {
 241         float value = -1.0f;
 242         MethodHandle mh =
 243             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_F_astore_2_aload_2_areturn_test",
 244                                          MethodType.methodType(float.class),
 245                                          CODE-> CODE.const_(value)
 246                                          .typed(TypeTag.F)
 247                                          .astore_2()
 248                                          .typed(TypeTag.F)
 249                                          .aload_2()
 250                                          .typed(TypeTag.F)
 251                                          .areturn());
 252         float r = (float) mh.invokeExact();
 253         Asserts.assertEquals(r, value, "invalid float value");
 254     }
 255     
 256     static void typed_F_astore_3_aload_3_areturn_test() throws Throwable {
 257         float value = Float.MAX_VALUE;
 258         MethodHandle mh =
 259             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_F_astore_3_aload_3_areturn_test",
 260                                          MethodType.methodType(float.class),
 261                                          CODE-> CODE.const_(value)
 262                                          .typed(TypeTag.F)
 263                                          .astore_3()
 264                                          .typed(TypeTag.F)
 265                                          .aload_3()
 266                                          .typed(TypeTag.F)
 267                                          .areturn());
 268         float r = (float) mh.invokeExact();
 269         Asserts.assertEquals(r, value, "invalid float value");
 270     }
 271 
 272     static void typed_F_astore_aload_areturn_test() throws Throwable {
 273         float value = -3.14f;
 274         MethodHandle mh =
 275             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_F_astore_aload_areturn_test",
 276                                          MethodType.methodType(float.class),
 277                                          CODE-> CODE.const_(value)
 278                                          .typed(TypeTag.F)
 279                                          .astore(5)
 280                                          .typed(TypeTag.F)
 281                                          .aload(5)
 282                                          .typed(TypeTag.F)
 283                                          .areturn());
 284         float r = (float) mh.invokeExact();
 285         Asserts.assertEquals(r, value, "invalid float value");
 286     }
 287 
 288     static void typed_F_aconst_null_areturn_test() throws Throwable {
 289         MethodHandle mh =
 290             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_F_aconst_null_areturn_test",
 291                                          MethodType.methodType(float.class),
 292                                          CODE-> CODE.typed(TypeTag.F)
 293                                          .aconst_null()
 294                                          .typed(TypeTag.F)
 295                                          .areturn());
 296         float r = (float) mh.invokeExact();
 297         Asserts.assertEquals(r, 0.0f, "invalid float value");
 298     }
 299 
 300      static void typed_F_anewarray_aastore_aaload_areturn_test() throws Throwable {
 301         MethodHandle mh =
 302             MethodHandleBuilder.loadCode(MethodHandles.lookup(), "typed_F_anewarray_aastore_aaload_areturn_test",
 303                                          MethodType.methodType(float.class),
 304                                          CODE-> CODE.const_(3)
 305                                          .typed(TypeTag.F)
 306                                          .anewarray(void.class)
 307                                          .astore_1()
 308                                          .aload_1()
 309                                          .const_(0)
 310                                          .const_(4f)
 311                                          .typed(TypeTag.F)
 312                                          .aastore()
 313                                          .aload_1()
 314                                          .const_(1)
 315                                          .const_(5f)
 316                                          .typed(TypeTag.F)
 317                                          .aastore()
 318                                          .aload_1()
 319                                          .const_(2)
 320                                          .const_(6f)
 321                                          .typed(TypeTag.F)
 322                                          .aastore()
 323                                          .aload_1()
 324                                          .const_(0)
 325                                          .typed(TypeTag.F)
 326                                          .aaload()
 327                                          .aload_1()
 328                                          .const_(1)
 329                                          .typed(TypeTag.F)
 330                                          .aaload()
 331                                          .fadd()
 332                                          .aload_1()
 333                                          .const_(2)
 334                                          .typed(TypeTag.F)
 335                                          .aaload()
 336                                          .fadd()
 337                                          .typed(TypeTag.F)
 338                                          .areturn());
 339         float r = (float) mh.invokeExact();
 340         Asserts.assertEquals(r, 15.0f, "invalid float value");
 341     }
 342 }
 343 
 344