3434import java .lang .reflect .Field ;
3535import java .lang .reflect .Modifier ;
3636import java .nio .ByteOrder ;
37+ import java .util .Collections ;
38+ import java .util .ArrayList ;
3739import java .util .HashMap ;
3840import java .util .List ;
3941
@@ -100,7 +102,7 @@ static HotSpotResolvedObjectTypeImpl getJavaLangObject() {
100102
101103 /**
102104 * Gets the JVMCI mirror from a HotSpot type.
103- *
105+ * <p>
104106 * Called from the VM.
105107 *
106108 * @param klassPointer a native pointer to the Klass*
@@ -183,6 +185,67 @@ public ResolvedJavaType getComponentType() {
183185 return this .equals (componentType ) ? null : componentType ;
184186 }
185187
188+ @ Override
189+ public List <JavaType > getPermittedSubclasses () {
190+ if (isArray () || isPrimitive ()) {
191+ return null ;
192+ }
193+ HotSpotVMConfig config = config ();
194+ final long metaspacePermittedSubclasses = UNSAFE .getAddress (getKlassPointer () + config .instanceKlassPermittedSubclassesOffset );
195+ if (metaspacePermittedSubclasses == 0 ) {
196+ return null ;
197+ }
198+ final int length = UNSAFE .getInt (metaspacePermittedSubclasses + config .arrayJUShortLengthOffset );
199+ if (length == 0 ) {
200+ return null ;
201+ }
202+ // is_sealed
203+ ArrayList <JavaType > permittedSubclasses = new ArrayList <>(length );
204+ for (long i = 0 ; i < length ; i ++) {
205+ int cpIndex = UNSAFE .getShort (metaspacePermittedSubclasses + config .arrayJUShortDataOffset + compilerToVM ().ARRAY_SHORT_INDEX_SCALE * i );
206+ Object cpEntry = getConstantPool ().lookupConstant (cpIndex );
207+ if (cpEntry instanceof ResolvedJavaType rjt ) {
208+ if (isDirectSubType (rjt )) {
209+ // only adding direct subtypes
210+ permittedSubclasses .add (rjt );
211+ }
212+ } else if (cpEntry instanceof UnresolvedJavaType ujr ) {
213+ // Unresolved - cannot tell if it is a direct or indirect subtype
214+ permittedSubclasses .add (ujr );
215+ } else {
216+ throw new InternalError ("Unexpected ConstantPool entry: " + cpEntry );
217+ }
218+ }
219+ return Collections .unmodifiableList (permittedSubclasses );
220+ }
221+
222+ @ Override
223+ public boolean isSealed () {
224+ if (isArray ()) {
225+ return false ;
226+ }
227+ HotSpotVMConfig config = config ();
228+ final long metaspacePermittedSubclasses = UNSAFE .getAddress (getKlassPointer () + config .instanceKlassPermittedSubclassesOffset );
229+ if (metaspacePermittedSubclasses == 0 ) {
230+ return false ;
231+ }
232+ final int length = UNSAFE .getInt (metaspacePermittedSubclasses + config .arrayJUShortLengthOffset );
233+ return length != 0 ;
234+ }
235+
236+ private boolean isDirectSubType (ResolvedJavaType c ) {
237+ if (isInterface ()) {
238+ for (ResolvedJavaType i : c .getInterfaces ()) {
239+ if (i == this ) {
240+ return true ;
241+ }
242+ }
243+ } else {
244+ return c .getSuperclass () == this ;
245+ }
246+ return false ;
247+ }
248+
186249 @ Override
187250 public AssumptionResult <ResolvedJavaType > findLeafConcreteSubtype () {
188251 if (isLeaf ()) {
@@ -694,11 +757,11 @@ static class FieldInfo {
694757 /**
695758 * Creates a field info with the provided indices.
696759 *
697- * @param nameIndex index of field's name in the constant pool
698- * @param signatureIndex index of field's signature in the constant pool
699- * @param offset field's offset
700- * @param classfileFlags field's access flags (from the class file)
701- * @param internalFlags field's internal flags (from the VM)
760+ * @param nameIndex index of field's name in the constant pool
761+ * @param signatureIndex index of field's signature in the constant pool
762+ * @param offset field's offset
763+ * @param classfileFlags field's access flags (from the class file)
764+ * @param internalFlags field's internal flags (from the VM)
702765 * @param initializerIndex field's initial value index in the constant pool
703766 */
704767 FieldInfo (int nameIndex , int signatureIndex , int offset , int classfileFlags , int internalFlags , int initializerIndex ) {
@@ -737,6 +800,7 @@ public int getOffset() {
737800 /**
738801 * Returns the name of this field as a {@link String}. If the field is an internal field the
739802 * name index is pointing into the vmSymbols table.
803+ *
740804 * @param klass field's holder class
741805 */
742806 public String getName (HotSpotResolvedObjectTypeImpl klass ) {
@@ -746,6 +810,7 @@ public String getName(HotSpotResolvedObjectTypeImpl klass) {
746810 /**
747811 * Returns the signature of this field as {@link String}. If the field is an internal field
748812 * the signature index is pointing into the vmSymbols table.
813+ *
749814 * @param klass field's holder class
750815 */
751816 public String getSignature (HotSpotResolvedObjectTypeImpl klass ) {
@@ -828,7 +893,7 @@ public ResolvedJavaField[] getStaticFields() {
828893 * Gets the instance or static fields of this class.
829894 *
830895 * @param retrieveStaticFields specifies whether to return instance or static fields
831- * @param prepend an array to be prepended to the returned result
896+ * @param prepend an array to be prepended to the returned result
832897 */
833898 private HotSpotResolvedJavaField [] getFields (boolean retrieveStaticFields , HotSpotResolvedJavaField [] prepend ) {
834899 HotSpotVMConfig config = config ();
@@ -954,7 +1019,7 @@ public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass
9541019
9551020 private boolean hasSameClassLoader (HotSpotResolvedObjectTypeImpl otherMirror ) {
9561021 return UnsafeAccess .UNSAFE .getAddress (getKlassPointer () + config ().classLoaderDataOffset ) == UnsafeAccess .UNSAFE .getAddress (
957- otherMirror .getKlassPointer () + config ().classLoaderDataOffset );
1022+ otherMirror .getKlassPointer () + config ().classLoaderDataOffset );
9581023 }
9591024
9601025 @ Override
0 commit comments