hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java
changeset 46459 7d4e637d3f21
parent 46344 694c102fd8ed
child 46551 d01034a83ab2
equal deleted inserted replaced
46458:3c12af929e7d 46459:7d4e637d3f21
    27 import java.lang.annotation.ElementType;
    27 import java.lang.annotation.ElementType;
    28 import java.lang.annotation.Retention;
    28 import java.lang.annotation.Retention;
    29 import java.lang.annotation.RetentionPolicy;
    29 import java.lang.annotation.RetentionPolicy;
    30 import java.lang.annotation.Target;
    30 import java.lang.annotation.Target;
    31 
    31 
    32 import org.graalvm.compiler.core.common.LocationIdentity;
    32 import org.graalvm.api.word.ComparableWord;
       
    33 import org.graalvm.api.word.LocationIdentity;
       
    34 import org.graalvm.api.word.Pointer;
       
    35 import org.graalvm.api.word.Signed;
       
    36 import org.graalvm.api.word.Unsigned;
       
    37 import org.graalvm.api.word.WordBase;
       
    38 import org.graalvm.api.word.WordFactory;
    33 import org.graalvm.compiler.core.common.calc.Condition;
    39 import org.graalvm.compiler.core.common.calc.Condition;
    34 import org.graalvm.compiler.core.common.calc.UnsignedMath;
    40 import org.graalvm.compiler.core.common.calc.UnsignedMath;
    35 import org.graalvm.compiler.debug.GraalError;
    41 import org.graalvm.compiler.debug.GraalError;
    36 import org.graalvm.compiler.nodes.ValueNode;
    42 import org.graalvm.compiler.nodes.ValueNode;
    37 import org.graalvm.compiler.nodes.calc.AddNode;
    43 import org.graalvm.compiler.nodes.calc.AddNode;
    48 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
    54 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
    49 import org.graalvm.compiler.nodes.calc.XorNode;
    55 import org.graalvm.compiler.nodes.calc.XorNode;
    50 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
    56 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
    51 import org.graalvm.compiler.nodes.memory.address.AddressNode.Address;
    57 import org.graalvm.compiler.nodes.memory.address.AddressNode.Address;
    52 
    58 
    53 public abstract class Word implements Signed, Unsigned, Pointer {
    59 public abstract class Word extends WordFactory implements Signed, Unsigned, Pointer {
    54 
    60 
    55     /**
    61     /**
    56      * Links a method to a canonical operation represented by an {@link Opcode} val.
    62      * Links a method to a canonical operation represented by an {@link Opcode} val.
    57      */
    63      */
    58     @Retention(RetentionPolicy.RUNTIME)
    64     @Retention(RetentionPolicy.RUNTIME)
    69     }
    75     }
    70 
    76 
    71     /**
    77     /**
    72      * The canonical {@link Operation} represented by a method in the {@link Word} class.
    78      * The canonical {@link Operation} represented by a method in the {@link Word} class.
    73      */
    79      */
    74     // @formatter:off
    80     public enum Opcode {
    75      public enum Opcode {
    81         NODE_CLASS,
    76          NODE_CLASS,
    82         COMPARISON,
    77          COMPARISON,
    83         NOT,
    78          NOT,
    84         READ_POINTER,
    79          READ_POINTER,
    85         READ_OBJECT,
    80          READ_OBJECT,
    86         READ_BARRIERED,
    81          READ_BARRIERED,
    87         READ_HEAP,
    82          READ_HEAP,
    88         WRITE_POINTER,
    83          WRITE_POINTER,
    89         WRITE_OBJECT,
    84          WRITE_OBJECT,
    90         WRITE_BARRIERED,
    85          WRITE_BARRIERED,
    91         CAS_POINTER,
    86          CAS_POINTER,
    92         INITIALIZE,
    87          INITIALIZE,
    93         FROM_ADDRESS,
    88          ZERO,
    94         OBJECT_TO_TRACKED,
    89          FROM_UNSIGNED,
    95         OBJECT_TO_UNTRACKED,
    90          FROM_SIGNED,
    96         TO_OBJECT,
    91          FROM_ADDRESS,
    97         TO_OBJECT_NON_NULL,
    92          OBJECT_TO_TRACKED,
    98         TO_RAW_VALUE,
    93          OBJECT_TO_UNTRACKED,
    99     }
    94          TO_OBJECT,
   100 
    95          TO_OBJECT_NON_NULL,
   101     public static class BoxFactoryImpl implements BoxFactory {
    96          TO_RAW_VALUE,
   102         @SuppressWarnings("unchecked")
    97     }
   103         @Override
    98      // @formatter:on
   104         public <T extends WordBase> T box(long val) {
       
   105             return (T) HostedWord.boxLong(val);
       
   106         }
       
   107     }
    99 
   108 
   100     /*
   109     /*
   101      * Outside users should use the different signed() and unsigned() methods to ensure proper
   110      * Outside users must use the different signed() and unsigned() methods to ensure proper
   102      * expansion of 32-bit values on 64-bit systems.
   111      * expansion of 32-bit values on 64-bit systems.
   103      */
   112      */
   104     private static Word box(long val) {
   113     @SuppressWarnings("unchecked")
   105         return HostedWord.boxLong(val);
   114     private static <T extends WordBase> T box(long val) {
       
   115         return (T) HostedWord.boxLong(val);
   106     }
   116     }
   107 
   117 
   108     protected abstract long unbox();
   118     protected abstract long unbox();
   109 
   119 
   110     private static Word intParam(int val) {
   120     private static Word intParam(int val) {
   111         return box(val);
       
   112     }
       
   113 
       
   114     /**
       
   115      * The constant 0, i.e., the word with no bits set. There is no difference between a signed and
       
   116      * unsigned zero.
       
   117      *
       
   118      * @return the constant 0.
       
   119      */
       
   120     @Operation(opcode = Opcode.ZERO)
       
   121     public static Word zero() {
       
   122         return box(0L);
       
   123     }
       
   124 
       
   125     /**
       
   126      * Unsafe conversion from a Java long value to a Word. The parameter is treated as an unsigned
       
   127      * 64-bit value (in contrast to the semantics of a Java long).
       
   128      *
       
   129      * @param val a 64 bit unsigned value
       
   130      * @return the value cast to Word
       
   131      */
       
   132     @Operation(opcode = Opcode.FROM_UNSIGNED)
       
   133     public static Word unsigned(long val) {
       
   134         return box(val);
       
   135     }
       
   136 
       
   137     /**
       
   138      * Unsafe conversion from a Java long value to a {@link PointerBase pointer}. The parameter is
       
   139      * treated as an unsigned 64-bit value (in contrast to the semantics of a Java long).
       
   140      *
       
   141      * @param val a 64 bit unsigned value
       
   142      * @return the value cast to PointerBase
       
   143      */
       
   144     @Operation(opcode = Opcode.FROM_UNSIGNED)
       
   145     @SuppressWarnings("unchecked")
       
   146     public static <T extends PointerBase> T pointer(long val) {
       
   147         return (T) box(val);
       
   148     }
       
   149 
       
   150     /**
       
   151      * Unsafe conversion from a Java int value to a Word. The parameter is treated as an unsigned
       
   152      * 32-bit value (in contrast to the semantics of a Java int).
       
   153      *
       
   154      * @param val a 32 bit unsigned value
       
   155      * @return the value cast to Word
       
   156      */
       
   157     @Operation(opcode = Opcode.FROM_UNSIGNED)
       
   158     public static Word unsigned(int val) {
       
   159         return box(val & 0xffffffffL);
       
   160     }
       
   161 
       
   162     /**
       
   163      * Unsafe conversion from a Java long value to a Word. The parameter is treated as a signed
       
   164      * 64-bit value (unchanged semantics of a Java long).
       
   165      *
       
   166      * @param val a 64 bit signed value
       
   167      * @return the value cast to Word
       
   168      */
       
   169     @Operation(opcode = Opcode.FROM_SIGNED)
       
   170     public static Word signed(long val) {
       
   171         return box(val);
       
   172     }
       
   173 
       
   174     /**
       
   175      * Unsafe conversion from a Java int value to a Word. The parameter is treated as a signed
       
   176      * 32-bit value (unchanged semantics of a Java int).
       
   177      *
       
   178      * @param val a 32 bit signed value
       
   179      * @return the value cast to Word
       
   180      */
       
   181     @Operation(opcode = Opcode.FROM_SIGNED)
       
   182     public static Word signed(int val) {
       
   183         return box(val);
   121         return box(val);
   184     }
   122     }
   185 
   123 
   186     @Override
   124     @Override
   187     @Operation(opcode = Opcode.TO_RAW_VALUE)
   125     @Operation(opcode = Opcode.TO_RAW_VALUE)
   194      * returned pointer or any value derived from it is alive across a safepoint, it will be
   132      * returned pointer or any value derived from it is alive across a safepoint, it will be
   195      * tracked. Depending on the arithmetic on the pointer and the capabilities of the backend to
   133      * tracked. Depending on the arithmetic on the pointer and the capabilities of the backend to
   196      * deal with derived references, this may work correctly, or result in a compiler error.
   134      * deal with derived references, this may work correctly, or result in a compiler error.
   197      */
   135      */
   198     @Operation(opcode = Opcode.OBJECT_TO_TRACKED)
   136     @Operation(opcode = Opcode.OBJECT_TO_TRACKED)
   199     public static native Pointer objectToTrackedPointer(Object val);
   137     public static native Word objectToTrackedPointer(Object val);
   200 
   138 
   201     /**
   139     /**
   202      * Convert an {@link Object} to a {@link Pointer}, dropping the reference information. If the
   140      * Convert an {@link Object} to a {@link Pointer}, dropping the reference information. If the
   203      * returned pointer or any value derived from it is alive across a safepoint, it will be treated
   141      * returned pointer or any value derived from it is alive across a safepoint, it will be treated
   204      * as a simple integer and not tracked by the garbage collector.
   142      * as a simple integer and not tracked by the garbage collector.
   209      * <p>
   147      * <p>
   210      * If the result value should not be alive across a safepoint, it's better to use
   148      * If the result value should not be alive across a safepoint, it's better to use
   211      * {@link #objectToTrackedPointer(Object)} instead.
   149      * {@link #objectToTrackedPointer(Object)} instead.
   212      */
   150      */
   213     @Operation(opcode = Opcode.OBJECT_TO_UNTRACKED)
   151     @Operation(opcode = Opcode.OBJECT_TO_UNTRACKED)
   214     public static native Pointer objectToUntrackedPointer(Object val);
   152     public static native Word objectToUntrackedPointer(Object val);
   215 
   153 
   216     @Operation(opcode = Opcode.FROM_ADDRESS)
   154     @Operation(opcode = Opcode.FROM_ADDRESS)
   217     public static native Pointer fromAddress(Address address);
   155     public static native Word fromAddress(Address address);
   218 
   156 
   219     @Override
   157     @Override
   220     @Operation(opcode = Opcode.TO_OBJECT)
   158     @Operation(opcode = Opcode.TO_OBJECT)
   221     public native Object toObject();
   159     public native Object toObject();
   222 
   160 
   723         return UNSAFE.getDouble(add((Word) offset).unbox());
   661         return UNSAFE.getDouble(add((Word) offset).unbox());
   724     }
   662     }
   725 
   663 
   726     @Override
   664     @Override
   727     @Operation(opcode = Opcode.READ_POINTER)
   665     @Operation(opcode = Opcode.READ_POINTER)
   728     public Word readWord(WordBase offset, LocationIdentity locationIdentity) {
   666     public <T extends WordBase> T readWord(WordBase offset, LocationIdentity locationIdentity) {
   729         return box(UNSAFE.getAddress(add((Word) offset).unbox()));
   667         return box(UNSAFE.getAddress(add((Word) offset).unbox()));
   730     }
   668     }
   731 
   669 
   732     @Override
   670     @Override
   733     @Operation(opcode = Opcode.READ_POINTER)
   671     @Operation(opcode = Opcode.READ_POINTER)
   775         return readDouble(signed(offset), locationIdentity);
   713         return readDouble(signed(offset), locationIdentity);
   776     }
   714     }
   777 
   715 
   778     @Override
   716     @Override
   779     @Operation(opcode = Opcode.READ_POINTER)
   717     @Operation(opcode = Opcode.READ_POINTER)
   780     public Word readWord(int offset, LocationIdentity locationIdentity) {
   718     public <T extends WordBase> T readWord(int offset, LocationIdentity locationIdentity) {
   781         return readWord(signed(offset), locationIdentity);
   719         return readWord(signed(offset), locationIdentity);
   782     }
   720     }
   783 
   721 
   784     @Override
   722     @Override
   785     @Operation(opcode = Opcode.READ_POINTER)
   723     @Operation(opcode = Opcode.READ_POINTER)
   947         return UNSAFE.getDouble(add((Word) offset).unbox());
   885         return UNSAFE.getDouble(add((Word) offset).unbox());
   948     }
   886     }
   949 
   887 
   950     @Override
   888     @Override
   951     @Operation(opcode = Opcode.READ_POINTER)
   889     @Operation(opcode = Opcode.READ_POINTER)
   952     public Word readWord(WordBase offset) {
   890     public <T extends WordBase> T readWord(WordBase offset) {
   953         return box(UNSAFE.getAddress(add((Word) offset).unbox()));
   891         return box(UNSAFE.getAddress(add((Word) offset).unbox()));
   954     }
   892     }
   955 
   893 
   956     @Override
   894     @Override
   957     @Operation(opcode = Opcode.READ_POINTER)
   895     @Operation(opcode = Opcode.READ_POINTER)
   958     public native Object readObject(WordBase offset);
   896     public native Object readObject(WordBase offset);
   959 
   897 
   960     @Override
       
   961     @Operation(opcode = Opcode.READ_HEAP)
   898     @Operation(opcode = Opcode.READ_HEAP)
   962     public native Object readObject(WordBase offset, BarrierType barrierType);
   899     public native Object readObject(WordBase offset, BarrierType barrierType);
   963 
   900 
   964     @Override
   901     @Override
   965     @Operation(opcode = Opcode.READ_POINTER)
   902     @Operation(opcode = Opcode.READ_POINTER)
  1003         return readDouble(signed(offset));
   940         return readDouble(signed(offset));
  1004     }
   941     }
  1005 
   942 
  1006     @Override
   943     @Override
  1007     @Operation(opcode = Opcode.READ_POINTER)
   944     @Operation(opcode = Opcode.READ_POINTER)
  1008     public Word readWord(int offset) {
   945     public <T extends WordBase> T readWord(int offset) {
  1009         return readWord(signed(offset));
   946         return readWord(signed(offset));
  1010     }
   947     }
  1011 
   948 
  1012     @Override
   949     @Override
  1013     @Operation(opcode = Opcode.READ_POINTER)
   950     @Operation(opcode = Opcode.READ_POINTER)
  1014     public Object readObject(int offset) {
   951     public Object readObject(int offset) {
  1015         return readObject(signed(offset));
   952         return readObject(signed(offset));
  1016     }
   953     }
  1017 
   954 
  1018     @Override
       
  1019     @Operation(opcode = Opcode.READ_HEAP)
   955     @Operation(opcode = Opcode.READ_HEAP)
  1020     public Object readObject(int offset, BarrierType barrierType) {
   956     public Object readObject(int offset, BarrierType barrierType) {
  1021         return readObject(signed(offset), barrierType);
   957         return readObject(signed(offset), barrierType);
  1022     }
   958     }
  1023 
   959 
  1071     @Operation(opcode = Opcode.CAS_POINTER)
  1007     @Operation(opcode = Opcode.CAS_POINTER)
  1072     public native long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
  1008     public native long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
  1073 
  1009 
  1074     @Override
  1010     @Override
  1075     @Operation(opcode = Opcode.CAS_POINTER)
  1011     @Operation(opcode = Opcode.CAS_POINTER)
  1076     public native Word compareAndSwapWord(WordBase offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
  1012     public native <T extends WordBase> T compareAndSwapWord(WordBase offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
  1077 
  1013 
  1078     @Override
  1014     @Override
  1079     @Operation(opcode = Opcode.CAS_POINTER)
  1015     @Operation(opcode = Opcode.CAS_POINTER)
  1080     public native Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
  1016     public native Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
  1081 
  1017 
  1177         return compareAndSwapLong(signed(offset), expectedValue, newValue, locationIdentity);
  1113         return compareAndSwapLong(signed(offset), expectedValue, newValue, locationIdentity);
  1178     }
  1114     }
  1179 
  1115 
  1180     @Override
  1116     @Override
  1181     @Operation(opcode = Opcode.CAS_POINTER)
  1117     @Operation(opcode = Opcode.CAS_POINTER)
  1182     public Word compareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity) {
  1118     public <T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity) {
  1183         return compareAndSwapWord(signed(offset), expectedValue, newValue, locationIdentity);
  1119         return compareAndSwapWord(signed(offset), expectedValue, newValue, locationIdentity);
  1184     }
  1120     }
  1185 
  1121 
  1186     @Override
  1122     @Override
  1187     @Operation(opcode = Opcode.CAS_POINTER)
  1123     @Operation(opcode = Opcode.CAS_POINTER)
  1211     @Operation(opcode = Opcode.CAS_POINTER)
  1147     @Operation(opcode = Opcode.CAS_POINTER)
  1212     public boolean logicCompareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity) {
  1148     public boolean logicCompareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity) {
  1213         return logicCompareAndSwapObject(signed(offset), expectedValue, newValue, locationIdentity);
  1149         return logicCompareAndSwapObject(signed(offset), expectedValue, newValue, locationIdentity);
  1214     }
  1150     }
  1215 
  1151 
       
  1152     /**
       
  1153      * This is deprecated because of the easy to mistype name collision between {@link #equals} and
       
  1154      * the other equals routines like {@link #equal(Word)}. In general you should never be
       
  1155      * statically calling this method for Word types.
       
  1156      */
       
  1157     @SuppressWarnings("deprecation")
       
  1158     @Deprecated
  1216     @Override
  1159     @Override
  1217     public final boolean equals(Object obj) {
  1160     public final boolean equals(Object obj) {
  1218         throw GraalError.shouldNotReachHere("equals must not be called on words");
  1161         throw GraalError.shouldNotReachHere("equals must not be called on words");
  1219     }
  1162     }
  1220 
  1163