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.StopTheWorldMutator;
016import org.mmtk.policy.MarkCompactLocal;
017import org.mmtk.policy.Space;
018
019import org.mmtk.utility.alloc.Allocator;
020
021import org.vmmagic.pragma.*;
022import org.vmmagic.unboxed.*;
023
024/**
025 * This class implements <i>per-mutator thread</i> behavior
026 * and state for the <i>MC</i> plan, which implements a full-heap
027 * mark-compact collector.<p>
028 *
029 * Specifically, this class defines <i>MC</i> mutator-time allocation
030 * and per-mutator thread collection semantics (flushing and restoring
031 * per-mutator allocator state).<p>
032 *
033 * See {@link MC} for an overview of the mark-compact algorithm.
034 *
035 * @see MC
036 * @see MCCollector
037 * @see org.mmtk.plan.StopTheWorldMutator
038 * @see org.mmtk.plan.MutatorContext
039 */
040@Uninterruptible public class MCMutator extends StopTheWorldMutator {
041
042  /****************************************************************************
043   * Instance fields
044   */
045  private final MarkCompactLocal mc;
046
047  /****************************************************************************
048   *
049   * Initialization
050   */
051
052  /**
053   * Constructor
054   */
055  public MCMutator() {
056    mc = new MarkCompactLocal(MC.mcSpace);
057  }
058
059  /****************************************************************************
060   *
061   * Mutator-time allocation
062   */
063
064  /**
065   * {@inheritDoc}<p>
066   *
067   * This class handles the default allocator from the mark sweep space,
068   * and delegates everything else to the superclass.
069   */
070  @Override
071  @Inline
072  public Address alloc(int bytes, int align, int offset, int allocator, int site) {
073    if (allocator == MC.ALLOC_DEFAULT) {
074      return mc.alloc(bytes, align, offset);
075    }
076    return super.alloc(bytes, align, offset, allocator, site);
077  }
078
079  /**
080   * {@inheritDoc}<p>
081   *
082   * Initialize the object header for objects in the mark-sweep space,
083   * and delegate to the superclass for other objects.
084   */
085  @Override
086  @Inline
087  public void postAlloc(ObjectReference ref, ObjectReference typeRef,
088      int bytes, int allocator) {
089    if (allocator == MC.ALLOC_DEFAULT)
090      MC.mcSpace.initializeHeader(ref);
091    else
092      super.postAlloc(ref, typeRef, bytes, allocator);
093  }
094
095  @Override
096  public Allocator getAllocatorFromSpace(Space space) {
097    if (space == MC.mcSpace) return mc;
098    return super.getAllocatorFromSpace(space);
099  }
100
101
102  /****************************************************************************
103   *
104   * Collection
105   */
106
107  /**
108   * {@inheritDoc}
109   */
110  @Override
111  @Inline
112  public final void collectionPhase(short phaseId, boolean primary) {
113    if (phaseId == MC.PREPARE) {
114      mc.prepare();
115      super.collectionPhase(phaseId, primary);
116      return;
117    }
118
119    if (phaseId == MC.RELEASE) {
120      super.collectionPhase(phaseId, primary);
121      return;
122    }
123    super.collectionPhase(phaseId, primary);
124  }
125
126  /**
127   * Flush the pages this mutator has allocated back to the global
128   * dirty page list, where the collectors can find them.
129   */
130  @Override
131  public void flush() {
132    super.flush();
133    mc.flush();
134  }
135
136
137
138}