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 /** 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 /** 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(false);
046 return null;
047 }
048
049 /* bool byte char short int long float double */
050
051 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
082 }
083
084 /**
085 * Barrier for writes of booleans into arrays (ie 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(false);
102 }
103
104 /**
105 * Barrier for loads of booleans from fields of instances (ie 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(false);
120 return false;
121 }
122
123 /**
124 * Barrier for loads of booleans from fields of arrays (ie 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(false);
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.arraycopy8Bit(Magic.objectAsAddress(src).plus(srcOffset), Magic.objectAsAddress(dst).plus(dstOffset), bytes);
157 }
158 }
159
160 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
191 }
192
193 /**
194 * Barrier for writes of bytes into arrays (ie 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(false);
211 }
212
213 /**
214 * Barrier for loads of bytes from fields of instances (ie 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(false);
229 return 0;
230 }
231
232 /**
233 * Barrier for loads of bytes from fields of arrays (ie 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(false);
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.arraycopy8Bit(Magic.objectAsAddress(src).plus(srcOffset), Magic.objectAsAddress(dst).plus(dstOffset), bytes);
266 }
267 }
268
269
270 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
301 }
302
303 /**
304 * Barrier for writes of chars into arrays (ie 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(false);
321 }
322
323 /**
324 * Barrier for loads of chars from fields of instances (ie 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(false);
339 return 0;
340 }
341
342 /**
343 * Barrier for loads of chars from fields of arrays (ie 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(false);
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.arraycopy16Bit(Magic.objectAsAddress(src).plus(srcOffset), Magic.objectAsAddress(dst).plus(dstOffset), bytes);
376 }
377 }
378
379
380 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
411 }
412
413 /**
414 * Barrier for writes of shorts into arrays (ie 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(false);
431 }
432
433 /**
434 * Barrier for loads of shorts from fields of instances (ie 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(false);
449 return 0;
450 }
451
452 /**
453 * Barrier for loads of shorts from fields of arrays (ie 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(false);
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.arraycopy16Bit(Magic.objectAsAddress(src).plus(srcOffset), Magic.objectAsAddress(dst).plus(dstOffset), bytes);
486 }
487 }
488
489
490
491 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
522 }
523
524 /**
525 * Barrier for writes of ints into arrays (ie 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(false);
542 }
543
544 /**
545 * Barrier for loads of ints from fields of instances (ie 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(false);
560 return 0;
561 }
562
563 /**
564 * Barrier for loads of ints from fields of arrays (ie 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(false);
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.arraycopy32Bit(Magic.objectAsAddress(src).plus(srcOffset), Magic.objectAsAddress(dst).plus(dstOffset), 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(false);
616 return false;
617 }
618
619
620 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
651 }
652
653 /**
654 * Barrier for writes of longs into arrays (ie 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(false);
671 }
672
673 /**
674 * Barrier for loads of longs from fields of instances (ie 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(false);
689 return 0;
690 }
691
692 /**
693 * Barrier for loads of longs from fields of arrays (ie 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(false);
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(false);
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.arraycopy64Bit(Magic.objectAsAddress(src).plus(srcOffset), Magic.objectAsAddress(dst).plus(dstOffset), bytes);
744 }
745 }
746
747
748 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
779 }
780
781 /**
782 * Barrier for writes of floats into arrays (ie 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(false);
799 }
800
801 /**
802 * Barrier for loads of floats from fields of instances (ie 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(false);
817 return 0;
818 }
819
820 /**
821 * Barrier for loads of floats from fields of arrays (ie 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(false);
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 srcIdx The starting source index
844 * @param dst The destination array
845 * @param dstIdx The starting source index
846 * @param len The number of array elements 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.arraycopy32Bit(Magic.objectAsAddress(src).plus(srcOffset), Magic.objectAsAddress(dst).plus(dstOffset), bytes);
854 }
855 }
856
857
858 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
889 }
890
891 /**
892 * Barrier for writes of doubles into arrays (ie 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(false);
909 }
910
911 /**
912 * Barrier for loads of doubles from fields of instances (ie 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(false);
927 return 0;
928 }
929
930 /**
931 * Barrier for loads of doubles from fields of arrays (ie 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(false);
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 srcIdx The starting source index
954 * @param dst The destination array
955 * @param dstIdx The starting source index
956 * @param len The number of array elements 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.arraycopy64Bit(Magic.objectAsAddress(src).plus(srcOffset), Magic.objectAsAddress(dst).plus(dstOffset), 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 * (ie 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
1002 }
1003
1004 /**
1005 * Barrier for loads of Words from fields of instances (ie 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(false);
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(false);
1040 return false;
1041 }
1042
1043 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
1068 }
1069
1070 /**
1071 * Barrier for loads of Address's from fields of instances (ie 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(false);
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(false);
1106 return false;
1107 }
1108
1109 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
1134 }
1135
1136 /**
1137 * Barrier for loads of Extents from fields of instances (ie 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(false);
1152 return Extent.zero();
1153 }
1154
1155 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
1180 }
1181
1182 /**
1183 * Barrier for loads of Offsets from fields of instances (ie 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(false);
1198 return Offset.zero();
1199 }
1200
1201 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 /** 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 (ie 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(false);
1232 }
1233
1234 /**
1235 * Barrier for writes of objects into arrays (ie 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(false);
1252 }
1253
1254 /**
1255 * Barrier for loads of objects from fields of instances (ie 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(false);
1270 return null;
1271 }
1272
1273 /**
1274 * Barrier for loads of objects from fields of arrays (ie 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(false);
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 /** 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 /** 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 /** 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 /** 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(false);
1338 }
1339
1340 /**
1341 * Barrier for loads of objects from statics (ie 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(false);
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(false);
1383 return false;
1384 }
1385 }