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