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 } |