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.MS;
016    
017    import org.vmmagic.pragma.*;
018    import org.vmmagic.unboxed.Address;
019    import org.vmmagic.unboxed.ObjectReference;
020    import org.vmmagic.unboxed.Word;
021    
022    /**
023     * This class implements a poisoned collector, that is essentially a test
024     * case for read and write barriers in the VM.
025     */
026    @Uninterruptible
027    public class Poisoned extends MS {
028      /**
029       * Perform any required write barrier action when installing an object reference
030       * a boot time.
031       *
032       * @param reference the reference value that is to be stored
033       * @return The raw value to be
034       */
035      public Word bootTimeWriteBarrier(Word reference) {
036        return reference.or(Word.one());
037      }
038    
039      /**
040       * Poison a reference value.
041       */
042      @Inline
043      public static Word poison(ObjectReference reference) {
044        return reference.toAddress().toWord().or(Word.one());
045      }
046    
047      /**
048       * DePoison a reference value.
049       */
050      @Inline
051      public static ObjectReference depoison(Word value) {
052        return value.and(Word.one().not()).toAddress().toObjectReference();
053      }
054    
055      /****************************************************************************
056       * Internal read/write barriers.
057       */
058    
059      /**
060       * Store an object reference
061       *
062       * @param slot The location of the reference
063       * @param value The value to store
064       */
065      @Inline
066      public void storeObjectReference(Address slot, ObjectReference value) {
067        slot.store(poison(value));
068      }
069    
070      /**
071       * Load an object reference
072       *
073       * @param slot The location of the reference
074       * @return the object reference loaded from slot
075       */
076      @Inline
077      public ObjectReference loadObjectReference(Address slot) {
078        return depoison(slot.loadWord());
079      }
080    }