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 }