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.mmtk.plan.poisoned;
014    
015    import org.mmtk.plan.marksweep.MSMutator;
016    import org.mmtk.vm.VM;
017    
018    import org.vmmagic.pragma.*;
019    import org.vmmagic.unboxed.Address;
020    import org.vmmagic.unboxed.ObjectReference;
021    import org.vmmagic.unboxed.Word;
022    
023    /**
024     * This class implements a poisoned collector, that is essentially a test
025     * case for read and write barriers in the VM.
026     */
027    @Uninterruptible
028    public class PoisonedMutator extends MSMutator {
029    
030      /****************************************************************************
031       *
032       * Write and read barriers. By default do nothing, override if
033       * appropriate.
034       */
035    
036      /**
037       * A new reference is about to be created. Take appropriate write
038       * barrier actions.<p>
039       *
040       * <b>By default do nothing, override if appropriate.</b>
041       *
042       * @param src The object into which the new reference will be stored
043       * @param slot The address into which the new reference will be
044       * stored.
045       * @param tgt The target of the new reference
046       * @param metaDataA A value that assists the host VM in creating a store
047       * @param metaDataB A value that assists the host VM in creating a store
048       * @param mode The context in which the store occurred
049       */
050      @Inline
051      @Override
052      public void objectReferenceWrite(ObjectReference src, Address slot, ObjectReference tgt, Word metaDataA, Word metaDataB, int mode) {
053        VM.barriers.wordWrite(src, Poisoned.poison(tgt), metaDataA, metaDataB, mode);
054      }
055    
056      /**
057       * Attempt to atomically exchange the value in the given slot
058       * with the passed replacement value. If a new reference is
059       * created, we must then take appropriate write barrier actions.<p>
060       *
061       * <b>By default do nothing, override if appropriate.</b>
062       *
063       * @param src The object into which the new reference will be stored
064       * @param slot The address into which the new reference will be
065       * stored.
066       * @param old The old reference to be swapped out
067       * @param tgt The target of the new reference
068       * @param metaDataA A value that assists the host VM in creating a store
069       * @param metaDataB A value that assists the host VM in creating a store
070       * @param mode The context in which the store occurred
071       * @return True if the swap was successful.
072       */
073      @Override
074      public boolean objectReferenceTryCompareAndSwap(ObjectReference src, Address slot, ObjectReference old, ObjectReference tgt,
075                                                   Word metaDataA, Word metaDataB, int mode) {
076        return VM.barriers.wordTryCompareAndSwap(src, Poisoned.poison(old), Poisoned.poison(tgt), metaDataA, metaDataB, mode);
077      }
078    
079      /**
080       * Read a reference. Take appropriate read barrier action, and
081       * return the value that was read.<p> This is a <b>substituting<b>
082       * barrier.  The call to this barrier takes the place of a load.<p>
083       *
084       * @param src The object reference holding the field being read.
085       * @param slot The address of the slot being read.
086       * @param metaDataA A value that assists the host VM in creating a load
087       * @param metaDataB A value that assists the host VM in creating a load
088       * @param mode The context in which the load occurred
089       * @return The reference that was read.
090       */
091      @Inline
092      @Override
093      public ObjectReference objectReferenceRead(ObjectReference src, Address slot, Word metaDataA, Word metaDataB, int mode) {
094        return Poisoned.depoison(VM.barriers.wordRead(src, metaDataA, metaDataB, mode));
095      }
096    }