src/java.base/share/classes/sun/misc/Unsafe.java

Print this page




 908 
 909     /**
 910      * Ensures that loads and stores before the fence will not be reordered
 911      * with loads and stores after the fence.  Implies the effects of both
 912      * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
 913      * barrier.
 914      *
 915      * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
 916      * @since 1.8
 917      */
 918     public native void fullFence();
 919 
 920     /**
 921      * Throws IllegalAccessError; for use by the VM for access control
 922      * error support.
 923      * @since 1.8
 924      */
 925     private static void throwIllegalAccessError() {
 926         throw new IllegalAccessError();
 927     }

















































































































































































































































































































































 928 }


 908 
 909     /**
 910      * Ensures that loads and stores before the fence will not be reordered
 911      * with loads and stores after the fence.  Implies the effects of both
 912      * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
 913      * barrier.
 914      *
 915      * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
 916      * @since 1.8
 917      */
 918     public native void fullFence();
 919 
 920     /**
 921      * Throws IllegalAccessError; for use by the VM for access control
 922      * error support.
 923      * @since 1.8
 924      */
 925     private static void throwIllegalAccessError() {
 926         throw new IllegalAccessError();
 927     }
 928  
 929     /**
 930      * @return Returns true if the native byte ordering of this
 931      * machine is big-endian, false if it is little-endian.
 932      */
 933     public final boolean isBigEndian() { return BE; }
 934 
 935     /**
 936      * @return Returns true if this machine is capable of performing
 937      * accesses at addresses which are not aligned for the type of the
 938      * primitive type being accessed, false otherwise.
 939      */
 940     public final boolean unalignedAccess() { return unalignedAccess; }
 941 
 942     /**
 943      * Fetches a value at some byte offset into a given Java object.
 944      * More specifically, fetches a value within the given object
 945      * <code>o</code> at the given offset, or (if <code>o</code> is
 946      * null) from the memory address whose numerical value is the
 947      * given offset.  <p>
 948      * 
 949      * The specification of this method is the same as {@link
 950      * #getLong(Object, long)} except that the offset does not need to
 951      * have been obtained from {@link #objectFieldOffset} on the
 952      * {@link java.lang.reflect.Field} of some Java field.  The value
 953      * in memory is raw data, and need not correspond to any Java
 954      * variable.  Unless <code>o</code> is null, the value accessed
 955      * must be entirely within the allocated object.  The endianness
 956      * of the value in memory is the endianness of the native machine.
 957      *
 958      * <p> The read will be atomic with respect to the largest power
 959      * of two that divides the GCD of the offset and the storage size.
 960      * For example, getLongUnaligned will make atomic reads of 2-, 4-,
 961      * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
 962      * respectively.  There are no other guarantees of atomicity.
 963      *
 964      * @param o Java heap object in which the value resides, if any, else
 965      *        null
 966      * @param offset The offset in bytes from the start of the object
 967      * @return the value fetched from the indicated object
 968      * @throws RuntimeException No defined exceptions are thrown, not even
 969      *         {@link NullPointerException}
 970      * @since 1.9
 971      */   
 972     public final long getLongUnaligned(Object o, long offset) {
 973         if ((offset & 7) == 0) {
 974             return getLong(o, offset);
 975         } else if ((offset & 3) == 0) {
 976             return makeLong(getInt(o, offset),
 977                             getInt(o, offset + 4));
 978         } else if ((offset & 1) == 0) {
 979             return makeLong(getShort(o, offset),
 980                             getShort(o, offset + 2),
 981                             getShort(o, offset + 4),
 982                             getShort(o, offset + 6));
 983         } else {
 984             return makeLong(getByte(o, offset),
 985                             getByte(o, offset + 1),
 986                             getByte(o, offset + 2),
 987                             getByte(o, offset + 3),
 988                             getByte(o, offset + 4),
 989                             getByte(o, offset + 5),
 990                             getByte(o, offset + 6),
 991                             getByte(o, offset + 7));
 992         }
 993     }
 994     /**
 995      * As {@link #getLongUnaligned(Object, long)} but with an
 996      * additional argument which specifies the endianness of the value
 997      * as stored in memory.
 998      * 
 999      * @param o Java heap object in which the variable resides
1000      * @param offset The offset in bytes from the start of the object
1001      * @param bigEndian The endianness of the value
1002      * @return the value fetched from the indicated object
1003      * @since 1.9
1004      */
1005     public final long getLongUnaligned(Object o, long offset, boolean bigEndian) {
1006         return convEndian(bigEndian, getLongUnaligned(o, offset));
1007     }
1008         
1009     /** @see #getLongUnaligned(Object, long) */
1010     public final int getIntUnaligned(Object o, long offset) {
1011         if ((offset & 3) == 0) {
1012             return getInt(o, offset);
1013         } else if ((offset & 1) == 0) {
1014             return makeInt(getShort(o, offset),
1015                            getShort(o, offset + 2));
1016         } else {
1017             return makeInt(getByte(o, offset),
1018                            getByte(o, offset + 1),
1019                            getByte(o, offset + 2),
1020                            getByte(o, offset + 3));
1021         }
1022     }
1023     /** @see #getLongUnaligned(Object, long, boolean) */
1024     public final int getIntUnaligned(Object o, long offset, boolean bigEndian) {
1025         return convEndian(bigEndian, getIntUnaligned(o, offset));
1026     }
1027     
1028     /** @see #getLongUnaligned(Object, long) */
1029     public final short getShortUnaligned(Object o, long offset) {
1030         if ((offset & 1) == 0) {
1031             return getShort(o, offset);
1032         } else {
1033             return makeShort(getByte(o, offset),
1034                              getByte(o, offset + 1));
1035         }
1036     }
1037     /** @see #getLongUnaligned(Object, long, boolean) */
1038     public final short getShortUnaligned(Object o, long offset, boolean bigEndian) {
1039         return convEndian(bigEndian, getShortUnaligned(o, offset));
1040     }
1041 
1042     /** @see #getLongUnaligned(Object, long) */
1043     public final char getCharUnaligned(Object o, long offset) {
1044         return (char)getShortUnaligned(o, offset);
1045     }
1046     /** @see #getLongUnaligned(Object, long, boolean) */
1047     public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
1048         return convEndian(bigEndian, getCharUnaligned(o, offset));
1049     }
1050 
1051     /**
1052      * Stores a value at some byte offset into a given Java object.
1053      * <p>
1054      * The specification of this method is the same as {@link
1055      * #getLong(Object, long)} except that the offset does not need to
1056      * have been obtained from {@link #objectFieldOffset} on the
1057      * {@link java.lang.reflect.Field} of some Java field.  The value
1058      * in memory is raw data, and need not correspond to any Java
1059      * variable.  The endianness of the value in memory is the
1060      * endianness of the native machine.
1061      * <p>
1062      * The write will be atomic with respect to the largest power of
1063      * two that divides the GCD of the offset and the storage size.
1064      * For example, getLongUnaligned will make atomic reads of 2-, 4-,
1065      * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
1066      * respectively.  There are no other guarantees of atomicity.
1067      * <p>
1068      *
1069      * @param o Java heap object in which the value resides, if any, else
1070      *        null
1071      * @param offset The offset in bytes from the start of the object
1072      * @param x the value to store
1073      * @throws RuntimeException No defined exceptions are thrown, not even
1074      *         {@link NullPointerException}
1075      * @since 1.9
1076      */
1077     public final void putLongUnaligned(Object o, long offset, long x) {
1078         if ((offset & 7) == 0) {
1079             putLong(o, offset, x);
1080         } else if ((offset & 3) == 0) {
1081             putLongParts(o, offset,
1082                          (int)(x >> 0),
1083                          (int)(x >>> 32));
1084         } else if ((offset & 1) == 0) {
1085             putLongParts(o, offset,
1086                          (short)(x >>> 0),
1087                          (short)(x >>> 16),
1088                          (short)(x >>> 32),
1089                          (short)(x >>> 48));
1090         } else {
1091             putLongParts(o, offset, 
1092                          (byte)(x >>> 0),
1093                          (byte)(x >>> 8),
1094                          (byte)(x >>> 16),
1095                          (byte)(x >>> 24),
1096                          (byte)(x >>> 32),
1097                          (byte)(x >>> 40),
1098                          (byte)(x >>> 48),
1099                          (byte)(x >>> 56));
1100         }
1101     }
1102     /**
1103      * As {@link #putLongUnaligned(Object, long, long)} but with an additional
1104      * argument which specifies the endianness of the value as stored in memory.
1105      * @param o Java heap object in which the value resides
1106      * @param offset The offset in bytes from the start of the object
1107      * @param x the value to store
1108      * @param bigEndian The endianness of the value
1109      * @throws RuntimeException No defined exceptions are thrown, not even
1110      *         {@link NullPointerException}
1111      * @since 1.9
1112      */
1113     public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) {
1114         putLongUnaligned(o, offset, convEndian(bigEndian, x));
1115     }
1116 
1117     /** @see #putLongUnaligned(Object, long, long) */
1118     public final void putIntUnaligned(Object o, long offset, int x) {
1119         if ((offset & 3) == 0) {
1120             putInt(o, offset, x);
1121         } else if ((offset & 1) == 0) {
1122             putIntParts(o, offset,
1123                         (short)(x >> 0),
1124                         (short)(x >>> 16));
1125         } else {
1126             putIntParts(o, offset, 
1127                         (byte)(x >>> 0),
1128                         (byte)(x >>> 8),
1129                         (byte)(x >>> 16),
1130                         (byte)(x >>> 24));
1131         }
1132     }
1133     /** @see #putLongUnaligned(Object, long, long, boolean) */
1134     public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) {
1135         putIntUnaligned(o, offset, convEndian(bigEndian, x));
1136     }
1137 
1138     /** @see #putLongUnaligned(Object, long, long) */
1139     public final void putShortUnaligned(Object o, long offset, short x) {
1140         if ((offset & 1) == 0) {
1141             putShort(o, offset, x);
1142         } else {
1143             putShortParts(o, offset, 
1144                           (byte)(x >>> 0),
1145                           (byte)(x >>> 8));
1146         }
1147     }
1148     /** @see #putLongUnaligned(Object, long, long, boolean) */
1149     public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
1150         putShortUnaligned(o, offset, convEndian(bigEndian, x));
1151     }
1152 
1153     /** @see #putLongUnaligned(Object, long, long) */
1154     public final void putCharUnaligned(Object o, long offset, char x) {
1155         putShortUnaligned(o, offset, (short)x);
1156     }
1157     /** @see #putLongUnaligned(Object, long, long, boolean) */
1158     public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
1159         putCharUnaligned(o, offset, convEndian(bigEndian, x));
1160     }
1161 
1162     // JVM interface methods
1163     private native boolean unalignedAccess0();
1164     private native boolean isBigEndian0();
1165 
1166     // BE is true iff the native endianness of this machine is big.
1167     private static final boolean BE = theUnsafe.isBigEndian0();
1168 
1169     // unalignedAccess is true iff this machine can perform unaligned accesses.
1170     private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
1171 
1172     private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
1173 
1174     // These methods construct integers from bytes.  The byte ordering
1175     // is the native endianness of this machine.
1176     private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
1177         return ((toUnsignedLong(i0) << pickPos(56, 0))
1178               | (toUnsignedLong(i1) << pickPos(56, 8))
1179               | (toUnsignedLong(i2) << pickPos(56, 16))
1180               | (toUnsignedLong(i3) << pickPos(56, 24))
1181               | (toUnsignedLong(i4) << pickPos(56, 32))
1182               | (toUnsignedLong(i5) << pickPos(56, 40))
1183               | (toUnsignedLong(i6) << pickPos(56, 48))
1184               | (toUnsignedLong(i7) << pickPos(56, 56)));
1185     }
1186     private static long makeLong(short i0, short i1, short i2, short i3) {
1187         return ((toUnsignedLong(i0) << pickPos(48, 0))
1188               | (toUnsignedLong(i1) << pickPos(48, 16))
1189               | (toUnsignedLong(i2) << pickPos(48, 32))
1190               | (toUnsignedLong(i3) << pickPos(48, 48)));
1191     }
1192     private static long makeLong(int i0, int i1) {
1193         return (toUnsignedLong(i0) << pickPos(32, 0))
1194              | (toUnsignedLong(i1) << pickPos(32, 32));
1195     }
1196     private static int makeInt(short i0, short i1) {
1197         return (toUnsignedInt(i0) << pickPos(16, 0))
1198              | (toUnsignedInt(i1) << pickPos(16, 16));
1199     }
1200     private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
1201         return ((toUnsignedInt(i0) << pickPos(24, 0))
1202               | (toUnsignedInt(i1) << pickPos(24, 8))
1203               | (toUnsignedInt(i2) << pickPos(24, 16))
1204               | (toUnsignedInt(i3) << pickPos(24, 24)));
1205     }
1206     private static short makeShort(byte i0, byte i1) {
1207         return (short)((toUnsignedInt(i0) << pickPos(8, 0))
1208                      | (toUnsignedInt(i1) << pickPos(8, 8)));
1209     }
1210 
1211     private static byte  pick(byte  le, byte  be) { return BE ? be : le; }
1212     private static short pick(short le, short be) { return BE ? be : le; }
1213     private static int   pick(int   le, int   be) { return BE ? be : le; }
1214 
1215     // These methods write integers to memory from smaller parts
1216     // provided by their caller.  The ordering in which these parts
1217     // are written is the native endianness of this machine.
1218     private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
1219         putByte(o, offset + 0, pick(i0, i7));
1220         putByte(o, offset + 1, pick(i1, i6));
1221         putByte(o, offset + 2, pick(i2, i5));
1222         putByte(o, offset + 3, pick(i3, i4));
1223         putByte(o, offset + 4, pick(i4, i3));
1224         putByte(o, offset + 5, pick(i5, i2));
1225         putByte(o, offset + 6, pick(i6, i1));
1226         putByte(o, offset + 7, pick(i7, i0));
1227     }
1228     private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
1229         putShort(o, offset + 0, pick(i0, i3));
1230         putShort(o, offset + 2, pick(i1, i2));
1231         putShort(o, offset + 4, pick(i2, i1));
1232         putShort(o, offset + 6, pick(i3, i0));
1233     }
1234     private void putLongParts(Object o, long offset, int i0, int i1) {
1235         putInt(o, offset + 0, pick(i0, i1));
1236         putInt(o, offset + 4, pick(i1, i0));
1237     }
1238     private void putIntParts(Object o, long offset, short i0, short i1) {
1239         putShort(o, offset + 0, pick(i0, i1));
1240         putShort(o, offset + 2, pick(i1, i0));
1241     }
1242     private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
1243         putByte(o, offset + 0, pick(i0, i3));
1244         putByte(o, offset + 1, pick(i1, i2));
1245         putByte(o, offset + 2, pick(i2, i1));
1246         putByte(o, offset + 3, pick(i3, i0));
1247     }
1248     private void putShortParts(Object o, long offset, byte i0, byte i1) {
1249         putByte(o, offset + 0, pick(i0, i1));
1250         putByte(o, offset + 1, pick(i1, i0));
1251     }
1252 
1253     // Zero-extend an integer
1254     private static int toUnsignedInt(byte n)    { return n & 0xff; }
1255     private static int toUnsignedInt(short n)   { return n & 0xffff; }
1256     private static long toUnsignedLong(byte n)  { return n & 0xffl; }
1257     private static long toUnsignedLong(short n) { return n & 0xffffl; }
1258     private static long toUnsignedLong(int n)   { return n & 0xffffffffl; }
1259 
1260     // Maybe byte-reverse an integer
1261     private static char convEndian(boolean big, char n)   { return big == BE ? n : Character.reverseBytes(n); }
1262     private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n)    ; }
1263     private static int convEndian(boolean big, int n)     { return big == BE ? n : Integer.reverseBytes(n)  ; }
1264     private static long convEndian(boolean big, long n)   { return big == BE ? n : Long.reverseBytes(n)     ; }
1265 }