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.markcompact;
014
015import org.mmtk.plan.*;
016import org.mmtk.policy.MarkCompactCollector;
017
018import org.mmtk.vm.VM;
019
020import org.vmmagic.pragma.*;
021
022/**
023 * This class implements <i>per-collector thread</i> behavior
024 * and state for the <i>MC</i> plan, which implements a full-heap
025 * mark-compact collector.<p>
026 *
027 * Specifically, this class defines <i>MC</i> collection behavior
028 * (through <code>trace</code> and the <code>collectionPhase</code>
029 * method), and collection-time allocation.<p>
030 *
031 * @see MC for an overview of the mark-compact algorithm
032 * @see MCMutator
033 * @see StopTheWorldCollector
034 * @see CollectorContext
035 */
036@Uninterruptible
037public class MCCollector extends StopTheWorldCollector {
038
039  private static final boolean TRACE_MARK = false;
040  private static final boolean TRACE_FORWARD = true;
041
042  /****************************************************************************
043   * Instance fields
044   */
045
046  /**
047   *
048   */
049  private final MCMarkTraceLocal markTrace;
050  private final MCForwardTraceLocal forwardTrace;
051  private final MarkCompactCollector mc;
052  private boolean currentTrace;
053
054  /****************************************************************************
055   *
056   * Initialization
057   */
058
059  /**
060   * Constructor
061   */
062  public MCCollector() {
063    markTrace = new MCMarkTraceLocal(global().markTrace);
064    forwardTrace = new MCForwardTraceLocal(global().forwardTrace);
065    mc = new MarkCompactCollector(MC.mcSpace);
066  }
067
068  /****************************************************************************
069   *
070   * Collection
071   */
072
073  /**
074   * {@inheritDoc}
075   */
076  @Override
077  @Inline
078  public final void collectionPhase(short phaseId, boolean primary) {
079    if (phaseId == MC.PREPARE) {
080      currentTrace = TRACE_MARK;
081      super.collectionPhase(phaseId, primary);
082      markTrace.prepare();
083      return;
084    }
085
086    if (phaseId == MC.CLOSURE) {
087      markTrace.completeTrace();
088      return;
089    }
090
091    if (phaseId == MC.CALCULATE_FP) {
092      mc.calculateForwardingPointers();
093      return;
094    }
095
096    if (phaseId == MC.COMPACT) {
097      mc.compact();
098      return;
099    }
100
101    if (phaseId == MC.RELEASE) {
102      markTrace.release();
103      super.collectionPhase(phaseId, primary);
104      return;
105    }
106
107    if (phaseId == MC.PREPARE_FORWARD) {
108      currentTrace = TRACE_FORWARD;
109      super.collectionPhase(MC.PREPARE, primary);
110      forwardTrace.prepare();
111      return;
112    }
113
114    if (phaseId == MC.FORWARD_CLOSURE) {
115      forwardTrace.completeTrace();
116      return;
117    }
118
119    if (phaseId == MC.RELEASE_FORWARD) {
120      forwardTrace.release();
121      super.collectionPhase(MC.RELEASE, primary);
122      return;
123    }
124
125    super.collectionPhase(phaseId, primary);
126  }
127
128  /****************************************************************************
129   *
130   * Miscellaneous
131   */
132
133  /**
134   * {@inheritDoc}
135   */
136  @Override
137  public final TraceLocal getCurrentTrace() {
138    if (currentTrace == TRACE_MARK) {
139      return markTrace;
140    }
141    return forwardTrace;
142  }
143
144  /** @return The active global plan as an <code>MC</code> instance. */
145  @Inline
146  private static MC global() {
147    return (MC) VM.activePlan.global();
148  }
149}