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.refcount.generational;
014    
015    import org.mmtk.plan.TraceLocal;
016    import org.mmtk.plan.TransitiveClosure;
017    import org.mmtk.plan.refcount.RCBase;
018    import org.mmtk.plan.refcount.RCBaseCollector;
019    import org.mmtk.plan.refcount.RCHeader;
020    import org.mmtk.policy.ExplicitFreeListLocal;
021    import org.mmtk.policy.ExplicitFreeListSpace;
022    import org.mmtk.utility.ForwardingWord;
023    import org.mmtk.vm.VM;
024    import org.vmmagic.pragma.*;
025    import org.vmmagic.unboxed.Address;
026    import org.vmmagic.unboxed.ObjectReference;
027    
028    /**
029     * This class implements the collector context for a simple reference counting
030     * collector.
031     */
032    @Uninterruptible
033    public class GenRCCollector extends RCBaseCollector {
034      private final GenRCFindRootSetTraceLocal rootTrace;
035      private final GenRCModifiedProcessor modProcessor;
036      private final ExplicitFreeListLocal rc;
037    
038      public GenRCCollector() {
039        rc = new ExplicitFreeListLocal(GenRC.rcSpace);
040        rootTrace = new GenRCFindRootSetTraceLocal(global().rootTrace, newRootBuffer);
041        modProcessor = new GenRCModifiedProcessor(rootTrace);
042      }
043    
044      /****************************************************************************
045       *
046       * Collection
047       */
048    
049      /**
050       * {@inheritDoc}
051       */
052      @Override
053      public final void collectionPhase(short phaseId, boolean primary) {
054        if (phaseId == RCBase.PREPARE) {
055          super.collectionPhase(phaseId, primary);
056          rc.prepare();
057          return;
058        }
059    
060        if (phaseId == RCBase.CLOSURE) {
061          super.collectionPhase(phaseId, primary);
062          rc.flush();
063          return;
064        }
065    
066        if (phaseId == RCBase.RELEASE) {
067          rc.release();
068          super.collectionPhase(phaseId, primary);
069          return;
070        }
071    
072        super.collectionPhase(phaseId, primary);
073      }
074    
075      /****************************************************************************
076       *
077       * Collection-time allocation
078       */
079    
080      /**
081       * {@inheritDoc}
082       */
083      @Override
084      @Inline
085      public final Address allocCopy(ObjectReference original, int bytes,
086          int align, int offset, int allocator) {
087        if (VM.VERIFY_ASSERTIONS) {
088          VM.assertions._assert(allocator == GenRC.ALLOC_RC);
089        }
090        return rc.alloc(bytes, align, offset);
091      }
092    
093      /**
094       * {@inheritDoc}<p>
095       *
096       * In this case nothing is required.
097       */
098      @Override
099      @Inline
100      public final void postCopy(ObjectReference object, ObjectReference typeRef,
101                                 int bytes, int allocator) {
102        ForwardingWord.clearForwardingBits(object);
103        RCHeader.initializeHeader(object, false);
104        RCHeader.makeUnlogged(object);
105        ExplicitFreeListSpace.unsyncSetLiveBit(object);
106      }
107    
108      @Override
109      protected final TransitiveClosure getModifiedProcessor() {
110        return modProcessor;
111      }
112    
113      @Override
114      protected final TraceLocal getRootTrace() {
115        return rootTrace;
116      }
117    }