001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.mm.mminterface; 014 015import static org.jikesrvm.runtime.JavaSizeConstants.LOG_BYTES_IN_BOOLEAN; 016import static org.jikesrvm.runtime.JavaSizeConstants.LOG_BYTES_IN_DOUBLE; 017import static org.jikesrvm.runtime.JavaSizeConstants.LOG_BYTES_IN_FLOAT; 018import static org.jikesrvm.runtime.JavaSizeConstants.LOG_BYTES_IN_LONG; 019import static org.mmtk.utility.Constants.ARRAY_ELEMENT; 020import static org.mmtk.utility.Constants.INSTANCE_FIELD; 021import static org.mmtk.utility.Constants.LOG_BYTES_IN_ADDRESS; 022import static org.mmtk.utility.Constants.LOG_BYTES_IN_CHAR; 023import static org.mmtk.utility.Constants.LOG_BYTES_IN_INT; 024import static org.mmtk.utility.Constants.LOG_BYTES_IN_SHORT; 025 026import org.jikesrvm.VM; 027import org.jikesrvm.runtime.Magic; 028import org.jikesrvm.runtime.Memory; 029import org.vmmagic.pragma.Entrypoint; 030import org.vmmagic.pragma.Inline; 031import org.vmmagic.pragma.Uninterruptible; 032import org.vmmagic.unboxed.Address; 033import org.vmmagic.unboxed.Extent; 034import org.vmmagic.unboxed.ObjectReference; 035import org.vmmagic.unboxed.Offset; 036import org.vmmagic.unboxed.Word; 037 038@Uninterruptible 039public class Barriers { 040 /** {@code true} if the selected plan requires a read barrier on java.lang.ref.Reference types */ 041 private static final boolean NEEDS_JAVA_LANG_REFERENCE_GC_READ_BARRIER = Selected.Constraints.get().needsJavaLangReferenceReadBarrier(); 042 /** {@code true} if the selected plan requires a read barrier on java.lang.ref.Reference types */ 043 public static final boolean NEEDS_JAVA_LANG_REFERENCE_READ_BARRIER = NEEDS_JAVA_LANG_REFERENCE_GC_READ_BARRIER; 044 045 /** 046 * A java.lang.ref.Reference is being read. 047 * 048 * @param obj The non-null referent about to be released to the mutator. 049 * @return The object to release to the mutator. 050 */ 051 public static Object javaLangReferenceReadBarrier(Object obj) { 052 if (NEEDS_JAVA_LANG_REFERENCE_GC_READ_BARRIER) { 053 ObjectReference result = Selected.Mutator.get().javaLangReferenceReadBarrier(ObjectReference.fromObject(obj)); 054 return result.toObject(); 055 } else if (VM.VerifyAssertions) 056 VM._assert(VM.NOT_REACHED); 057 return null; 058 } 059 060 /* bool byte char short int long float double */ 061 062 /** {@code true} if the garbage collector requires write barriers on boolean putfield, arraystore or modifycheck */ 063 private static final boolean NEEDS_BOOLEAN_GC_WRITE_BARRIER = Selected.Constraints.get().needsBooleanWriteBarrier(); 064 /** {@code true} if the VM requires write barriers on boolean putfield */ 065 public static final boolean NEEDS_BOOLEAN_PUTFIELD_BARRIER = NEEDS_BOOLEAN_GC_WRITE_BARRIER; 066 /** {@code true} if the VM requires write barriers on boolean arraystore */ 067 public static final boolean NEEDS_BOOLEAN_ASTORE_BARRIER = NEEDS_BOOLEAN_GC_WRITE_BARRIER; 068 /** {@code true} if the garbage collector requires read barriers on boolean getfield or arrayload */ 069 private static final boolean NEEDS_BOOLEAN_GC_READ_BARRIER = Selected.Constraints.get().needsBooleanReadBarrier(); 070 /** {@code true} if the VM requires read barriers on boolean getfield */ 071 public static final boolean NEEDS_BOOLEAN_GETFIELD_BARRIER = NEEDS_BOOLEAN_GC_READ_BARRIER; 072 /** {@code true} if the VM requires read barriers on boolean arrayload */ 073 public static final boolean NEEDS_BOOLEAN_ALOAD_BARRIER = NEEDS_BOOLEAN_GC_READ_BARRIER; 074 /** {@code true} if the garbage collector does not support the bulk copy operation */ 075 public static final boolean BOOLEAN_BULK_COPY_SUPPORTED = !(NEEDS_BOOLEAN_ASTORE_BARRIER || NEEDS_BOOLEAN_ALOAD_BARRIER) || Selected.Constraints.get().booleanBulkCopySupported(); 076 077 /** 078 * Barrier for writes of booleans into fields of instances (i.e. putfield). 079 * 080 * @param ref the object which is the subject of the putfield 081 * @param value the new value for the field 082 * @param offset the offset of the field to be modified 083 * @param locationMetadata an int that encodes the source location being modified 084 */ 085 @Inline 086 @Entrypoint 087 public static void booleanFieldWrite(Object ref, boolean value, Offset offset, int locationMetadata) { 088 if (NEEDS_BOOLEAN_GC_WRITE_BARRIER) { 089 ObjectReference src = ObjectReference.fromObject(ref); 090 Selected.Mutator.get().booleanWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 091 } else if (VM.VerifyAssertions) 092 VM._assert(VM.NOT_REACHED); 093 } 094 095 /** 096 * Barrier for writes of booleans into arrays (i.e. bastore). 097 * 098 * @param ref the array which is the subject of the astore 099 * @param index the index into the array where the new reference 100 * resides. The index is the "natural" index into the array, for 101 * example a[index]. 102 * @param value the value to be stored. 103 */ 104 @Inline 105 @Entrypoint 106 public static void booleanArrayWrite(boolean[] ref, int index, boolean value) { 107 if (NEEDS_BOOLEAN_GC_WRITE_BARRIER) { 108 ObjectReference array = ObjectReference.fromObject(ref); 109 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_BOOLEAN); 110 Selected.Mutator.get().booleanWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT); 111 } else if (VM.VerifyAssertions) 112 VM._assert(VM.NOT_REACHED); 113 } 114 115 /** 116 * Barrier for loads of booleans from fields of instances (i.e. getfield). 117 * 118 * @param ref the object which is the subject of the getfield 119 * @param offset the offset of the field to be read 120 * @param locationMetadata an int that encodes the source location being read 121 * @return The value read from the field. 122 */ 123 @Inline 124 @Entrypoint 125 public static boolean booleanFieldRead(Object ref, Offset offset, int locationMetadata) { 126 if (NEEDS_BOOLEAN_GC_READ_BARRIER) { 127 ObjectReference src = ObjectReference.fromObject(ref); 128 return Selected.Mutator.get().booleanRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 129 } else if (VM.VerifyAssertions) 130 VM._assert(VM.NOT_REACHED); 131 return false; 132 } 133 134 /** 135 * Barrier for loads of booleans from fields of arrays (i.e. aload). 136 * 137 * @param ref the array containing the reference. 138 * @param index the index into the array were the reference resides. 139 * @return the value read from the array 140 */ 141 @Inline 142 @Entrypoint 143 public static boolean booleanArrayRead(boolean[] ref, int index) { 144 if (NEEDS_BOOLEAN_GC_READ_BARRIER) { 145 ObjectReference array = ObjectReference.fromObject(ref); 146 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_BOOLEAN); 147 return Selected.Mutator.get().booleanRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 148 } else if (VM.VerifyAssertions) 149 VM._assert(VM.NOT_REACHED); 150 return false; 151 } 152 153 /** 154 * Barrier for a bulk copy of booleans (i.e. in an array copy). 155 * 156 * @param src The source array 157 * @param srcOffset The starting source offset 158 * @param dst The destination array 159 * @param dstOffset The starting destination offset 160 * @param bytes The number of bytes to be copied 161 */ 162 @Inline 163 public static void booleanBulkCopy(boolean[] src, Offset srcOffset, boolean[] dst, Offset dstOffset, int bytes) { 164 if (VM.VerifyAssertions) VM._assert(BOOLEAN_BULK_COPY_SUPPORTED); 165 166 if (!Selected.Mutator.get().booleanBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 167 Memory.aligned8Copy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 168 } 169 } 170 171 /** {@code true} if the garbage collector requires write barriers on byte putfield, arraystore or modifycheck */ 172 private static final boolean NEEDS_BYTE_GC_WRITE_BARRIER = Selected.Constraints.get().needsByteWriteBarrier(); 173 /** {@code true} if the VM requires write barriers on byte putfield */ 174 public static final boolean NEEDS_BYTE_PUTFIELD_BARRIER = NEEDS_BYTE_GC_WRITE_BARRIER; 175 /** {@code true} if the VM requires write barriers on byte arraystore */ 176 public static final boolean NEEDS_BYTE_ASTORE_BARRIER = NEEDS_BYTE_GC_WRITE_BARRIER; 177 /** {@code true} if the garbage collector requires read barriers on byte getfield or arrayload */ 178 private static final boolean NEEDS_BYTE_GC_READ_BARRIER = Selected.Constraints.get().needsByteReadBarrier(); 179 /** {@code true} if the VM requires read barriers on byte getfield */ 180 public static final boolean NEEDS_BYTE_GETFIELD_BARRIER = NEEDS_BYTE_GC_READ_BARRIER; 181 /** {@code true} if the VM requires read barriers on byte arrayload */ 182 public static final boolean NEEDS_BYTE_ALOAD_BARRIER = NEEDS_BYTE_GC_READ_BARRIER; 183 /** {@code true} if the garbage collector does not support the bulk copy operation */ 184 public static final boolean BYTE_BULK_COPY_SUPPORTED = !(NEEDS_BYTE_ASTORE_BARRIER || NEEDS_BYTE_ALOAD_BARRIER) || Selected.Constraints.get().byteBulkCopySupported(); 185 186 /** 187 * Barrier for writes of bytes into fields of instances (i.e. putfield). 188 * 189 * @param ref the object which is the subject of the putfield 190 * @param value the new value for the field 191 * @param offset the offset of the field to be modified 192 * @param locationMetadata an int that encodes the source location being modified 193 */ 194 @Inline 195 @Entrypoint 196 public static void byteFieldWrite(Object ref, byte value, Offset offset, int locationMetadata) { 197 if (NEEDS_BYTE_GC_WRITE_BARRIER) { 198 ObjectReference src = ObjectReference.fromObject(ref); 199 Selected.Mutator.get().byteWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 200 } else if (VM.VerifyAssertions) 201 VM._assert(VM.NOT_REACHED); 202 } 203 204 /** 205 * Barrier for writes of bytes into arrays (i.e. bastore). 206 * 207 * @param ref the array which is the subject of the astore 208 * @param index the index into the array where the new reference 209 * resides. The index is the "natural" index into the array, for 210 * example a[index]. 211 * @param value the value to be stored. 212 */ 213 @Inline 214 @Entrypoint 215 public static void byteArrayWrite(byte[] ref, int index, byte value) { 216 if (NEEDS_BYTE_GC_WRITE_BARRIER) { 217 ObjectReference array = ObjectReference.fromObject(ref); 218 Offset offset = Offset.fromIntZeroExtend(index); 219 Selected.Mutator.get().byteWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT); 220 } else if (VM.VerifyAssertions) 221 VM._assert(VM.NOT_REACHED); 222 } 223 224 /** 225 * Barrier for loads of bytes from fields of instances (i.e. getfield). 226 * 227 * @param ref the object which is the subject of the getfield 228 * @param offset the offset of the field to be read 229 * @param locationMetadata an int that encodes the source location being read 230 * @return The value read from the field. 231 */ 232 @Inline 233 @Entrypoint 234 public static byte byteFieldRead(Object ref, Offset offset, int locationMetadata) { 235 if (NEEDS_BYTE_GC_READ_BARRIER) { 236 ObjectReference src = ObjectReference.fromObject(ref); 237 return Selected.Mutator.get().byteRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 238 } else if (VM.VerifyAssertions) 239 VM._assert(VM.NOT_REACHED); 240 return 0; 241 } 242 243 /** 244 * Barrier for loads of bytes from fields of arrays (i.e. baload). 245 * 246 * @param ref the array containing the reference. 247 * @param index the index into the array were the reference resides. 248 * @return the value read from the array 249 */ 250 @Inline 251 @Entrypoint 252 public static byte byteArrayRead(byte[] ref, int index) { 253 if (NEEDS_BYTE_GC_READ_BARRIER) { 254 ObjectReference array = ObjectReference.fromObject(ref); 255 Offset offset = Offset.fromIntZeroExtend(index); 256 return Selected.Mutator.get().byteRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 257 } else if (VM.VerifyAssertions) 258 VM._assert(VM.NOT_REACHED); 259 return 0; 260 } 261 262 /** 263 * Barrier for a bulk copy of bytes (i.e. in an array copy). 264 * 265 * @param src The source array 266 * @param srcOffset The starting source offset 267 * @param dst The destination array 268 * @param dstOffset The starting destination offset 269 * @param bytes The number of bytes to be copied 270 */ 271 @Inline 272 public static void byteBulkCopy(byte[] src, Offset srcOffset, byte[] dst, Offset dstOffset, int bytes) { 273 if (VM.VerifyAssertions) VM._assert(BYTE_BULK_COPY_SUPPORTED); 274 275 if (!Selected.Mutator.get().byteBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 276 Memory.aligned8Copy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 277 } 278 } 279 280 281 /** {@code true} if the garbage collector requires write barriers on char putfield, arraystore or modifycheck */ 282 private static final boolean NEEDS_CHAR_GC_WRITE_BARRIER = Selected.Constraints.get().needsCharWriteBarrier(); 283 /** {@code true} if the VM requires write barriers on char putfield */ 284 public static final boolean NEEDS_CHAR_PUTFIELD_BARRIER = NEEDS_CHAR_GC_WRITE_BARRIER; 285 /** {@code true} if the VM requires write barriers on char arraystore */ 286 public static final boolean NEEDS_CHAR_ASTORE_BARRIER = NEEDS_CHAR_GC_WRITE_BARRIER; 287 /** {@code true} if the garbage collector requires read barriers on char getfield or arrayload */ 288 private static final boolean NEEDS_CHAR_GC_READ_BARRIER = Selected.Constraints.get().needsCharReadBarrier(); 289 /** {@code true} if the VM requires read barriers on char getfield */ 290 public static final boolean NEEDS_CHAR_GETFIELD_BARRIER = NEEDS_CHAR_GC_READ_BARRIER; 291 /** {@code true} if the VM requires read barriers on char arrayload */ 292 public static final boolean NEEDS_CHAR_ALOAD_BARRIER = NEEDS_CHAR_GC_READ_BARRIER; 293 /** {@code true} if the garbage collector does not support the bulk copy operation */ 294 public static final boolean CHAR_BULK_COPY_SUPPORTED = !(NEEDS_CHAR_ASTORE_BARRIER || NEEDS_CHAR_ALOAD_BARRIER) || Selected.Constraints.get().charBulkCopySupported(); 295 296 /** 297 * Barrier for writes of chars into fields of instances (i.e. putfield). 298 * 299 * @param ref the object which is the subject of the putfield 300 * @param value the new value for the field 301 * @param offset the offset of the field to be modified 302 * @param locationMetadata an int that encodes the source location being modified 303 */ 304 @Inline 305 @Entrypoint 306 public static void charFieldWrite(Object ref, char value, Offset offset, int locationMetadata) { 307 if (NEEDS_CHAR_GC_WRITE_BARRIER) { 308 ObjectReference src = ObjectReference.fromObject(ref); 309 Selected.Mutator.get().charWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 310 } else if (VM.VerifyAssertions) 311 VM._assert(VM.NOT_REACHED); 312 } 313 314 /** 315 * Barrier for writes of chars into arrays (i.e. castore). 316 * 317 * @param ref the array which is the subject of the astore 318 * @param index the index into the array where the new reference 319 * resides. The index is the "natural" index into the array, for 320 * example a[index]. 321 * @param value the value to be stored. 322 */ 323 @Inline 324 @Entrypoint 325 public static void charArrayWrite(char[] ref, int index, char value) { 326 if (NEEDS_CHAR_GC_WRITE_BARRIER) { 327 ObjectReference array = ObjectReference.fromObject(ref); 328 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_CHAR); 329 Selected.Mutator.get().charWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT); 330 } else if (VM.VerifyAssertions) 331 VM._assert(VM.NOT_REACHED); 332 } 333 334 /** 335 * Barrier for loads of chars from fields of instances (i.e. getfield). 336 * 337 * @param ref the object which is the subject of the getfield 338 * @param offset the offset of the field to be read 339 * @param locationMetadata an int that encodes the source location being read 340 * @return The value read from the field. 341 */ 342 @Inline 343 @Entrypoint 344 public static char charFieldRead(Object ref, Offset offset, int locationMetadata) { 345 if (NEEDS_CHAR_GC_READ_BARRIER) { 346 ObjectReference src = ObjectReference.fromObject(ref); 347 return Selected.Mutator.get().charRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 348 } else if (VM.VerifyAssertions) 349 VM._assert(VM.NOT_REACHED); 350 return 0; 351 } 352 353 /** 354 * Barrier for loads of chars from fields of arrays (i.e. caload). 355 * 356 * @param ref the array containing the reference. 357 * @param index the index into the array were the reference resides. 358 * @return the value read from the array 359 */ 360 @Inline 361 @Entrypoint 362 public static char charArrayRead(char[] ref, int index) { 363 if (NEEDS_CHAR_GC_READ_BARRIER) { 364 ObjectReference array = ObjectReference.fromObject(ref); 365 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_CHAR); 366 return Selected.Mutator.get().charRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 367 } else if (VM.VerifyAssertions) 368 VM._assert(VM.NOT_REACHED); 369 return 0; 370 } 371 372 /** 373 * Barrier for a bulk copy of chars (i.e. in an array copy). 374 * 375 * @param src The source array 376 * @param srcOffset The starting source offset 377 * @param dst The destination array 378 * @param dstOffset The starting destination offset 379 * @param bytes The number of bytes to be copied 380 */ 381 @Inline 382 public static void charBulkCopy(char[] src, Offset srcOffset, char[] dst, Offset dstOffset, int bytes) { 383 if (VM.VerifyAssertions) VM._assert(CHAR_BULK_COPY_SUPPORTED); 384 385 if (!Selected.Mutator.get().charBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 386 Memory.aligned16Copy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 387 } 388 } 389 390 391 /** {@code true} if the garbage collector requires write barriers on short putfield, arraystore or modifycheck */ 392 private static final boolean NEEDS_SHORT_GC_WRITE_BARRIER = Selected.Constraints.get().needsShortWriteBarrier(); 393 /** {@code true} if the VM requires write barriers on short putfield */ 394 public static final boolean NEEDS_SHORT_PUTFIELD_BARRIER = NEEDS_SHORT_GC_WRITE_BARRIER; 395 /** {@code true} if the VM requires write barriers on short arraystore */ 396 public static final boolean NEEDS_SHORT_ASTORE_BARRIER = NEEDS_SHORT_GC_WRITE_BARRIER; 397 /** {@code true} if the garbage collector requires read barriers on short getfield or arrayload */ 398 private static final boolean NEEDS_SHORT_GC_READ_BARRIER = Selected.Constraints.get().needsShortReadBarrier(); 399 /** {@code true} if the VM requires read barriers on short getfield */ 400 public static final boolean NEEDS_SHORT_GETFIELD_BARRIER = NEEDS_SHORT_GC_READ_BARRIER; 401 /** {@code true} if the VM requires read barriers on short arrayload */ 402 public static final boolean NEEDS_SHORT_ALOAD_BARRIER = NEEDS_SHORT_GC_READ_BARRIER; 403 /** {@code true} if the garbage collector does not support the bulk copy operation */ 404 public static final boolean SHORT_BULK_COPY_SUPPORTED = !(NEEDS_SHORT_ASTORE_BARRIER || NEEDS_SHORT_ALOAD_BARRIER) || Selected.Constraints.get().shortBulkCopySupported(); 405 406 /** 407 * Barrier for writes of shorts into fields of instances (i.e. putfield). 408 * 409 * @param ref the object which is the subject of the putfield 410 * @param value the new value for the field 411 * @param offset the offset of the field to be modified 412 * @param locationMetadata an int that encodes the source location being modified 413 */ 414 @Inline 415 @Entrypoint 416 public static void shortFieldWrite(Object ref, short value, Offset offset, int locationMetadata) { 417 if (NEEDS_SHORT_GC_WRITE_BARRIER) { 418 ObjectReference src = ObjectReference.fromObject(ref); 419 Selected.Mutator.get().shortWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 420 } else if (VM.VerifyAssertions) 421 VM._assert(VM.NOT_REACHED); 422 } 423 424 /** 425 * Barrier for writes of shorts into arrays (i.e. sastore). 426 * 427 * @param ref the array which is the subject of the astore 428 * @param index the index into the array where the new reference 429 * resides. The index is the "natural" index into the array, for 430 * example a[index]. 431 * @param value the value to be stored. 432 */ 433 @Inline 434 @Entrypoint 435 public static void shortArrayWrite(short[] ref, int index, short value) { 436 if (NEEDS_SHORT_GC_WRITE_BARRIER) { 437 ObjectReference array = ObjectReference.fromObject(ref); 438 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_SHORT); 439 Selected.Mutator.get().shortWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT); 440 } else if (VM.VerifyAssertions) 441 VM._assert(VM.NOT_REACHED); 442 } 443 444 /** 445 * Barrier for loads of shorts from fields of instances (i.e. getfield). 446 * 447 * @param ref the object which is the subject of the getfield 448 * @param offset the offset of the field to be read 449 * @param locationMetadata an int that encodes the source location being read 450 * @return The value read from the field. 451 */ 452 @Inline 453 @Entrypoint 454 public static short shortFieldRead(Object ref, Offset offset, int locationMetadata) { 455 if (NEEDS_SHORT_GC_READ_BARRIER) { 456 ObjectReference src = ObjectReference.fromObject(ref); 457 return Selected.Mutator.get().shortRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 458 } else if (VM.VerifyAssertions) 459 VM._assert(VM.NOT_REACHED); 460 return 0; 461 } 462 463 /** 464 * Barrier for loads of shorts from fields of arrays (i.e. saload). 465 * 466 * @param ref the array containing the reference. 467 * @param index the index into the array were the reference resides. 468 * @return the value read from the array 469 */ 470 @Inline 471 @Entrypoint 472 public static short shortArrayRead(short[] ref, int index) { 473 if (NEEDS_SHORT_GC_READ_BARRIER) { 474 ObjectReference array = ObjectReference.fromObject(ref); 475 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_SHORT); 476 return Selected.Mutator.get().shortRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 477 } else if (VM.VerifyAssertions) 478 VM._assert(VM.NOT_REACHED); 479 return 0; 480 } 481 482 /** 483 * Barrier for a bulk copy of shorts (i.e. in an array copy). 484 * 485 * @param src The source array 486 * @param srcOffset The starting source offset 487 * @param dst The destination array 488 * @param dstOffset The starting destination offset 489 * @param bytes The number of bytes to be copied 490 */ 491 @Inline 492 public static void shortBulkCopy(short[] src, Offset srcOffset, short[] dst, Offset dstOffset, int bytes) { 493 if (VM.VerifyAssertions) VM._assert(SHORT_BULK_COPY_SUPPORTED); 494 495 if (!Selected.Mutator.get().shortBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 496 Memory.aligned16Copy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 497 } 498 } 499 500 501 502 /** {@code true} if the garbage collector requires write barriers on int putfield, arraystore or modifycheck */ 503 private static final boolean NEEDS_INT_GC_WRITE_BARRIER = Selected.Constraints.get().needsIntWriteBarrier(); 504 /** {@code true} if the VM requires write barriers on int putfield */ 505 public static final boolean NEEDS_INT_PUTFIELD_BARRIER = NEEDS_INT_GC_WRITE_BARRIER; 506 /** {@code true} if the VM requires write barriers on int arraystore */ 507 public static final boolean NEEDS_INT_ASTORE_BARRIER = NEEDS_INT_GC_WRITE_BARRIER; 508 /** {@code true} if the garbage collector requires read barriers on int getfield or arrayload */ 509 private static final boolean NEEDS_INT_GC_READ_BARRIER = Selected.Constraints.get().needsIntReadBarrier(); 510 /** {@code true} if the VM requires read barriers on int getfield */ 511 public static final boolean NEEDS_INT_GETFIELD_BARRIER = NEEDS_INT_GC_READ_BARRIER; 512 /** {@code true} if the VM requires read barriers on int arrayload */ 513 public static final boolean NEEDS_INT_ALOAD_BARRIER = NEEDS_INT_GC_READ_BARRIER; 514 /** {@code true} if the garbage collector does not support the bulk copy operation */ 515 public static final boolean INT_BULK_COPY_SUPPORTED = !(NEEDS_INT_ASTORE_BARRIER || NEEDS_INT_ALOAD_BARRIER) || Selected.Constraints.get().intBulkCopySupported(); 516 517 /** 518 * Barrier for writes of ints into fields of instances (i.e. putfield). 519 * 520 * @param ref the object which is the subject of the putfield 521 * @param value the new value for the field 522 * @param offset the offset of the field to be modified 523 * @param locationMetadata an int that encodes the source location being modified 524 */ 525 @Inline 526 @Entrypoint 527 public static void intFieldWrite(Object ref, int value, Offset offset, int locationMetadata) { 528 if (NEEDS_INT_GC_WRITE_BARRIER) { 529 ObjectReference src = ObjectReference.fromObject(ref); 530 Selected.Mutator.get().intWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 531 } else if (VM.VerifyAssertions) 532 VM._assert(VM.NOT_REACHED); 533 } 534 535 /** 536 * Barrier for writes of ints into arrays (i.e. iastore). 537 * 538 * @param ref the array which is the subject of the astore 539 * @param index the index into the array where the new reference 540 * resides. The index is the "natural" index into the array, for 541 * example a[index]. 542 * @param value the value to be stored. 543 */ 544 @Inline 545 @Entrypoint 546 public static void intArrayWrite(int[] ref, int index, int value) { 547 if (NEEDS_INT_GC_WRITE_BARRIER) { 548 ObjectReference array = ObjectReference.fromObject(ref); 549 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_INT); 550 Selected.Mutator.get().intWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT); 551 } else if (VM.VerifyAssertions) 552 VM._assert(VM.NOT_REACHED); 553 } 554 555 /** 556 * Barrier for loads of ints from fields of instances (i.e. getfield). 557 * 558 * @param ref the object which is the subject of the getfield 559 * @param offset the offset of the field to be read 560 * @param locationMetadata an int that encodes the source location being read 561 * @return The value read from the field. 562 */ 563 @Inline 564 @Entrypoint 565 public static int intFieldRead(Object ref, Offset offset, int locationMetadata) { 566 if (NEEDS_INT_GC_READ_BARRIER) { 567 ObjectReference src = ObjectReference.fromObject(ref); 568 return Selected.Mutator.get().intRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 569 } else if (VM.VerifyAssertions) 570 VM._assert(VM.NOT_REACHED); 571 return 0; 572 } 573 574 /** 575 * Barrier for loads of ints from fields of arrays (i.e. iaload). 576 * 577 * @param ref the array containing the reference. 578 * @param index the index into the array were the reference resides. 579 * @return the value read from the array 580 */ 581 @Inline 582 @Entrypoint 583 public static int intArrayRead(int[] ref, int index) { 584 if (NEEDS_INT_GC_READ_BARRIER) { 585 ObjectReference array = ObjectReference.fromObject(ref); 586 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_INT); 587 return Selected.Mutator.get().intRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 588 } else if (VM.VerifyAssertions) 589 VM._assert(VM.NOT_REACHED); 590 return 0; 591 } 592 593 /** 594 * Barrier for a bulk copy of ints (i.e. in an array copy). 595 * 596 * @param src The source array 597 * @param srcOffset The starting source offset 598 * @param dst The destination array 599 * @param dstOffset The starting destination offset 600 * @param bytes The number of bytes to be copied 601 */ 602 @Inline 603 public static void intBulkCopy(int[] src, Offset srcOffset, int[] dst, Offset dstOffset, int bytes) { 604 if (VM.VerifyAssertions) VM._assert(INT_BULK_COPY_SUPPORTED); 605 606 if (!Selected.Mutator.get().intBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 607 Memory.aligned32Copy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 608 } 609 } 610 611 /** 612 * Barrier for conditional compare and exchange of int fields. 613 * @param ref the object which is the subject of the compare and exchanges 614 * @param offset the offset of the field to be modified 615 * @param old the old value to swap out 616 * @param value the new value for the field 617 * @return {@code true} if and only if the swap was successful 618 */ 619 @Inline 620 public static boolean intTryCompareAndSwap(Object ref, Offset offset, int old, int value) { 621 if (NEEDS_INT_GC_WRITE_BARRIER || NEEDS_INT_GC_READ_BARRIER) { 622 ObjectReference src = ObjectReference.fromObject(ref); 623 return Selected.Mutator.get().intTryCompareAndSwap(src, src.toAddress().plus(offset), old, value, offset.toWord(), 624 Word.zero(), // do not have location metadata 625 INSTANCE_FIELD); 626 } else if (VM.VerifyAssertions) 627 VM._assert(VM.NOT_REACHED); 628 return false; 629 } 630 631 632 /** {@code true} if the garbage collector requires write barriers on long putfield, arraystore or modifycheck */ 633 private static final boolean NEEDS_LONG_GC_WRITE_BARRIER = Selected.Constraints.get().needsLongWriteBarrier(); 634 /** {@code true} if the VM requires write barriers on long putfield */ 635 public static final boolean NEEDS_LONG_PUTFIELD_BARRIER = NEEDS_LONG_GC_WRITE_BARRIER; 636 /** {@code true} if the VM requires write barriers on long arraystore */ 637 public static final boolean NEEDS_LONG_ASTORE_BARRIER = NEEDS_LONG_GC_WRITE_BARRIER; 638 /** {@code true} if the garbage collector requires read barriers on long getfield or arrayload */ 639 private static final boolean NEEDS_LONG_GC_READ_BARRIER = Selected.Constraints.get().needsLongReadBarrier(); 640 /** {@code true} if the VM requires read barriers on long getfield */ 641 public static final boolean NEEDS_LONG_GETFIELD_BARRIER = NEEDS_LONG_GC_READ_BARRIER; 642 /** {@code true} if the VM requires read barriers on long arrayload */ 643 public static final boolean NEEDS_LONG_ALOAD_BARRIER = NEEDS_LONG_GC_READ_BARRIER; 644 /** {@code true} if the garbage collector supports the bulk copy operation */ 645 public static final boolean LONG_BULK_COPY_SUPPORTED = !(NEEDS_LONG_ASTORE_BARRIER || NEEDS_LONG_ALOAD_BARRIER) || Selected.Constraints.get().longBulkCopySupported(); 646 647 /** 648 * Barrier for writes of longs into fields of instances (i.e. putfield). 649 * 650 * @param ref the object which is the subject of the putfield 651 * @param value the new value for the field 652 * @param offset the offset of the field to be modified 653 * @param locationMetadata an int that encodes the source location being modified 654 */ 655 @Inline 656 @Entrypoint 657 public static void longFieldWrite(Object ref, long value, Offset offset, int locationMetadata) { 658 if (NEEDS_LONG_GC_WRITE_BARRIER) { 659 ObjectReference src = ObjectReference.fromObject(ref); 660 Selected.Mutator.get().longWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 661 } else if (VM.VerifyAssertions) 662 VM._assert(VM.NOT_REACHED); 663 } 664 665 /** 666 * Barrier for writes of longs into arrays (i.e. lastore). 667 * 668 * @param ref the array which is the subject of the astore 669 * @param index the index into the array where the new reference 670 * resides. The index is the "natural" index into the array, for 671 * example a[index]. 672 * @param value the value to be stored. 673 */ 674 @Inline 675 @Entrypoint 676 public static void longArrayWrite(long[] ref, int index, long value) { 677 if (NEEDS_LONG_GC_WRITE_BARRIER) { 678 ObjectReference array = ObjectReference.fromObject(ref); 679 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_LONG); 680 Selected.Mutator.get().longWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT); 681 } else if (VM.VerifyAssertions) 682 VM._assert(VM.NOT_REACHED); 683 } 684 685 /** 686 * Barrier for loads of longs from fields of instances (i.e. getfield). 687 * 688 * @param ref the object which is the subject of the getfield 689 * @param offset the offset of the field to be read 690 * @param locationMetadata an int that encodes the source location being read 691 * @return The value read from the field. 692 */ 693 @Inline 694 @Entrypoint 695 public static long longFieldRead(Object ref, Offset offset, int locationMetadata) { 696 if (NEEDS_LONG_GC_READ_BARRIER) { 697 ObjectReference src = ObjectReference.fromObject(ref); 698 return Selected.Mutator.get().longRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 699 } else if (VM.VerifyAssertions) 700 VM._assert(VM.NOT_REACHED); 701 return 0; 702 } 703 704 /** 705 * Barrier for loads of longs from fields of arrays (i.e. laload). 706 * 707 * @param ref the array containing the reference. 708 * @param index the index into the array were the reference resides. 709 * @return the value read from the array 710 */ 711 @Inline 712 @Entrypoint 713 public static long longArrayRead(long[] ref, int index) { 714 if (NEEDS_LONG_GC_READ_BARRIER) { 715 ObjectReference array = ObjectReference.fromObject(ref); 716 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_LONG); 717 return Selected.Mutator.get().longRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 718 } else if (VM.VerifyAssertions) 719 VM._assert(VM.NOT_REACHED); 720 return 0; 721 } 722 723 /** 724 * Barrier for conditional compare and exchange of long fields. 725 * @param ref the object which is the subject of the compare and exchanges 726 * @param offset the offset of the field to be modified 727 * @param old the old value to swap out 728 * @param value the new value for the field 729 * @return {@code true} if and only if the swap was successful 730 */ 731 @Inline 732 public static boolean longTryCompareAndSwap(Object ref, Offset offset, long old, long value) { 733 if (NEEDS_LONG_GC_WRITE_BARRIER || NEEDS_LONG_GC_READ_BARRIER) { 734 ObjectReference src = ObjectReference.fromObject(ref); 735 return Selected.Mutator.get().longTryCompareAndSwap(src, src.toAddress().plus(offset), old, value, offset.toWord(), 736 Word.zero(), // do not have location metadata 737 INSTANCE_FIELD); 738 } else if (VM.VerifyAssertions) 739 VM._assert(VM.NOT_REACHED); 740 return false; 741 } 742 743 /** 744 * Barrier for a bulk copy of longs (i.e. in an array copy). 745 * @param src The source array 746 * @param srcOffset The starting source offset 747 * @param dst The destination array 748 * @param dstOffset The starting destination offset 749 * @param bytes The number of bytes to be copied 750 */ 751 @Inline 752 public static void longBulkCopy(long[] src, Offset srcOffset, long[] dst, Offset dstOffset, int bytes) { 753 if (VM.VerifyAssertions) VM._assert(LONG_BULK_COPY_SUPPORTED); 754 755 if (!Selected.Mutator.get().longBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 756 Memory.aligned64Copy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 757 } 758 } 759 760 761 /** {@code true} if the garbage collector requires write barriers on float putfield, arraystore or modifycheck */ 762 private static final boolean NEEDS_FLOAT_GC_WRITE_BARRIER = Selected.Constraints.get().needsFloatWriteBarrier(); 763 /** {@code true} if the VM requires write barriers on float putfield */ 764 public static final boolean NEEDS_FLOAT_PUTFIELD_BARRIER = NEEDS_FLOAT_GC_WRITE_BARRIER; 765 /** {@code true} if the VM requires write barriers on float arraystore */ 766 public static final boolean NEEDS_FLOAT_ASTORE_BARRIER = NEEDS_FLOAT_GC_WRITE_BARRIER; 767 /** {@code true} if the garbage collector requires read barriers on float getfield or arrayload */ 768 private static final boolean NEEDS_FLOAT_GC_READ_BARRIER = Selected.Constraints.get().needsFloatReadBarrier(); 769 /** {@code true} if the VM requires read barriers on float getfield */ 770 public static final boolean NEEDS_FLOAT_GETFIELD_BARRIER = NEEDS_FLOAT_GC_READ_BARRIER; 771 /** {@code true} if the VM requires read barriers on float arrayload */ 772 public static final boolean NEEDS_FLOAT_ALOAD_BARRIER = NEEDS_FLOAT_GC_READ_BARRIER; 773 /** {@code true} if the garbage collector supports the bulk copy operation */ 774 public static final boolean FLOAT_BULK_COPY_SUPPORTED = !(NEEDS_FLOAT_ASTORE_BARRIER || NEEDS_FLOAT_ALOAD_BARRIER) || Selected.Constraints.get().floatBulkCopySupported(); 775 776 /** 777 * Barrier for writes of floats into fields of instances (i.e. putfield). 778 * 779 * @param ref the object which is the subject of the putfield 780 * @param value the new value for the field 781 * @param offset the offset of the field to be modified 782 * @param locationMetadata an int that encodes the source location being modified 783 */ 784 @Inline 785 @Entrypoint 786 public static void floatFieldWrite(Object ref, float value, Offset offset, int locationMetadata) { 787 if (NEEDS_FLOAT_GC_WRITE_BARRIER) { 788 ObjectReference src = ObjectReference.fromObject(ref); 789 Selected.Mutator.get().floatWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 790 } else if (VM.VerifyAssertions) 791 VM._assert(VM.NOT_REACHED); 792 } 793 794 /** 795 * Barrier for writes of floats into arrays (i.e. fastore). 796 * 797 * @param ref the array which is the subject of the astore 798 * @param index the index into the array where the new reference 799 * resides. The index is the "natural" index into the array, for 800 * example a[index]. 801 * @param value the value to be stored. 802 */ 803 @Inline 804 @Entrypoint 805 public static void floatArrayWrite(float[] ref, int index, float value) { 806 if (NEEDS_FLOAT_GC_WRITE_BARRIER) { 807 ObjectReference array = ObjectReference.fromObject(ref); 808 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_FLOAT); 809 Selected.Mutator.get().floatWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT); 810 } else if (VM.VerifyAssertions) 811 VM._assert(VM.NOT_REACHED); 812 } 813 814 /** 815 * Barrier for loads of floats from fields of instances (i.e. getfield). 816 * 817 * @param ref the object which is the subject of the getfield 818 * @param offset the offset of the field to be read 819 * @param locationMetadata an int that encodes the source location being read 820 * @return The value read from the field. 821 */ 822 @Inline 823 @Entrypoint 824 public static float floatFieldRead(Object ref, Offset offset, int locationMetadata) { 825 if (NEEDS_FLOAT_GC_READ_BARRIER) { 826 ObjectReference src = ObjectReference.fromObject(ref); 827 return Selected.Mutator.get().floatRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 828 } else if (VM.VerifyAssertions) 829 VM._assert(VM.NOT_REACHED); 830 return 0; 831 } 832 833 /** 834 * Barrier for loads of floats from fields of arrays (i.e. faload). 835 * 836 * @param ref the array containing the reference. 837 * @param index the index into the array were the reference resides. 838 * @return the value read from the array 839 */ 840 @Inline 841 @Entrypoint 842 public static float floatArrayRead(float[] ref, int index) { 843 if (NEEDS_FLOAT_GC_READ_BARRIER) { 844 ObjectReference array = ObjectReference.fromObject(ref); 845 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_FLOAT); 846 return Selected.Mutator.get().floatRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 847 } else if (VM.VerifyAssertions) 848 VM._assert(VM.NOT_REACHED); 849 return 0; 850 } 851 852 /** 853 * Barrier for a bulk copy of floats (i.e. in an array copy). 854 * 855 * @param src The source array 856 * @param srcOffset The starting source offset 857 * @param dst The destination array 858 * @param dstOffset The starting destination offset 859 * @param bytes The number of bytes to be copied 860 */ 861 @Inline 862 public static void floatBulkCopy(float[] src, Offset srcOffset, float[] dst, Offset dstOffset, int bytes) { 863 if (VM.VerifyAssertions) VM._assert(FLOAT_BULK_COPY_SUPPORTED); 864 865 if (!Selected.Mutator.get().floatBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 866 Memory.aligned32Copy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 867 } 868 } 869 870 871 /** {@code true} if the garbage collector requires write barriers on double putfield, arraystore or modifycheck */ 872 private static final boolean NEEDS_DOUBLE_GC_WRITE_BARRIER = Selected.Constraints.get().needsDoubleWriteBarrier(); 873 /** {@code true} if the VM requires write barriers on double putfield */ 874 public static final boolean NEEDS_DOUBLE_PUTFIELD_BARRIER = NEEDS_DOUBLE_GC_WRITE_BARRIER; 875 /** {@code true} if the VM requires write barriers on double arraystore */ 876 public static final boolean NEEDS_DOUBLE_ASTORE_BARRIER = NEEDS_DOUBLE_GC_WRITE_BARRIER; 877 /** {@code true} if the garbage collector requires read barriers on double getfield or arrayload */ 878 private static final boolean NEEDS_DOUBLE_GC_READ_BARRIER = Selected.Constraints.get().needsDoubleReadBarrier(); 879 /** {@code true} if the VM requires read barriers on double getfield */ 880 public static final boolean NEEDS_DOUBLE_GETFIELD_BARRIER = NEEDS_DOUBLE_GC_READ_BARRIER; 881 /** {@code true} if the VM requires read barriers on double arrayload */ 882 public static final boolean NEEDS_DOUBLE_ALOAD_BARRIER = NEEDS_DOUBLE_GC_READ_BARRIER; 883 /** {@code true} if the garbage collector supports the bulk copy operation */ 884 public static final boolean DOUBLE_BULK_COPY_SUPPORTED = !(NEEDS_DOUBLE_ASTORE_BARRIER || NEEDS_DOUBLE_ALOAD_BARRIER) || Selected.Constraints.get().doubleBulkCopySupported(); 885 886 /** 887 * Barrier for writes of doubles into fields of instances (i.e. putfield). 888 * 889 * @param ref the object which is the subject of the putfield 890 * @param value the new value for the field 891 * @param offset the offset of the field to be modified 892 * @param locationMetadata an int that encodes the source location being modified 893 */ 894 @Inline 895 @Entrypoint 896 public static void doubleFieldWrite(Object ref, double value, Offset offset, int locationMetadata) { 897 if (NEEDS_DOUBLE_GC_WRITE_BARRIER) { 898 ObjectReference src = ObjectReference.fromObject(ref); 899 Selected.Mutator.get().doubleWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 900 } else if (VM.VerifyAssertions) 901 VM._assert(VM.NOT_REACHED); 902 } 903 904 /** 905 * Barrier for writes of doubles into arrays (i.e. dastore). 906 * 907 * @param ref the array which is the subject of the astore 908 * @param index the index into the array where the new reference 909 * resides. The index is the "natural" index into the array, for 910 * example a[index]. 911 * @param value the value to be stored. 912 */ 913 @Inline 914 @Entrypoint 915 public static void doubleArrayWrite(double[] ref, int index, double value) { 916 if (NEEDS_DOUBLE_GC_WRITE_BARRIER) { 917 ObjectReference array = ObjectReference.fromObject(ref); 918 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_DOUBLE); 919 Selected.Mutator.get().doubleWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT); 920 } else if (VM.VerifyAssertions) 921 VM._assert(VM.NOT_REACHED); 922 } 923 924 /** 925 * Barrier for loads of doubles from fields of instances (i.e. getfield). 926 * 927 * @param ref the object which is the subject of the getfield 928 * @param offset the offset of the field to be read 929 * @param locationMetadata an int that encodes the source location being read 930 * @return The value read from the field. 931 */ 932 @Inline 933 @Entrypoint 934 public static double doubleFieldRead(Object ref, Offset offset, int locationMetadata) { 935 if (NEEDS_DOUBLE_GC_READ_BARRIER) { 936 ObjectReference src = ObjectReference.fromObject(ref); 937 return Selected.Mutator.get().doubleRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 938 } else if (VM.VerifyAssertions) 939 VM._assert(VM.NOT_REACHED); 940 return 0; 941 } 942 943 /** 944 * Barrier for loads of doubles from fields of arrays (i.e. daload). 945 * 946 * @param ref the array containing the reference. 947 * @param index the index into the array were the reference resides. 948 * @return the value read from the array 949 */ 950 @Inline 951 @Entrypoint 952 public static double doubleArrayRead(double[] ref, int index) { 953 if (NEEDS_DOUBLE_GC_READ_BARRIER) { 954 ObjectReference array = ObjectReference.fromObject(ref); 955 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_DOUBLE); 956 return Selected.Mutator.get().doubleRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 957 } else if (VM.VerifyAssertions) 958 VM._assert(VM.NOT_REACHED); 959 return 0; 960 } 961 962 /** 963 * Barrier for a bulk copy of doubles (i.e. in an array copy). 964 * 965 * @param src The source array 966 * @param srcOffset The starting source offset 967 * @param dst The destination array 968 * @param dstOffset The starting destination offset 969 * @param bytes The number of bytes to be copied 970 */ 971 @Inline 972 public static void doubleBulkCopy(double[] src, Offset srcOffset, double[] dst, Offset dstOffset, int bytes) { 973 if (VM.VerifyAssertions) VM._assert(DOUBLE_BULK_COPY_SUPPORTED); 974 975 if (!Selected.Mutator.get().doubleBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 976 Memory.aligned64Copy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 977 } 978 } 979 980 /******************************************************************************** 981 * Begin support for org.vmmagic.unboxed types (Word, Address, Extent and Offset) 982 * 983 * These types can be witten or read from Object fields via putfield and getfield 984 * Arrays of these special types should not be created in the normal Java way 985 * (i.e. new Word[]) but should be created using WordArray.create() etc. 986 * 987 * TODO: is there a RVM mechanism that prevents new Word[]? 988 */ 989 990 /** {@code true} if the garbage collector requires write barriers on Word putfield, arraystore or modifycheck */ 991 private static final boolean NEEDS_WORD_GC_WRITE_BARRIER = Selected.Constraints.get().needsWordWriteBarrier(); 992 /** {@code true} if the VM requires write barriers on Word putfield */ 993 public static final boolean NEEDS_WORD_PUTFIELD_BARRIER = NEEDS_WORD_GC_WRITE_BARRIER; 994 /** {@code true} if the garbage collector requires read barriers on Word getfield or arrayload */ 995 private static final boolean NEEDS_WORD_GC_READ_BARRIER = Selected.Constraints.get().needsWordReadBarrier(); 996 /** {@code true} if the VM requires read barriers on Word getfield */ 997 public static final boolean NEEDS_WORD_GETFIELD_BARRIER = NEEDS_WORD_GC_READ_BARRIER; 998 999 /** 1000 * Barrier for writes of Words into fields of instances (i.e. putfield). 1001 * 1002 * @param ref the object which is the subject of the putfield 1003 * @param value the new value for the field 1004 * @param offset the offset of the field to be modified 1005 * @param locationMetadata an int that encodes the source location being modified 1006 */ 1007 @Inline 1008 @Entrypoint 1009 public static void wordFieldWrite(Object ref, Word value, Offset offset, int locationMetadata) { 1010 if (NEEDS_WORD_GC_WRITE_BARRIER) { 1011 ObjectReference src = ObjectReference.fromObject(ref); 1012 Selected.Mutator.get().wordWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1013 } else if (VM.VerifyAssertions) 1014 VM._assert(VM.NOT_REACHED); 1015 } 1016 1017 /** 1018 * Barrier for loads of Words from fields of instances (i.e. getfield). 1019 * 1020 * @param ref the object which is the subject of the getfield 1021 * @param offset the offset of the field to be read 1022 * @param locationMetadata an int that encodes the source location being read 1023 * @return The value read from the field. 1024 */ 1025 @Inline 1026 @Entrypoint 1027 public static Word wordFieldRead(Object ref, Offset offset, int locationMetadata) { 1028 if (NEEDS_WORD_GC_READ_BARRIER) { 1029 ObjectReference src = ObjectReference.fromObject(ref); 1030 return Selected.Mutator.get().wordRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1031 } else if (VM.VerifyAssertions) 1032 VM._assert(VM.NOT_REACHED); 1033 return Word.zero(); 1034 } 1035 1036 /** 1037 * Barrier for conditional compare and exchange of Word fields. 1038 * 1039 * @param ref the object which is the subject of the compare and exchanges 1040 * @param offset the offset of the field to be modified 1041 * @param old the old value to swap out 1042 * @param value the new value for the field 1043 * @return {@code true} if and only if the swap was successful 1044 */ 1045 @Inline 1046 public static boolean wordTryCompareAndSwap(Object ref, Offset offset, Word old, Word value) { 1047 if (NEEDS_WORD_GC_WRITE_BARRIER || NEEDS_WORD_GC_READ_BARRIER) { 1048 ObjectReference src = ObjectReference.fromObject(ref); 1049 return Selected.Mutator.get().wordTryCompareAndSwap(src, src.toAddress().plus(offset), old, value, offset.toWord(), 1050 Word.zero(), // do not have location metadata 1051 INSTANCE_FIELD); 1052 } else if (VM.VerifyAssertions) 1053 VM._assert(VM.NOT_REACHED); 1054 return false; 1055 } 1056 1057 /** {@code true} if the garbage collector requires write barriers on Address putfield, arraystore or modifycheck */ 1058 private static final boolean NEEDS_ADDRESS_GC_WRITE_BARRIER = Selected.Constraints.get().needsAddressWriteBarrier(); 1059 /** {@code true} if the VM requires write barriers on Address putfield */ 1060 public static final boolean NEEDS_ADDRESS_PUTFIELD_BARRIER = NEEDS_ADDRESS_GC_WRITE_BARRIER; 1061 /** {@code true} if the garbage collector requires read barriers on Address getfield or arrayload */ 1062 private static final boolean NEEDS_ADDRESS_GC_READ_BARRIER = Selected.Constraints.get().needsAddressReadBarrier(); 1063 /** {@code true} if the VM requires read barriers on Address getfield */ 1064 public static final boolean NEEDS_ADDRESS_GETFIELD_BARRIER = NEEDS_ADDRESS_GC_READ_BARRIER; 1065 1066 /** 1067 * Barrier for writes of Address's into fields of instances (i.e. putfield). 1068 * 1069 * @param ref the object which is the subject of the putfield 1070 * @param value the new value for the field 1071 * @param offset the offset of the field to be modified 1072 * @param locationMetadata an int that encodes the source location being modified 1073 */ 1074 @Inline 1075 @Entrypoint 1076 public static void addressFieldWrite(Object ref, Address value, Offset offset, int locationMetadata) { 1077 if (NEEDS_ADDRESS_GC_WRITE_BARRIER) { 1078 ObjectReference src = ObjectReference.fromObject(ref); 1079 Selected.Mutator.get().addressWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1080 } else if (VM.VerifyAssertions) 1081 VM._assert(VM.NOT_REACHED); 1082 } 1083 1084 /** 1085 * Barrier for loads of Address's from fields of instances (i.e. getfield). 1086 * 1087 * @param ref the object which is the subject of the getfield 1088 * @param offset the offset of the field to be read 1089 * @param locationMetadata an int that encodes the source location being read 1090 * @return The value read from the field. 1091 */ 1092 @Inline 1093 @Entrypoint 1094 public static Address addressFieldRead(Object ref, Offset offset, int locationMetadata) { 1095 if (NEEDS_ADDRESS_GC_READ_BARRIER) { 1096 ObjectReference src = ObjectReference.fromObject(ref); 1097 return Selected.Mutator.get().addressRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1098 } else if (VM.VerifyAssertions) 1099 VM._assert(VM.NOT_REACHED); 1100 return Address.zero(); 1101 } 1102 1103 /** 1104 * Barrier for conditional compare and exchange of Address fields. 1105 * 1106 * @param ref the object which is the subject of the compare and exchanges 1107 * @param offset the offset of the field to be modified 1108 * @param old the old value to swap out 1109 * @param value the new value for the field 1110 * @return {@code true} if and only if the swap was successful 1111 */ 1112 @Inline 1113 public static boolean addressTryCompareAndSwap(Object ref, Offset offset, Address old, Address value) { 1114 if (NEEDS_ADDRESS_GC_WRITE_BARRIER || NEEDS_ADDRESS_GC_READ_BARRIER) { 1115 ObjectReference src = ObjectReference.fromObject(ref); 1116 return Selected.Mutator.get().addressTryCompareAndSwap(src, src.toAddress().plus(offset), old, value, offset.toWord(), 1117 Word.zero(), // do not have location metadata 1118 INSTANCE_FIELD); 1119 } else if (VM.VerifyAssertions) 1120 VM._assert(VM.NOT_REACHED); 1121 return false; 1122 } 1123 1124 /** {@code true} if the garbage collector requires write barriers on Extent putfield, arraystore or modifycheck */ 1125 private static final boolean NEEDS_EXTENT_GC_WRITE_BARRIER = Selected.Constraints.get().needsExtentWriteBarrier(); 1126 /** {@code true} if the VM requires write barriers on Extent putfield */ 1127 public static final boolean NEEDS_EXTENT_PUTFIELD_BARRIER = NEEDS_EXTENT_GC_WRITE_BARRIER; 1128 /** {@code true} if the garbage collector requires read barriers on Extent getfield or arrayload */ 1129 private static final boolean NEEDS_EXTENT_GC_READ_BARRIER = Selected.Constraints.get().needsExtentReadBarrier(); 1130 /** {@code true} if the VM requires read barriers on Extent getfield */ 1131 public static final boolean NEEDS_EXTENT_GETFIELD_BARRIER = NEEDS_EXTENT_GC_READ_BARRIER; 1132 1133 /** 1134 * Barrier for writes of Extents into fields of instances (i.e. putfield). 1135 * 1136 * @param ref the object which is the subject of the putfield 1137 * @param value the new value for the field 1138 * @param offset the offset of the field to be modified 1139 * @param locationMetadata an int that encodes the source location being modified 1140 */ 1141 @Inline 1142 @Entrypoint 1143 public static void extentFieldWrite(Object ref, Extent value, Offset offset, int locationMetadata) { 1144 if (NEEDS_EXTENT_GC_WRITE_BARRIER) { 1145 ObjectReference src = ObjectReference.fromObject(ref); 1146 Selected.Mutator.get().extentWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1147 } else if (VM.VerifyAssertions) 1148 VM._assert(VM.NOT_REACHED); 1149 } 1150 1151 /** 1152 * Barrier for loads of Extents from fields of instances (i.e. getfield). 1153 * 1154 * @param ref the object which is the subject of the getfield 1155 * @param offset the offset of the field to be read 1156 * @param locationMetadata an int that encodes the source location being read 1157 * @return The value read from the field. 1158 */ 1159 @Inline 1160 @Entrypoint 1161 public static Extent extentFieldRead(Object ref, Offset offset, int locationMetadata) { 1162 if (NEEDS_EXTENT_GC_READ_BARRIER) { 1163 ObjectReference src = ObjectReference.fromObject(ref); 1164 return Selected.Mutator.get().extentRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1165 } else if (VM.VerifyAssertions) 1166 VM._assert(VM.NOT_REACHED); 1167 return Extent.zero(); 1168 } 1169 1170 /** {@code true} if the garbage collector requires write barriers on Offset putfield, arraystore or modifycheck */ 1171 private static final boolean NEEDS_OFFSET_GC_WRITE_BARRIER = Selected.Constraints.get().needsOffsetWriteBarrier(); 1172 /** {@code true} if the VM requires write barriers on Offset putfield */ 1173 public static final boolean NEEDS_OFFSET_PUTFIELD_BARRIER = NEEDS_OFFSET_GC_WRITE_BARRIER; 1174 /** {@code true} if the garbage collector requires read barriers on Offset getfield or arrayload */ 1175 private static final boolean NEEDS_OFFSET_GC_READ_BARRIER = Selected.Constraints.get().needsOffsetReadBarrier(); 1176 /** {@code true} if the VM requires read barriers on Offset getfield */ 1177 public static final boolean NEEDS_OFFSET_GETFIELD_BARRIER = NEEDS_OFFSET_GC_READ_BARRIER; 1178 1179 /** 1180 * Barrier for writes of Offsets into fields of instances (i.e. putfield). 1181 * 1182 * @param ref the object which is the subject of the putfield 1183 * @param value the new value for the field 1184 * @param offset the offset of the field to be modified 1185 * @param locationMetadata an int that encodes the source location being modified 1186 */ 1187 @Inline 1188 @Entrypoint 1189 public static void offsetFieldWrite(Object ref, Offset value, Offset offset, int locationMetadata) { 1190 if (NEEDS_OFFSET_GC_WRITE_BARRIER) { 1191 ObjectReference src = ObjectReference.fromObject(ref); 1192 Selected.Mutator.get().offsetWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1193 } else if (VM.VerifyAssertions) 1194 VM._assert(VM.NOT_REACHED); 1195 } 1196 1197 /** 1198 * Barrier for loads of Offsets from fields of instances (i.e. getfield). 1199 * 1200 * @param ref the object which is the subject of the getfield 1201 * @param offset the offset of the field to be read 1202 * @param locationMetadata an int that encodes the source location being read 1203 * @return The value read from the field. 1204 */ 1205 @Inline 1206 @Entrypoint 1207 public static Offset offsetFieldRead(Object ref, Offset offset, int locationMetadata) { 1208 if (NEEDS_OFFSET_GC_READ_BARRIER) { 1209 ObjectReference src = ObjectReference.fromObject(ref); 1210 return Selected.Mutator.get().offsetRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1211 } else if (VM.VerifyAssertions) 1212 VM._assert(VM.NOT_REACHED); 1213 return Offset.zero(); 1214 } 1215 1216 /** {@code true} if the garbage collector requires write barriers on reference putfield, arraystore or modifycheck */ 1217 private static final boolean NEEDS_OBJECT_GC_WRITE_BARRIER = Selected.Constraints.get().needsObjectReferenceWriteBarrier(); 1218 /** {@code true} if the VM requires write barriers on reference putfield */ 1219 public static final boolean NEEDS_OBJECT_PUTFIELD_BARRIER = NEEDS_OBJECT_GC_WRITE_BARRIER; 1220 /** {@code true} if the VM requires write barriers on reference arraystore */ 1221 public static final boolean NEEDS_OBJECT_ASTORE_BARRIER = NEEDS_OBJECT_GC_WRITE_BARRIER; 1222 /** {@code true} if the garbage collector requires read barriers on reference getfield or arrayload */ 1223 private static final boolean NEEDS_OBJECT_GC_READ_BARRIER = Selected.Constraints.get().needsObjectReferenceReadBarrier(); 1224 /** {@code true} if the VM requires read barriers on reference getfield */ 1225 public static final boolean NEEDS_OBJECT_GETFIELD_BARRIER = NEEDS_OBJECT_GC_READ_BARRIER; 1226 /** {@code true} if the VM requires read barriers on reference arrayload */ 1227 public static final boolean NEEDS_OBJECT_ALOAD_BARRIER = NEEDS_OBJECT_GC_READ_BARRIER; 1228 /** {@code true} if the garbage collector supports the bulk copy operation */ 1229 public static final boolean OBJECT_BULK_COPY_SUPPORTED = !(NEEDS_OBJECT_ASTORE_BARRIER || NEEDS_OBJECT_ALOAD_BARRIER) || Selected.Constraints.get().objectReferenceBulkCopySupported(); 1230 1231 /** 1232 * Barrier for writes of objects into fields of instances (i.e. putfield). 1233 * 1234 * @param ref the object which is the subject of the putfield 1235 * @param value the new value for the field 1236 * @param offset the offset of the field to be modified 1237 * @param locationMetadata an int that encodes the source location being modified 1238 */ 1239 @Inline 1240 @Entrypoint 1241 public static void objectFieldWrite(Object ref, Object value, Offset offset, int locationMetadata) { 1242 if (NEEDS_OBJECT_GC_WRITE_BARRIER) { 1243 ObjectReference src = ObjectReference.fromObject(ref); 1244 Selected.Mutator.get().objectReferenceWrite(src, src.toAddress().plus(offset), ObjectReference.fromObject(value), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD); 1245 } else if (VM.VerifyAssertions) 1246 VM._assert(VM.NOT_REACHED); 1247 } 1248 1249 /** 1250 * Barrier for writes of objects into arrays (i.e. aastore). 1251 * 1252 * @param ref the array which is the subject of the astore 1253 * @param index the index into the array where the new reference 1254 * resides. The index is the "natural" index into the array, for 1255 * example a[index]. 1256 * @param value the value to be stored. 1257 */ 1258 @Inline 1259 @Entrypoint 1260 public static void objectArrayWrite(Object[] ref, int index, Object value) { 1261 if (NEEDS_OBJECT_GC_WRITE_BARRIER) { 1262 ObjectReference array = ObjectReference.fromObject(ref); 1263 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_ADDRESS); 1264 Selected.Mutator.get().objectReferenceWrite(array, array.toAddress().plus(offset), ObjectReference.fromObject(value), offset.toWord(), Word.zero(), ARRAY_ELEMENT); 1265 } else if (VM.VerifyAssertions) 1266 VM._assert(VM.NOT_REACHED); 1267 } 1268 1269 /** 1270 * Barrier for loads of objects from fields of instances (i.e. getfield). 1271 * 1272 * @param ref the object which is the subject of the getfield 1273 * @param offset the offset of the field to be read 1274 * @param locationMetadata an int that encodes the source location being read 1275 * @return The value read from the field. 1276 */ 1277 @Inline 1278 @Entrypoint 1279 public static Object objectFieldRead(Object ref, Offset offset, int locationMetadata) { 1280 if (NEEDS_OBJECT_GC_READ_BARRIER) { 1281 ObjectReference src = ObjectReference.fromObject(ref); 1282 return Selected.Mutator.get().objectReferenceRead(src, src.toAddress().plus(offset), offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD).toObject(); 1283 } else if (VM.VerifyAssertions) 1284 VM._assert(VM.NOT_REACHED); 1285 return null; 1286 } 1287 1288 /** 1289 * Barrier for loads of objects from fields of arrays (i.e. aaload). 1290 * 1291 * @param ref the array containing the reference. 1292 * @param index the index into the array were the reference resides. 1293 * @return the value read from the array 1294 */ 1295 @Inline 1296 @Entrypoint 1297 public static Object objectArrayRead(Object[] ref, int index) { 1298 if (NEEDS_OBJECT_GC_READ_BARRIER) { 1299 ObjectReference array = ObjectReference.fromObject(ref); 1300 Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_ADDRESS); 1301 return Selected.Mutator.get().objectReferenceRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT).toObject(); 1302 } else if (VM.VerifyAssertions) 1303 VM._assert(VM.NOT_REACHED); 1304 return null; 1305 } 1306 1307 /** 1308 * Barrier for a bulk copy of objects (i.e. in an array copy). 1309 * 1310 * @param src The source array 1311 * @param srcOffset The starting source offset 1312 * @param dst The destination array 1313 * @param dstOffset The starting destination offset 1314 * @param bytes The number of bytes to be copied 1315 */ 1316 @Inline 1317 public static void objectBulkCopy(Object[] src, Offset srcOffset, Object[] dst, Offset dstOffset, int bytes) { 1318 if (VM.VerifyAssertions) VM._assert(OBJECT_BULK_COPY_SUPPORTED); 1319 1320 if (!Selected.Mutator.get().objectReferenceBulkCopy(ObjectReference.fromObject(src), srcOffset, ObjectReference.fromObject(dst), dstOffset, bytes)) { 1321 Memory.alignedWordCopy(Magic.objectAsAddress(dst).plus(dstOffset), Magic.objectAsAddress(src).plus(srcOffset), bytes); 1322 } 1323 } 1324 1325 1326 /** {@code true} if the selected plan requires write barriers on reference putstatic */ 1327 private static final boolean NEEDS_OBJECT_GC_PUTSTATIC_BARRIER = Selected.Constraints.get().needsObjectReferenceNonHeapWriteBarrier(); 1328 /** {@code true} if the selected plan requires write barriers on reference putstatic */ 1329 public static final boolean NEEDS_OBJECT_PUTSTATIC_BARRIER = NEEDS_OBJECT_GC_PUTSTATIC_BARRIER; 1330 /** {@code true} if the selected plan requires read barriers on reference getstatic */ 1331 private static final boolean NEEDS_OBJECT_GC_GETSTATIC_BARRIER = Selected.Constraints.get().needsObjectReferenceNonHeapReadBarrier(); 1332 /** {@code true} if the selected plan requires read barriers on reference getstatic */ 1333 public static final boolean NEEDS_OBJECT_GETSTATIC_BARRIER = NEEDS_OBJECT_GC_GETSTATIC_BARRIER; 1334 1335 /** 1336 * Barrier for writes of objects from statics (eg putstatic) 1337 * 1338 * @param value the new value to be stored 1339 * @param offset the offset of the field to be modified 1340 * @param locationMetadata an int that encodes the source location being modified 1341 */ 1342 @Inline 1343 @Entrypoint 1344 public static void objectStaticWrite(Object value, Offset offset, int locationMetadata) { 1345 if (NEEDS_OBJECT_GC_PUTSTATIC_BARRIER) { 1346 ObjectReference src = ObjectReference.fromObject(Magic.getJTOC()); 1347 Selected.Mutator.get().objectReferenceNonHeapWrite(src.toAddress().plus(offset), 1348 ObjectReference.fromObject(value), 1349 offset.toWord(), 1350 Word.fromIntZeroExtend(locationMetadata)); 1351 } else if (VM.VerifyAssertions) 1352 VM._assert(VM.NOT_REACHED); 1353 } 1354 1355 /** 1356 * Barrier for loads of objects from statics (i.e. getstatic) 1357 * 1358 * @param offset the offset of the field to be modified 1359 * @param locationMetadata an int that encodes the source location being read 1360 * @return the value read from the field 1361 */ 1362 @Inline 1363 @Entrypoint 1364 public static Object objectStaticRead(Offset offset, int locationMetadata) { 1365 if (NEEDS_OBJECT_GC_GETSTATIC_BARRIER) { 1366 ObjectReference src = ObjectReference.fromObject(Magic.getJTOC()); 1367 return Selected.Mutator.get().objectReferenceNonHeapRead( 1368 src.toAddress().plus(offset), 1369 offset.toWord(), 1370 Word.fromIntZeroExtend(locationMetadata)).toObject(); 1371 } else if (VM.VerifyAssertions) 1372 VM._assert(VM.NOT_REACHED); 1373 return null; 1374 } 1375 1376 1377 /** 1378 * Barrier for conditional compare and exchange of reference fields. 1379 * 1380 * @param ref the object which is the subject of the compare and exchanges 1381 * @param offset the offset of the field to be modified 1382 * @param old the old value to swap out 1383 * @param value the new value for the field 1384 * @return {@code true} if and only if the swap was successful 1385 */ 1386 @Inline 1387 public static boolean objectTryCompareAndSwap(Object ref, Offset offset, Object old, Object value) { 1388 if (NEEDS_OBJECT_GC_WRITE_BARRIER || NEEDS_OBJECT_GC_READ_BARRIER) { 1389 ObjectReference src = ObjectReference.fromObject(ref); 1390 return Selected.Mutator.get().objectReferenceTryCompareAndSwap(src, 1391 src.toAddress().plus(offset), 1392 ObjectReference.fromObject(old), 1393 ObjectReference.fromObject(value), 1394 offset.toWord(), 1395 Word.zero(), // do not have location metadata 1396 INSTANCE_FIELD); 1397 } else if (VM.VerifyAssertions) 1398 VM._assert(VM.NOT_REACHED); 1399 return false; 1400 } 1401}