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.semispace;
014
015import org.mmtk.plan.*;
016import org.mmtk.policy.CopyLocal;
017import org.mmtk.policy.LargeObjectLocal;
018import org.mmtk.policy.Space;
019import org.mmtk.utility.ForwardingWord;
020import org.mmtk.vm.VM;
021
022import org.vmmagic.unboxed.*;
023import org.vmmagic.pragma.*;
024
025/**
026 * This class implements <i>per-collector thread</i> behavior
027 * and state for the <i>SS</i> plan, which implements a full-heap
028 * semi-space collector.<p>
029 *
030 * Specifically, this class defines <i>SS</i> collection behavior
031 * (through <code>trace</code> and the <code>collectionPhase</code>
032 * method), and collection-time allocation (copying of objects).<p>
033 *
034 * See {@link SS} for an overview of the semi-space algorithm.
035 *
036 * @see SS
037 * @see SSMutator
038 * @see StopTheWorldCollector
039 * @see CollectorContext
040 */
041@Uninterruptible
042public class SSCollector extends StopTheWorldCollector {
043
044  /****************************************************************************
045   * Instance fields
046   */
047
048  /**
049   *
050   */
051  protected final SSTraceLocal trace;
052  protected final CopyLocal ss;
053  protected final LargeObjectLocal los;
054
055  /****************************************************************************
056   *
057   * Initialization
058   */
059
060  /**
061   * Constructor
062   */
063  public SSCollector() {
064    this(new SSTraceLocal(global().ssTrace));
065  }
066
067  /**
068   * Constructor
069   * @param tr The trace to use
070   */
071  protected SSCollector(SSTraceLocal tr) {
072    ss = new CopyLocal();
073    los = new LargeObjectLocal(Plan.loSpace);
074    trace = tr;
075  }
076
077  /****************************************************************************
078   *
079   * Collection-time allocation
080   */
081
082  /**
083   * {@inheritDoc}
084   */
085  @Override
086  @Inline
087  public Address allocCopy(ObjectReference original, int bytes,
088      int align, int offset, int allocator) {
089    if (allocator == Plan.ALLOC_LOS) {
090      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bytes > Plan.MAX_NON_LOS_COPY_BYTES);
091      return los.alloc(bytes, align, offset);
092    } else {
093      if (VM.VERIFY_ASSERTIONS) {
094        VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
095        VM.assertions._assert(allocator == SS.ALLOC_SS);
096      }
097      return ss.alloc(bytes, align, offset);
098    }
099  }
100
101  @Override
102  @Inline
103  public void postCopy(ObjectReference object, ObjectReference typeRef,
104      int bytes, int allocator) {
105    ForwardingWord.clearForwardingBits(object);
106    if (allocator == Plan.ALLOC_LOS)
107      Plan.loSpace.initializeHeader(object, false);
108  }
109
110  /****************************************************************************
111   *
112   * Collection
113   */
114
115  /**
116   * {@inheritDoc}
117   */
118  @Override
119  @Inline
120  public void collectionPhase(short phaseId, boolean primary) {
121    if (phaseId == SS.PREPARE) {
122      // rebind the copy bump pointer to the appropriate semispace.
123      ss.rebind(SS.toSpace());
124      los.prepare(true);
125      super.collectionPhase(phaseId, primary);
126      return;
127    }
128
129    if (phaseId == SS.CLOSURE) {
130      trace.completeTrace();
131      return;
132    }
133
134    if (phaseId == SS.RELEASE) {
135      trace.release();
136      los.release(true);
137      super.collectionPhase(phaseId, primary);
138      return;
139    }
140
141    super.collectionPhase(phaseId, primary);
142  }
143
144
145  /****************************************************************************
146   *
147   * Object processing and tracing
148   */
149
150  /**
151   * Return {@code true} if the given reference is to an object that is within
152   * one of the semi-spaces.
153   *
154   * @param object The object in question
155   * @return {@code true} if the given reference is to an object that is within
156   * one of the semi-spaces.
157   */
158  public static boolean isSemiSpaceObject(ObjectReference object) {
159    return Space.isInSpace(SS.SS0, object) || Space.isInSpace(SS.SS1, object);
160  }
161
162  /****************************************************************************
163   *
164   * Miscellaneous
165   */
166
167  /** @return The active global plan as an <code>SS</code> instance. */
168  @Inline
169  private static SS global() {
170    return (SS) VM.activePlan.global();
171  }
172
173  @Override
174  public TraceLocal getCurrentTrace() {
175    return trace;
176  }
177}