< prev index next >

src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template

Print this page
rev 52865 : [mq]: 8210031

@@ -25,11 +25,13 @@
 package java.lang.invoke;
 
 import jdk.internal.util.Preconditions;
 import jdk.internal.vm.annotation.ForceInline;
 
+import java.lang.invoke.VarHandle.VarHandleDesc;
 import java.util.Objects;
+import java.util.Optional;
 
 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
 
 #warn
 

@@ -59,10 +61,34 @@
         @Override
         final MethodType accessModeTypeUncached(AccessMode accessMode) {
             return accessMode.at.accessModeType(receiverType, {#if[Object]?fieldType:$type$.class});
         }
 
+        @Override
+        final boolean internalEquals(VarHandle vh) {
+            FieldInstanceReadOnly that = (FieldInstanceReadOnly) vh;
+            return fieldOffset == that.fieldOffset;
+        }
+
+        @Override
+        final int internalHashCode() {
+            return Long.hashCode(fieldOffset);
+        }
+
+        @Override
+        public Optional<VarHandleDesc> describeConstable() {
+            var receiverTypeRef = receiverType.describeConstable();
+            var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable();
+            if (!receiverTypeRef.isPresent() || !fieldTypeRef.isPresent())
+                return Optional.empty();
+
+            // Reflect on this VarHandle to extract the field name
+            String name = VarHandles.getFieldFromReceiverAndOffset(
+                receiverType, fieldOffset, {#if[Object]?fieldType:$type$.class}).getName();
+            return Optional.of(VarHandleDesc.ofField(receiverTypeRef.get(), name, fieldTypeRef.get()));
+        }
+
         @ForceInline
         static $type$ get(FieldInstanceReadOnly handle, Object holder) {
             return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
                                  handle.fieldOffset);
         }

@@ -322,10 +348,36 @@
             this.fieldType = fieldType;
 #end[Object]
         }
 
         @Override
+        final boolean internalEquals(VarHandle vh) {
+            FieldStaticReadOnly that = (FieldStaticReadOnly) vh;
+            return base == that.base && fieldOffset == that.fieldOffset;
+        }
+
+        @Override
+        final int internalHashCode() {
+            return 31 * Long.hashCode(fieldOffset) + base.hashCode();
+        }
+
+        @Override
+        public Optional<VarHandleDesc> describeConstable() {
+            var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable();
+            if (!fieldTypeRef.isPresent())
+                return Optional.empty();
+
+            // Reflect on this VarHandle to extract the field name
+            var staticField = VarHandles.getStaticFieldFromBaseAndOffset(
+                base, fieldOffset, {#if[Object]?fieldType:$type$.class});
+            var receiverTypeRef = staticField.getDeclaringClass().describeConstable();
+            if (!receiverTypeRef.isPresent())
+                return Optional.empty();
+            return Optional.of(VarHandleDesc.ofStaticField(receiverTypeRef.get(), staticField.getName(), fieldTypeRef.get()));
+        }
+
+        @Override
         final MethodType accessModeTypeUncached(AccessMode accessMode) {
             return accessMode.at.accessModeType(null, {#if[Object]?fieldType:$type$.class});
         }
 
         @ForceInline

@@ -586,10 +638,33 @@
             this.componentType = arrayType.getComponentType();
 #end[Object]
         }
 
         @Override
+        final boolean internalEquals(VarHandle vh) {
+            // Equality of access mode types of AccessMode.GET is sufficient for
+            // equality checks
+            return true;
+        }
+
+        @Override
+        final int internalHashCode() {
+            // The hash code of the access mode types of AccessMode.GET is
+            // sufficient for hash code generation
+            return 0;
+        }
+
+        @Override
+        public Optional<VarHandleDesc> describeConstable() {
+            var arrayTypeRef = {#if[Object]?arrayType:$type$[].class}.describeConstable();
+            if (!arrayTypeRef.isPresent())
+                return Optional.empty();
+
+            return Optional.of(VarHandleDesc.ofArray(arrayTypeRef.get()));
+        }
+
+        @Override
         final MethodType accessModeTypeUncached(AccessMode accessMode) {
             return accessMode.at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
         }
 
 #if[Object]
< prev index next >