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 */
013package org.mmtk.plan.refcount.generational;
014
015import org.mmtk.plan.TraceLocal;
016import org.mmtk.plan.TransitiveClosure;
017import org.mmtk.plan.refcount.RCBase;
018import org.mmtk.plan.refcount.RCBaseCollector;
019import org.mmtk.plan.refcount.RCHeader;
020import org.mmtk.policy.ExplicitFreeListLocal;
021import org.mmtk.policy.ExplicitFreeListSpace;
022import org.mmtk.utility.ForwardingWord;
023import org.mmtk.vm.VM;
024import org.vmmagic.pragma.*;
025import org.vmmagic.unboxed.Address;
026import org.vmmagic.unboxed.ObjectReference;
027
028/**
029 * This class implements the collector context for a simple reference counting
030 * collector.
031 */
032@Uninterruptible
033public 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}