OpenJDK / amber / amber
changeset 56998:a8905b85b1f8 amber-demo-II
Automatic merge with records-and-sealed
author | mcimadamore |
---|---|
date | Fri, 16 Aug 2019 16:05:45 +0000 |
parents | 7ddffaf8b702 6fbc84eefe66 |
children | 3d7072d56e6d |
files | test/hotspot/jtreg/runtime/sealedTypes/noLoadSubtypes.jcod |
diffstat | 9 files changed, 375 insertions(+), 124 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/classfile/classFileParser.cpp Fri Aug 16 15:05:55 2019 +0000 +++ b/src/hotspot/share/classfile/classFileParser.cpp Fri Aug 16 16:05:45 2019 +0000 @@ -3411,6 +3411,11 @@ CHECK); } +bool ClassFileParser::supports_sealed_types() { + return _major_version == JAVA_14_VERSION; + // TBD: add: && _minor_version == JAVA_PREVIEW_MINOR_VERSION && Arguments::enable_preview() +} + void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cfs, ConstantPool* cp, ClassFileParser::ClassAnnotationCollector* parsed_annotations, @@ -3641,18 +3646,20 @@ class_info_index, CHECK); _nest_host = class_info_index; } else if (tag == vmSymbols::tag_permitted_subtypes()) { - // Check for PermittedSubtypes tag - if (!_access_flags.is_final()) { - classfile_parse_error("PermittedSubtypes attribute in non-final class file %s", CHECK); + if (supports_sealed_types()) { + // Check for PermittedSubtypes tag + if (!_access_flags.is_final()) { + classfile_parse_error("PermittedSubtypes attribute in non-final class file %s", CHECK); + } + if (parsed_permitted_subtypes_attribute) { + classfile_parse_error("Multiple PermittedSubtypes attributes in class file %s", CHECK); + } else { + parsed_permitted_subtypes_attribute = true; + } + permitted_subtypes_attribute_start = cfs->current(); + permitted_subtypes_attribute_length = attribute_length; } - if (parsed_permitted_subtypes_attribute) { - classfile_parse_error("Multiple PermittedSubtypes attributes in class file %s", CHECK); - } else { - parsed_permitted_subtypes_attribute = true; - } - permitted_subtypes_attribute_start = cfs->current(); - permitted_subtypes_attribute_length = attribute_length; - cfs->skip_u1(permitted_subtypes_attribute_length, CHECK); + cfs->skip_u1(attribute_length, CHECK); } else if (tag == vmSymbols::tag_record()) { if (parsed_record_attribute) { classfile_parse_error("Multiple Record attributes in class file %s", CHECK);
--- a/src/hotspot/share/classfile/classFileParser.hpp Fri Aug 16 15:05:55 2019 +0000 +++ b/src/hotspot/share/classfile/classFileParser.hpp Fri Aug 16 16:05:45 2019 +0000 @@ -299,6 +299,7 @@ ConstantPool* cp, int* const record_params_count_ptr, TRAPS); + bool supports_sealed_types(); void parse_classfile_attributes(const ClassFileStream* const cfs, ConstantPool* cp,
--- a/src/hotspot/share/memory/heapInspection.hpp Fri Aug 16 15:05:55 2019 +0000 +++ b/src/hotspot/share/memory/heapInspection.hpp Fri Aug 16 16:05:45 2019 +0000 @@ -88,6 +88,8 @@ "Number of bytes used by the InstanceKlass::inner_classes() array") \ f(nest_members_bytes, IK_nest_members, \ "Number of bytes used by the InstanceKlass::nest_members() array") \ + f(permitted_subtypes_bytes, IK_nest_members, \ + "Number of bytes used by the InstanceKlass::permitted_subtypes() array") \ f(signers_bytes, IK_signers, \ "Number of bytes used by the InstanceKlass::singers() array") \ f(class_annotations_bytes, class_annotations, \
--- a/src/hotspot/share/oops/instanceKlass.cpp Fri Aug 16 15:05:55 2019 +0000 +++ b/src/hotspot/share/oops/instanceKlass.cpp Fri Aug 16 16:05:45 2019 +0000 @@ -3586,6 +3586,7 @@ n += (sz->_fields_bytes = sz->count_array(fields())); n += (sz->_inner_classes_bytes = sz->count_array(inner_classes())); n += (sz->_nest_members_bytes = sz->count_array(nest_members())); + n += (sz->_permitted_subtypes_bytes = sz->count_array(permitted_subtypes())); sz->_ro_bytes += n; const ConstantPool* cp = constants();
--- a/src/hotspot/share/oops/instanceKlass.hpp Fri Aug 16 15:05:55 2019 +0000 +++ b/src/hotspot/share/oops/instanceKlass.hpp Fri Aug 16 16:05:45 2019 +0000 @@ -468,7 +468,7 @@ _record_params_count = record_params_count; } -// permitted subtypes + // permitted subtypes Array<u2>* permitted_subtypes() const { return _permitted_subtypes; } void set_permitted_subtypes(Array<u2>* s) { _permitted_subtypes = s; }
--- a/src/java.base/share/classes/java/lang/Class.java Fri Aug 16 15:05:55 2019 +0000 +++ b/src/java.base/share/classes/java/lang/Class.java Fri Aug 16 16:05:45 2019 +0000 @@ -4151,7 +4151,7 @@ ClassDesc[] constants = new ClassDesc[descriptors.length]; int i = 0; for (String descriptor : descriptors) { - ClassDesc cd = ClassDesc.of(descriptor); + ClassDesc cd = ClassDesc.of(descriptor.replace('/', '.')); constants[i++] = cd; } return constants;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/sealedTypes/getPermittedSubtypes.jcod Fri Aug 16 16:05:45 2019 +0000 @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This class has entries in its PermittedSubtypes attribute that do not exist. +// Test that this does not prevent JVM_GetPermittedSubtypes() from returning +// their names. +// +// sealed class noLoadSubtypes permits iDontExist, I/Dont/Exist/Either { } +// +class noLoadSubtypes { + 0xCAFEBABE; + 0; // minor version + 58; // version + [18] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 "<init>"; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "noLoadSubtypes"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x4D + Utf8 "LineNumberTable"; // #10 at 0x54 + Utf8 "SourceFile"; // #11 at 0x66 + Utf8 "noLoadSubtypes.java"; // #12 at 0x73 + Utf8 "PermittedSubtypes"; // #13 at 0x89 + class #15; // #14 at 0x9D + Utf8 "iDontExist"; // #15 at 0xA0 + class #17; // #16 at 0xAA + Utf8 "I/Dont/Exist/Either"; // #17 at 0xAD + } // Constant Pool + + 0x0030; // access [ ACC_SUPER ACC_FINAL ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [1] { // methods + { // Member at 0xC1 + 0x0000; // access + #5; // name_cpx + #6; // sig_cpx + [1] { // Attributes + Attr(#9, 29) { // Code at 0xC9 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xE0 + [1] { // LineNumberTable + 0 1; // at 0xEC + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [2] { // Attributes + Attr(#13, 6) { // PermittedSubtypes at 0xF6 + 0x0002000E0010; + } // end PermittedSubtypes + ; + Attr(#11, 2) { // SourceFile at 0xEE + #12; + } // end SourceFile + } // Attributes +} // end class noLoadSubtypes + + + +// This class contains an empty PermittedSubtypes attribute. Test that +// this does not cause an exception to get thrown. +class noSubtypes { + 0xCAFEBABE; + 0; // minor version + 58; // version + [14] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 "<init>"; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "noSubtypes"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x49 + Utf8 "LineNumberTable"; // #10 at 0x50 + Utf8 "SourceFile"; // #11 at 0x62 + Utf8 "noSubtypes.java"; // #12 at 0x6F + Utf8 "PermittedSubtypes"; // #13 at 0x81 + } // Constant Pool + + 0x0030; // access [ ACC_SUPER ACC_FINAL ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [1] { // methods + { // Member at 0xAB + 0x0000; // access + #5; // name_cpx + #6; // sig_cpx + [1] { // Attributes + Attr(#9, 29) { // Code at 0xB3 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xCA + [1] { // LineNumberTable + 0 1; // at 0xD6 + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [2] { // Attributes + Attr(#11, 2) { // SourceFile at 0xD8 + #12; + } // end SourceFile + ; + Attr(#13, 2) { // PermittedSubtypes at 0xE0 + 0x0000; + } // end PermittedSubtypes + } // Attributes +} // end class noSubtypes + + + +// This class has a PermittedSubtypes attribute but an old class file version. +// The PermittedSubtypes attribute should be ignored. +// +// sealed class oldClassFile permits iDontExist, I/Dont/Exist/Either { } +// +class oldClassFile { + 0xCAFEBABE; + 0; // minor version + 57; // version + [18] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 "<init>"; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "oldClassFile"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x4D + Utf8 "LineNumberTable"; // #10 at 0x54 + Utf8 "SourceFile"; // #11 at 0x66 + Utf8 "oldClassFile.java"; // #12 at 0x73 + Utf8 "PermittedSubtypes"; // #13 at 0x89 + class #15; // #14 at 0x9D + Utf8 "iDontExist"; // #15 at 0xA0 + class #17; // #16 at 0xAA + Utf8 "I/Dont/Exist/Either"; // #17 at 0xAD + } // Constant Pool + + 0x0030; // access [ ACC_SUPER ACC_FINAL ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [1] { // methods + { // Member at 0xC1 + 0x0000; // access + #5; // name_cpx + #6; // sig_cpx + [1] { // Attributes + Attr(#9, 29) { // Code at 0xC9 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xE0 + [1] { // LineNumberTable + 0 1; // at 0xEC + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [2] { // Attributes + Attr(#11, 2) { // SourceFile at 0xEE + #12; + } // end SourceFile + ; + Attr(#13, 6) { // PermittedSubtypes at 0xF6 + 0x0002000E0010; + } // end PermittedSubtypes + } // Attributes +} // end class oldClassFile + + + +// This class has a corrupted PermittedSubtypes attribute. Attempts to load it +// should throw ClassFormatError. +class badPermittedAttr { + 0xCAFEBABE; + 0; // minor version + 58; // version + [18] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 at 0x0A + class #4; // #2 at 0x0F + NameAndType #5 #6; // #3 at 0x12 + Utf8 "java/lang/Object"; // #4 at 0x17 + Utf8 "<init>"; // #5 at 0x2A + Utf8 "()V"; // #6 at 0x33 + class #8; // #7 at 0x39 + Utf8 "badPermittedAttr"; // #8 at 0x3C + Utf8 "Code"; // #9 at 0x4D + Utf8 "LineNumberTable"; // #10 at 0x54 + Utf8 "SourceFile"; // #11 at 0x66 + Utf8 "badPermittedAttr.java"; // #12 at 0x73 + Utf8 "PermittedSubtypes"; // #13 at 0x89 + class #15; // #14 at 0x9D + Utf8 "iDontExist"; // #15 at 0xA0 + class #17; // #16 at 0xAA + Utf8 "I/Dont/Exist/Either"; // #17 at 0xAD + } // Constant Pool + + 0x0030; // access [ ACC_SUPER ACC_FINAL ] + #7;// this_cpx + #2;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [1] { // methods + { // Member at 0xC1 + 0x0000; // access + #5; // name_cpx + #6; // sig_cpx + [1] { // Attributes + Attr(#9, 29) { // Code at 0xC9 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70001B1; + } + [0] { // Traps + } // end Traps + [1] { // Attributes + Attr(#10, 6) { // LineNumberTable at 0xE0 + [1] { // LineNumberTable + 0 1; // at 0xEC + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [2] { // Attributes + Attr(#11, 2) { // SourceFile at 0xEE + #12; + } // end SourceFile + ; + Attr(#13, 6) { // PermittedSubtypes at 0xF6 + 0x0002000F0010; + } // end PermittedSubtypes + } // Attributes +} // end class badPermittedAttr
--- a/test/hotspot/jtreg/runtime/sealedTypes/getPermittedSubtypesTest.java Fri Aug 16 15:05:55 2019 +0000 +++ b/test/hotspot/jtreg/runtime/sealedTypes/getPermittedSubtypesTest.java Fri Aug 16 16:05:45 2019 +0000 @@ -23,7 +23,7 @@ /* * @test - * @compile noLoadSubtypes.jcod + * @compile getPermittedSubtypes.jcod * @run main getPermittedSubtypesTest */ @@ -63,7 +63,7 @@ // Create ArrayList of permitted subtypes class names. ArrayList<String> permittedNames = new ArrayList<String>(); for (int i = 0; i < permitted.length; i++) { - permittedNames.add(((ClassDesc)permitted[i]).displayName()); + permittedNames.add(((ClassDesc)permitted[i]).descriptorString()); } if (permittedNames.size() != expected.length) { @@ -87,21 +87,33 @@ } } - public static void main(String... args) { - testSealedInfo(SealedI1.class, new String[] {"getPermittedSubtypesTest$notSealed", - "getPermittedSubtypesTest$Sub1", - "getPermittedSubtypesTest$Extender"}); - testSealedInfo(Sealed1.class, new String[] {"getPermittedSubtypesTest$Sub1"}); + public static void main(String... args) throws Throwable { + testSealedInfo(SealedI1.class, new String[] {"LgetPermittedSubtypesTest$notSealed;", + "LgetPermittedSubtypesTest$Sub1;", + "LgetPermittedSubtypesTest$Extender;"}); + testSealedInfo(Sealed1.class, new String[] {"LgetPermittedSubtypesTest$Sub1;"}); testSealedInfo(noPermits.class, new String[] { }); testSealedInfo(Final4.class, new String[] { }); testSealedInfo(notSealed.class, new String[] { }); + + // Test class with PermittedSubtypes attribute but old class file version. + testSealedInfo(oldClassFile.class, new String[] { }); + + // Test class with empty PermittedSubtypes attribute. + testSealedInfo(noSubtypes.class, new String[] { }); + // Test returning names of non-existing classes. + testSealedInfo(noLoadSubtypes.class, new String[]{"LiDontExist;", "LI/Dont/Exist/Either;"}); + + // Test that loading a class with a corrupted PermittedSubtypes attribute + // causes a ClassFormatError. try { - testSealedInfo(noLoadSubtypes.class, new String[]{"iDontExist", - "I/Dont/Exist/Either"}); - throw new AssertionError("should fail"); - } catch (IllegalArgumentException iae) { - // ok + Class.forName("badPermittedAttr"); + throw new RuntimeException("Expected ClasFormatError exception not thrown"); + } catch (ClassFormatError cfe) { + if (!cfe.getMessage().contains("Permitted subtype class_info_index 15 has bad constant type")) { + throw new RuntimeException("Unexpected ClassFormatError exception: " + cfe.getMessage()); + } } } }
--- a/test/hotspot/jtreg/runtime/sealedTypes/noLoadSubtypes.jcod Fri Aug 16 15:05:55 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// This class has PermittedSubtypes that do not exist. Test that this does -// not prevent JVM_GetPermittedSubtypes() from returning their names. -// -// sealed class noLoadSubtypes permits iDontExist, I/Dont/Exist/Either { } -// -class noLoadSubtypes { - 0xCAFEBABE; - 0; // minor version - 58; // version - [18] { // Constant Pool - ; // first element is empty - Method #2 #3; // #1 at 0x0A - class #4; // #2 at 0x0F - NameAndType #5 #6; // #3 at 0x12 - Utf8 "java/lang/Object"; // #4 at 0x17 - Utf8 "<init>"; // #5 at 0x2A - Utf8 "()V"; // #6 at 0x33 - class #8; // #7 at 0x39 - Utf8 "noLoadSubtypes"; // #8 at 0x3C - Utf8 "Code"; // #9 at 0x4D - Utf8 "LineNumberTable"; // #10 at 0x54 - Utf8 "SourceFile"; // #11 at 0x66 - Utf8 "noLoadSubtypes.java"; // #12 at 0x73 - Utf8 "PermittedSubtypes"; // #13 at 0x89 - class #15; // #14 at 0x9D - Utf8 "iDontExist"; // #15 at 0xA0 - class #17; // #16 at 0xAA - Utf8 "I/Dont/Exist/Either"; // #17 at 0xAD - } // Constant Pool - - 0x0030; // access [ ACC_SUPER ACC_FINAL ] - #7;// this_cpx - #2;// super_cpx - - [0] { // Interfaces - } // Interfaces - - [0] { // fields - } // fields - - [1] { // methods - { // Member at 0xC1 - 0x0000; // access - #5; // name_cpx - #6; // sig_cpx - [1] { // Attributes - Attr(#9, 29) { // Code at 0xC9 - 1; // max_stack - 1; // max_locals - Bytes[5]{ - 0x2AB70001B1; - } - [0] { // Traps - } // end Traps - [1] { // Attributes - Attr(#10, 6) { // LineNumberTable at 0xE0 - [1] { // LineNumberTable - 0 1; // at 0xEC - } - } // end LineNumberTable - } // Attributes - } // end Code - } // Attributes - } // Member - } // methods - - [2] { // Attributes - Attr(#11, 2) { // SourceFile at 0xEE - #12; - } // end SourceFile - ; - Attr(#13, 6) { // PermittedSubtypes at 0xF6 - 0x0002000E0010; - } // end PermittedSubtypes - } // Attributes -} // end class noLoadSubtypes