< prev index next >

hotspot/test/runtime/valhalla/valuetypes/DeriveValueTypeCreation.java

Print this page




   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 package runtime.valhalla.valuetypes;
  24 
  25 import java.io.IOException;
  26 import java.io.RandomAccessFile;
  27 import java.lang.reflect.Field;

  28 import java.lang.reflect.Method;
  29 import static java.lang.reflect.Modifier.*;
  30 import java.net.URL;
  31 import java.util.Enumeration;

  32 

  33 import jdk.experimental.value.ValueType;
  34 
  35 import jdk.internal.org.objectweb.asm.*;
  36 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  37 
  38 import static jdk.test.lib.Asserts.*;
  39 
  40 /*
  41  * @test DeriveValueTypeCreation
  42  * @summary Derive Value Type creation test
  43  * @library /test/lib

  44  * @modules java.base/jdk.internal.org.objectweb.asm
  45  * @build runtime.valhalla.valuetypes.ValueCapableClass
  46  * @run main/othervm -Xint -XX:+EnableMVT runtime.valhalla.valuetypes.DeriveValueTypeCreation
  47  * @run main/othervm -Xcomp -XX:+EnableMVT runtime.valhalla.valuetypes.DeriveValueTypeCreation
  48  */
  49 public class DeriveValueTypeCreation {
  50 
  51     public static final String VCC_CLASSNAME = "runtime.valhalla.valuetypes.ValueCapableClass";





  52 
  53     public static void main(String[] args) {
  54         DeriveValueTypeCreation test = new DeriveValueTypeCreation();
  55         test.run();
  56     }
  57 
  58     public void run() {
  59         loadAndRunTest();
  60         notValueCapableClasses();

  61     }
  62 
  63     void loadAndRunTest() {
  64         Class<?> clazz = null;
  65         try {
  66             clazz = Class.forName(VCC_CLASSNAME, true, getClass().getClassLoader());
  67             clazz.getDeclaredMethod("test").invoke(null);
  68         }
  69         catch (ClassNotFoundException cnfe) { fail("VCC class missing", cnfe); }
  70         catch (NoSuchMethodException nsme) { fail("VCC test method missing", nsme); }
  71         catch (Throwable t) { fail("Failed to invoke VCC.test()", t); }
  72 
  73         checkValueCapableClass(clazz);
  74     }
  75 
  76     void checkValueCapableClass(Class<?> clazz) {
  77         if (!ValueType.classHasValueType(clazz)) {
  78             fail("!classHasValueType: " + clazz);
  79         }
  80 
  81         ValueType<?> vt = ValueType.forClass(clazz);
  82         if (vt == null) {
  83             fail("ValueType.forClass failed");
  84         }
  85 
  86         System.out.println("ValueType: " + vt);
  87 
  88         if (vt.boxClass() != clazz) {
  89             fail("ValueType.boxClass() failed");
  90         }
  91         if (vt.sourceClass() != clazz) {
  92             fail("ValueType.sourceClass() failed");
  93         }
  94 
  95         // DVT class matches our expectations for the current implementation...
  96         Class<?> vtClass = vt.valueClass();
  97         if (!vtClass.getName().equals(clazz.getName() + "$Value")) {
  98             fail("ValueType.valueClass() failed");
  99         }
 100         if (!vtClass.getSuperclass().getName().equals("java.lang.__Value")) {
 101             fail("ValueType.valueClass() isn't a Value Type class");
 102         }
 103 
 104         // Exercise "Class.getSimpleName()", we've cause problems with it before
 105         String sn = vtClass.getSimpleName();
 106         System.out.println("SimpleName: " + sn);
 107 
 108         if (clazz.getClassLoader() != vtClass.getClassLoader()) {
 109             fail("ClassLoader mismatch");
 110         }
 111         if (clazz.getProtectionDomain() != vtClass.getProtectionDomain()) {
 112             fail("ProtectionDomain mismatch");
 113         }
 114     }
 115 
 116     void notValueCapableClasses() {
 117         int vccKlassAccess = ACC_SUPER | ACC_PUBLIC | ACC_FINAL;
 118         int vccFieldAccess = ACC_PUBLIC | ACC_FINAL;
 119         String vccSuperClass = "java/lang/Object";
 120 
 121         // First a control test to check createTestClass is working
 122         try {
 123             Class<?> cls = createTestClass("Control_Case_is_a_VCC", vccKlassAccess, vccSuperClass, "I", vccFieldAccess);
 124             checkValueCapableClass(cls);
 125         }
 126         catch (Exception e) {
 127             fail("Control test failed", e);
 128         }
 129 
 130         testFailCase("Not_a_final_class", ACC_SUPER | ACC_PUBLIC, vccSuperClass, "I", vccFieldAccess, "not a final class");
 131         testFailCase("No_fields", vccKlassAccess, vccSuperClass, null, vccFieldAccess, "has no instance fields");
 132         testFailCase("Not_final_field", vccKlassAccess, vccSuperClass, "I", ACC_PUBLIC, "contains non-final instance field");
 133         testFailCase("Super_not_Object", vccKlassAccess, "java/lang/Throwable", "I", vccFieldAccess, "does not derive from Object");
 134     }
 135 
 136     void testFailCase(String clsName,
 137                       int klassAccess,
 138                       String superKlass,
 139                       String fieldType,
 140                       int fieldAccess,
 141                       String errMsgRequired) {
 142         try {
 143             createTestClass(clsName, klassAccess, superKlass, fieldType, fieldAccess);
 144             fail(clsName + " : failed to fail with Error");
 145         }
 146         catch (ClassNotFoundException cnfe) {
 147             fail(clsName + " : Unexpected ClassNotFoundException", cnfe);
 148         }
 149         catch (Error err) {
 150             if (!err.getMessage().contains(errMsgRequired)) {
 151                 fail(clsName + " : Not the error we were looking for", err);
 152             }
 153         }
 154     }
 155 
 156     Class<?> createTestClass(String name,





 157                              int klassAccess,
 158                              String superKlass,
 159                              String fieldType,
 160                              int fieldAccess) throws ClassNotFoundException {









 161         ClassWriter cw = new ClassWriter(0);
 162         cw.visit(52, klassAccess, name, null, superKlass, null);

 163         cw.visitAnnotation("Ljvm/internal/value/ValueCapableClass;", true);

 164         if (fieldType != null) {
 165             cw.visitField(fieldAccess, "x", fieldType, null, null);
 166         }
 167         cw.visitEnd();
 168         return new TestClassLoader(name, cw.toByteArray()).loadClass(name);









 169     }
 170 
 171     class TestClassLoader extends ClassLoader {
 172 
 173         String name;
 174         byte[] classBytes;
 175 

 176         TestClassLoader(String name, byte[] classBytes) {
 177             this.name = name;
 178             this.classBytes = classBytes;



 179         }
 180 
 181         @Override
 182         public Class findClass(String name) throws ClassNotFoundException {
 183             if (this.name.equals(name)) {





 184                 return defineClass(name, classBytes, 0, classBytes.length);
 185             }
 186             throw new ClassNotFoundException();




 187         }
 188     }
 189 





















































































 190 }


   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 package runtime.valhalla.valuetypes;
  24 


  25 import java.lang.reflect.Field;
  26 import java.lang.reflect.InvocationTargetException;
  27 import java.lang.reflect.Method;
  28 import static java.lang.reflect.Modifier.*;
  29 import java.net.URL;
  30 import java.util.ArrayList;
  31 import java.util.HashMap;
  32 
  33 import jdk.experimental.bytecode.*;
  34 import jdk.experimental.value.ValueType;
  35 
  36 import jdk.internal.org.objectweb.asm.*;
  37 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  38 
  39 import static jdk.test.lib.Asserts.*;
  40 
  41 /*
  42  * @test DeriveValueTypeCreation
  43  * @summary Derive Value Type creation test
  44  * @library /test/lib
  45  * @compile DeriveValueTypeCreation.java
  46  * @modules java.base/jdk.internal.org.objectweb.asm
  47  * @build runtime.valhalla.valuetypes.ValueCapableClass
  48  * @run main/othervm -Xint -XX:+EnableMVT runtime.valhalla.valuetypes.DeriveValueTypeCreation
  49  * @run main/othervm -Xcomp -XX:+EnableMVT runtime.valhalla.valuetypes.DeriveValueTypeCreation
  50  */
  51 public class DeriveValueTypeCreation {
  52 
  53     public static final String VCC_CLASSNAME = "runtime.valhalla.valuetypes.ValueCapableClass";
  54     public static final String DVT_SUFFIX = "$Value";
  55 
  56     public static final int TEST_DEF_CLASS_ACCESS = ACC_SUPER | ACC_PUBLIC | ACC_FINAL;
  57     public static final int TEST_DEF_FIELD_ACCESS = ACC_PUBLIC | ACC_FINAL;
  58     public static final String OBJECT_CLASS_DESC  = "java/lang/Object";
  59 
  60     public static void main(String[] args) {
  61         DeriveValueTypeCreation test = new DeriveValueTypeCreation();
  62         test.run();
  63     }
  64 
  65     public void run() {
  66         loadAndRunTest();
  67         notValueCapableClasses();
  68         loadDvtFirst();
  69     }
  70 
  71     void loadAndRunTest() {
  72         Class<?> clazz = null;
  73         try {
  74             clazz = Class.forName(VCC_CLASSNAME, true, getClass().getClassLoader());
  75             clazz.getDeclaredMethod("test").invoke(null);
  76         }
  77         catch (ClassNotFoundException cnfe) { fail("VCC class missing", cnfe); }
  78         catch (NoSuchMethodException nsme) { fail("VCC test method missing", nsme); }
  79         catch (Throwable t) { fail("Failed to invoke VCC.test()", t); }
  80 
  81         checkValueCapableClass(clazz);
  82     }
  83 
  84     void checkValueCapableClass(Class<?> clazz) {
  85         if (!ValueType.classHasValueType(clazz)) {
  86             fail("!classHasValueType: " + clazz);
  87         }
  88 
  89         ValueType<?> vt = ValueType.forClass(clazz);
  90         if (vt == null) {
  91             fail("ValueType.forClass failed");
  92         }
  93 
  94         System.out.println("ValueType: " + vt);
  95 
  96         if (vt.boxClass() != clazz) {
  97             fail("ValueType.boxClass() failed");
  98         }
  99         if (vt.sourceClass() != clazz) {
 100             fail("ValueType.sourceClass() failed");
 101         }
 102 
 103         // DVT class matches our expectations for the current implementation...
 104         Class<?> vtClass = vt.valueClass();
 105         if (!vtClass.getName().equals(clazz.getName() + DVT_SUFFIX)) {
 106             fail("ValueType.valueClass() failed");
 107         }
 108         if (!vtClass.getSuperclass().getName().equals("java.lang.__Value")) {
 109             fail("ValueType.valueClass() isn't a Value Type class");
 110         }
 111 
 112         // Exercise "Class.getSimpleName()", we've cause problems with it before
 113         String sn = vtClass.getSimpleName();
 114         System.out.println("SimpleName: " + sn);
 115 
 116         if (clazz.getClassLoader() != vtClass.getClassLoader()) {
 117             fail("ClassLoader mismatch");
 118         }
 119         if (clazz.getProtectionDomain() != vtClass.getProtectionDomain()) {
 120             fail("ProtectionDomain mismatch");
 121         }
 122     }
 123 
 124     void notValueCapableClasses() {
 125         // First a control test to check createTestVccClass is working




 126         try {
 127             Class<?> cls = createTestVccClass("Control_Case_is_a_VCC", TEST_DEF_CLASS_ACCESS, OBJECT_CLASS_DESC, "I", TEST_DEF_FIELD_ACCESS);
 128             checkValueCapableClass(cls);
 129         }
 130         catch (Exception e) {
 131             fail("Control test failed", e);
 132         }
 133 
 134         testFailCase("Not_a_final_class", ACC_SUPER | ACC_PUBLIC, OBJECT_CLASS_DESC, "I", TEST_DEF_FIELD_ACCESS, "not a final class");
 135         testFailCase("No_fields", TEST_DEF_CLASS_ACCESS, OBJECT_CLASS_DESC, null, TEST_DEF_FIELD_ACCESS, "has no instance fields");
 136         testFailCase("Not_final_field", TEST_DEF_CLASS_ACCESS, OBJECT_CLASS_DESC, "I", ACC_PUBLIC, "contains non-final instance field");
 137         testFailCase("Super_not_Object", TEST_DEF_CLASS_ACCESS, "java/lang/Throwable", "I", TEST_DEF_FIELD_ACCESS, "does not derive from Object");
 138     }
 139 
 140     void testFailCase(String clsName,
 141                       int klassAccess,
 142                       String superKlass,
 143                       String fieldType,
 144                       int fieldAccess,
 145                       String errMsgRequired) {
 146         try {
 147             createTestVccClass(clsName, klassAccess, superKlass, fieldType, fieldAccess);
 148             fail(clsName + " : failed to fail with Error");
 149         }
 150         catch (ClassNotFoundException cnfe) {
 151             fail(clsName + " : Unexpected ClassNotFoundException", cnfe);
 152         }
 153         catch (Error err) {
 154             if (!err.getMessage().contains(errMsgRequired)) {
 155                 fail(clsName + " : Not the error we were looking for", err);
 156             }
 157         }
 158     }
 159 
 160     byte[] createTestVccClassBytes(String name,
 161                                 boolean vccAnnotation) {
 162         return createTestVccClassBytes(name, TEST_DEF_CLASS_ACCESS, vccAnnotation, OBJECT_CLASS_DESC, "I", TEST_DEF_FIELD_ACCESS);
 163     }
 164 
 165     byte[] createTestVccClassBytes(String name,
 166                                 int klassAccess,
 167                                 String superKlass,
 168                                 String fieldType,
 169                                 int fieldAccess)  {
 170         return createTestVccClassBytes(name, klassAccess, true, superKlass, fieldType, fieldAccess);
 171     }
 172 
 173     byte[] createTestVccClassBytes(String name,
 174                                 int klassAccess,
 175                                 boolean vccAnnotation,
 176                                 String superKlass,
 177                                 String fieldType,
 178                                 int fieldAccess)  {
 179         ClassWriter cw = new ClassWriter(0);
 180         cw.visit(52, klassAccess, name, null, superKlass, null);
 181         if (vccAnnotation ) {
 182             cw.visitAnnotation("Ljvm/internal/value/ValueCapableClass;", true);
 183         }
 184         if (fieldType != null) {
 185             cw.visitField(fieldAccess, "x", fieldType, null, null);
 186         }
 187         cw.visitEnd();
 188         return cw.toByteArray();
 189     }
 190 
 191     Class<?> createTestVccClass(String name,
 192                              int klassAccess,
 193                              String superKlass,
 194                              String fieldType,
 195                              int fieldAccess) throws ClassNotFoundException {
 196         return new TestClassLoader(name,
 197                                    createTestVccClassBytes(name, klassAccess, superKlass, fieldType, fieldAccess)).loadClass(name);
 198     }
 199 
 200     class TestClassLoader extends ClassLoader {
 201 
 202         HashMap<String, byte[]> namedBytes = new HashMap<>();
 203         ArrayList<String> findNames = new ArrayList<String>();
 204 
 205         TestClassLoader() {}
 206         TestClassLoader(String name, byte[] classBytes) {
 207             addNamedBytes(name, classBytes);
 208         }
 209 
 210         void addNamedBytes(String name, byte[] classBytes) {
 211             namedBytes.put(name, classBytes);
 212         }
 213 
 214         @Override
 215         public Class findClass(String name) throws ClassNotFoundException {
 216             byte[] classBytes = null;
 217             synchronized (findNames) {
 218                 findNames.add(name);
 219                 classBytes = namedBytes.get(name);
 220             }
 221             if (classBytes != null) {
 222                 return defineClass(name, classBytes, 0, classBytes.length);
 223             }
 224             throw new ClassNotFoundException(name);
 225         }
 226 
 227         public ArrayList<String> getFindNames() {
 228             return findNames;
 229         }
 230     }
 231 
 232     void loadDvtFirst() {
 233         try {
 234             loadDvtFirstNoVcc();
 235             loadDvtFirstNotVcc();
 236             loadDvtFirstBadVcc();
 237             loadDvtFirstVcc();
 238         } catch (Throwable t) {
 239             fail("loadDvtFirst failed", t);
 240         }
 241     }
 242 
 243     void loadDvtFirstNoVcc() throws Throwable {
 244         String vccName = "TestNoVcc";
 245         try {
 246             newDvtUserInstance(vccName, null, false);
 247         } catch (NoClassDefFoundError ncdfe) {}
 248         try {
 249             newDvtUserInstance(vccName, null, true);
 250         } catch (NoClassDefFoundError ncdfe) {}
 251     }
 252 
 253     void loadDvtFirstNotVcc() throws Throwable {
 254         String vccName = "TestNotVcc";
 255         byte[] vccBytes = createTestVccClassBytes(vccName, false);
 256         try {
 257             newDvtUserInstance(vccName, vccBytes, false);
 258         } catch (NoClassDefFoundError ncdfe) {}
 259         try {
 260             newDvtUserInstance(vccName, vccBytes, true);
 261         } catch (NoClassDefFoundError ncdfe) {}
 262     }
 263 
 264     void loadDvtFirstBadVcc() throws Throwable {
 265         String vccName = "TestBadVcc";
 266         byte[] vccBytes = createTestVccClassBytes(vccName, TEST_DEF_CLASS_ACCESS,
 267                                                   true, OBJECT_CLASS_DESC, "I",
 268                                                   ACC_PUBLIC);
 269         try {
 270             newDvtUserInstance(vccName, vccBytes, false);
 271         } catch (IncompatibleClassChangeError icce) {}
 272         try {
 273             newDvtUserInstance(vccName, vccBytes, true);
 274         } catch (IncompatibleClassChangeError icce) {}
 275     }
 276 
 277     void loadDvtFirstVcc() throws Throwable {
 278         String vccName = "TestValidVcc";
 279         byte[] vccBytes = createTestVccClassBytes(vccName, TEST_DEF_CLASS_ACCESS,
 280                                                   true, OBJECT_CLASS_DESC, "I",
 281                                                   TEST_DEF_FIELD_ACCESS);
 282         newDvtUserInstance(vccName, vccBytes, false);
 283         newDvtUserInstance(vccName, vccBytes, true);
 284     }
 285 
 286     void newDvtUserInstance(String vccName, byte[] vccBytes, boolean withField) throws Throwable {
 287         TestClassLoader cl = new TestClassLoader();
 288         if (vccBytes != null) {
 289             cl.addNamedBytes(vccName, vccBytes);
 290         }
 291         String dvtUserName = "UseValidDvt";
 292         String dvtName = vccName + DVT_SUFFIX;
 293         String dvtFieldDesc = "Q" + dvtName + ";";
 294         String dvtClassDesc = ";" + dvtFieldDesc;
 295         byte[] classBytes = createTestDvtUserClassBytes(dvtUserName, dvtClassDesc, (withField) ? dvtFieldDesc : null);
 296         cl.addNamedBytes(dvtUserName, classBytes);
 297         try {
 298             Class.forName(dvtUserName, true, cl).getDeclaredConstructor().newInstance();
 299         } catch (InvocationTargetException ite) { throw ite.getTargetException(); }
 300     }
 301 
 302     byte[] createTestDvtUserClassBytes(String className, String dvtDesc, String dvtFieldDesc) {
 303         BasicClassBuilder builder = new BasicClassBuilder(className, 53, 1)
 304             .withFlags(Flag.ACC_PUBLIC)
 305             .withSuperclass("java/lang/Object")
 306             .withMethod("<init>", "()V", M ->
 307                 M.withFlags(Flag.ACC_PUBLIC).withCode(TypedCodeBuilder::new, C ->
 308                     C
 309                     .load(0).invokespecial("java/lang/Object", "<init>", "()V", false)
 310                     .iconst_1().anewarray(dvtDesc).pop()
 311                     .return_()));
 312         if (dvtFieldDesc != null) {
 313             builder.withField("dvtField", dvtFieldDesc);
 314         }
 315         return builder.build();
 316     }
 317 }
< prev index next >