34
34
import java .lang .reflect .Field ;
35
35
import java .lang .reflect .Modifier ;
36
36
import java .nio .ByteOrder ;
37
+ import java .util .Collections ;
38
+ import java .util .ArrayList ;
37
39
import java .util .HashMap ;
38
40
import java .util .List ;
39
41
@@ -100,7 +102,7 @@ static HotSpotResolvedObjectTypeImpl getJavaLangObject() {
100
102
101
103
/**
102
104
* Gets the JVMCI mirror from a HotSpot type.
103
- *
105
+ * <p>
104
106
* Called from the VM.
105
107
*
106
108
* @param klassPointer a native pointer to the Klass*
@@ -183,6 +185,67 @@ public ResolvedJavaType getComponentType() {
183
185
return this .equals (componentType ) ? null : componentType ;
184
186
}
185
187
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
+
186
249
@ Override
187
250
public AssumptionResult <ResolvedJavaType > findLeafConcreteSubtype () {
188
251
if (isLeaf ()) {
@@ -694,11 +757,11 @@ static class FieldInfo {
694
757
/**
695
758
* Creates a field info with the provided indices.
696
759
*
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)
702
765
* @param initializerIndex field's initial value index in the constant pool
703
766
*/
704
767
FieldInfo (int nameIndex , int signatureIndex , int offset , int classfileFlags , int internalFlags , int initializerIndex ) {
@@ -737,6 +800,7 @@ public int getOffset() {
737
800
/**
738
801
* Returns the name of this field as a {@link String}. If the field is an internal field the
739
802
* name index is pointing into the vmSymbols table.
803
+ *
740
804
* @param klass field's holder class
741
805
*/
742
806
public String getName (HotSpotResolvedObjectTypeImpl klass ) {
@@ -746,6 +810,7 @@ public String getName(HotSpotResolvedObjectTypeImpl klass) {
746
810
/**
747
811
* Returns the signature of this field as {@link String}. If the field is an internal field
748
812
* the signature index is pointing into the vmSymbols table.
813
+ *
749
814
* @param klass field's holder class
750
815
*/
751
816
public String getSignature (HotSpotResolvedObjectTypeImpl klass ) {
@@ -828,7 +893,7 @@ public ResolvedJavaField[] getStaticFields() {
828
893
* Gets the instance or static fields of this class.
829
894
*
830
895
* @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
832
897
*/
833
898
private HotSpotResolvedJavaField [] getFields (boolean retrieveStaticFields , HotSpotResolvedJavaField [] prepend ) {
834
899
HotSpotVMConfig config = config ();
@@ -954,7 +1019,7 @@ public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass
954
1019
955
1020
private boolean hasSameClassLoader (HotSpotResolvedObjectTypeImpl otherMirror ) {
956
1021
return UnsafeAccess .UNSAFE .getAddress (getKlassPointer () + config ().classLoaderDataOffset ) == UnsafeAccess .UNSAFE .getAddress (
957
- otherMirror .getKlassPointer () + config ().classLoaderDataOffset );
1022
+ otherMirror .getKlassPointer () + config ().classLoaderDataOffset );
958
1023
}
959
1024
960
1025
@ Override
0 commit comments