Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8227046: compiler implementation for sealed classes
8225056: VM support for sealed classes
8227044: javax.lang.model for sealed classes
8227045: Preview APIs support for sealed classes
8227047: Javadoc for sealed types
8245854: JVM TI Specification for sealed classes

Co-authored-by: Harold Seigel <harold.seigel@oracle.com>
Co-authored-by: Jan Lahoda <jan.lahoda@oracle.com>
Reviewed-by: mcimadamore, forax, darcy, dholmes, jlahoda, lfoltan, mchung, sspitsyn, vromero
  • Loading branch information
3 people committed Jun 1, 2020
1 parent 567692e commit d42bfef8a44673aa9ae993d3f5bad954add5f6c9
Showing with 6,875 additions and 190 deletions.
  1. +1 −0 make/autoconf/spec.gmk.in
  2. +3 −3 make/data/jdwp/jdwp.spec
  3. +1 −0 make/hotspot/symbols/symbols-unix
  4. +124 −7 src/hotspot/share/classfile/classFileParser.cpp
  5. +6 −0 src/hotspot/share/classfile/classFileParser.hpp
  6. +1 −0 src/hotspot/share/classfile/vmSymbols.hpp
  7. +5 −0 src/hotspot/share/include/jvm.h
  8. +1 −0 src/hotspot/share/logging/logTag.hpp
  9. +67 −0 src/hotspot/share/oops/instanceKlass.cpp
  10. +14 −0 src/hotspot/share/oops/instanceKlass.hpp
  11. +27 −0 src/hotspot/share/prims/jvm.cpp
  12. +10 −3 src/hotspot/share/prims/jvmti.xml
  13. +27 −1 src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp
  14. +2 −1 src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp
  15. +84 −0 src/hotspot/share/prims/jvmtiRedefineClasses.cpp
  16. +1 −0 src/hotspot/share/prims/jvmtiRedefineClasses.hpp
  17. +67 −0 src/java.base/share/classes/java/lang/Class.java
  18. +2 −1 src/java.base/share/classes/jdk/internal/PreviewFeature.java
  19. +12 −12 src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java
  20. +6 −6 src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java
  21. +20 −20 src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java
  22. +1 −1 src/java.base/share/classes/jdk/internal/org/objectweb/asm/Constants.java
  23. +3 −3 src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java
  24. +10 −10 src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java
  25. +4 −4 src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java
  26. +4 −4 src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java
  27. +4 −4 src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java
  28. +4 −4 src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java
  29. +4 −4 src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java
  30. +2 −1 src/java.base/share/native/libjava/Class.c
  31. +4 −0 src/java.compiler/share/classes/javax/lang/model/SourceVersion.java
  32. +35 −1 src/java.compiler/share/classes/javax/lang/model/element/Modifier.java
  33. +24 −1 src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java
  34. +2 −2 src/java.instrument/share/native/libinstrument/JavaExceptions.c
  35. +24 −1 src/jdk.compiler/share/classes/com/sun/source/tree/ClassTree.java
  36. +3 −1 src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java
  37. +26 −4 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
  38. +3 −2 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java
  39. +2 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java
  40. +21 −0 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
  41. +2 −2 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
  42. +84 −0 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
  43. +18 −6 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
  44. +42 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
  45. +28 −2 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java
  46. +20 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
  47. +6 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java
  48. +115 −10 src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
  49. +14 −3 src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java
  50. +62 −0 src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
  51. +9 −0 src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java
  52. +9 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java
  53. +68 −36 src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java
  54. +13 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
  55. +2 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java
  56. +2 −1 src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java
  57. +13 −3 src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java
  58. +1 −2 ...vadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java
  59. +27 −0 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java
  60. +6 −0 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkInfoImpl.java
  61. +1 −0 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java
  62. +2 −1 ...jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties
  63. +12 −1 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java
  64. +4 −1 src/jdk.jdeps/share/classes/com/sun/tools/classfile/Attribute.java
  65. +11 −1 src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassWriter.java
  66. +65 −0 src/jdk.jdeps/share/classes/com/sun/tools/classfile/PermittedSubclasses_attribute.java
  67. +18 −6 src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java
  68. +95 −0 test/hotspot/jtreg/runtime/modules/SealedModuleTest.java
  69. +23 −0 test/hotspot/jtreg/runtime/modules/TEST.properties
  70. +30 −0 test/hotspot/jtreg/runtime/modules/sealedP1/C1.java
  71. +105 −0 test/hotspot/jtreg/runtime/modules/sealedP1/SuperClass.jcod
  72. +29 −0 test/hotspot/jtreg/runtime/modules/sealedP2/C2.java
  73. +29 −0 test/hotspot/jtreg/runtime/modules/sealedP3/C3.java
  74. +45 −0 test/hotspot/jtreg/runtime/sealedClasses/AbstractSealedTest.java
  75. +560 −0 test/hotspot/jtreg/runtime/sealedClasses/GetPermittedSubclasses.jcod
  76. +138 −0 test/hotspot/jtreg/runtime/sealedClasses/GetPermittedSubclassesTest.java
  77. +73 −0 test/hotspot/jtreg/runtime/sealedClasses/OverrideSealedTest.java
  78. +95 −0 test/hotspot/jtreg/runtime/sealedClasses/Pkg/NotPermitted.jcod
  79. +26 −0 test/hotspot/jtreg/runtime/sealedClasses/Pkg/Permitted.java
  80. +72 −0 test/hotspot/jtreg/runtime/sealedClasses/Pkg/SealedInterface.jcod
  81. +112 −0 test/hotspot/jtreg/runtime/sealedClasses/RedefineSealedClass.java
  82. +49 −0 test/hotspot/jtreg/runtime/sealedClasses/SealedTest.java
  83. +59 −0 test/hotspot/jtreg/runtime/sealedClasses/SealedUnnamedModuleIntfTest.java
  84. +65 −0 test/hotspot/jtreg/runtime/sealedClasses/SealedUnnamedModuleTest.java
  85. +23 −0 test/hotspot/jtreg/runtime/sealedClasses/TEST.properties
  86. +27 −0 test/hotspot/jtreg/runtime/sealedClasses/asteroids/Pluto.java
  87. +26 −0 test/hotspot/jtreg/runtime/sealedClasses/otherPkg/WrongPackage.java
  88. +92 −0 test/hotspot/jtreg/runtime/sealedClasses/planets/Mars.jcod
  89. +26 −0 test/hotspot/jtreg/runtime/sealedClasses/planets/Neptune.java
  90. +98 −0 test/hotspot/jtreg/runtime/sealedClasses/planets/OuterPlanets.jcod
  91. +24 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/ClassFour.java
  92. +24 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/ClassOne.java
  93. +24 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/ClassThree.java
  94. +24 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/ClassTwo.java
  95. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/Host/Host.java
  96. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/Host/redef/Host.java
  97. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostA/Host.java
  98. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostA/redef/Host.java
  99. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostAB/Host.java
  100. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostAB/redef/Host.java
  101. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostABC/Host.java
  102. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostABC/redef/Host.java
  103. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostABCD/redef/Host.java
  104. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostABD/redef/Host.java
  105. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostAC/redef/Host.java
  106. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostACB/redef/Host.java
  107. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostB/redef/Host.java
  108. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostBA/redef/Host.java
  109. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostBAC/redef/Host.java
  110. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostBCA/redef/Host.java
  111. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostCAB/redef/Host.java
  112. +29 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/HostCBA/redef/Host.java
  113. +273 −0 test/jdk/java/lang/instrument/RedefinePermittedSubclassesAttr/TestPermittedSubclassesAttr.java
  114. +239 −0 test/jdk/java/lang/reflect/sealed_classes/SealedClassesReflectionTest.java
  115. +322 −0 test/langtools/jdk/javadoc/doclet/testSealedTypes/TestSealedTypes.java
  116. +6 −1 test/langtools/lib/annotations/annotations/classfile/ClassfileInspector.java
  117. +2 −1 test/langtools/tools/javac/MethodParameters/AttributeVisitor.java
  118. +40 −0 test/langtools/tools/javac/diags/examples/CantInheritFromSealed.java
  119. +32 −0 test/langtools/tools/javac/diags/examples/CantInheritFromSealed2.java
  120. +32 −0 test/langtools/tools/javac/diags/examples/DuplicateTypeInPermits.java
  121. +34 −0 test/langtools/tools/javac/diags/examples/LocalCantInheritFromSealed.java
  122. +31 −0 test/langtools/tools/javac/diags/examples/NonSealedWithNoSealedSuper.java
  123. +30 −0 test/langtools/tools/javac/diags/examples/PermitsCantListDeclaringClass.java
  124. +32 −0 test/langtools/tools/javac/diags/examples/PermitsCantListSuperType.java
  125. +32 −0 test/langtools/tools/javac/diags/examples/PermitsInNoSealedClass.java
  126. +29 −0 test/langtools/tools/javac/diags/examples/SealedMustHaveSubtypes.java
  127. +33 −0 test/langtools/tools/javac/diags/examples/SealedNotAllowedInLocalClass.java
  128. +30 −0 test/langtools/tools/javac/diags/examples/SealedTypes.java
  129. +32 −0 test/langtools/tools/javac/diags/examples/SubtypeDoesntExtendSealed.java
  130. +32 −0 test/langtools/tools/javac/diags/examples/TypeVarInPermits.java
  131. +1 −0 test/langtools/tools/javac/enum/FauxEnum3.java
  132. +2 −2 test/langtools/tools/javac/enum/FauxEnum3.out
  133. +2 −0 test/langtools/tools/javac/enum/FauxEnum3.preview.out
  134. +20 −0 test/langtools/tools/javac/parser/JavacParserTest.java
  135. +3 −3 test/langtools/tools/javac/processing/model/TestSourceVersion.java
  136. +203 −0 test/langtools/tools/javac/processing/model/element/TestSealed.java
  137. +120 −0 test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java
  138. +753 −0 test/langtools/tools/javac/sealed/SealedCompilationTests.java
  139. +680 −0 test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java
@@ -650,6 +650,7 @@ INTERIM_LANGTOOLS_ADD_EXPORTS := \
--add-exports java.base/sun.reflect.annotation=jdk.compiler.interim \
--add-exports java.base/jdk.internal.jmod=jdk.compiler.interim \
--add-exports java.base/jdk.internal.misc=jdk.compiler.interim \
--add-exports java.base/sun.invoke.util=jdk.compiler.interim \
#
INTERIM_LANGTOOLS_MODULES_COMMA := $(strip $(subst $(SPACE),$(COMMA),$(strip \
$(INTERIM_LANGTOOLS_MODULES))))
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, 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
@@ -3160,8 +3160,8 @@ JDWP "Java(tm) Debug Wire Protocol"
"canUnrestrictedlyRedefineClasses is false.")
(Constant CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED
=72 "The new class version has a different NestHost, "
"NestMembers, or Record class attribute and "
"canUnrestrictedlyRedefineClasses is false.")
"NestMembers, PermittedSubclasses, or Record class attribute "
"and canUnrestrictedlyRedefineClasses is false.")
(Constant NOT_IMPLEMENTED =99 "The functionality is not implemented in "
"this virtual machine.")
(Constant NULL_POINTER =100 "Invalid pointer.")
@@ -119,6 +119,7 @@ JVM_GetMethodTypeAnnotations
JVM_GetNanoTimeAdjustment
JVM_GetNestHost
JVM_GetNestMembers
JVM_GetPermittedSubclasses
JVM_GetPrimitiveArrayElement
JVM_GetProperties
JVM_GetProtectionDomain
@@ -3212,6 +3212,41 @@ u2 ClassFileParser::parse_classfile_nest_members_attribute(const ClassFileStream
return length;
}

u2 ClassFileParser::parse_classfile_permitted_subclasses_attribute(const ClassFileStream* const cfs,
const u1* const permitted_subclasses_attribute_start,
TRAPS) {
const u1* const current_mark = cfs->current();
u2 length = 0;
if (permitted_subclasses_attribute_start != NULL) {
cfs->set_current(permitted_subclasses_attribute_start);
cfs->guarantee_more(2, CHECK_0); // length
length = cfs->get_u2_fast();
}
if (length < 1) {
classfile_parse_error("PermittedSubclasses attribute is empty in class file %s", CHECK_0);
}
const int size = length;
Array<u2>* const permitted_subclasses = MetadataFactory::new_array<u2>(_loader_data, size, CHECK_0);
_permitted_subclasses = permitted_subclasses;

int index = 0;
cfs->guarantee_more(2 * length, CHECK_0);
for (int n = 0; n < length; n++) {
const u2 class_info_index = cfs->get_u2_fast();
check_property(
valid_klass_reference_at(class_info_index),
"Permitted subclass class_info_index %u has bad constant type in class file %s",
class_info_index, CHECK_0);
permitted_subclasses->at_put(index++, class_info_index);
}
assert(index == size, "wrong size");

// Restore buffer's current position.
cfs->set_current(current_mark);

return length;
}

// Record {
// u2 attribute_name_index;
// u4 attribute_length;
@@ -3476,10 +3511,16 @@ void ClassFileParser::parse_classfile_bootstrap_methods_attribute(const ClassFil
CHECK);
}

bool ClassFileParser::supports_sealed_types() {
return _major_version == JVM_CLASSFILE_MAJOR_VERSION &&
_minor_version == JAVA_PREVIEW_MINOR_VERSION &&
Arguments::enable_preview();
}

bool ClassFileParser::supports_records() {
return _major_version == JVM_CLASSFILE_MAJOR_VERSION &&
_minor_version == JAVA_PREVIEW_MINOR_VERSION &&
Arguments::enable_preview();
_minor_version == JAVA_PREVIEW_MINOR_VERSION &&
Arguments::enable_preview();
}

void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cfs,
@@ -3494,11 +3535,14 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
_inner_classes = Universe::the_empty_short_array();
// Set nest members attribute to default sentinel
_nest_members = Universe::the_empty_short_array();
// Set _permitted_subclasses attribute to default sentinel
_permitted_subclasses = Universe::the_empty_short_array();
cfs->guarantee_more(2, CHECK); // attributes_count
u2 attributes_count = cfs->get_u2_fast();
bool parsed_sourcefile_attribute = false;
bool parsed_innerclasses_attribute = false;
bool parsed_nest_members_attribute = false;
bool parsed_permitted_subclasses_attribute = false;
bool parsed_nest_host_attribute = false;
bool parsed_record_attribute = false;
bool parsed_enclosingmethod_attribute = false;
@@ -3522,6 +3566,8 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
u4 nest_members_attribute_length = 0;
const u1* record_attribute_start = NULL;
u4 record_attribute_length = 0;
const u1* permitted_subclasses_attribute_start = NULL;
u4 permitted_subclasses_attribute_length = 0;

// Iterate over attributes
while (attributes_count--) {
@@ -3738,6 +3784,26 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
}
}
cfs->skip_u1(attribute_length, CHECK);
} else if (_major_version >= JAVA_15_VERSION) {
// Check for PermittedSubclasses tag
if (tag == vmSymbols::tag_permitted_subclasses()) {
if (supports_sealed_types()) {
if (parsed_permitted_subclasses_attribute) {
classfile_parse_error("Multiple PermittedSubclasses attributes in class file %s", CHECK);
}
// Classes marked ACC_FINAL cannot have a PermittedSubclasses attribute.
if (_access_flags.is_final()) {
classfile_parse_error("PermittedSubclasses attribute in final class file %s", CHECK);
}
parsed_permitted_subclasses_attribute = true;
permitted_subclasses_attribute_start = cfs->current();
permitted_subclasses_attribute_length = attribute_length;
}
cfs->skip_u1(attribute_length, CHECK);
} else {
// Unknown attribute
cfs->skip_u1(attribute_length, CHECK);
}
} else {
// Unknown attribute
cfs->skip_u1(attribute_length, CHECK);
@@ -3806,6 +3872,18 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
}
}

if (parsed_permitted_subclasses_attribute) {
const u2 num_subclasses = parse_classfile_permitted_subclasses_attribute(
cfs,
permitted_subclasses_attribute_start,
CHECK);
if (_need_verify) {
guarantee_property(
permitted_subclasses_attribute_length == sizeof(num_subclasses) + sizeof(u2) * num_subclasses,
"Wrong PermittedSubclasses attribute length in class file %s", CHECK);
}
}

if (_max_bootstrap_specifier_index >= 0) {
guarantee_property(parsed_bootstrap_methods_attribute,
"Missing BootstrapMethods attribute in class file %s", CHECK);
@@ -3873,6 +3951,7 @@ void ClassFileParser::apply_parsed_class_metadata(
this_klass->set_nest_host_index(_nest_host);
this_klass->set_local_interfaces(_local_interfaces);
this_klass->set_annotations(_combined_annotations);
this_klass->set_permitted_subclasses(_permitted_subclasses);
this_klass->set_record_components(_record_components);
// Delay the setting of _transitive_interfaces until after initialize_supers() in
// fill_instance_klass(). It is because the _transitive_interfaces may be shared with
@@ -4681,12 +4760,34 @@ static void check_super_class_access(const InstanceKlass* this_klass, TRAPS) {
const Klass* const super = this_klass->super();

if (super != NULL) {
const InstanceKlass* super_ik = InstanceKlass::cast(super);

if (super->is_final()) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_VerifyError(),
"class %s cannot inherit from final class %s",
this_klass->external_name(),
super_ik->external_name());
return;
}

if (super_ik->is_sealed() && !super_ik->has_as_permitted_subclass(this_klass)) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IncompatibleClassChangeError(),
"class %s cannot inherit from sealed class %s",
this_klass->external_name(),
super_ik->external_name());
return;
}

// If the loader is not the boot loader then throw an exception if its
// superclass is in package jdk.internal.reflect and its loader is not a
// special reflection class loader
if (!this_klass->class_loader_data()->is_the_null_class_loader_data()) {
assert(super->is_instance_klass(), "super is not instance klass");
PackageEntry* super_package = super->package();
if (super_package != NULL &&
super_package->name()->fast_compare(vmSymbols::jdk_internal_reflect()) == 0 &&
@@ -4742,6 +4843,19 @@ static void check_super_interface_access(const InstanceKlass* this_klass, TRAPS)
for (int i = lng - 1; i >= 0; i--) {
InstanceKlass* const k = local_interfaces->at(i);
assert (k != NULL && k->is_interface(), "invalid interface");

if (k->is_sealed() && !k->has_as_permitted_subclass(this_klass)) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IncompatibleClassChangeError(),
"class %s cannot %s sealed interface %s",
this_klass->external_name(),
this_klass->is_interface() ? "extend" : "implement",
k->external_name());
return;
}

Reflection::VerifyClassAccessResults vca_result =
Reflection::verify_class_access(this_klass, k, false);
if (vca_result != Reflection::ACCESS_OK) {
@@ -5677,6 +5791,7 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik,
assert(NULL == _local_interfaces, "invariant");
assert(NULL == _combined_annotations, "invariant");
assert(NULL == _record_components, "invariant");
assert(NULL == _permitted_subclasses, "invariant");

if (_has_final_method) {
ik->set_has_final_method();
@@ -5965,6 +6080,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
_inner_classes(NULL),
_nest_members(NULL),
_nest_host(0),
_permitted_subclasses(NULL),
_record_components(NULL),
_local_interfaces(NULL),
_transitive_interfaces(NULL),
@@ -6073,6 +6189,7 @@ void ClassFileParser::clear_class_metadata() {
_methods = NULL;
_inner_classes = NULL;
_nest_members = NULL;
_permitted_subclasses = NULL;
_local_interfaces = NULL;
_combined_annotations = NULL;
_class_annotations = _class_type_annotations = NULL;
@@ -6109,6 +6226,10 @@ ClassFileParser::~ClassFileParser() {
InstanceKlass::deallocate_record_components(_loader_data, _record_components);
}

if (_permitted_subclasses != NULL && _permitted_subclasses != Universe::the_empty_short_array()) {
MetadataFactory::free_array<u2>(_loader_data, _permitted_subclasses);
}

// Free interfaces
InstanceKlass::deallocate_interfaces(_loader_data, _super_klass,
_local_interfaces, _transitive_interfaces);
@@ -6507,10 +6628,6 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st
);
return;
}
// Make sure super class is not final
if (_super_klass->is_final()) {
THROW_MSG(vmSymbols::java_lang_VerifyError(), "Cannot inherit from final class");
}
}

// Compute the transitive list of all unique interfaces implemented by this class
@@ -132,6 +132,7 @@ class ClassFileParser {
Array<u2>* _inner_classes;
Array<u2>* _nest_members;
u2 _nest_host;
Array<u2>* _permitted_subclasses;
Array<RecordComponent*>* _record_components;
Array<InstanceKlass*>* _local_interfaces;
Array<InstanceKlass*>* _transitive_interfaces;
@@ -327,11 +328,16 @@ class ClassFileParser {
const u1* const nest_members_attribute_start,
TRAPS);

u2 parse_classfile_permitted_subclasses_attribute(const ClassFileStream* const cfs,
const u1* const permitted_subclasses_attribute_start,
TRAPS);

u2 parse_classfile_record_attribute(const ClassFileStream* const cfs,
const ConstantPool* cp,
const u1* const record_attribute_start,
TRAPS);

bool supports_sealed_types();
bool supports_records();

void parse_classfile_attributes(const ClassFileStream* const cfs,
@@ -173,6 +173,7 @@
template(tag_runtime_invisible_type_annotations, "RuntimeInvisibleTypeAnnotations") \
template(tag_enclosing_method, "EnclosingMethod") \
template(tag_bootstrap_methods, "BootstrapMethods") \
template(tag_permitted_subclasses, "PermittedSubclasses") \
\
/* exception klasses: at least all exceptions thrown by the VM have entries here */ \
template(java_lang_ArithmeticException, "java/lang/ArithmeticException") \
@@ -567,6 +567,11 @@ JVM_IsRecord(JNIEnv *env, jclass cls);
JNIEXPORT jobjectArray JNICALL
JVM_GetRecordComponents(JNIEnv *env, jclass ofClass);

/* Sealed types - since JDK 15 */

JNIEXPORT jobjectArray JNICALL
JVM_GetPermittedSubclasses(JNIEnv *env, jclass current);

/* The following two reflection routines are still needed due to startup time issues */
/*
* java.lang.reflect.Method
@@ -147,6 +147,7 @@
LOG_TAG(safepoint) \
LOG_TAG(sampling) \
LOG_TAG(scavenge) \
LOG_TAG(sealed) \
LOG_TAG(setting) \
LOG_TAG(smr) \
LOG_TAG(stacktrace) \

0 comments on commit d42bfef

Please sign in to comment.