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    }